int PKCS7_add_certificate(PKCS7 *p7, X509 *x509) { int i; STACK_OF(X509) **sk; i = OBJ_obj2nid(p7->type); switch (i) { case NID_pkcs7_signed: sk = &(p7->d.sign->cert); break; case NID_pkcs7_signedAndEnveloped: sk = &(p7->d.signed_and_enveloped->cert); break; default: PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, PKCS7_R_WRONG_CONTENT_TYPE); return (0); } if (*sk == NULL) *sk = sk_X509_new_null(); if (*sk == NULL) { PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE); return 0; } X509_up_ref(x509); if (!sk_X509_push(*sk, x509)) { X509_free(x509); return 0; } return (1); }
static int ssl_set_cert(CERT *c, X509 *x) { EVP_PKEY *pkey; int i; pkey = X509_get0_pubkey(x); if (pkey == NULL) { SSLerr(SSL_F_SSL_SET_CERT, SSL_R_X509_LIB); return (0); } i = ssl_cert_type(x, pkey); if (i < 0) { SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); return 0; } #ifndef OPENSSL_NO_EC if (i == SSL_PKEY_ECC && !EC_KEY_can_sign(EVP_PKEY_get0_EC_KEY(pkey))) { SSLerr(SSL_F_SSL_SET_CERT, SSL_R_ECC_CERT_NOT_FOR_SIGNING); return 0; } #endif if (c->pkeys[i].privatekey != NULL) { /* * The return code from EVP_PKEY_copy_parameters is deliberately * ignored. Some EVP_PKEY types cannot do this. */ EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey); ERR_clear_error(); #ifndef OPENSSL_NO_RSA /* * Don't check the public/private key, this is mostly for smart * cards. */ if (EVP_PKEY_id(c->pkeys[i].privatekey) == EVP_PKEY_RSA && RSA_flags(EVP_PKEY_get0_RSA(c->pkeys[i].privatekey)) & RSA_METHOD_FLAG_NO_CHECK) ; else #endif /* OPENSSL_NO_RSA */ if (!X509_check_private_key(x, c->pkeys[i].privatekey)) { /* * don't fail for a cert/key mismatch, just free current private * key (when switching to a different cert & key, first this * function should be used, then ssl_set_pkey */ EVP_PKEY_free(c->pkeys[i].privatekey); c->pkeys[i].privatekey = NULL; /* clear error queue */ ERR_clear_error(); } } X509_free(c->pkeys[i].x509); X509_up_ref(x); c->pkeys[i].x509 = x; c->key = &(c->pkeys[i]); return 1; }
void HsOpenSSL_X509_ref(X509* x509) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L X509_up_ref(x509); #else CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); #endif }
static int ssl_set_cert(CERT *c, X509 *x) { EVP_PKEY *pkey = X509_get_pubkey(x); if (pkey == NULL) { OPENSSL_PUT_ERROR(SSL, SSL_R_X509_LIB); return 0; } if (!is_key_type_supported(pkey->type)) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); EVP_PKEY_free(pkey); return 0; } if (c->privatekey != NULL) { /* Sanity-check that the private key and the certificate match, unless the * key is opaque (in case of, say, a smartcard). */ if (!EVP_PKEY_is_opaque(c->privatekey) && !X509_check_private_key(x, c->privatekey)) { /* don't fail for a cert/key mismatch, just free current private key * (when switching to a different cert & key, first this function should * be used, then ssl_set_pkey */ EVP_PKEY_free(c->privatekey); c->privatekey = NULL; /* clear error queue */ ERR_clear_error(); } } EVP_PKEY_free(pkey); X509_free(c->x509); c->x509 = X509_up_ref(x); return 1; }
STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms) { STACK_OF(X509) *certs = NULL; CMS_CertificateChoices *cch; STACK_OF(CMS_CertificateChoices) **pcerts; int i; pcerts = cms_get0_certificate_choices(cms); if (!pcerts) return NULL; for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { cch = sk_CMS_CertificateChoices_value(*pcerts, i); if (cch->type == 0) { if (!certs) { certs = sk_X509_new_null(); if (!certs) return NULL; } if (!sk_X509_push(certs, cch->d.certificate)) { sk_X509_pop_free(certs, X509_free); return NULL; } X509_up_ref(cch->d.certificate); } } return certs; }
int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert) { int r; r = CMS_add0_cert(cms, cert); if (r > 0) X509_up_ref(cert); return r; }
void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer) { if (signer) { X509_up_ref(signer); EVP_PKEY_free(si->pkey); si->pkey = X509_get_pubkey(signer); } X509_free(si->signer); si->signer = signer; }
int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert) { if (resp->certs == NULL && (resp->certs = sk_X509_new_null()) == NULL) return 0; if (!sk_X509_push(resp->certs, cert)) return 0; X509_up_ref(cert); return 1; }
static int ssl_set_cert(CERT *c, X509 *x) { EVP_PKEY *pkey; int i; pkey = X509_get_pubkey(x); if (pkey == NULL) { SSLerr(SSL_F_SSL_SET_CERT, SSL_R_X509_LIB); return (0); } i = ssl_cert_type(x, pkey); if (i < 0) { SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); EVP_PKEY_free(pkey); return (0); } if (c->pkeys[i].privatekey != NULL) { EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey); ERR_clear_error(); #ifndef OPENSSL_NO_RSA /* * Don't check the public/private key, this is mostly for smart * cards. */ if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) && (RSA_flags(c->pkeys[i].privatekey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) ; else #endif /* OPENSSL_NO_RSA */ if (!X509_check_private_key(x, c->pkeys[i].privatekey)) { /* * don't fail for a cert/key mismatch, just free current private * key (when switching to a different cert & key, first this * function should be used, then ssl_set_pkey */ EVP_PKEY_free(c->pkeys[i].privatekey); c->pkeys[i].privatekey = NULL; /* clear error queue */ ERR_clear_error(); } } EVP_PKEY_free(pkey); X509_free(c->pkeys[i].x509); X509_up_ref(x); c->pkeys[i].x509 = x; c->key = &(c->pkeys[i]); return (1); }
int X509_OBJECT_up_ref_count(X509_OBJECT *a) { switch (a->type) { default: break; case X509_LU_X509: return X509_up_ref(a->data.x509); case X509_LU_CRL: return X509_CRL_up_ref(a->data.crl); } return 1; }
int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer) { if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1) { TSerr(TS_F_TS_RESP_CTX_SET_SIGNER_CERT, TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE); return 0; } X509_free(ctx->signer_cert); ctx->signer_cert = signer; X509_up_ref(ctx->signer_cert); return 1; }
X509 *SSL_get_peer_certificate(const SSL *ssl) { check_ssl_x509_method(ssl); if (ssl == NULL) { return NULL; } SSL_SESSION *session = SSL_get_session(ssl); if (session == NULL || session->x509_peer == NULL) { return NULL; } X509_up_ref(session->x509_peer); return session->x509_peer; }
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; }
void X509_OBJECT_up_ref_count(X509_OBJECT *a) { switch (a->type) { default: break; case X509_LU_X509: X509_up_ref(a->data.x509); break; case X509_LU_CRL: X509_CRL_up_ref(a->data.crl); break; } }
MONO_API X509 * mono_btls_x509_lookup_by_fingerprint (MonoBtlsX509Lookup *lookup, unsigned char *bytes, int len) { X509_OBJECT obj; X509 *x509; int ret; ret = X509_LOOKUP_by_fingerprint (lookup->lookup, X509_LU_X509, bytes, len, &obj); if (ret != X509_LU_X509) { X509_OBJECT_free_contents (&obj); return NULL; } x509 = X509_up_ref (obj.data.x509); return x509; }
MONO_API X509 * mono_btls_x509_lookup_by_subject (MonoBtlsX509Lookup *lookup, MonoBtlsX509Name *name) { X509_OBJECT obj; X509 *x509; int ret; ret = X509_LOOKUP_by_subject (lookup->lookup, X509_LU_X509, mono_btls_x509_name_peek_name (name), &obj); if (ret != X509_LU_X509) { X509_OBJECT_free_contents (&obj); return NULL; } x509 = X509_up_ref (obj.data.x509); return x509; }
static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *pk, unsigned int flags) { CMS_KeyTransRecipientInfo *ktri; int idtype; ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo); if (!ri->d.ktri) return 0; ri->type = CMS_RECIPINFO_TRANS; ktri = ri->d.ktri; if (flags & CMS_USE_KEYID) { ktri->version = 2; idtype = CMS_RECIPINFO_KEYIDENTIFIER; } else { ktri->version = 0; idtype = CMS_RECIPINFO_ISSUER_SERIAL; } /* * Not a typo: RecipientIdentifier and SignerIdentifier are the same * structure. */ if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype)) return 0; X509_up_ref(recip); CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY); ktri->pkey = pk; ktri->recip = recip; if (flags & CMS_KEY_PARAM) { ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); if (!ktri->pctx) return 0; if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0) return 0; } else if (!cms_env_asn1_ctrl(ri, 0)) return 0; return 1; }
int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) { int ret; EVP_PKEY *pkey = NULL; if (!ASN1_INTEGER_set(p7i->version, 0)) return 0; if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, X509_get_issuer_name(x509))) return 0; ASN1_INTEGER_free(p7i->issuer_and_serial->serial); if (!(p7i->issuer_and_serial->serial = ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) return 0; pkey = X509_get0_pubkey(x509); if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl) { PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); goto err; } ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, 0, p7i); if (ret == -2) { PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); goto err; } if (ret <= 0) { PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, PKCS7_R_ENCRYPTION_CTRL_FAILURE); goto err; } X509_up_ref(x509); p7i->cert = x509; return 1; err: return 0; }
int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert) { OCSP_SIGNATURE *sig; if (req->optionalSignature == NULL) req->optionalSignature = OCSP_SIGNATURE_new(); sig = req->optionalSignature; if (sig == NULL) return 0; if (cert == NULL) return 1; if (sig->certs == NULL && (sig->certs = sk_X509_new_null()) == NULL) return 0; if (!sk_X509_push(sig->certs, cert)) return 0; X509_up_ref(cert); return 1; }
STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl) { check_ssl_x509_method(ssl); if (ssl == NULL) { return NULL; } SSL_SESSION *session = SSL_get_session(ssl); if (session == NULL || session->x509_chain == NULL) { return NULL; } if (!ssl->server) { return session->x509_chain; } /* OpenSSL historically didn't include the leaf certificate in the returned * certificate chain, but only for servers. */ if (session->x509_chain_without_leaf == NULL) { session->x509_chain_without_leaf = sk_X509_new_null(); if (session->x509_chain_without_leaf == NULL) { return NULL; } for (size_t i = 1; i < sk_X509_num(session->x509_chain); i++) { X509 *cert = sk_X509_value(session->x509_chain, i); if (!sk_X509_push(session->x509_chain_without_leaf, cert)) { sk_X509_pop_free(session->x509_chain_without_leaf, X509_free); session->x509_chain_without_leaf = NULL; return NULL; } X509_up_ref(cert); } } return session->x509_chain_without_leaf; }
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; }
int tls13_process_certificate(SSL *ssl, int allow_anonymous) { CBS cbs, context; CBS_init(&cbs, ssl->init_msg, ssl->init_num); if (!CBS_get_u8_length_prefixed(&cbs, &context) || CBS_len(&context) != 0) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); return 0; } const int retain_sha256 = ssl->server && ssl->ctx->retain_only_sha256_of_client_certs; int ret = 0; uint8_t alert; STACK_OF(X509) *chain = ssl_parse_cert_chain( ssl, &alert, retain_sha256 ? ssl->s3->new_session->peer_sha256 : NULL, &cbs); if (chain == NULL) { ssl3_send_alert(ssl, SSL3_AL_FATAL, alert); goto err; } if (CBS_len(&cbs) != 0) { OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); goto err; } if (sk_X509_num(chain) == 0) { if (!allow_anonymous) { OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_CERTIFICATE_REQUIRED); goto err; } /* OpenSSL returns X509_V_OK when no certificates are requested. This is * classed by them as a bug, but it's assumed by at least NGINX. */ ssl->s3->new_session->verify_result = X509_V_OK; /* No certificate, so nothing more to do. */ ret = 1; goto err; } ssl->s3->new_session->peer_sha256_valid = retain_sha256; if (!ssl_verify_cert_chain(ssl, &ssl->s3->new_session->verify_result, chain)) { goto err; } X509_free(ssl->s3->new_session->peer); X509 *leaf = sk_X509_value(chain, 0); X509_up_ref(leaf); ssl->s3->new_session->peer = leaf; sk_X509_pop_free(ssl->s3->new_session->cert_chain, X509_free); ssl->s3->new_session->cert_chain = chain; chain = NULL; ret = 1; err: sk_X509_pop_free(chain, X509_free); return ret; }
/* * 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; }
CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, X509 *signer, EVP_PKEY *pk, const EVP_MD *md, unsigned int flags) { CMS_SignedData *sd; CMS_SignerInfo *si = NULL; X509_ALGOR *alg; int i, type; if (!X509_check_private_key(signer, pk)) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); return NULL; } sd = cms_signed_data_init(cms); if (!sd) goto err; si = M_ASN1_new_of(CMS_SignerInfo); if (!si) goto merr; /* Call for side-effect of computing hash and caching extensions */ X509_check_purpose(signer, -1, -1); X509_up_ref(signer); EVP_PKEY_up_ref(pk); si->pkey = pk; si->signer = signer; si->mctx = EVP_MD_CTX_new(); si->pctx = NULL; if (si->mctx == NULL) { CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE); goto err; } if (flags & CMS_USE_KEYID) { si->version = 3; if (sd->version < 3) sd->version = 3; type = CMS_SIGNERINFO_KEYIDENTIFIER; } else { type = CMS_SIGNERINFO_ISSUER_SERIAL; si->version = 1; } if (!cms_set1_SignerIdentifier(si->sid, signer, type)) goto err; if (md == NULL) { int def_nid; if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0) goto err; md = EVP_get_digestbynid(def_nid); if (md == NULL) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST); goto err; } } if (!md) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET); goto err; } X509_ALGOR_set_md(si->digestAlgorithm, md); /* See if digest is present in digestAlgorithms */ for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { const ASN1_OBJECT *aoid; alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i); X509_ALGOR_get0(&aoid, NULL, NULL, alg); if (OBJ_obj2nid(aoid) == EVP_MD_type(md)) break; } if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) { alg = X509_ALGOR_new(); if (alg == NULL) goto merr; X509_ALGOR_set_md(alg, md); if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) { X509_ALGOR_free(alg); goto merr; } } if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0)) goto err; if (!(flags & CMS_NOATTR)) { /* * Initialize signed attributes structure so other attributes * such as signing time etc are added later even if we add none here. */ if (!si->signedAttrs) { si->signedAttrs = sk_X509_ATTRIBUTE_new_null(); if (!si->signedAttrs) goto merr; } if (!(flags & CMS_NOSMIMECAP)) { STACK_OF(X509_ALGOR) *smcap = NULL; i = CMS_add_standard_smimecap(&smcap); if (i) i = CMS_add_smimecap(si, smcap); sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); if (!i) goto merr; } if (flags & CMS_REUSE_DIGEST) { if (!cms_copy_messageDigest(cms, si)) goto err; if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) && !CMS_SignerInfo_sign(si)) goto err; } } if (!(flags & CMS_NOCERTS)) { /* NB ignore -1 return for duplicate cert */ if (!CMS_add1_cert(cms, signer)) goto merr; } if (flags & CMS_KEY_PARAM) { if (flags & CMS_NOATTR) { si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL); if (si->pctx == NULL) goto err; if (EVP_PKEY_sign_init(si->pctx) <= 0) goto err; if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0) goto err; } else if (EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, pk) <= 0) goto err; } if (!sd->signerInfos) sd->signerInfos = sk_CMS_SignerInfo_new_null(); if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si)) goto merr; return si; merr: CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE); err: M_ASN1_free_of(si, CMS_SignerInfo); return NULL; }
static int execute_test_large_message(const SSL_METHOD *smeth, const SSL_METHOD *cmeth, int read_ahead) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; int testresult = 0; int i; BIO *certbio = BIO_new_file(cert, "r"); X509 *chaincert = NULL; int certlen; if (certbio == NULL) { printf("Can't load the certificate file\n"); goto end; } chaincert = PEM_read_bio_X509(certbio, NULL, NULL, NULL); BIO_free(certbio); certbio = NULL; if (chaincert == NULL) { printf("Unable to load certificate for chain\n"); goto end; } if (!create_ssl_ctx_pair(smeth, cmeth, &sctx, &cctx, cert, privkey)) { printf("Unable to create SSL_CTX pair\n"); goto end; } if(read_ahead) { /* * Test that read_ahead works correctly when dealing with large * records */ SSL_CTX_set_read_ahead(cctx, 1); } /* * We assume the supplied certificate is big enough so that if we add * NUM_EXTRA_CERTS it will make the overall message large enough. The * default buffer size is requested to be 16k, but due to the way BUF_MEM * works, it ends up allocating a little over 21k (16 * 4/3). So, in this test * we need to have a message larger than that. */ certlen = i2d_X509(chaincert, NULL); OPENSSL_assert((certlen * NUM_EXTRA_CERTS) > ((SSL3_RT_MAX_PLAIN_LENGTH * 4) / 3)); for (i = 0; i < NUM_EXTRA_CERTS; i++) { if (!X509_up_ref(chaincert)) { printf("Unable to up ref cert\n"); goto end; } if (!SSL_CTX_add_extra_chain_cert(sctx, chaincert)) { printf("Unable to add extra chain cert %d\n", i); X509_free(chaincert); goto end; } } if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) { printf("Unable to create SSL objects\n"); goto end; } if (!create_ssl_connection(serverssl, clientssl)) { printf("Unable to create SSL connection\n"); goto end; } /* * Calling SSL_clear() first is not required but this tests that SSL_clear() * doesn't leak (when using enable-crypto-mdebug). */ if (!SSL_clear(serverssl)) { printf("Unexpected failure from SSL_clear()\n"); goto end; } testresult = 1; end: X509_free(chaincert); SSL_free(serverssl); SSL_free(clientssl); SSL_CTX_free(sctx); SSL_CTX_free(cctx); return testresult; }
static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl) { int i, n, rc; X509 *cert, *issuer; X509_STORE *store; X509_STORE_CTX *store_ctx; STACK_OF(X509) *chain; ngx_ssl_stapling_t *staple; staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index); cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index); #if OPENSSL_VERSION_NUMBER >= 0x10001000L SSL_CTX_get_extra_chain_certs(ssl->ctx, &chain); #else chain = ssl->ctx->extra_certs; #endif n = sk_X509_num(chain); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0, "SSL get issuer: %d extra certs", n); for (i = 0; i < n; i++) { issuer = sk_X509_value(chain, i); if (X509_check_issued(issuer, cert) == X509_V_OK) { #if OPENSSL_VERSION_NUMBER >= 0x10100001L X509_up_ref(issuer); #else CRYPTO_add(&issuer->references, 1, CRYPTO_LOCK_X509); #endif ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0, "SSL get issuer: found %p in extra certs", issuer); staple->cert = cert; staple->issuer = issuer; return NGX_OK; } } store = SSL_CTX_get_cert_store(ssl->ctx); if (store == NULL) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_get_cert_store() failed"); return NGX_ERROR; } store_ctx = X509_STORE_CTX_new(); if (store_ctx == NULL) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_STORE_CTX_new() failed"); return NGX_ERROR; } if (X509_STORE_CTX_init(store_ctx, store, NULL, NULL) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_STORE_CTX_init() failed"); X509_STORE_CTX_free(store_ctx); return NGX_ERROR; } rc = X509_STORE_CTX_get1_issuer(&issuer, store_ctx, cert); if (rc == -1) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_STORE_CTX_get1_issuer() failed"); X509_STORE_CTX_free(store_ctx); return NGX_ERROR; } if (rc == 0) { ngx_log_error(NGX_LOG_WARN, ssl->log, 0, "\"ssl_stapling\" ignored, issuer certificate not found"); X509_STORE_CTX_free(store_ctx); return NGX_DECLINED; } X509_STORE_CTX_free(store_ctx); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0, "SSL get issuer: found %p in cert store", issuer); staple->cert = cert; staple->issuer = issuer; return NGX_OK; }
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; }
int tls13_process_certificate(SSL *ssl) { CBS cbs, context; CBS_init(&cbs, ssl->init_msg, ssl->init_num); if (!CBS_get_u8_length_prefixed(&cbs, &context) || CBS_len(&context) != 0) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); return 0; } int ret = 0; uint8_t alert; STACK_OF(X509) *chain = ssl_parse_cert_chain( ssl, &alert, ssl->ctx->retain_only_sha256_of_client_certs ? ssl->s3->new_session->peer_sha256 : NULL, &cbs); if (chain == NULL) { ssl3_send_alert(ssl, SSL3_AL_FATAL, alert); goto err; } if (CBS_len(&cbs) != 0) { OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); goto err; } if (sk_X509_num(chain) == 0) { /* Clients must receive a certificate from the server. */ if (!ssl->server) { OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); goto err; } /* Servers may be configured to accept anonymous clients. */ if ((ssl->verify_mode & SSL_VERIFY_PEER) && (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); goto err; } /* No certificate, so nothing more to do. */ ret = 1; goto err; } if (ssl->server && ssl->ctx->retain_only_sha256_of_client_certs) { /* The hash was filled in by |ssl_parse_cert_chain|. */ ssl->s3->new_session->peer_sha256_valid = 1; } X509 *leaf = sk_X509_value(chain, 0); if (!ssl->server && !ssl_check_leaf_certificate(ssl, leaf)) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); goto err; } int verify_ret = ssl_verify_cert_chain(ssl, chain); /* If |SSL_VERIFY_NONE|, the error is non-fatal, but we keep the result. */ if (ssl->verify_mode != SSL_VERIFY_NONE && verify_ret <= 0) { int al = ssl_verify_alarm_type(ssl->verify_result); ssl3_send_alert(ssl, SSL3_AL_FATAL, al); OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED); goto err; } ERR_clear_error(); ssl->s3->new_session->verify_result = ssl->verify_result; X509_free(ssl->s3->new_session->peer); /* For historical reasons, the client and server differ on whether the chain * includes the leaf. */ if (ssl->server) { ssl->s3->new_session->peer = sk_X509_shift(chain); } else { ssl->s3->new_session->peer = X509_up_ref(leaf); } sk_X509_pop_free(ssl->s3->new_session->cert_chain, X509_free); ssl->s3->new_session->cert_chain = chain; chain = NULL; ret = 1; err: sk_X509_pop_free(chain, X509_free); return ret; }
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 = 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; }