CERT *ssl_cert_dup(CERT *cert) { CERT *ret = OPENSSL_malloc(sizeof(CERT)); if (ret == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return NULL; } memset(ret, 0, sizeof(CERT)); ret->mask_k = cert->mask_k; ret->mask_a = cert->mask_a; if (cert->dh_tmp != NULL) { ret->dh_tmp = DHparams_dup(cert->dh_tmp); if (ret->dh_tmp == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB); goto err; } } ret->dh_tmp_cb = cert->dh_tmp_cb; if (cert->x509 != NULL) { ret->x509 = X509_up_ref(cert->x509); } if (cert->privatekey != NULL) { ret->privatekey = EVP_PKEY_up_ref(cert->privatekey); } if (cert->chain) { ret->chain = X509_chain_up_ref(cert->chain); if (!ret->chain) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } ret->key_method = cert->key_method; ret->cert_cb = cert->cert_cb; ret->cert_cb_arg = cert->cert_cb_arg; if (cert->verify_store != NULL) { X509_STORE_up_ref(cert->verify_store); ret->verify_store = cert->verify_store; } return ret; err: ssl_cert_free(ret); return NULL; }
CERT *ssl_cert_dup(CERT *cert) { CERT *ret = OPENSSL_zalloc(sizeof(*ret)); int i; if (ret == NULL) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); return NULL; } ret->references = 1; ret->key = &ret->pkeys[cert->key - cert->pkeys]; ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); OPENSSL_free(ret); return NULL; } #ifndef OPENSSL_NO_DH if (cert->dh_tmp != NULL) { ret->dh_tmp = cert->dh_tmp; EVP_PKEY_up_ref(ret->dh_tmp); } ret->dh_tmp_cb = cert->dh_tmp_cb; ret->dh_tmp_auto = cert->dh_tmp_auto; #endif for (i = 0; i < SSL_PKEY_NUM; i++) { CERT_PKEY *cpk = cert->pkeys + i; CERT_PKEY *rpk = ret->pkeys + i; if (cpk->x509 != NULL) { rpk->x509 = cpk->x509; X509_up_ref(rpk->x509); } if (cpk->privatekey != NULL) { rpk->privatekey = cpk->privatekey; EVP_PKEY_up_ref(cpk->privatekey); } if (cpk->chain) { rpk->chain = X509_chain_up_ref(cpk->chain); if (!rpk->chain) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); goto err; } } if (cert->pkeys[i].serverinfo != NULL) { /* Just copy everything. */ ret->pkeys[i].serverinfo = OPENSSL_malloc(cert->pkeys[i].serverinfo_length); if (ret->pkeys[i].serverinfo == NULL) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); goto err; } ret->pkeys[i].serverinfo_length = cert->pkeys[i].serverinfo_length; memcpy(ret->pkeys[i].serverinfo, cert->pkeys[i].serverinfo, cert->pkeys[i].serverinfo_length); } } /* Configured sigalgs copied across */ if (cert->conf_sigalgs) { ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen * sizeof(*cert->conf_sigalgs)); if (ret->conf_sigalgs == NULL) goto err; memcpy(ret->conf_sigalgs, cert->conf_sigalgs, cert->conf_sigalgslen * sizeof(*cert->conf_sigalgs)); ret->conf_sigalgslen = cert->conf_sigalgslen; } else ret->conf_sigalgs = NULL; if (cert->client_sigalgs) { ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen * sizeof(*cert->client_sigalgs)); if (ret->client_sigalgs == NULL) goto err; memcpy(ret->client_sigalgs, cert->client_sigalgs, cert->client_sigalgslen * sizeof(*cert->client_sigalgs)); ret->client_sigalgslen = cert->client_sigalgslen; } else ret->client_sigalgs = NULL; /* Shared sigalgs also NULL */ ret->shared_sigalgs = NULL; /* Copy any custom client certificate types */ if (cert->ctype) { ret->ctype = OPENSSL_memdup(cert->ctype, cert->ctype_len); if (ret->ctype == NULL) goto err; ret->ctype_len = cert->ctype_len; } ret->cert_flags = cert->cert_flags; ret->cert_cb = cert->cert_cb; ret->cert_cb_arg = cert->cert_cb_arg; if (cert->verify_store) { X509_STORE_up_ref(cert->verify_store); ret->verify_store = cert->verify_store; } if (cert->chain_store) { X509_STORE_up_ref(cert->chain_store); ret->chain_store = cert->chain_store; } ret->sec_cb = cert->sec_cb; ret->sec_level = cert->sec_level; ret->sec_ex = cert->sec_ex; if (!custom_exts_copy(&ret->custext, &cert->custext)) goto err; #ifndef OPENSSL_NO_PSK if (cert->psk_identity_hint) { ret->psk_identity_hint = OPENSSL_strdup(cert->psk_identity_hint); if (ret->psk_identity_hint == NULL) goto err; } #endif return ret; err: ssl_cert_free(ret); return NULL; }
CERT *ssl_cert_dup(CERT *cert) { CERT *ret; int i; ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); if (ret == NULL) { OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_MALLOC_FAILURE); return NULL; } memset(ret, 0, sizeof(CERT)); ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]]; /* or ret->key = ret->pkeys + (cert->key - cert->pkeys), if you find that * more readable */ ret->mask_k = cert->mask_k; ret->mask_a = cert->mask_a; if (cert->dh_tmp != NULL) { ret->dh_tmp = DHparams_dup(cert->dh_tmp); if (ret->dh_tmp == NULL) { OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_DH_LIB); goto err; } if (cert->dh_tmp->priv_key) { BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); if (!b) { OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_BN_LIB); goto err; } ret->dh_tmp->priv_key = b; } if (cert->dh_tmp->pub_key) { BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); if (!b) { OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_BN_LIB); goto err; } ret->dh_tmp->pub_key = b; } } ret->dh_tmp_cb = cert->dh_tmp_cb; if (cert->ecdh_tmp) { ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp); if (ret->ecdh_tmp == NULL) { OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_EC_LIB); goto err; } } ret->ecdh_tmp_cb = cert->ecdh_tmp_cb; ret->ecdh_tmp_auto = cert->ecdh_tmp_auto; for (i = 0; i < SSL_PKEY_NUM; i++) { CERT_PKEY *cpk = cert->pkeys + i; CERT_PKEY *rpk = ret->pkeys + i; if (cpk->x509 != NULL) { rpk->x509 = X509_up_ref(cpk->x509); } if (cpk->privatekey != NULL) { rpk->privatekey = EVP_PKEY_dup(cpk->privatekey); } if (cpk->chain) { rpk->chain = X509_chain_up_ref(cpk->chain); if (!rpk->chain) { OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_MALLOC_FAILURE); goto err; } } } /* Peer sigalgs set to NULL as we get these from handshake too */ ret->peer_sigalgs = NULL; ret->peer_sigalgslen = 0; /* Configured sigalgs however we copy across */ if (cert->conf_sigalgs) { ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen); if (!ret->conf_sigalgs) { goto err; } memcpy(ret->conf_sigalgs, cert->conf_sigalgs, cert->conf_sigalgslen); ret->conf_sigalgslen = cert->conf_sigalgslen; } else { ret->conf_sigalgs = NULL; } if (cert->client_sigalgs) { ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen); if (!ret->client_sigalgs) { goto err; } memcpy(ret->client_sigalgs, cert->client_sigalgs, cert->client_sigalgslen); ret->client_sigalgslen = cert->client_sigalgslen; } else { ret->client_sigalgs = NULL; } /* Shared sigalgs also NULL */ ret->shared_sigalgs = NULL; /* Copy any custom client certificate types */ if (cert->client_certificate_types) { ret->client_certificate_types = BUF_memdup( cert->client_certificate_types, cert->num_client_certificate_types); if (!ret->client_certificate_types) { goto err; } ret->num_client_certificate_types = cert->num_client_certificate_types; } ret->cert_flags = cert->cert_flags; ret->cert_cb = cert->cert_cb; ret->cert_cb_arg = cert->cert_cb_arg; if (cert->verify_store) { CRYPTO_add(&cert->verify_store->references, 1, CRYPTO_LOCK_X509_STORE); ret->verify_store = cert->verify_store; } if (cert->chain_store) { CRYPTO_add(&cert->chain_store->references, 1, CRYPTO_LOCK_X509_STORE); ret->chain_store = cert->chain_store; } ret->ciphers_raw = NULL; return ret; err: ssl_cert_free(ret); return NULL; }
CERT *ssl_cert_dup(CERT *cert) { CERT *ret; int i; ret = OPENSSL_malloc(sizeof(CERT)); if (ret == NULL) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); return (NULL); } memset(ret, 0, sizeof(CERT)); ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]]; /* * or ret->key = ret->pkeys + (cert->key - cert->pkeys), if you find that * more readable */ ret->valid = cert->valid; ret->mask_k = cert->mask_k; ret->mask_a = cert->mask_a; ret->export_mask_k = cert->export_mask_k; ret->export_mask_a = cert->export_mask_a; #ifndef OPENSSL_NO_RSA if (cert->rsa_tmp != NULL) { RSA_up_ref(cert->rsa_tmp); ret->rsa_tmp = cert->rsa_tmp; } ret->rsa_tmp_cb = cert->rsa_tmp_cb; #endif #ifndef OPENSSL_NO_DH if (cert->dh_tmp != NULL) { ret->dh_tmp = DHparams_dup(cert->dh_tmp); if (ret->dh_tmp == NULL) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB); goto err; } if (cert->dh_tmp->priv_key) { BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); if (!b) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); goto err; } ret->dh_tmp->priv_key = b; } if (cert->dh_tmp->pub_key) { BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); if (!b) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); goto err; } ret->dh_tmp->pub_key = b; } } ret->dh_tmp_cb = cert->dh_tmp_cb; ret->dh_tmp_auto = cert->dh_tmp_auto; #endif #ifndef OPENSSL_NO_EC if (cert->ecdh_tmp) { ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp); if (ret->ecdh_tmp == NULL) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB); goto err; } } ret->ecdh_tmp_cb = cert->ecdh_tmp_cb; ret->ecdh_tmp_auto = cert->ecdh_tmp_auto; #endif for (i = 0; i < SSL_PKEY_NUM; i++) { CERT_PKEY *cpk = cert->pkeys + i; CERT_PKEY *rpk = ret->pkeys + i; if (cpk->x509 != NULL) { rpk->x509 = cpk->x509; CRYPTO_add(&rpk->x509->references, 1, CRYPTO_LOCK_X509); } if (cpk->privatekey != NULL) { rpk->privatekey = cpk->privatekey; CRYPTO_add(&cpk->privatekey->references, 1, CRYPTO_LOCK_EVP_PKEY); } if (cpk->chain) { rpk->chain = X509_chain_up_ref(cpk->chain); if (!rpk->chain) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); goto err; } } rpk->valid_flags = 0; #ifndef OPENSSL_NO_TLSEXT if (cert->pkeys[i].serverinfo != NULL) { /* Just copy everything. */ ret->pkeys[i].serverinfo = OPENSSL_malloc(cert->pkeys[i].serverinfo_length); if (ret->pkeys[i].serverinfo == NULL) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); goto err; } ret->pkeys[i].serverinfo_length = cert->pkeys[i].serverinfo_length; memcpy(ret->pkeys[i].serverinfo, cert->pkeys[i].serverinfo, cert->pkeys[i].serverinfo_length); } #endif } ret->references = 1; /* * Set digests to defaults. NB: we don't copy existing values as they * will be set during handshake. */ ssl_cert_set_default_md(ret); /* Peer sigalgs set to NULL as we get these from handshake too */ ret->peer_sigalgs = NULL; ret->peer_sigalgslen = 0; /* Configured sigalgs however we copy across */ if (cert->conf_sigalgs) { ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen); if (!ret->conf_sigalgs) goto err; memcpy(ret->conf_sigalgs, cert->conf_sigalgs, cert->conf_sigalgslen); ret->conf_sigalgslen = cert->conf_sigalgslen; } else ret->conf_sigalgs = NULL; if (cert->client_sigalgs) { ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen); if (!ret->client_sigalgs) goto err; memcpy(ret->client_sigalgs, cert->client_sigalgs, cert->client_sigalgslen); ret->client_sigalgslen = cert->client_sigalgslen; } else ret->client_sigalgs = NULL; /* Shared sigalgs also NULL */ ret->shared_sigalgs = NULL; /* Copy any custom client certificate types */ if (cert->ctypes) { ret->ctypes = OPENSSL_malloc(cert->ctype_num); if (!ret->ctypes) goto err; memcpy(ret->ctypes, cert->ctypes, cert->ctype_num); ret->ctype_num = cert->ctype_num; } ret->cert_flags = cert->cert_flags; ret->cert_cb = cert->cert_cb; ret->cert_cb_arg = cert->cert_cb_arg; if (cert->verify_store) { CRYPTO_add(&cert->verify_store->references, 1, CRYPTO_LOCK_X509_STORE); ret->verify_store = cert->verify_store; } if (cert->chain_store) { CRYPTO_add(&cert->chain_store->references, 1, CRYPTO_LOCK_X509_STORE); ret->chain_store = cert->chain_store; } ret->ciphers_raw = NULL; ret->sec_cb = cert->sec_cb; ret->sec_level = cert->sec_level; ret->sec_ex = cert->sec_ex; #ifndef OPENSSL_NO_TLSEXT if (!custom_exts_copy(&ret->cli_ext, &cert->cli_ext)) goto err; if (!custom_exts_copy(&ret->srv_ext, &cert->srv_ext)) goto err; #endif return (ret); err: ssl_cert_free(ret); return NULL; }
CERT *ssl_cert_dup(CERT *cert) { CERT *ret; int i; ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); if (ret == NULL) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); return(NULL); } memset(ret, 0, sizeof(CERT)); ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]]; /* or ret->key = ret->pkeys + (cert->key - cert->pkeys), * if you find that more readable */ ret->valid = cert->valid; ret->mask_k = cert->mask_k; ret->mask_a = cert->mask_a; ret->export_mask_k = cert->export_mask_k; ret->export_mask_a = cert->export_mask_a; #ifndef OPENSSL_NO_RSA if (cert->rsa_tmp != NULL) { RSA_up_ref(cert->rsa_tmp); ret->rsa_tmp = cert->rsa_tmp; } ret->rsa_tmp_cb = cert->rsa_tmp_cb; #endif #ifndef OPENSSL_NO_DH if (cert->dh_tmp != NULL) { ret->dh_tmp = DHparams_dup(cert->dh_tmp); if (ret->dh_tmp == NULL) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB); goto err; } if (cert->dh_tmp->priv_key) { BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); if (!b) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); goto err; } ret->dh_tmp->priv_key = b; } if (cert->dh_tmp->pub_key) { BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); if (!b) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); goto err; } ret->dh_tmp->pub_key = b; } } ret->dh_tmp_cb = cert->dh_tmp_cb; ret->dh_tmp_auto = cert->dh_tmp_auto; #endif #ifndef OPENSSL_NO_ECDH if (cert->ecdh_tmp) { ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp); if (ret->ecdh_tmp == NULL) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB); goto err; } } ret->ecdh_tmp_cb = cert->ecdh_tmp_cb; ret->ecdh_tmp_auto = cert->ecdh_tmp_auto; #endif for (i = 0; i < SSL_PKEY_NUM; i++) { CERT_PKEY *cpk = cert->pkeys + i; CERT_PKEY *rpk = ret->pkeys + i; if (cpk->x509 != NULL) { rpk->x509 = cpk->x509; CRYPTO_add(&rpk->x509->references, 1, CRYPTO_LOCK_X509); } if (cpk->privatekey != NULL) { rpk->privatekey = cpk->privatekey; CRYPTO_add(&cpk->privatekey->references, 1, CRYPTO_LOCK_EVP_PKEY); switch(i) { /* If there was anything special to do for * certain types of keys, we'd do it here. * (Nothing at the moment, I think.) */ case SSL_PKEY_RSA_ENC: case SSL_PKEY_RSA_SIGN: /* We have an RSA key. */ break; case SSL_PKEY_DSA_SIGN: /* We have a DSA key. */ break; case SSL_PKEY_DH_RSA: case SSL_PKEY_DH_DSA: /* We have a DH key. */ break; case SSL_PKEY_ECC: /* We have an ECC key */ break; default: /* Can't happen. */ SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG); } } if (cpk->chain) { rpk->chain = X509_chain_up_ref(cpk->chain); if (!rpk->chain) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); goto err; } } rpk->valid_flags = 0; #ifndef OPENSSL_NO_TLSEXT if (cert->pkeys[i].serverinfo != NULL) { /* Just copy everything. */ ret->pkeys[i].serverinfo = OPENSSL_malloc(cert->pkeys[i].serverinfo_length); if (ret->pkeys[i].serverinfo == NULL) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); return NULL; } ret->pkeys[i].serverinfo_length = cert->pkeys[i].serverinfo_length; memcpy(ret->pkeys[i].serverinfo, cert->pkeys[i].serverinfo, cert->pkeys[i].serverinfo_length); } #endif } ret->references=1; /* Set digests to defaults. NB: we don't copy existing values as they * will be set during handshake. */ ssl_cert_set_default_md(ret); /* Peer sigalgs set to NULL as we get these from handshake too */ ret->peer_sigalgs = NULL; ret->peer_sigalgslen = 0; /* Configured sigalgs however we copy across */ if (cert->conf_sigalgs) { ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen); if (!ret->conf_sigalgs) goto err; memcpy(ret->conf_sigalgs, cert->conf_sigalgs, cert->conf_sigalgslen); ret->conf_sigalgslen = cert->conf_sigalgslen; } else ret->conf_sigalgs = NULL; if (cert->client_sigalgs) { ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen); if (!ret->client_sigalgs) goto err; memcpy(ret->client_sigalgs, cert->client_sigalgs, cert->client_sigalgslen); ret->client_sigalgslen = cert->client_sigalgslen; } else ret->client_sigalgs = NULL; /* Shared sigalgs also NULL */ ret->shared_sigalgs = NULL; /* Copy any custom client certificate types */ if (cert->ctypes) { ret->ctypes = OPENSSL_malloc(cert->ctype_num); if (!ret->ctypes) goto err; memcpy(ret->ctypes, cert->ctypes, cert->ctype_num); ret->ctype_num = cert->ctype_num; } ret->cert_flags = cert->cert_flags; ret->cert_cb = cert->cert_cb; ret->cert_cb_arg = cert->cert_cb_arg; if (cert->verify_store) { CRYPTO_add(&cert->verify_store->references, 1, CRYPTO_LOCK_X509_STORE); ret->verify_store = cert->verify_store; } if (cert->chain_store) { CRYPTO_add(&cert->chain_store->references, 1, CRYPTO_LOCK_X509_STORE); ret->chain_store = cert->chain_store; } ret->ciphers_raw = NULL; ret->sec_cb = cert->sec_cb; ret->sec_level = cert->sec_level; ret->sec_ex = cert->sec_ex; return(ret); #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH) err: #endif #ifndef OPENSSL_NO_RSA if (ret->rsa_tmp != NULL) RSA_free(ret->rsa_tmp); #endif #ifndef OPENSSL_NO_DH if (ret->dh_tmp != NULL) DH_free(ret->dh_tmp); #endif #ifndef OPENSSL_NO_ECDH if (ret->ecdh_tmp != NULL) EC_KEY_free(ret->ecdh_tmp); #endif ssl_cert_clear_certs(ret); return NULL; }
CERT *ssl_cert_dup(CERT *cert) { CERT *ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); if (ret == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return NULL; } memset(ret, 0, sizeof(CERT)); ret->mask_k = cert->mask_k; ret->mask_a = cert->mask_a; if (cert->dh_tmp != NULL) { ret->dh_tmp = DHparams_dup(cert->dh_tmp); if (ret->dh_tmp == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB); goto err; } if (cert->dh_tmp->priv_key) { BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); if (!b) { OPENSSL_PUT_ERROR(SSL, ERR_R_BN_LIB); goto err; } ret->dh_tmp->priv_key = b; } if (cert->dh_tmp->pub_key) { BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); if (!b) { OPENSSL_PUT_ERROR(SSL, ERR_R_BN_LIB); goto err; } ret->dh_tmp->pub_key = b; } } ret->dh_tmp_cb = cert->dh_tmp_cb; ret->ecdh_nid = cert->ecdh_nid; ret->ecdh_tmp_cb = cert->ecdh_tmp_cb; if (cert->x509 != NULL) { ret->x509 = X509_up_ref(cert->x509); } if (cert->privatekey != NULL) { ret->privatekey = EVP_PKEY_up_ref(cert->privatekey); } if (cert->chain) { ret->chain = X509_chain_up_ref(cert->chain); if (!ret->chain) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } /* Copy over signature algorithm configuration. */ if (cert->conf_sigalgs) { ret->conf_sigalgs = BUF_memdup(cert->conf_sigalgs, cert->conf_sigalgslen); if (!ret->conf_sigalgs) { goto err; } ret->conf_sigalgslen = cert->conf_sigalgslen; } if (cert->client_sigalgs) { ret->client_sigalgs = BUF_memdup(cert->client_sigalgs, cert->client_sigalgslen); if (!ret->client_sigalgs) { goto err; } ret->client_sigalgslen = cert->client_sigalgslen; } /* Copy any custom client certificate types */ if (cert->client_certificate_types) { ret->client_certificate_types = BUF_memdup( cert->client_certificate_types, cert->num_client_certificate_types); if (!ret->client_certificate_types) { goto err; } ret->num_client_certificate_types = cert->num_client_certificate_types; } ret->cert_cb = cert->cert_cb; ret->cert_cb_arg = cert->cert_cb_arg; if (cert->verify_store) { CRYPTO_refcount_inc(&cert->verify_store->references); ret->verify_store = cert->verify_store; } if (cert->chain_store) { CRYPTO_refcount_inc(&cert->chain_store->references); ret->chain_store = cert->chain_store; } return ret; err: ssl_cert_free(ret); return NULL; }
CERT *ssl_cert_dup(CERT *cert) { CERT *ret = OPENSSL_zalloc(sizeof(*ret)); int i; if (ret == NULL) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); return (NULL); } ret->references = 1; ret->key = &ret->pkeys[cert->key - cert->pkeys]; #ifndef OPENSSL_NO_DH if (cert->dh_tmp != NULL) { ret->dh_tmp = DHparams_dup(cert->dh_tmp); if (ret->dh_tmp == NULL) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB); goto err; } if (cert->dh_tmp->priv_key) { BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); if (!b) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); goto err; } ret->dh_tmp->priv_key = b; } if (cert->dh_tmp->pub_key) { BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); if (!b) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); goto err; } ret->dh_tmp->pub_key = b; } } ret->dh_tmp_cb = cert->dh_tmp_cb; ret->dh_tmp_auto = cert->dh_tmp_auto; #endif for (i = 0; i < SSL_PKEY_NUM; i++) { CERT_PKEY *cpk = cert->pkeys + i; CERT_PKEY *rpk = ret->pkeys + i; if (cpk->x509 != NULL) { rpk->x509 = cpk->x509; X509_up_ref(rpk->x509); } if (cpk->privatekey != NULL) { rpk->privatekey = cpk->privatekey; CRYPTO_add(&cpk->privatekey->references, 1, CRYPTO_LOCK_EVP_PKEY); } if (cpk->chain) { rpk->chain = X509_chain_up_ref(cpk->chain); if (!rpk->chain) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); goto err; } } if (cert->pkeys[i].serverinfo != NULL) { /* Just copy everything. */ ret->pkeys[i].serverinfo = OPENSSL_malloc(cert->pkeys[i].serverinfo_length); if (ret->pkeys[i].serverinfo == NULL) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); goto err; } ret->pkeys[i].serverinfo_length = cert->pkeys[i].serverinfo_length; memcpy(ret->pkeys[i].serverinfo, cert->pkeys[i].serverinfo, cert->pkeys[i].serverinfo_length); } } /* Configured sigalgs copied across */ if (cert->conf_sigalgs) { ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen); if (ret->conf_sigalgs == NULL) goto err; memcpy(ret->conf_sigalgs, cert->conf_sigalgs, cert->conf_sigalgslen); ret->conf_sigalgslen = cert->conf_sigalgslen; } else ret->conf_sigalgs = NULL; if (cert->client_sigalgs) { ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen); if (ret->client_sigalgs == NULL) goto err; memcpy(ret->client_sigalgs, cert->client_sigalgs, cert->client_sigalgslen); ret->client_sigalgslen = cert->client_sigalgslen; } else ret->client_sigalgs = NULL; /* Shared sigalgs also NULL */ ret->shared_sigalgs = NULL; /* Copy any custom client certificate types */ if (cert->ctypes) { ret->ctypes = OPENSSL_malloc(cert->ctype_num); if (ret->ctypes == NULL) goto err; memcpy(ret->ctypes, cert->ctypes, cert->ctype_num); ret->ctype_num = cert->ctype_num; } ret->cert_flags = cert->cert_flags; ret->cert_cb = cert->cert_cb; ret->cert_cb_arg = cert->cert_cb_arg; if (cert->verify_store) { CRYPTO_add(&cert->verify_store->references, 1, CRYPTO_LOCK_X509_STORE); ret->verify_store = cert->verify_store; } if (cert->chain_store) { CRYPTO_add(&cert->chain_store->references, 1, CRYPTO_LOCK_X509_STORE); ret->chain_store = cert->chain_store; } ret->sec_cb = cert->sec_cb; ret->sec_level = cert->sec_level; ret->sec_ex = cert->sec_ex; if (!custom_exts_copy(&ret->cli_ext, &cert->cli_ext)) goto err; if (!custom_exts_copy(&ret->srv_ext, &cert->srv_ext)) goto err; #ifndef OPENSSL_NO_PSK if (cert->psk_identity_hint) { ret->psk_identity_hint = OPENSSL_strdup(cert->psk_identity_hint); if (ret->psk_identity_hint == NULL) goto err; } #endif return (ret); err: ssl_cert_free(ret); return NULL; }
/* * 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; #ifndef OPENSSL_NO_SRP dest->srp_username = NULL; #endif 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 (src->peer != NULL) X509_up_ref(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) { 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; } #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; }
CERT * ssl_cert_dup(CERT *cert) { CERT *ret; int i; ret = calloc(1, sizeof(CERT)); if (ret == NULL) { SSLerrorx(ERR_R_MALLOC_FAILURE); return (NULL); } /* * same as ret->key = ret->pkeys + (cert->key - cert->pkeys), * if you find that more readable */ ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]]; ret->valid = cert->valid; ret->mask_k = cert->mask_k; ret->mask_a = cert->mask_a; if (cert->dh_tmp != NULL) { ret->dh_tmp = DHparams_dup(cert->dh_tmp); if (ret->dh_tmp == NULL) { SSLerrorx(ERR_R_DH_LIB); goto err; } if (cert->dh_tmp->priv_key) { BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); if (!b) { SSLerrorx(ERR_R_BN_LIB); goto err; } ret->dh_tmp->priv_key = b; } if (cert->dh_tmp->pub_key) { BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); if (!b) { SSLerrorx(ERR_R_BN_LIB); goto err; } ret->dh_tmp->pub_key = b; } } ret->dh_tmp_cb = cert->dh_tmp_cb; ret->dh_tmp_auto = cert->dh_tmp_auto; for (i = 0; i < SSL_PKEY_NUM; i++) { if (cert->pkeys[i].x509 != NULL) { ret->pkeys[i].x509 = cert->pkeys[i].x509; CRYPTO_add(&ret->pkeys[i].x509->references, 1, CRYPTO_LOCK_X509); } if (cert->pkeys[i].privatekey != NULL) { ret->pkeys[i].privatekey = cert->pkeys[i].privatekey; CRYPTO_add(&ret->pkeys[i].privatekey->references, 1, CRYPTO_LOCK_EVP_PKEY); switch (i) { /* * If there was anything special to do for * certain types of keys, we'd do it here. * (Nothing at the moment, I think.) */ case SSL_PKEY_RSA_ENC: case SSL_PKEY_RSA_SIGN: /* We have an RSA key. */ break; case SSL_PKEY_DH_RSA: /* We have a DH key. */ break; case SSL_PKEY_ECC: /* We have an ECC key */ break; default: /* Can't happen. */ SSLerrorx(SSL_R_LIBRARY_BUG); } } if (cert->pkeys[i].chain != NULL) { if ((ret->pkeys[i].chain = X509_chain_up_ref(cert->pkeys[i].chain)) == NULL) goto err; } } /* * ret->extra_certs *should* exist, but currently the own certificate * chain is held inside SSL_CTX */ ret->references = 1; return (ret); err: DH_free(ret->dh_tmp); for (i = 0; i < SSL_PKEY_NUM; i++) { X509_free(ret->pkeys[i].x509); EVP_PKEY_free(ret->pkeys[i].privatekey); sk_X509_pop_free(ret->pkeys[i].chain, X509_free); } free (ret); return NULL; }
CERT *ssl_cert_dup(CERT *cert) { CERT *ret; int i; ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); if (ret == NULL) { OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_MALLOC_FAILURE); return(NULL); } memset(ret, 0, sizeof(CERT)); ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]]; /* or ret->key = ret->pkeys + (cert->key - cert->pkeys), * if you find that more readable */ ret->mask_k = cert->mask_k; ret->mask_a = cert->mask_a; if (cert->dh_tmp != NULL) { ret->dh_tmp = DHparams_dup(cert->dh_tmp); if (ret->dh_tmp == NULL) { OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_DH_LIB); goto err; } if (cert->dh_tmp->priv_key) { BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); if (!b) { OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_BN_LIB); goto err; } ret->dh_tmp->priv_key = b; } if (cert->dh_tmp->pub_key) { BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); if (!b) { OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_BN_LIB); goto err; } ret->dh_tmp->pub_key = b; } } ret->dh_tmp_cb = cert->dh_tmp_cb; if (cert->ecdh_tmp) { ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp); if (ret->ecdh_tmp == NULL) { OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_EC_LIB); goto err; } } ret->ecdh_tmp_cb = cert->ecdh_tmp_cb; ret->ecdh_tmp_auto = cert->ecdh_tmp_auto; for (i = 0; i < SSL_PKEY_NUM; i++) { CERT_PKEY *cpk = cert->pkeys + i; CERT_PKEY *rpk = ret->pkeys + i; if (cpk->x509 != NULL) { rpk->x509 = X509_up_ref(cpk->x509); } if (cpk->privatekey != NULL) { rpk->privatekey = cpk->privatekey; CRYPTO_add(&cpk->privatekey->references, 1, CRYPTO_LOCK_EVP_PKEY); switch(i) { /* If there was anything special to do for * certain types of keys, we'd do it here. * (Nothing at the moment, I think.) */ case SSL_PKEY_RSA_ENC: case SSL_PKEY_RSA_SIGN: /* We have an RSA key. */ break; case SSL_PKEY_ECC: /* We have an ECC key */ break; default: /* Can't happen. */ OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, SSL_R_LIBRARY_BUG); } } if (cpk->chain) { rpk->chain = X509_chain_up_ref(cpk->chain); if (!rpk->chain) { OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_MALLOC_FAILURE); goto err; } } } /* Peer sigalgs set to NULL as we get these from handshake too */ ret->peer_sigalgs = NULL; ret->peer_sigalgslen = 0; /* Configured sigalgs however we copy across */ if (cert->conf_sigalgs) { ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen); if (!ret->conf_sigalgs) goto err; memcpy(ret->conf_sigalgs, cert->conf_sigalgs, cert->conf_sigalgslen); ret->conf_sigalgslen = cert->conf_sigalgslen; } else ret->conf_sigalgs = NULL; if (cert->client_sigalgs) { ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen); if (!ret->client_sigalgs) goto err; memcpy(ret->client_sigalgs, cert->client_sigalgs, cert->client_sigalgslen); ret->client_sigalgslen = cert->client_sigalgslen; } else ret->client_sigalgs = NULL; /* Shared sigalgs also NULL */ ret->shared_sigalgs = NULL; /* Copy any custom client certificate types */ if (cert->client_certificate_types) { ret->client_certificate_types = BUF_memdup( cert->client_certificate_types, cert->num_client_certificate_types); if (!ret->client_certificate_types) goto err; ret->num_client_certificate_types = cert->num_client_certificate_types; } ret->cert_flags = cert->cert_flags; ret->cert_cb = cert->cert_cb; ret->cert_cb_arg = cert->cert_cb_arg; if (cert->verify_store) { CRYPTO_add(&cert->verify_store->references, 1, CRYPTO_LOCK_X509_STORE); ret->verify_store = cert->verify_store; } if (cert->chain_store) { CRYPTO_add(&cert->chain_store->references, 1, CRYPTO_LOCK_X509_STORE); ret->chain_store = cert->chain_store; } ret->ciphers_raw = NULL; return(ret); err: ssl_cert_free(ret); return NULL; }