static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) { switch (op) { case ASN1_PKEY_CTRL_PKCS7_SIGN: if (arg1 == 0) { int snid, hnid; X509_ALGOR *alg1, *alg2; PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); if (alg1 == NULL || alg1->algorithm == NULL) return -1; hnid = OBJ_obj2nid(alg1->algorithm); if (hnid == NID_undef) return -1; if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) return -1; X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); } return 1; #ifndef OPENSSL_NO_CMS case ASN1_PKEY_CTRL_CMS_SIGN: if (arg1 == 0) { int snid, hnid; X509_ALGOR *alg1, *alg2; CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); if (alg1 == NULL || alg1->algorithm == NULL) return -1; hnid = OBJ_obj2nid(alg1->algorithm); if (hnid == NID_undef) return -1; if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) return -1; X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); } return 1; case ASN1_PKEY_CTRL_CMS_ENVELOPE: if (arg1 == 1) return ecdh_cms_decrypt(arg2); else if (arg1 == 0) return ecdh_cms_encrypt(arg2); return -2; case ASN1_PKEY_CTRL_CMS_RI_TYPE: *(int *)arg2 = CMS_RECIPINFO_AGREE; return 1; #endif case ASN1_PKEY_CTRL_DEFAULT_MD_NID: *(int *)arg2 = NID_sha256; return 2; default: return -2; } }
EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, long length) { EVP_PKEY *ret; if ((a == NULL) || (*a == NULL)) { if ((ret = EVP_PKEY_new()) == NULL) { ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB); return NULL; } } else ret = *a; if (type != EVP_PKEY_id(ret) && !EVP_PKEY_set_type(ret, type)) { ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB); goto err; } switch (EVP_PKEY_id(ret)) { #ifndef OPENSSL_NO_RSA case EVP_PKEY_RSA: if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL, pp, length)) == NULL) { ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); goto err; } break; #endif #ifndef OPENSSL_NO_DSA case EVP_PKEY_DSA: /* TMP UGLY CAST */ if (!d2i_DSAPublicKey(&ret->pkey.dsa, pp, length)) { ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); goto err; } break; #endif #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: if (!o2i_ECPublicKey(&ret->pkey.ec, pp, length)) { ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); goto err; } break; #endif default: ASN1err(ASN1_F_D2I_PUBLICKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); goto err; } if (a != NULL) (*a) = ret; return ret; err: if (a == NULL || *a != ret) EVP_PKEY_free(ret); return NULL; }
static int test_d2i_AutoPrivateKey(const unsigned char *input, size_t input_len, int expected_id) { int ret = 0; const unsigned char *p; EVP_PKEY *pkey = NULL; p = input; pkey = d2i_AutoPrivateKey(NULL, &p, input_len); if (pkey == NULL || p != input + input_len) { fprintf(stderr, "d2i_AutoPrivateKey failed\n"); goto done; } if (EVP_PKEY_id(pkey) != expected_id) { fprintf(stderr, "Did not decode expected type\n"); goto done; } ret = 1; done: if (!ret) { ERR_print_errors_fp(stderr); } EVP_PKEY_free(pkey); return ret; }
EVP_PKEY *d2i_KeyParams(int type, EVP_PKEY **a, const unsigned char **pp, long length) { EVP_PKEY *ret = NULL; const unsigned char *p = *pp; if ((a == NULL) || (*a == NULL)) { if ((ret = EVP_PKEY_new()) == NULL) return NULL; } else ret = *a; if (type != EVP_PKEY_id(ret) && !EVP_PKEY_set_type(ret, type)) goto err; if (ret->ameth == NULL || ret->ameth->param_decode == NULL) { ASN1err(ASN1_F_D2I_KEYPARAMS, ASN1_R_UNSUPPORTED_TYPE); goto err; } if (!ret->ameth->param_decode(ret, &p, length)) goto err; if (a != NULL) (*a) = ret; return ret; err: if (a == NULL || *a != ret) EVP_PKEY_free(ret); return NULL; }
int ssl_cert_type(const X509 *x, const EVP_PKEY *pk) { if (pk == NULL && (pk = X509_get0_pubkey(x)) == NULL) return -1; switch (EVP_PKEY_id(pk)) { default: return -1; case EVP_PKEY_RSA: return SSL_PKEY_RSA_ENC; case EVP_PKEY_DSA: return SSL_PKEY_DSA_SIGN; #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: return SSL_PKEY_ECC; #endif #ifndef OPENSSL_NO_GOST case NID_id_GostR3410_2001: return SSL_PKEY_GOST01; case NID_id_GostR3410_2012_256: return SSL_PKEY_GOST12_256; case NID_id_GostR3410_2012_512: return SSL_PKEY_GOST12_512; #endif } }
soter_status_t soter_ec_gen_key(EVP_PKEY_CTX *pkey_ctx) { EVP_PKEY *pkey; EC_KEY *ec=NULL; if (!pkey_ctx){ return SOTER_INVALID_PARAMETER; } pkey = EVP_PKEY_CTX_get0_pkey(pkey_ctx); if (!pkey){ return SOTER_INVALID_PARAMETER; } if (EVP_PKEY_EC != EVP_PKEY_id(pkey)){ return SOTER_INVALID_PARAMETER; } /* ec = EVP_PKEY_get0_EC_KEY(pkey); */ /* if (NULL == ec){ */ /* return SOTER_INVALID_PARAMETER; */ /* } */ ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); if(!ec){ return SOTER_ENGINE_FAIL; } if (!EC_KEY_generate_key(ec)){ return SOTER_ENGINE_FAIL; } if(!EVP_PKEY_set1_EC_KEY(pkey, ec)){ return SOTER_ENGINE_FAIL; } EC_KEY_free(ec); return SOTER_SUCCESS; }
soter_status_t soter_asym_ka_export_key(soter_asym_ka_t* asym_ka_ctx, void* key, size_t* key_length, bool isprivate) { EVP_PKEY* pkey; if (!asym_ka_ctx) { return SOTER_INVALID_PARAMETER; } pkey = EVP_PKEY_CTX_get0_pkey(asym_ka_ctx->pkey_ctx); if (!pkey) { return SOTER_INVALID_PARAMETER; } if (EVP_PKEY_EC != EVP_PKEY_id(pkey)) { return SOTER_INVALID_PARAMETER; } if (isprivate) { return soter_engine_specific_to_ec_priv_key((const soter_engine_specific_ec_key_t*)pkey, (soter_container_hdr_t*)key, key_length); } return soter_engine_specific_to_ec_pub_key((const soter_engine_specific_ec_key_t*)pkey, (soter_container_hdr_t*)key, key_length); }
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; }
static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) { switch (op) { case ASN1_PKEY_CTRL_PKCS7_SIGN: if (arg1 == 0) { int snid, hnid; X509_ALGOR *alg1, *alg2; PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); if (alg1 == NULL || alg1->algorithm == NULL) return -1; hnid = OBJ_obj2nid(alg1->algorithm); if (hnid == NID_undef) return -1; if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) return -1; X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); } return 1; case ASN1_PKEY_CTRL_DEFAULT_MD_NID: *(int *)arg2 = NID_sha1; return 2; default: return -2; } }
soter_status_t soter_asym_ka_gen_key(soter_asym_ka_t* asym_ka_ctx) { EVP_PKEY* pkey; EC_KEY* ec; if (!asym_ka_ctx) { return SOTER_INVALID_PARAMETER; } pkey = EVP_PKEY_CTX_get0_pkey(asym_ka_ctx->pkey_ctx); if (!pkey) { return SOTER_INVALID_PARAMETER; } if (EVP_PKEY_EC != EVP_PKEY_id(pkey)) { return SOTER_INVALID_PARAMETER; } ec = EVP_PKEY_get0_EC_KEY(pkey); if (NULL == ec) { return SOTER_INVALID_PARAMETER; } if (1 == EC_KEY_generate_key(ec)) { return SOTER_SUCCESS; } return SOTER_FAIL; }
int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) { EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); if (pkey == NULL) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_CONTEXT_NOT_INITIALISED); return 0; } if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { int pad_mode; if (!EVP_PKEY_CTX_get_rsa_padding(ctx->pctx, &pad_mode)) { return 0; } /* RSA-PSS has special signature algorithm logic. */ if (pad_mode == RSA_PKCS1_PSS_PADDING) { return x509_rsa_ctx_to_pss(ctx, algor); } } if (EVP_PKEY_id(pkey) == EVP_PKEY_ED25519) { return X509_ALGOR_set0(algor, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL); } /* Default behavior: look up the OID for the algorithm/hash pair and encode * that. */ const EVP_MD *digest = EVP_MD_CTX_md(ctx); if (digest == NULL) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_CONTEXT_NOT_INITIALISED); return 0; } int sign_nid; if (!OBJ_find_sigid_by_algs(&sign_nid, EVP_MD_type(digest), EVP_PKEY_id(pkey))) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); return 0; } /* RSA signature algorithms include an explicit NULL parameter. Others omit * it. */ int paramtype = (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) ? V_ASN1_NULL : V_ASN1_UNDEF; X509_ALGOR_set0(algor, OBJ_nid2obj(sign_nid), paramtype, NULL); return 1; }
int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx, EVP_PKEY *private_key) { ctx->tlsext_channel_id_enabled = 1; if (EVP_PKEY_id(private_key) != EVP_PKEY_EC || EVP_PKEY_bits(private_key) != 256) { OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256); return 0; } EVP_PKEY_free(ctx->tlsext_channel_id_private); ctx->tlsext_channel_id_private = EVP_PKEY_up_ref(private_key); return 1; }
static int pkey_type(EVP_PKEY *pkey) { int nid = EVP_PKEY_id(pkey); #ifndef OPENSSL_NO_EC if (nid == EVP_PKEY_EC) { const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); return EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); } #endif return nid; }
int ssl_check_leaf_certificate(SSL_HANDSHAKE *hs, EVP_PKEY *pkey, const CRYPTO_BUFFER *leaf) { SSL *const ssl = hs->ssl; assert(ssl3_protocol_version(ssl) < TLS1_3_VERSION); /* Check the certificate's type matches the cipher. */ if (!(hs->new_cipher->algorithm_auth & ssl_cipher_auth_mask_for_key(pkey))) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CERTIFICATE_TYPE); return 0; } /* Check key usages for all key types but RSA. This is needed to distinguish * ECDH certificates, which we do not support, from ECDSA certificates. In * principle, we should check RSA key usages based on cipher, but this breaks * buggy antivirus deployments. Other key types are always used for signing. * * TODO(davidben): Get more recent data on RSA key usages. */ if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) { CBS leaf_cbs; CBS_init(&leaf_cbs, CRYPTO_BUFFER_data(leaf), CRYPTO_BUFFER_len(leaf)); if (!ssl_cert_check_digital_signature_key_usage(&leaf_cbs)) { return 0; } } if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { /* Check the key's group and point format are acceptable. */ EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); uint16_t group_id; if (!ssl_nid_to_group_id( &group_id, EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key))) || !tls1_check_group_id(ssl, group_id) || EC_KEY_get_conv_form(ec_key) != POINT_CONVERSION_UNCOMPRESSED) { OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECC_CERT); return 0; } } return 1; }
int main(int argc, char *argv[]) { const char *cert_filename = "ecc_server.crt"; BIO *cert_bio = NULL; BIO *out_bio = NULL; X509 *cert = NULL; EVP_PKEY *pkey = NULL; int ret; OpenSSL_add_all_algorithms(); ERR_load_BIO_strings(); ERR_load_crypto_strings(); cert_bio = BIO_new(BIO_s_file()); out_bio = BIO_new_fp(stdout, BIO_NOCLOSE); ret = BIO_read_filename(cert_bio, cert_filename); if (!(cert = PEM_read_bio_X509(cert_bio, NULL, 0, NULL))) { BIO_printf(out_bio, "Error loading cert into memory\n"); exit(-1); } if ((pkey = X509_get_pubkey(cert)) == NULL) BIO_printf(out_bio, "Error getting public key from certificate\n"); if (pkey) { switch (EVP_PKEY_id(pkey)) { case EVP_PKEY_RSA: BIO_printf(out_bio, "%d bit RSA Key\n\n", EVP_PKEY_bits(pkey)); break; case EVP_PKEY_DSA: BIO_printf(out_bio, "%d bit DSA Key\n\n", EVP_PKEY_bits(pkey)); break; default: BIO_printf(out_bio, "%d bit non-RSA/DSA\n\n", EVP_PKEY_bits(pkey)); break; } } if (!PEM_write_bio_PUBKEY(out_bio, pkey)) BIO_printf(out_bio, "Error writing public key data in PEM format\n"); EVP_PKEY_free(pkey); X509_free(cert); BIO_free_all(cert_bio); BIO_free_all(out_bio); return 0; }
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) { int i; i = ssl_cert_type(NULL, pkey); if (i < 0) { SSLerr(SSL_F_SSL_SET_PKEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); return (0); } #ifndef OPENSSL_NO_GMTLS if (i == SSL_PKEY_SM2 && c->pkeys[SSL_PKEY_SM2_ENC].x509) i = SSL_PKEY_SM2_ENC; #endif if (c->pkeys[i].x509 != NULL) { EVP_PKEY *pktmp; pktmp = X509_get0_pubkey(c->pkeys[i].x509); if (pktmp == NULL) { SSLerr(SSL_F_SSL_SET_PKEY, ERR_R_MALLOC_FAILURE); return 0; } /* * The return code from EVP_PKEY_copy_parameters is deliberately * ignored. Some EVP_PKEY types cannot do this. */ EVP_PKEY_copy_parameters(pktmp, pkey); ERR_clear_error(); #ifndef OPENSSL_NO_RSA /* * Don't check the public/private key, this is mostly for smart * cards. */ if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA && RSA_flags(EVP_PKEY_get0_RSA(pkey)) & RSA_METHOD_FLAG_NO_CHECK) ; else #endif if (!X509_check_private_key(c->pkeys[i].x509, pkey)) { X509_free(c->pkeys[i].x509); c->pkeys[i].x509 = NULL; return 0; } } EVP_PKEY_free(c->pkeys[i].privatekey); EVP_PKEY_up_ref(pkey); c->pkeys[i].privatekey = pkey; c->key = &(c->pkeys[i]); return (1); }
int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) { EVP_PKEY *xk = NULL; int ok = 0; xk = X509_REQ_get_pubkey(x); switch (EVP_PKEY_cmp(xk, k)) { case 1: ok = 1; break; case 0: X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_KEY_VALUES_MISMATCH); break; case -1: X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_KEY_TYPE_MISMATCH); break; case -2: #ifndef OPENSSL_NO_EC if (EVP_PKEY_id(k) == EVP_PKEY_EC) { X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, ERR_R_EC_LIB); break; } #endif #ifndef OPENSSL_NO_DH if (EVP_PKEY_id(k) == EVP_PKEY_DH) { /* No idea */ X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_CANT_CHECK_DH_KEY); break; } #endif X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE); } EVP_PKEY_free(xk); return (ok); }
int ssl_private_key_type(SSL *ssl) { if (ssl->cert->key_method != NULL) { return ssl->cert->key_method->type(ssl); } switch (EVP_PKEY_id(ssl->cert->privatekey)) { case EVP_PKEY_RSA: return NID_rsaEncryption; case EVP_PKEY_EC: return EC_GROUP_get_curve_name( EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(ssl->cert->privatekey))); default: return NID_undef; } }
int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key) { if (EVP_PKEY_id(private_key) != EVP_PKEY_EC || EC_GROUP_get_curve_name(EC_KEY_get0_group(private_key->pkey.ec)) != NID_X9_62_prime256v1) { OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256); return 0; } EVP_PKEY_free(ssl->tlsext_channel_id_private); ssl->tlsext_channel_id_private = EVP_PKEY_up_ref(private_key); ssl->tlsext_channel_id_enabled = 1; return 1; }
static void set_server_temporary_key_info(TLS_REC *tls, SSL *ssl) { #ifdef SSL_get_server_tmp_key /* Show ephemeral key information. */ EVP_PKEY *ephemeral_key = NULL; /* OPENSSL_NO_EC is for solaris 11.3 (2016), github ticket #598 */ #ifndef OPENSSL_NO_EC EC_KEY *ec_key = NULL; #endif char *ephemeral_key_algorithm = NULL; char *cname = NULL; int nid; g_return_if_fail(tls != NULL); g_return_if_fail(ssl != NULL); if (SSL_get_server_tmp_key(ssl, &ephemeral_key)) { switch (EVP_PKEY_id(ephemeral_key)) { case EVP_PKEY_DH: tls_rec_set_ephemeral_key_algorithm(tls, "DH"); tls_rec_set_ephemeral_key_size(tls, EVP_PKEY_bits(ephemeral_key)); break; #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: ec_key = EVP_PKEY_get1_EC_KEY(ephemeral_key); nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); EC_KEY_free(ec_key); cname = (char *)OBJ_nid2sn(nid); ephemeral_key_algorithm = g_strdup_printf("ECDH: %s", cname); tls_rec_set_ephemeral_key_algorithm(tls, ephemeral_key_algorithm); tls_rec_set_ephemeral_key_size(tls, EVP_PKEY_bits(ephemeral_key)); g_free_and_null(ephemeral_key_algorithm); break; #endif default: tls_rec_set_ephemeral_key_algorithm(tls, "Unknown"); tls_rec_set_ephemeral_key_size(tls, EVP_PKEY_bits(ephemeral_key)); break; } EVP_PKEY_free(ephemeral_key); } #endif /* SSL_get_server_tmp_key. */ }
soter_status_t soter_rsa_key_pair_gen_export_key(soter_rsa_key_pair_gen_t* ctx, void* key, size_t* key_length, bool isprivate){ EVP_PKEY *pkey; SOTER_CHECK_PARAM(ctx); pkey = EVP_PKEY_CTX_get0_pkey(ctx->pkey_ctx); SOTER_CHECK_PARAM(pkey); SOTER_CHECK_PARAM(EVP_PKEY_RSA == EVP_PKEY_id(pkey)); if (isprivate) { return soter_engine_specific_to_rsa_priv_key((const soter_engine_specific_rsa_key_t *)pkey, (soter_container_hdr_t *)key, key_length); } else { return soter_engine_specific_to_rsa_pub_key((const soter_engine_specific_rsa_key_t *)pkey, (soter_container_hdr_t *)key, key_length); } }
int ssl_print_tmp_key(BIO *out, SSL *s) { const char *cname; EVP_PKEY *pkey; EC_KEY *ec; int nid; if (!SSL_get_server_tmp_key(s, &pkey)) return 0; BIO_puts(out, "Server Temp Key: "); switch (EVP_PKEY_id(pkey)) { case EVP_PKEY_DH: BIO_printf(out, "DH, %d bits\n", EVP_PKEY_bits(pkey)); break; case EVP_PKEY_EC: ec = EVP_PKEY_get1_EC_KEY(pkey); nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); EC_KEY_free(ec); if ((cname = EC_curve_nid2nist(nid)) == NULL) cname = OBJ_nid2sn(nid); BIO_printf(out, "ECDH, %s, %d bits\n", cname, EVP_PKEY_bits(pkey)); break; default: BIO_printf(out, "%s, %d bits\n", OBJ_nid2sn(EVP_PKEY_id(pkey)), EVP_PKEY_bits(pkey)); } EVP_PKEY_free(pkey); return 1; }
ssize_t tls_get_connection_info(struct tls *ctx, char *buf, size_t buflen) { SSL *conn = ctx->ssl_conn; const char *ocsp_pfx = "", *ocsp_info = ""; const char *proto = "-", *cipher = "-"; char dh[64]; int used_dh_bits = ctx->used_dh_bits, used_ecdh_nid = ctx->used_ecdh_nid; if (conn != NULL) { proto = SSL_get_version(conn); cipher = SSL_get_cipher(conn); #ifdef SSL_get_server_tmp_key if (ctx->flags & TLS_CLIENT) { EVP_PKEY *pk = NULL; int ok = SSL_get_server_tmp_key(conn, &pk); int pk_type = EVP_PKEY_id(pk); if (ok && pk) { if (pk_type == EVP_PKEY_DH) { DH *dh = EVP_PKEY_get0(pk); used_dh_bits = DH_size(dh) * 8; } else if (pk_type == EVP_PKEY_EC) { EC_KEY *ecdh = EVP_PKEY_get0(pk); const EC_GROUP *eg = EC_KEY_get0_group(ecdh); used_ecdh_nid = EC_GROUP_get_curve_name(eg); } EVP_PKEY_free(pk); } } #endif } if (used_dh_bits) { snprintf(dh, sizeof dh, "/DH=%d", used_dh_bits); } else if (used_ecdh_nid) { snprintf(dh, sizeof dh, "/ECDH=%s", OBJ_nid2sn(used_ecdh_nid)); } else { dh[0] = 0; } if (ctx->ocsp_result) { ocsp_info = ctx->ocsp_result; ocsp_pfx = "/OCSP="; } return snprintf(buf, buflen, "%s/%s%s%s%s", proto, cipher, dh, ocsp_pfx, ocsp_info); }
static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub) { unsigned char *p; unsigned int bitlen, magic = 0, keyalg; int outlen, noinc = 0; int pktype = EVP_PKEY_id(pk); if (pktype == EVP_PKEY_DSA) { bitlen = check_bitlen_dsa(EVP_PKEY_get0_DSA(pk), ispub, &magic); keyalg = MS_KEYALG_DSS_SIGN; } else if (pktype == EVP_PKEY_RSA) { bitlen = check_bitlen_rsa(EVP_PKEY_get0_RSA(pk), ispub, &magic); keyalg = MS_KEYALG_RSA_KEYX; } else return -1; if (bitlen == 0) return -1; outlen = 16 + blob_length(bitlen, keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub); if (out == NULL) return outlen; if (*out) p = *out; else { if ((p = OPENSSL_malloc(outlen)) == NULL) { PEMerr(PEM_F_DO_I2B, ERR_R_MALLOC_FAILURE); return -1; } *out = p; noinc = 1; } if (ispub) *p++ = MS_PUBLICKEYBLOB; else *p++ = MS_PRIVATEKEYBLOB; *p++ = 0x2; *p++ = 0; *p++ = 0; write_ledword(&p, keyalg); write_ledword(&p, magic); write_ledword(&p, bitlen); if (keyalg == MS_KEYALG_DSS_SIGN) write_dsa(&p, EVP_PKEY_get0_DSA(pk), ispub); else write_rsa(&p, EVP_PKEY_get0_RSA(pk), ispub); if (!noinc) *out += outlen; return outlen; }
/** Returns a friendly identifier for the public key type of a certificate * * @param[in] cert The X509 cert to return the type of. * @return the type string. */ char const *tls_utils_x509_pkey_type(X509 *cert) { EVP_PKEY *pkey; int pkey_type; char const *type_str; if (!cert) return NULL; pkey = X509_get_pubkey(cert); if (!pkey) return NULL; pkey_type = EVP_PKEY_type(EVP_PKEY_id(pkey)); type_str = fr_int2str(pkey_types, pkey_type, OBJ_nid2sn(pkey_type)); EVP_PKEY_free(pkey); return type_str; }
soter_status_t soter_rsa_import_key(EVP_PKEY *pkey, const void* key, const size_t key_length) { const soter_container_hdr_t *hdr = key; if (!pkey){ return SOTER_INVALID_PARAMETER; } if (EVP_PKEY_RSA != EVP_PKEY_id(pkey) || key_length < sizeof(soter_container_hdr_t)){ return SOTER_INVALID_PARAMETER; } switch (hdr->tag[0]){ case 'R': return soter_rsa_priv_key_to_engine_specific(hdr, key_length, ((soter_engine_specific_rsa_key_t **)&pkey)); case 'U': return soter_rsa_pub_key_to_engine_specific(hdr, key_length, ((soter_engine_specific_rsa_key_t **)&pkey)); } return SOTER_INVALID_PARAMETER; }
soter_status_t soter_rsa_gen_key(EVP_PKEY_CTX *pkey_ctx) { /* it is copy-paste from /src/soter/openssl/soter_asym_cipher.c */ BIGNUM *pub_exp; EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pkey_ctx); if (!pkey){ return SOTER_INVALID_PARAMETER; } if (EVP_PKEY_RSA != EVP_PKEY_id(pkey)){ return SOTER_INVALID_PARAMETER; } if (!EVP_PKEY_keygen_init(pkey_ctx)){ return SOTER_INVALID_PARAMETER; } /* Although it seems that OpenSSL/LibreSSL use 0x10001 as default public exponent, we will set it explicitly just in case */ pub_exp = BN_new(); if (!pub_exp){ return SOTER_NO_MEMORY; } if (!BN_set_word(pub_exp, RSA_F4)){ BN_free(pub_exp); return SOTER_FAIL; } if (1 > EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pub_exp)){ BN_free(pub_exp); return SOTER_FAIL; } /* Override default key size for RSA key. Currently OpenSSL has default key size of 1024. LibreSSL has 2048. We will put 2048 explicitly */ if (1 > EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_RSA_KEYGEN_BITS, SOTER_RSA_KEY_LENGTH, NULL)){ return SOTER_FAIL; } if(!EVP_PKEY_keygen(pkey_ctx, &pkey)){ return SOTER_FAIL; } return SOTER_SUCCESS; /* end of copy-paste from /src/soter/openssl/soter_asym_cipher.c*/ }
int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl, EVP_PKEY *priv) { int ret = -1; #ifndef OPENSSL_NO_RSA if (EVP_PKEY_id(priv) != EVP_PKEY_RSA) { #endif EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA); #ifndef OPENSSL_NO_RSA goto err; } ret = RSA_private_decrypt(ekl, ek, key, EVP_PKEY_get0_RSA(priv), RSA_PKCS1_PADDING); err: #endif return ret; }
int i2d_PublicKey(const EVP_PKEY *a, unsigned char **pp) { switch (EVP_PKEY_id(a)) { #ifndef OPENSSL_NO_RSA case EVP_PKEY_RSA: return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(a), pp); #endif #ifndef OPENSSL_NO_DSA case EVP_PKEY_DSA: return i2d_DSAPublicKey(EVP_PKEY_get0_DSA(a), pp); #endif #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: return i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY(a), pp); #endif default: ASN1err(ASN1_F_I2D_PUBLICKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); return -1; } }
int x509_digest_verify_init(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) { /* Convert the signature OID into digest and public key OIDs. */ int sigalg_nid = OBJ_obj2nid(sigalg->algorithm); int digest_nid, pkey_nid; if (!OBJ_find_sigid_algs(sigalg_nid, &digest_nid, &pkey_nid)) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); return 0; } /* Check the public key OID matches the public key type. */ if (pkey_nid != EVP_PKEY_id(pkey)) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_PUBLIC_KEY_TYPE); return 0; } /* NID_undef signals that there are custom parameters to set. */ if (digest_nid == NID_undef) { if (sigalg_nid == NID_rsassaPss) { return x509_rsa_pss_to_ctx(ctx, sigalg, pkey); } if (sigalg_nid == NID_ED25519) { if (sigalg->parameter != NULL) { OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PARAMETER); return 0; } return EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey); } OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); return 0; } /* Otherwise, initialize with the digest from the OID. */ const EVP_MD *digest = EVP_get_digestbynid(digest_nid); if (digest == NULL) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); return 0; } return EVP_DigestVerifyInit(ctx, NULL, digest, NULL, pkey); }