struct ntb_key * ntb_key_copy(struct ntb_key *key) { key = ntb_memdup(key, sizeof *key); ntb_ref_count_init(&key->ref_count); key->label = ntb_strdup(key->label); key->signing_key = EC_KEY_dup(key->signing_key); assert(key->signing_key); key->encryption_key = EC_KEY_dup(key->encryption_key); assert(key->encryption_key); return key; }
CKey::CKey(const CKey& b) { pkey = EC_KEY_dup(b.pkey); if (pkey == NULL) throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed"); fSet = b.fSet; }
static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { EC_PKEY_CTX *dctx, *sctx; if (!pkey_ec_init(dst)) return 0; sctx = src->data; dctx = dst->data; if (sctx->gen_group) { dctx->gen_group = EC_GROUP_dup(sctx->gen_group); if (!dctx->gen_group) return 0; } dctx->md = sctx->md; if (sctx->co_key) { dctx->co_key = EC_KEY_dup(sctx->co_key); if (!dctx->co_key) return 0; } dctx->kdf_type = sctx->kdf_type; dctx->kdf_md = sctx->kdf_md; dctx->kdf_outlen = sctx->kdf_outlen; if (sctx->kdf_ukm) { dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen); if (!dctx->kdf_ukm) return 0; } else dctx->kdf_ukm = NULL; dctx->kdf_ukmlen = sctx->kdf_ukmlen; return 1; }
/* call-seq: * OpenSSL::PKey::EC.new() * OpenSSL::PKey::EC.new(ec_key) * OpenSSL::PKey::EC.new(ec_group) * OpenSSL::PKey::EC.new("secp112r1") * OpenSSL::PKey::EC.new(pem_string) * OpenSSL::PKey::EC.new(pem_string [, pwd]) * OpenSSL::PKey::EC.new(der_string) * * See the OpenSSL documentation for: * EC_KEY_* */ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; EC_KEY *ec; VALUE arg, pass; GetPKey(self, pkey); if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) ossl_raise(eECError, "EC_KEY already initialized"); rb_scan_args(argc, argv, "02", &arg, &pass); if (NIL_P(arg)) { if (!(ec = EC_KEY_new())) ossl_raise(eECError, NULL); } else if (rb_obj_is_kind_of(arg, cEC)) { EC_KEY *other_ec = NULL; SafeRequire_EC_KEY(arg, other_ec); if (!(ec = EC_KEY_dup(other_ec))) ossl_raise(eECError, NULL); } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) { ec = ec_key_new_from_group(arg); } else { BIO *in; pass = ossl_pem_passwd_value(pass); in = ossl_obj2bio(arg); ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass); if (!ec) { OSSL_BIO_reset(in); ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, (void *)pass); } if (!ec) { OSSL_BIO_reset(in); ec = d2i_ECPrivateKey_bio(in, NULL); } if (!ec) { OSSL_BIO_reset(in); ec = d2i_EC_PUBKEY_bio(in, NULL); } BIO_free(in); if (!ec) { ossl_clear_error(); ec = ec_key_new_from_group(arg); } } if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { EC_KEY_free(ec); ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); } rb_iv_set(self, "@group", Qnil); return self; }
ec_key::ec_key (const ec_key& that) { if (that.ptr == nullptr) { ptr = nullptr; return; } ptr = (pointer_t) EC_KEY_dup (get_EC_KEY (that)); if (ptr == nullptr) { throw std::runtime_error ("ec_key::ec_key() : EC_KEY_dup failed"); } EC_KEY_set_conv_form (get_EC_KEY (*this), POINT_CONVERSION_COMPRESSED); }
static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { EC_PKEY_CTX *dctx, *sctx; if (!pkey_ec_init(dst)) return 0; sctx = src->data; dctx = dst->data; if (sctx->gen_group) { dctx->gen_group = EC_GROUP_dup(sctx->gen_group); if (!dctx->gen_group) return 0; } dctx->md = sctx->md; if (sctx->co_key) { dctx->co_key = EC_KEY_dup(sctx->co_key); if (!dctx->co_key) return 0; } dctx->kdf_type = sctx->kdf_type; dctx->kdf_md = sctx->kdf_md; dctx->kdf_outlen = sctx->kdf_outlen; if (sctx->kdf_ukm) { dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen); if (!dctx->kdf_ukm) return 0; } else dctx->kdf_ukm = NULL; dctx->kdf_ukmlen = sctx->kdf_ukmlen; #ifndef OPENSSL_NO_SM2 dctx->ec_scheme = sctx->ec_scheme; if (sctx->signer_id) { dctx->signer_id = OPENSSL_strdup(sctx->signer_id); if (!dctx->signer_id) return 0; } dctx->signer_zid = NULL; dctx->ec_encrypt_param = sctx->ec_encrypt_param; #endif return 1; }
static VALUE ossl_ec_key_initialize_copy(VALUE self, VALUE other) { EVP_PKEY *pkey; EC_KEY *ec, *ec_new; GetPKey(self, pkey); if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) ossl_raise(eECError, "EC already initialized"); SafeRequire_EC_KEY(other, ec); ec_new = EC_KEY_dup(ec); if (!ec_new) ossl_raise(eECError, "EC_KEY_dup"); if (!EVP_PKEY_assign_EC_KEY(pkey, ec_new)) { EC_KEY_free(ec_new); ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); } rb_iv_set(self, "@group", Qnil); /* EC_KEY_dup() also copies the EC_GROUP */ return self; }
/* call-seq: * OpenSSL::PKey::EC.new() * OpenSSL::PKey::EC.new(ec_key) * OpenSSL::PKey::EC.new(ec_group) * OpenSSL::PKey::EC.new("secp112r1") * OpenSSL::PKey::EC.new(pem_string) * OpenSSL::PKey::EC.new(pem_string [, pwd]) * OpenSSL::PKey::EC.new(der_string) * * See the OpenSSL documentation for: * EC_KEY_* */ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; EC_KEY *ec = NULL; VALUE arg, pass; VALUE group = Qnil; char *passwd = NULL; GetPKey(self, pkey); if (pkey->pkey.ec) rb_raise(eECError, "EC_KEY already initialized"); rb_scan_args(argc, argv, "02", &arg, &pass); if (NIL_P(arg)) { ec = EC_KEY_new(); } else { if (rb_obj_is_kind_of(arg, cEC)) { EC_KEY *other_ec = NULL; SafeRequire_EC_KEY(arg, other_ec); ec = EC_KEY_dup(other_ec); } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) { ec = EC_KEY_new(); group = arg; } else { BIO *in = ossl_obj2bio(arg); if (!NIL_P(pass)) { passwd = StringValuePtr(pass); } ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd); if (!ec) { (void)BIO_reset(in); (void)ERR_get_error(); ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, passwd); } if (!ec) { (void)BIO_reset(in); (void)ERR_get_error(); ec = d2i_ECPrivateKey_bio(in, NULL); } if (!ec) { (void)BIO_reset(in); (void)ERR_get_error(); ec = d2i_EC_PUBKEY_bio(in, NULL); } BIO_free(in); if (ec == NULL) { const char *name = StringValueCStr(arg); int nid = OBJ_sn2nid(name); (void)ERR_get_error(); if (nid == NID_undef) ossl_raise(eECError, "unknown curve name (%s)\n", name); if ((ec = EC_KEY_new_by_curve_name(nid)) == NULL) ossl_raise(eECError, "unable to create curve (%s)\n", name); EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE); EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED); } } } if (ec == NULL) ossl_raise(eECError, NULL); if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { EC_KEY_free(ec); ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); } rb_iv_set(self, "@group", Qnil); if (!NIL_P(group)) rb_funcall(self, rb_intern("group="), 1, arg); return self; }
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; }
EVP_PKEY * EVP_PKEY_dup(EVP_PKEY *key) { EVP_PKEY *out = NULL; DH *dh_in = NULL, *dh_out = NULL; EC_KEY *ec_in = NULL, *ec_out = NULL; RSA *rsa_in = NULL, *rsa_out = NULL; check(key, "Invalid arguments"); out = EVP_PKEY_new(); if (!out) goto err; switch (EVP_PKEY_base_id(key)) { case EVP_PKEY_DH: dh_in = EVP_PKEY_get1_DH(key); if (!dh_in) goto err; dh_out = DHparams_dup_with_q(dh_in); if (!dh_out) goto err; EVP_PKEY_set1_DH(out, dh_out); DH_free(dh_out); DH_free(dh_in); break; case EVP_PKEY_EC: ec_in = EVP_PKEY_get1_EC_KEY(key); if (!ec_in) goto err; ec_out = EC_KEY_dup(ec_in); if (!ec_out) goto err; EVP_PKEY_set1_EC_KEY(out, ec_out); EC_KEY_free(ec_out); EC_KEY_free(ec_in); break; case EVP_PKEY_RSA: rsa_in = EVP_PKEY_get1_RSA(key); if (!rsa_in) goto err; rsa_out = RSAPrivateKey_dup(rsa_in); if (!rsa_out) goto err; EVP_PKEY_set1_RSA(out, rsa_out); RSA_free(rsa_out); RSA_free(rsa_in); break; default: log_err("Unknown protocol"); goto err; } return out; err: if (dh_in) DH_free(dh_in); if (ec_in) EC_KEY_free(ec_in); if (rsa_in) RSA_free(rsa_in); return NULL; }
u2fs_EC_KEY_t *dup_key(const u2fs_EC_KEY_t * key) { return (u2fs_EC_KEY_t *) EC_KEY_dup((EC_KEY *) key); }
int ecdh_im_compute_key(PACE_CTX * ctx, const BUF_MEM * s, const BUF_MEM * in, BN_CTX *bn_ctx) { int ret = 0; BUF_MEM * x_mem = NULL; BIGNUM * a = NULL, *b = NULL, *p = NULL; BIGNUM * x = NULL, *y = NULL, *v = NULL, *u = NULL; BIGNUM * tmp = NULL, *tmp2 = NULL, *bn_inv = NULL; BIGNUM * two = NULL, *three = NULL, *four = NULL, *six = NULL; BIGNUM * twentyseven = NULL; EC_KEY *static_key = NULL, *ephemeral_key = NULL; EC_POINT *g = NULL; BN_CTX_start(bn_ctx); check((ctx && ctx->static_key && s && ctx->ka_ctx), "Invalid arguments"); static_key = EVP_PKEY_get1_EC_KEY(ctx->static_key); if (!static_key) goto err; /* Setup all the variables*/ a = BN_CTX_get(bn_ctx); b = BN_CTX_get(bn_ctx); p = BN_CTX_get(bn_ctx); x = BN_CTX_get(bn_ctx); y = BN_CTX_get(bn_ctx); v = BN_CTX_get(bn_ctx); two = BN_CTX_get(bn_ctx); three = BN_CTX_get(bn_ctx); four = BN_CTX_get(bn_ctx); six = BN_CTX_get(bn_ctx); twentyseven = BN_CTX_get(bn_ctx); tmp = BN_CTX_get(bn_ctx); tmp2 = BN_CTX_get(bn_ctx); bn_inv = BN_CTX_get(bn_ctx); if (!bn_inv) goto err; /* Encrypt the Nonce using the symmetric key in */ x_mem = cipher_no_pad(ctx->ka_ctx, NULL, in, s, 1); if (!x_mem) goto err; /* Fetch the curve parameters */ if (!EC_GROUP_get_curve_GFp(EC_KEY_get0_group(static_key), p, a, b, bn_ctx)) goto err; /* Assign constants */ if ( !BN_set_word(two,2)|| !BN_set_word(three,3)|| !BN_set_word(four,4)|| !BN_set_word(six,6)|| !BN_set_word(twentyseven,27) ) goto err; /* Check prerequisites for curve parameters */ check( /* p > 3;*/ (BN_cmp(p, three) == 1) && /* p mod 3 = 2; (p has the form p=q^n, q prime) */ BN_nnmod(tmp, p, three, bn_ctx) && (BN_cmp(tmp, two) == 0), "Unsuited curve"); /* Convert encrypted nonce to BIGNUM */ u = BN_bin2bn((unsigned char *) x_mem->data, x_mem->length, u); if (!u) goto err; if ( /* v = (3a - u^4) / 6u mod p */ !BN_mod_mul(tmp, three, a, p, bn_ctx) || !BN_mod_exp(tmp2, u, four, p, bn_ctx) || !BN_mod_sub(v, tmp, tmp2, p, bn_ctx) || !BN_mod_mul(tmp, u, six, p, bn_ctx) || /* For division within a galois field we need to compute * the multiplicative inverse of a number */ !BN_mod_inverse(bn_inv, tmp, p, bn_ctx) || !BN_mod_mul(v, v, bn_inv, p, bn_ctx) || /* x = (v^2 - b - ((u^6)/27)) */ !BN_mod_sqr(tmp, v, p, bn_ctx) || !BN_mod_sub(tmp2, tmp, b, p, bn_ctx) || !BN_mod_exp(tmp, u, six, p, bn_ctx) || !BN_mod_inverse(bn_inv, twentyseven, p, bn_ctx) || !BN_mod_mul(tmp, tmp, bn_inv, p, bn_ctx) || !BN_mod_sub(x, tmp2, tmp, p, bn_ctx) || /* x -> x^(1/3) = x^((2p^n -1)/3) */ !BN_mul(tmp, two, p, bn_ctx) || !BN_sub(tmp, tmp, BN_value_one()) || /* Division is defined, because p^n = 2 mod 3 */ !BN_div(tmp, y, tmp, three, bn_ctx) || !BN_mod_exp(tmp2, x, tmp, p, bn_ctx) || !BN_copy(x, tmp2) || /* x += (u^2)/3 */ !BN_mod_sqr(tmp, u, p, bn_ctx) || !BN_mod_inverse(bn_inv, three, p, bn_ctx) || !BN_mod_mul(tmp2, tmp, bn_inv, p, bn_ctx) || !BN_mod_add(tmp, x, tmp2, p, bn_ctx) || !BN_copy(x, tmp) || /* y = ux + v */ !BN_mod_mul(y, u, x, p, bn_ctx) || !BN_mod_add(tmp, y, v, p, bn_ctx) || !BN_copy(y, tmp) ) goto err; /* Initialize ephemeral parameters with parameters from the static key */ ephemeral_key = EC_KEY_dup(static_key); if (!ephemeral_key) goto err; EVP_PKEY_set1_EC_KEY(ctx->ka_ctx->key, ephemeral_key); /* configure the new EC_KEY */ g = EC_POINT_new(EC_KEY_get0_group(ephemeral_key)); if (!g) goto err; if (!EC_POINT_set_affine_coordinates_GFp(EC_KEY_get0_group(ephemeral_key), g, x, y, bn_ctx)) goto err; ret = 1; err: if (x_mem) BUF_MEM_free(x_mem); if (u) BN_free(u); BN_CTX_end(bn_ctx); if (g) EC_POINT_clear_free(g); /* Decrement reference count, keys are still available via PACE_CTX */ if (static_key) EC_KEY_free(static_key); if (ephemeral_key) EC_KEY_free(ephemeral_key); return ret; }
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 = calloc(1, sizeof(CERT)); if (ret == NULL) { SSLerr(SSL_F_SSL_CERT_DUP, 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) { 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; 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; 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_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); } } } /* * ret->extra_certs *should* exist, but currently the own certificate * chain is held inside SSL_CTX */ 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); return (ret); err: DH_free(ret->dh_tmp); EC_KEY_free(ret->ecdh_tmp); for (i = 0; i < SSL_PKEY_NUM; i++) { if (ret->pkeys[i].x509 != NULL) X509_free(ret->pkeys[i].x509); EVP_PKEY_free(ret->pkeys[i].privatekey); } 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->key = &ret->pkeys[cert->key - cert->pkeys]; #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; 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); } } ret->references = 1; /* Configured sigalgs copied 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->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; if (cert->psk_identity_hint) { ret->psk_identity_hint = BUF_strdup(cert->psk_identity_hint); if (ret->psk_identity_hint == NULL) goto err; } return (ret); err: ssl_cert_free(ret); return NULL; }
static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { EC_PKEY_CTX *dctx = ctx->data; EC_GROUP *group; switch (type) { case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: group = EC_GROUP_new_by_curve_name(p1); if (group == NULL) { ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE); return 0; } EC_GROUP_free(dctx->gen_group); dctx->gen_group = group; return 1; case EVP_PKEY_CTRL_EC_PARAM_ENC: if (!dctx->gen_group) { ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET); return 0; } EC_GROUP_set_asn1_flag(dctx->gen_group, p1); return 1; #ifndef OPENSSL_NO_EC case EVP_PKEY_CTRL_EC_ECDH_COFACTOR: if (p1 == -2) { if (dctx->cofactor_mode != -1) return dctx->cofactor_mode; else { EC_KEY *ec_key = ctx->pkey->pkey.ec; return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : 0; } } else if (p1 < -1 || p1 > 1) return -2; dctx->cofactor_mode = p1; if (p1 != -1) { EC_KEY *ec_key = ctx->pkey->pkey.ec; if (!ec_key->group) return -2; /* If cofactor is 1 cofactor mode does nothing */ if (BN_is_one(ec_key->group->cofactor)) return 1; if (!dctx->co_key) { dctx->co_key = EC_KEY_dup(ec_key); if (!dctx->co_key) return 0; } if (p1) EC_KEY_set_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH); else EC_KEY_clear_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH); } else { EC_KEY_free(dctx->co_key); dctx->co_key = NULL; } return 1; #endif case EVP_PKEY_CTRL_EC_KDF_TYPE: if (p1 == -2) return dctx->kdf_type; if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_62) return -2; dctx->kdf_type = p1; return 1; #ifndef OPENSSL_NO_SM2 case EVP_PKEY_CTRL_EC_SCHEME: if (p1 == -2) { return dctx->ec_scheme; } if (p1 != NID_secg_scheme && p1 != NID_sm_scheme) { ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_EC_SCHEME); return 0; } dctx->ec_scheme = p1; return 1; case EVP_PKEY_CTRL_SIGNER_ID: if (!p2 || !strlen((char *)p2) || strlen((char *)p2) > SM2_MAX_ID_LENGTH) { ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_SIGNER_ID); return 0; } else { char *id = NULL; if (!(id = OPENSSL_strdup((char *)p2))) { ECerr(EC_F_PKEY_EC_CTRL, ERR_R_MALLOC_FAILURE); return 0; } if (dctx->signer_id) OPENSSL_free(dctx->signer_id); dctx->signer_id = id; if (dctx->ec_scheme == NID_sm_scheme) { EC_KEY *ec_key = ctx->pkey->pkey.ec; unsigned char zid[SM3_DIGEST_LENGTH]; size_t zidlen = SM3_DIGEST_LENGTH; if (!SM2_compute_id_digest(EVP_sm3(), dctx->signer_id, strlen(dctx->signer_id), zid, &zidlen, ec_key)) { ECerr(EC_F_PKEY_EC_CTRL, ERR_R_SM2_LIB); return 0; } if (!dctx->signer_zid) { if (!(dctx->signer_zid = OPENSSL_malloc(zidlen))) { ECerr(EC_F_PKEY_EC_CTRL, ERR_R_MALLOC_FAILURE); return 0; } } memcpy(dctx->signer_zid, zid, zidlen); } } return 1; case EVP_PKEY_CTRL_GET_SIGNER_ID: *(const char **)p2 = dctx->signer_id; return 1; case EVP_PKEY_CTRL_GET_SIGNER_ZID: if (dctx->ec_scheme != NID_sm_scheme) { *(const unsigned char **)p2 = NULL; return -2; } if (!dctx->signer_zid) { EC_KEY *ec_key = ctx->pkey->pkey.ec; unsigned char *zid; size_t zidlen = SM3_DIGEST_LENGTH; if (!(zid = OPENSSL_malloc(zidlen))) { ECerr(EC_F_PKEY_EC_CTRL, ERR_R_MALLOC_FAILURE); return 0; } if (!SM2_compute_id_digest(EVP_sm3(), SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH, zid, &zidlen, ec_key)) { ECerr(EC_F_PKEY_EC_CTRL, ERR_R_SM2_LIB); OPENSSL_free(zid); return 0; } dctx->signer_zid = zid; } *(const unsigned char **)p2 = dctx->signer_zid; return 1; case EVP_PKEY_CTRL_EC_ENCRYPT_PARAM: if (p1 == -2) { return dctx->ec_encrypt_param; } dctx->ec_encrypt_param = p1; return 1; #endif case EVP_PKEY_CTRL_EC_KDF_MD: dctx->kdf_md = p2; return 1; case EVP_PKEY_CTRL_GET_EC_KDF_MD: *(const EVP_MD **)p2 = dctx->kdf_md; return 1; case EVP_PKEY_CTRL_EC_KDF_OUTLEN: if (p1 <= 0) return -2; dctx->kdf_outlen = (size_t)p1; return 1; case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN: *(int *)p2 = dctx->kdf_outlen; return 1; case EVP_PKEY_CTRL_EC_KDF_UKM: OPENSSL_free(dctx->kdf_ukm); dctx->kdf_ukm = p2; if (p2) dctx->kdf_ukmlen = p1; else dctx->kdf_ukmlen = 0; return 1; case EVP_PKEY_CTRL_GET_EC_KDF_UKM: *(unsigned char **)p2 = dctx->kdf_ukm; return dctx->kdf_ukmlen; case EVP_PKEY_CTRL_MD: if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && #ifndef OPENSSL_NO_SM3 EVP_MD_type((const EVP_MD *)p2) != NID_sm3 && #endif EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 && EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && EVP_MD_type((const EVP_MD *)p2) != NID_sha512) { ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE); return 0; } dctx->md = p2; return 1; case EVP_PKEY_CTRL_GET_MD: *(const EVP_MD **)p2 = dctx->md; return 1; case EVP_PKEY_CTRL_PEER_KEY: /* Default behaviour is OK */ case EVP_PKEY_CTRL_DIGESTINIT: case EVP_PKEY_CTRL_PKCS7_SIGN: case EVP_PKEY_CTRL_CMS_SIGN: return 1; default: return -2; } }
static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { EC_PKEY_CTX *dctx = ctx->data; EC_GROUP *group; switch (type) { case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: group = EC_GROUP_new_by_curve_name(p1); if (group == NULL) { ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE); return 0; } EC_GROUP_free(dctx->gen_group); dctx->gen_group = group; return 1; case EVP_PKEY_CTRL_EC_PARAM_ENC: if (!dctx->gen_group) { ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET); return 0; } EC_GROUP_set_asn1_flag(dctx->gen_group, p1); return 1; #ifndef OPENSSL_NO_EC case EVP_PKEY_CTRL_EC_ECDH_COFACTOR: if (p1 == -2) { if (dctx->cofactor_mode != -1) return dctx->cofactor_mode; else { EC_KEY *ec_key = ctx->pkey->pkey.ec; return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : 0; } } else if (p1 < -1 || p1 > 1) return -2; dctx->cofactor_mode = p1; if (p1 != -1) { EC_KEY *ec_key = ctx->pkey->pkey.ec; if (!ec_key->group) return -2; /* If cofactor is 1 cofactor mode does nothing */ if (BN_is_one(ec_key->group->cofactor)) return 1; if (!dctx->co_key) { dctx->co_key = EC_KEY_dup(ec_key); if (!dctx->co_key) return 0; } if (p1) EC_KEY_set_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH); else EC_KEY_clear_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH); } else { EC_KEY_free(dctx->co_key); dctx->co_key = NULL; } return 1; #endif case EVP_PKEY_CTRL_EC_KDF_TYPE: if (p1 == -2) return dctx->kdf_type; if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_62) return -2; dctx->kdf_type = p1; return 1; case EVP_PKEY_CTRL_EC_KDF_MD: dctx->kdf_md = p2; return 1; case EVP_PKEY_CTRL_GET_EC_KDF_MD: *(const EVP_MD **)p2 = dctx->kdf_md; return 1; case EVP_PKEY_CTRL_EC_KDF_OUTLEN: if (p1 <= 0) return -2; dctx->kdf_outlen = (size_t)p1; return 1; case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN: *(int *)p2 = dctx->kdf_outlen; return 1; case EVP_PKEY_CTRL_EC_KDF_UKM: OPENSSL_free(dctx->kdf_ukm); dctx->kdf_ukm = p2; if (p2) dctx->kdf_ukmlen = p1; else dctx->kdf_ukmlen = 0; return 1; case EVP_PKEY_CTRL_GET_EC_KDF_UKM: *(unsigned char **)p2 = dctx->kdf_ukm; return dctx->kdf_ukmlen; case EVP_PKEY_CTRL_MD: if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 && EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && EVP_MD_type((const EVP_MD *)p2) != NID_sha512) { ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE); return 0; } dctx->md = p2; return 1; case EVP_PKEY_CTRL_GET_MD: *(const EVP_MD **)p2 = dctx->md; return 1; case EVP_PKEY_CTRL_PEER_KEY: /* Default behaviour is OK */ case EVP_PKEY_CTRL_DIGESTINIT: case EVP_PKEY_CTRL_PKCS7_SIGN: case EVP_PKEY_CTRL_CMS_SIGN: return 1; default: return -2; } }
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; }
elliptic_curve_key::elliptic_curve_key(const elliptic_curve_key& other) { key_ = EC_KEY_dup(other.key_); }
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; }
int ecdh_gm_compute_key(PACE_CTX * ctx, const BUF_MEM * s, const BUF_MEM * in, BN_CTX *bn_ctx) { int ret = 0; BUF_MEM * mem_h = NULL; BIGNUM * bn_s = NULL, *order = NULL, *cofactor = NULL; EC_POINT * ecp_h = NULL, *ecp_g = NULL; const ECDH_METHOD *default_method; EC_GROUP *group = NULL; EC_KEY *static_key = NULL, *ephemeral_key = NULL; BN_CTX_start(bn_ctx); check((ctx && ctx->static_key && s && ctx->ka_ctx), "Invalid arguments"); static_key = EVP_PKEY_get1_EC_KEY(ctx->static_key); check(static_key, "could not get key object"); /* Extract group parameters */ group = EC_GROUP_dup(EC_KEY_get0_group(static_key)); order = BN_CTX_get(bn_ctx); cofactor = BN_CTX_get(bn_ctx); check(group && cofactor, "internal error"); if (!EC_GROUP_get_order(group, order, bn_ctx) || !EC_GROUP_get_cofactor(group, cofactor, bn_ctx)) goto err; /* Convert nonce to BIGNUM */ bn_s = BN_bin2bn((unsigned char *) s->data, s->length, bn_s); if (!bn_s) goto err; default_method = ECDH_get_default_method(); ECDH_set_default_method(ECDH_OpenSSL_Point()); /* complete the ECDH and get the resulting point h */ mem_h = ecdh_compute_key(ctx->static_key, in, bn_ctx); ECDH_set_default_method(default_method); ecp_h = EC_POINT_new(group); if (!mem_h || !ecp_h || !EC_POINT_oct2point(group, ecp_h, (unsigned char *) mem_h->data, mem_h->length, bn_ctx)) goto err; /* map to new generator */ ecp_g = EC_POINT_new(group); /* g' = g*s + h*1 */ if (!EC_POINT_mul(group, ecp_g, bn_s, ecp_h, BN_value_one(), bn_ctx)) goto err; /* Initialize ephemeral parameters with parameters from the static key */ ephemeral_key = EC_KEY_dup(static_key); if (!ephemeral_key) goto err; EVP_PKEY_set1_EC_KEY(ctx->ka_ctx->key, ephemeral_key); /* configure the new EC_KEY */ if (!EC_GROUP_set_generator(group, ecp_g, order, cofactor) || !EC_GROUP_check(group, bn_ctx) || !EC_KEY_set_group(ephemeral_key, group)) goto err; ret = 1; err: if (ecp_g) EC_POINT_clear_free(ecp_g); if (ecp_h) EC_POINT_clear_free(ecp_h); if (mem_h) BUF_MEM_free(mem_h); if (bn_s) BN_clear_free(bn_s); BN_CTX_end(bn_ctx); /* Decrement reference count, keys are still available via PACE_CTX */ if (static_key) EC_KEY_free(static_key); if (ephemeral_key) EC_KEY_free(ephemeral_key); if (group) EC_GROUP_clear_free(group); return ret; }