/* Convert unsigned char buf's that shouldn't contain any NUL-bytes to char. */ static char *dup_str(const unsigned char *in, size_t len) { char *ret; if(len == 0) return NULL; /* Assert that the string does not contain NUL-bytes. */ OPENSSL_assert(OPENSSL_strnlen((const char*)(in), len) == len); ret = OPENSSL_strndup((const char*)(in), len); OPENSSL_assert(ret != NULL); return ret; }
static int int_x509_param_set_hosts(X509_VERIFY_PARAM *vpm, int mode, const char *name, size_t namelen) { char *copy; /* * Refuse names with embedded NUL bytes, except perhaps as final byte. * XXX: Do we need to push an error onto the error stack? */ if (namelen == 0 || name == NULL) namelen = name ? strlen(name) : 0; else if (name && memchr(name, '\0', namelen > 1 ? namelen - 1 : namelen)) return 0; if (namelen > 0 && name[namelen - 1] == '\0') --namelen; if (mode == SET_HOST) { sk_OPENSSL_STRING_pop_free(vpm->hosts, str_free); vpm->hosts = NULL; } if (name == NULL || namelen == 0) return 1; copy = OPENSSL_strndup(name, namelen); if (copy == NULL) return 0; if (vpm->hosts == NULL && (vpm->hosts = sk_OPENSSL_STRING_new_null()) == NULL) { OPENSSL_free(copy); return 0; } if (!sk_OPENSSL_STRING_push(vpm->hosts, copy)) { OPENSSL_free(copy); if (sk_OPENSSL_STRING_num(vpm->hosts) == 0) { sk_OPENSSL_STRING_free(vpm->hosts); vpm->hosts = NULL; } return 0; } return 1; }
static int cryptodev_select_digest_cb(const char *str, int len, void *usr) { int *digest_list = (int *)usr; char *name; const EVP_MD *EVP; size_t i; if (len == 0) return 1; if (usr == NULL || (name = OPENSSL_strndup(str, len)) == NULL) return 0; EVP = EVP_get_digestbyname(name); if (EVP == NULL) fprintf(stderr, "devcrypto: unknown digest %s\n", name); else if ((i = find_digest_data_index(EVP_MD_type(EVP))) != (size_t)-1) digest_list[i] = 1; else fprintf(stderr, "devcrypto: digest %s not available\n", name); OPENSSL_free(name); return 1; }
static int execute_heartbeat(HEARTBEAT_TEST_FIXTURE fixture) { int result = 0; SSL *s = fixture.s; unsigned char *payload = fixture.payload; unsigned char sent_buf[MAX_PRINTABLE_CHARACTERS + 1]; int return_value; unsigned const char *p; int actual_payload_len; s->rlayer.rrec.data = payload; s->rlayer.rrec.length = strlen((const char *)payload); *payload++ = TLS1_HB_REQUEST; s2n(fixture.sent_payload_len, payload); /* * Make a local copy of the request, since it gets overwritten at some * point */ memcpy(sent_buf, payload, sizeof(sent_buf)); return_value = fixture.process_heartbeat(s, s->rlayer.rrec.data, s->rlayer.rrec.length); if (return_value != fixture.expected_return_value) { printf("%s failed: expected return value %d, received %d\n", fixture.test_case_name, fixture.expected_return_value, return_value); result = 1; } /* * If there is any byte alignment, it will be stored in wbuf.offset. */ p = &(s->rlayer. wbuf.buf[fixture.return_payload_offset + s->rlayer.wbuf.offset]); actual_payload_len = 0; n2s(p, actual_payload_len); if (actual_payload_len != fixture.expected_payload_len) { printf("%s failed:\n expected payload len: %d\n received: %d\n", fixture.test_case_name, fixture.expected_payload_len, actual_payload_len); print_payload("sent", sent_buf, strlen((const char *)sent_buf)); print_payload("received", p, actual_payload_len); result = 1; } else { char *actual_payload = OPENSSL_strndup((const char *)p, actual_payload_len); if (strcmp(actual_payload, fixture.expected_return_payload) != 0) { printf ("%s failed:\n expected payload: \"%s\"\n received: \"%s\"\n", fixture.test_case_name, fixture.expected_return_payload, actual_payload); result = 1; } OPENSSL_free(actual_payload); } if (result != 0) { printf("** %s failed **\n--------\n", fixture.test_case_name); } return result; }
/*- * The specs in hostserv can take these forms: * * host:service => *host = "host", *service = "service" * host:* => *host = "host", *service = NULL * host: => *host = "host", *service = NULL * :service => *host = NULL, *service = "service" * *:service => *host = NULL, *service = "service" * * in case no : is present in the string, the result depends on * hostserv_prio, as follows: * * when hostserv_prio == BIO_PARSE_PRIO_HOST * host => *host = "host", *service untouched * * when hostserv_prio == BIO_PARSE_PRIO_SERV * service => *host untouched, *service = "service" * */ int BIO_parse_hostserv(const char *hostserv, char **host, char **service, enum BIO_hostserv_priorities hostserv_prio) { const char *h = NULL; size_t hl = 0; const char *p = NULL; size_t pl = 0; if (*hostserv == '[') { if ((p = strchr(hostserv, ']')) == NULL) goto spec_err; h = hostserv + 1; hl = p - h; p++; if (*p == '\0') p = NULL; else if (*p != ':') goto spec_err; else { p++; pl = strlen(p); } } else { const char *p2 = strrchr(hostserv, ':'); p = strchr(hostserv, ':'); /*- * Check for more than one colon. There are three possible * interpretations: * 1. IPv6 address with port number, last colon being separator. * 2. IPv6 address only. * 3. IPv6 address only if hostserv_prio == BIO_PARSE_PRIO_HOST, * IPv6 address and port number if hostserv_prio == BIO_PARSE_PRIO_SERV * Because of this ambiguity, we currently choose to make it an * error. */ if (p != p2) goto amb_err; if (p != NULL) { h = hostserv; hl = p - h; p++; pl = strlen(p); } else if (hostserv_prio == BIO_PARSE_PRIO_HOST) { h = hostserv; hl = strlen(h); } else { p = hostserv; pl = strlen(p); } } if (p != NULL && strchr(p, ':')) goto spec_err; if (h != NULL && host != NULL) { if (hl == 0 || (hl == 1 && h[0] == '*')) { *host = NULL; } else { *host = OPENSSL_strndup(h, hl); if (*host == NULL) goto memerr; } } if (p != NULL && service != NULL) { if (pl == 0 || (pl == 1 && p[0] == '*')) { *service = NULL; } else { *service = OPENSSL_strndup(p, pl); if (*service == NULL) goto memerr; } } return 1; amb_err: BIOerr(BIO_F_BIO_PARSE_HOSTSERV, BIO_R_AMBIGUOUS_HOST_OR_SERVICE); return 0; spec_err: BIOerr(BIO_F_BIO_PARSE_HOSTSERV, BIO_R_MALFORMED_HOST_OR_SERVICE); return 0; memerr: BIOerr(BIO_F_BIO_PARSE_HOSTSERV, ERR_R_MALLOC_FAILURE); return 0; }
static void prepare_digest_methods(void) { size_t i; struct session_op sess1, sess2; #ifdef CIOCGSESSINFO struct session_info_op siop; #endif struct cphash_op cphash; memset(&digest_driver_info, 0, sizeof(digest_driver_info)); memset(&sess1, 0, sizeof(sess1)); memset(&sess2, 0, sizeof(sess2)); for (i = 0, known_digest_nids_amount = 0; i < OSSL_NELEM(digest_data); i++) { selected_digests[i] = 1; /* * Check that the digest is usable */ sess1.mac = digest_data[i].devcryptoid; sess2.ses = 0; if (ioctl(cfd, CIOCGSESSION, &sess1) < 0) { digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION; goto finish; } #ifdef CIOCGSESSINFO /* gather hardware acceleration info from the driver */ siop.ses = sess1.ses; if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) { digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN; } else { digest_driver_info[i].driver_name = OPENSSL_strndup(siop.hash_info.cra_driver_name, CRYPTODEV_MAX_ALG_NAME); if (siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY) digest_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED; else digest_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED; } #endif /* digest must be capable of hash state copy */ sess2.mac = sess1.mac; if (ioctl(cfd, CIOCGSESSION, &sess2) < 0) { digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE; goto finish; } cphash.src_ses = sess1.ses; cphash.dst_ses = sess2.ses; if (ioctl(cfd, CIOCCPHASH, &cphash) < 0) { digest_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCCPHASH; goto finish; } if ((known_digest_methods[i] = EVP_MD_meth_new(digest_data[i].nid, NID_undef)) == NULL || !EVP_MD_meth_set_input_blocksize(known_digest_methods[i], digest_data[i].blocksize) || !EVP_MD_meth_set_result_size(known_digest_methods[i], digest_data[i].digestlen) || !EVP_MD_meth_set_init(known_digest_methods[i], digest_init) || !EVP_MD_meth_set_update(known_digest_methods[i], digest_update) || !EVP_MD_meth_set_final(known_digest_methods[i], digest_final) || !EVP_MD_meth_set_copy(known_digest_methods[i], digest_copy) || !EVP_MD_meth_set_cleanup(known_digest_methods[i], digest_cleanup) || !EVP_MD_meth_set_app_datasize(known_digest_methods[i], sizeof(struct digest_ctx))) { digest_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE; EVP_MD_meth_free(known_digest_methods[i]); known_digest_methods[i] = NULL; goto finish; } digest_driver_info[i].status = DEVCRYPTO_STATUS_USABLE; finish: ioctl(cfd, CIOCFSESSION, &sess1.ses); if (sess2.ses != 0) ioctl(cfd, CIOCFSESSION, &sess2.ses); if (devcrypto_test_digest(i)) known_digest_nids[known_digest_nids_amount++] = digest_data[i].nid; } }
static void prepare_cipher_methods(void) { size_t i; struct session_op sess; unsigned long cipher_mode; #ifdef CIOCGSESSINFO struct session_info_op siop; #endif memset(&cipher_driver_info, 0, sizeof(cipher_driver_info)); memset(&sess, 0, sizeof(sess)); sess.key = (void *)"01234567890123456789012345678901234567890123456789"; for (i = 0, known_cipher_nids_amount = 0; i < OSSL_NELEM(cipher_data); i++) { selected_ciphers[i] = 1; /* * Check that the cipher is usable */ sess.cipher = cipher_data[i].devcryptoid; sess.keylen = cipher_data[i].keylen; if (ioctl(cfd, CIOCGSESSION, &sess) < 0) { cipher_driver_info[i].status = DEVCRYPTO_STATUS_NO_CIOCGSESSION; continue; } cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE; if ((known_cipher_methods[i] = EVP_CIPHER_meth_new(cipher_data[i].nid, cipher_mode == EVP_CIPH_CTR_MODE ? 1 : cipher_data[i].blocksize, cipher_data[i].keylen)) == NULL || !EVP_CIPHER_meth_set_iv_length(known_cipher_methods[i], cipher_data[i].ivlen) || !EVP_CIPHER_meth_set_flags(known_cipher_methods[i], cipher_data[i].flags | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1) || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init) || !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i], cipher_mode == EVP_CIPH_CTR_MODE ? ctr_do_cipher : cipher_do_cipher) || !EVP_CIPHER_meth_set_ctrl(known_cipher_methods[i], cipher_ctrl) || !EVP_CIPHER_meth_set_cleanup(known_cipher_methods[i], cipher_cleanup) || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i], sizeof(struct cipher_ctx))) { cipher_driver_info[i].status = DEVCRYPTO_STATUS_FAILURE; EVP_CIPHER_meth_free(known_cipher_methods[i]); known_cipher_methods[i] = NULL; } else { cipher_driver_info[i].status = DEVCRYPTO_STATUS_USABLE; #ifdef CIOCGSESSINFO siop.ses = sess.ses; if (ioctl(cfd, CIOCGSESSINFO, &siop) < 0) { cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATION_UNKNOWN; } else { cipher_driver_info[i].driver_name = OPENSSL_strndup(siop.cipher_info.cra_driver_name, CRYPTODEV_MAX_ALG_NAME); if (!(siop.flags & SIOP_FLAG_KERNEL_DRIVER_ONLY)) cipher_driver_info[i].accelerated = DEVCRYPTO_NOT_ACCELERATED; else cipher_driver_info[i].accelerated = DEVCRYPTO_ACCELERATED; } #endif /* CIOCGSESSINFO */ } ioctl(cfd, CIOCFSESSION, &sess.ses); if (devcrypto_test_cipher(i)) { known_cipher_nids[known_cipher_nids_amount++] = cipher_data[i].nid; } } }
/* * Create a new SSL_SESSION and duplicate the contents of |src| into it. If * ticket == 0 then no ticket information is duplicated, otherwise it is. */ SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) { SSL_SESSION *dest; dest = OPENSSL_malloc(sizeof(*src)); if (dest == NULL) { goto err; } memcpy(dest, src, sizeof(*dest)); /* * Set the various pointers to NULL so that we can call SSL_SESSION_free in * the case of an error whilst halfway through constructing dest */ #ifndef OPENSSL_NO_PSK dest->psk_identity_hint = NULL; dest->psk_identity = NULL; #endif dest->ciphers = NULL; dest->ext.hostname = NULL; #ifndef OPENSSL_NO_EC dest->ext.ecpointformats = NULL; dest->ext.supportedgroups = NULL; #endif dest->ext.tick = NULL; dest->ext.alpn_selected = NULL; #ifndef OPENSSL_NO_SRP dest->srp_username = NULL; #endif dest->peer_chain = NULL; dest->peer = NULL; dest->ext.tick_nonce = NULL; memset(&dest->ex_data, 0, sizeof(dest->ex_data)); /* We deliberately don't copy the prev and next pointers */ dest->prev = NULL; dest->next = NULL; dest->references = 1; dest->lock = CRYPTO_THREAD_lock_new(); if (dest->lock == NULL) goto err; if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, dest, &dest->ex_data)) goto err; if (src->peer != NULL) { if (!X509_up_ref(src->peer)) goto err; dest->peer = src->peer; } if (src->peer_chain != NULL) { dest->peer_chain = X509_chain_up_ref(src->peer_chain); if (dest->peer_chain == NULL) goto err; } #ifndef OPENSSL_NO_PSK if (src->psk_identity_hint) { dest->psk_identity_hint = OPENSSL_strdup(src->psk_identity_hint); if (dest->psk_identity_hint == NULL) { goto err; } } if (src->psk_identity) { dest->psk_identity = OPENSSL_strdup(src->psk_identity); if (dest->psk_identity == NULL) { goto err; } } #endif if (src->ciphers != NULL) { dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers); if (dest->ciphers == NULL) goto err; } if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, &dest->ex_data, &src->ex_data)) { goto err; } if (src->ext.hostname) { dest->ext.hostname = OPENSSL_strdup(src->ext.hostname); if (dest->ext.hostname == NULL) { goto err; } } #ifndef OPENSSL_NO_EC if (src->ext.ecpointformats) { dest->ext.ecpointformats = OPENSSL_memdup(src->ext.ecpointformats, src->ext.ecpointformats_len); if (dest->ext.ecpointformats == NULL) goto err; } if (src->ext.supportedgroups) { dest->ext.supportedgroups = OPENSSL_memdup(src->ext.supportedgroups, src->ext.supportedgroups_len); if (dest->ext.supportedgroups == NULL) goto err; } #endif if (ticket != 0 && src->ext.tick != NULL) { dest->ext.tick = OPENSSL_memdup(src->ext.tick, src->ext.ticklen); if (dest->ext.tick == NULL) goto err; } else { dest->ext.tick_lifetime_hint = 0; dest->ext.ticklen = 0; } if (src->ext.alpn_selected) { dest->ext.alpn_selected = (unsigned char*)OPENSSL_strndup((char*)src->ext.alpn_selected, src->ext.alpn_selected_len); if (dest->ext.alpn_selected == NULL) { goto err; } } if (src->ext.tick_nonce != NULL) { dest->ext.tick_nonce = OPENSSL_memdup(src->ext.tick_nonce, src->ext.tick_nonce_len); if (dest->ext.tick_nonce == NULL) goto err; } #ifndef OPENSSL_NO_SRP if (src->srp_username) { dest->srp_username = OPENSSL_strdup(src->srp_username); if (dest->srp_username == NULL) { goto err; } } #endif return dest; err: SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE); SSL_SESSION_free(dest); return NULL; }