/* Retrieve EC point from cert into ec * return nonzero on error */ static int pkcs11_get_point_cert(EC_KEY *ec, PKCS11_CERT *cert) { EVP_PKEY *pubkey = NULL; EC_KEY *pubkey_ec; const EC_POINT *point; int rv = -1; if (cert == NULL) goto error; #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) pubkey = X509_get0_pubkey(cert->x509); #else pubkey = X509_get_pubkey(cert->x509); #endif if (pubkey == NULL) goto error; pubkey_ec = EVP_PKEY_get0_EC_KEY(pubkey); if (pubkey_ec == NULL) goto error; point = EC_KEY_get0_public_key(pubkey_ec); if (point == NULL) goto error; if (EC_KEY_set_public_key(ec, point) == 0) goto error; rv = 0; error: #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) EVP_PKEY_free(pubkey); #endif return rv; }
static int ssl_verify_ecdsa(SSL *ssl, const uint8_t *signature, size_t signature_len, int curve, const EVP_MD *md, EVP_PKEY *pkey, const uint8_t *in, size_t in_len) { EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); if (ec_key == NULL) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } /* In TLS 1.3, the curve is also specified by the signature algorithm. */ if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION && (curve == NID_undef || EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) != curve)) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } EVP_MD_CTX md_ctx; EVP_MD_CTX_init(&md_ctx); int ret = EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, pkey) && EVP_DigestVerifyUpdate(&md_ctx, in, in_len) && EVP_DigestVerifyFinal(&md_ctx, signature, signature_len); EVP_MD_CTX_cleanup(&md_ctx); return ret; }
static int cardfingerprint(void *ctx,char *file,void *out) { int r=NOCARD; int len; EVP_PKEY *key; RSA *rsa=NULL; EC_KEY *ec=NULL; ENGINE *e=(ENGINE *)ctx; unsigned char bfr[2048]; unsigned char *p=bfr; resume_engine(e,engbits); if(!(key=ENGINE_load_public_key(e,file,NULL,NULL)))goto err1; r=CRYPTOFAIL; #if OPENSSL_VERSION_NUMBER >= 0x1010000fL if(EVP_PKEY_get0_RSA(key)) { if(!(rsa=EVP_PKEY_get1_RSA(key)))goto err2; if((len=i2d_RSA_PUBKEY(rsa,NULL))>sizeof(bfr))goto err3; if(i2d_RSA_PUBKEY(rsa,&p)!=len)goto err3; } else if(EVP_PKEY_get0_EC_KEY(key)) { if(!(ec=EVP_PKEY_get1_EC_KEY(key)))goto err2; if((len=i2d_EC_PUBKEY(ec,NULL))>sizeof(bfr))goto err3; if(i2d_EC_PUBKEY(ec,&p)!=len)goto err3; } else goto err2; #else switch(EVP_PKEY_type(key->type)) { case EVP_PKEY_RSA: if(!(rsa=EVP_PKEY_get1_RSA(key)))goto err2; if((len=i2d_RSA_PUBKEY(rsa,NULL))>sizeof(bfr))goto err3; if(i2d_RSA_PUBKEY(rsa,&p)!=len)goto err3; break; case EVP_PKEY_EC: if(!(ec=EVP_PKEY_get1_EC_KEY(key)))goto err2; if((len=i2d_EC_PUBKEY(ec,NULL))>sizeof(bfr))goto err3; if(i2d_EC_PUBKEY(ec,&p)!=len)goto err3; break; default:goto err2; } #endif if(out)sha256(bfr,len,out); r=OK; err3: if(rsa)RSA_free(rsa); if(ec)EC_KEY_free(ec); memclear(bfr,0,sizeof(bfr)); err2: EVP_PKEY_free(key); err1: suspend_engine(e,&engbits); return r; }
EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) { EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); if (ec_key != NULL) { EC_KEY_up_ref(ec_key); } return ec_key; }
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; }
EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) { EC_KEY *ret = EVP_PKEY_get0_EC_KEY(pkey); if (ret != NULL) EC_KEY_up_ref(ret); return ret; }
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; }
static int ssl_sign_ecdsa(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, int curve, const EVP_MD *md, const uint8_t *in, size_t in_len) { EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ssl->cert->privatekey); if (ec_key == NULL) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } /* In TLS 1.3, the curve is also specified by the signature algorithm. */ if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION && (curve == NID_undef || EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) != curve)) { OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); *out_len = max_out; int ret = EVP_DigestSignInit(&ctx, NULL, md, NULL, ssl->cert->privatekey) && EVP_DigestSignUpdate(&ctx, in, in_len) && EVP_DigestSignFinal(&ctx, out, out_len); EVP_MD_CTX_cleanup(&ctx); return ret; }
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_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) { EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(private_key); if (ec_key == NULL || EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) != 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; }
int ssl_private_key_supports_signature_algorithm(SSL *ssl, uint16_t signature_algorithm) { const EVP_MD *md; if (is_rsa_pkcs1(&md, signature_algorithm)) { return ssl_private_key_type(ssl) == EVP_PKEY_RSA; } int curve; if (is_ecdsa(&curve, &md, signature_algorithm)) { if (ssl_private_key_type(ssl) != EVP_PKEY_EC) { return 0; } /* For non-custom keys, also check the curve matches. Custom private keys * must instead configure the signature algorithms accordingly. */ if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION && ssl->cert->key_method == NULL) { EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ssl->cert->privatekey); if (curve == NID_undef || EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) != curve) { return 0; } } return 1; } if (is_rsa_pss(&md, signature_algorithm)) { if (ssl3_protocol_version(ssl) < TLS1_3_VERSION || ssl_private_key_type(ssl) != EVP_PKEY_RSA) { return 0; } /* Ensure the RSA key is large enough for the hash. RSASSA-PSS requires that * emLen be at least hLen + sLen + 2. Both hLen and sLen are the size of the * hash in TLS. Reasonable RSA key sizes are large enough for the largest * defined RSASSA-PSS algorithm, but 1024-bit RSA is slightly too large for * SHA-512. 1024-bit RSA is sometimes used for test credentials, so check * the size to fall back to another algorithm. */ if (ssl_private_key_max_signature_len(ssl) < 2 * EVP_MD_size(md) + 2) { return 0; } return 1; } return 0; }
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 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; }
PKI_X509_CERT * PKI_X509_CERT_new (const PKI_X509_CERT * ca_cert, const PKI_X509_KEYPAIR * kPair, const PKI_X509_REQ * req, const char * subj_s, const char * serial_s, uint64_t validity, const PKI_X509_PROFILE * conf, const PKI_ALGOR * algor, const PKI_CONFIG * oids, HSM *hsm ) { PKI_X509_CERT *ret = NULL; PKI_X509_CERT_VALUE *val = NULL; PKI_X509_NAME *subj = NULL; PKI_X509_NAME *issuer = NULL; PKI_DIGEST_ALG *digest = NULL; PKI_X509_KEYPAIR_VALUE *signingKey = NULL; PKI_TOKEN *tk = NULL; PKI_X509_KEYPAIR_VALUE *certPubKeyVal = NULL; int rv = 0; int ver = 2; int64_t notBeforeVal = 0; ASN1_INTEGER *serial = NULL; char *ver_s = NULL; /* Check if the REQUIRED PKEY has been passed */ if (!kPair || !kPair->value) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return (NULL); }; signingKey = kPair->value; /* TODO: This has to be fixed, to work on every option */ if ( subj_s ) { subj = PKI_X509_NAME_new ( subj_s ); } else if (conf || req) { char *tmp_s = NULL; // Let's use the configuration option first if (conf) { // Get the value of the DN, if present if ((tmp_s = PKI_CONFIG_get_value( conf, "/profile/subject/dn")) != NULL ) { // Builds from the DN in the config subj = PKI_X509_NAME_new(tmp_s); PKI_Free ( tmp_s ); } } // If we still do not have a name, let's check // the request for one if (req && !subj) { const PKI_X509_NAME * req_subj = NULL; // Copy the name from the request if ((req_subj = PKI_X509_REQ_get_data(req, PKI_X509_DATA_SUBJECT)) != NULL) { subj = PKI_X509_NAME_dup(req_subj); } } // If no name is provided, let's use an empty one // TODO: Shall we remove this and fail instead ? if (!subj) subj = PKI_X509_NAME_new( "" ); } else { struct utsname myself; char tmp_name[1024]; if (uname(&myself) < 0) { subj = PKI_X509_NAME_new( "" ); } else { sprintf( tmp_name, "CN=%s", myself.nodename ); subj = PKI_X509_NAME_new( tmp_name ); } } if (!subj) { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SUBJECT, subj_s ); goto err; } if( ca_cert ) { const PKI_X509_NAME *ca_subject = NULL; /* Let's get the ca_cert subject and dup that data */ // ca_subject = (PKI_X509_NAME *) // X509_get_subject_name( (X509 *) ca_cert ); ca_subject = PKI_X509_CERT_get_data( ca_cert, PKI_X509_DATA_SUBJECT ); if( ca_subject ) { issuer = (PKI_X509_NAME *) X509_NAME_dup((X509_NAME *)ca_subject); } else { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_ISSUER, NULL); goto err; } } else { issuer = (PKI_X509_NAME *) X509_NAME_dup((X509_NAME *) subj); } if( !issuer ) { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_ISSUER, NULL); goto err; } if(( ret = PKI_X509_CERT_new_null()) == NULL ) { PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL); goto err; } /* Alloc memory structure for the Certificate */ if((ret->value = ret->cb->create()) == NULL ) { PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL); return (NULL); } val = ret->value; if(( ver_s = PKI_CONFIG_get_value( conf, "/profile/version")) != NULL ) { ver = atoi( ver_s ) - 1; if ( ver < 0 ) ver = 0; PKI_Free ( ver_s ); } else { ver = 2; }; if (!X509_set_version(val,ver)) { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_VERSION, NULL); goto err; } if (serial_s) { char * tmp_s = (char *) serial_s; serial = s2i_ASN1_INTEGER(NULL, tmp_s); } else { // If cacert we assume it is a normal cert - let's create a // random serial number, otherwise - it's a self-signed, use // the usual 'fake' 0 if ( ca_cert ) { unsigned char bytes[11]; RAND_bytes(bytes, sizeof(bytes)); bytes[0] = 0; serial = PKI_INTEGER_new_bin(bytes, sizeof(bytes)); } else { serial = s2i_ASN1_INTEGER( NULL, "0"); }; }; if(!X509_set_serialNumber( val, serial )) { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SERIAL, serial_s); goto err; } /* Set the issuer Name */ // rv = X509_set_issuer_name((X509 *) ret, (X509_NAME *) issuer); if(!X509_set_issuer_name( val, (X509_NAME *) issuer)) { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_ISSUER, NULL); goto err; } /* Set the subject Name */ if(!X509_set_subject_name(val, (X509_NAME *) subj)) { PKI_ERROR(PKI_ERR_X509_CERT_CREATE_SUBJECT, NULL); goto err; } /* Set the start date (notBefore) */ if (conf) { int years = 0; int days = 0; int hours = 0; int mins = 0; int secs = 0; char *tmp_s = NULL; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/notBefore/years")) != NULL ) { years = atoi( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/notBefore/days")) != NULL ) { days = atoi( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/notBefore/hours")) != NULL ) { hours = atoi( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/notBefore/minutes")) != NULL ) { mins = atoi( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/notBefore/seconds")) != NULL ) { secs = atoi( tmp_s ); PKI_Free ( tmp_s ); }; notBeforeVal = secs + ( mins * 60 ) + ( hours * 3600 ) + ( days * 3600 * 24 ) + ( years * 3600 * 24 * 365 ); }; /* Set the validity (notAfter) */ if( conf && validity == 0 ) { long long years = 0; long long days = 0; long long hours = 0; long long mins = 0; long long secs = 0; char *tmp_s = NULL; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/validity/years")) != NULL ) { years = atoll( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/validity/days")) != NULL ) { days = atoll( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/validity/hours")) != NULL ) { hours = atoll( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/validity/minutes")) != NULL ) { mins = atoll( tmp_s ); PKI_Free ( tmp_s ); }; if(( tmp_s = PKI_CONFIG_get_value( conf, "/profile/validity/minutes")) != NULL ) { secs = atoll( tmp_s ); PKI_Free ( tmp_s ); }; validity = (unsigned long long) secs + (unsigned long long) ( mins * 60 ) + (unsigned long long) ( hours * 3600 ) + (unsigned long long) ( days * 3600 * 24 ) + (unsigned long long) ( years * 3600 * 24 * 365 ); }; if (validity <= 0) validity = 30 * 3600 * 24; #if ( LIBPKI_OS_BITS == LIBPKI_OS32 ) long notBeforeVal32 = (long) notBeforeVal; if (X509_gmtime_adj(X509_get_notBefore(val), notBeforeVal32 ) == NULL) { #else if (X509_gmtime_adj(X509_get_notBefore(val), notBeforeVal ) == NULL) { #endif PKI_ERROR(PKI_ERR_X509_CERT_CREATE_NOTBEFORE, NULL); goto err; } /* Set the end date in a year */ if (X509_gmtime_adj(X509_get_notAfter(val),(long int) validity) == NULL) { PKI_DEBUG("ERROR: can not set notAfter field!"); goto err; } /* Copy the PKEY if it is in the request, otherwise use the public part of the PKI_X509_CERT */ if (req) { certPubKeyVal = (PKI_X509_KEYPAIR_VALUE *) PKI_X509_REQ_get_data(req, PKI_X509_DATA_KEYPAIR_VALUE); if( !certPubKeyVal ) { PKI_DEBUG("ERROR, can not get pubkey from req!"); goto err; } } else { /* Self Signed -- Same Public Key! */ certPubKeyVal = signingKey; } if (!ca_cert && conf) { char *tmp_s = NULL; if(( tmp_s = PKI_X509_PROFILE_get_value( conf, "/profile/keyParams/algorithm")) != NULL ) { PKI_ALGOR *myAlg = NULL; PKI_DIGEST_ALG *dgst = NULL; if((myAlg = PKI_ALGOR_get_by_name( tmp_s )) != NULL ) { if(!algor) algor = myAlg; if((dgst = PKI_ALGOR_get_digest( myAlg )) != NULL ) { PKI_DEBUG("Got Signing Algorithm: %s, %s", PKI_DIGEST_ALG_get_parsed(dgst), PKI_ALGOR_get_parsed(myAlg)); digest = dgst; } else { PKI_DEBUG("Can not parse digest algorithm from %s", tmp_s); } } else { PKI_DEBUG("Can not parse key algorithm from %s", tmp_s); } PKI_Free ( tmp_s ); } } if (conf) { PKI_KEYPARAMS *kParams = NULL; PKI_SCHEME_ID scheme; scheme = PKI_ALGOR_get_scheme( algor ); kParams = PKI_KEYPARAMS_new(scheme, conf); if (kParams) { /* Sets the point compression */ switch ( kParams->scheme ) { #ifdef ENABLE_ECDSA case PKI_SCHEME_ECDSA: if ( (int) kParams->ec.form > 0 ) { # if OPENSSL_VERSION_NUMBER < 0x1010000fL EC_KEY_set_conv_form(certPubKeyVal->pkey.ec, (point_conversion_form_t) kParams->ec.form); # else EC_KEY_set_conv_form(EVP_PKEY_get0_EC_KEY(certPubKeyVal), (point_conversion_form_t) kParams->ec.form); # endif } if ( kParams->ec.asn1flags > -1 ) { # if OPENSSL_VERSION_NUMBER < 0x1010000fL EC_KEY_set_asn1_flag(certPubKeyVal->pkey.ec, kParams->ec.asn1flags ); # else EC_KEY_set_asn1_flag(EVP_PKEY_get0_EC_KEY(certPubKeyVal), kParams->ec.asn1flags ); # endif } break; #endif case PKI_SCHEME_RSA: case PKI_SCHEME_DSA: break; default: // Nothing to do PKI_ERROR(PKI_ERR_GENERAL, "Signing Scheme Uknown %d!", kParams->scheme); break; } } } if (!X509_set_pubkey(val, certPubKeyVal)) { PKI_DEBUG("ERROR, can not set pubkey in cert!"); goto err; } if (conf) { if((tk = PKI_TOKEN_new_null()) == NULL ) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); goto err; } PKI_TOKEN_set_cert(tk, ret); if (ca_cert) { PKI_TOKEN_set_cacert(tk, (PKI_X509_CERT *)ca_cert); } else { PKI_TOKEN_set_cacert(tk, (PKI_X509_CERT *)ret); } if (req) PKI_TOKEN_set_req(tk, (PKI_X509_REQ *)req ); if (kPair) PKI_TOKEN_set_keypair ( tk, (PKI_X509_KEYPAIR *)kPair ); rv = PKI_X509_EXTENSIONS_cert_add_profile(conf, oids, ret, tk); if (rv != PKI_OK) { PKI_DEBUG( "ERROR, can not set extensions!"); tk->cert = NULL; tk->cacert = NULL; tk->req = NULL; tk->keypair = NULL; PKI_TOKEN_free ( tk ); goto err; } // Cleanup for the token (used only to add extensions) tk->cert = NULL; tk->cacert = NULL; tk->req = NULL; tk->keypair = NULL; PKI_TOKEN_free ( tk ); } if (!digest) { if (!algor) { PKI_log_debug("Getting the Digest Algorithm from the CA cert"); // Let's get the Digest Algorithm from the CA Cert if (ca_cert) { if((algor = PKI_X509_CERT_get_data(ca_cert, PKI_X509_DATA_ALGORITHM )) == NULL) { PKI_log_err("Can not retrieve DATA algorithm from CA cert"); } } } // If we have an Algor from either the passed argument or // the CA Certificate, extract the digest from it. Otherwise // get the digest from the signing key if (algor) { if((digest = PKI_ALGOR_get_digest(algor)) == NULL ) { PKI_log_err("Can not get digest from algor"); } } // Check, if still no digest, let's try from the signing Key if (digest == NULL) { if ((digest = PKI_DIGEST_ALG_get_by_key( kPair )) == NULL) { PKI_log_err("Can not infer digest algor from the key pair"); } } } // No Digest Here ? We failed... if (digest == NULL) { PKI_log_err("PKI_X509_CERT_new()::Can not get the digest!"); return( NULL ); } // Sign the data if (PKI_X509_sign(ret, digest, kPair) == PKI_ERR) { PKI_log_err ("Can not sign certificate [%s]", ERR_error_string(ERR_get_error(), NULL )); PKI_X509_CERT_free ( ret ); return NULL; } #if ( OPENSSL_VERSION_NUMBER >= 0x0090900f ) # if OPENSSL_VERSION_NUMBER < 0x1010000fL PKI_X509_CERT_VALUE *cVal = (PKI_X509_CERT_VALUE *) ret->value; if (cVal && cVal->cert_info) { PKI_log_debug("Signature = %s", PKI_ALGOR_get_parsed(cVal->cert_info->signature)); } # endif // PKI_X509_CINF_FULL *cFull = NULL; // cFull = (PKI_X509_CINF_FULL *) cVal->cert_info; // cFull->enc.modified = 1; #endif return ret; err: if (ret) PKI_X509_CERT_free(ret); if (subj) PKI_X509_NAME_free(subj); if (issuer) PKI_X509_NAME_free(issuer); return NULL; } /*! * \brief Signs a PKI_X509_CERT */ int PKI_X509_CERT_sign(PKI_X509_CERT *cert, PKI_X509_KEYPAIR *kp, PKI_DIGEST_ALG *digest) { const PKI_ALGOR *alg = NULL; if( !cert || !cert->value || !kp || !kp->value ) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return PKI_ERR; } if(!digest) { if((alg = PKI_X509_CERT_get_data(cert, PKI_X509_DATA_ALGORITHM))!=NULL) { digest = PKI_ALGOR_get_digest ( alg ); } } if(!digest) { if((digest = PKI_DIGEST_ALG_get_by_key(kp)) == NULL) { PKI_log_err("PKI_X509_CERT_new()::Can not get digest algor " "from key"); return PKI_ERR; } } if( PKI_X509_sign(cert, digest, kp) == PKI_ERR) { PKI_log_err ("PKI_X509_CERT_new()::Can not sign certificate [%s]", ERR_error_string(ERR_get_error(), NULL )); return PKI_ERR; } return PKI_OK; }; /*! * \brief Signs a PKI_X509_CERT by using a configured PKI_TOKEN */ int PKI_X509_CERT_sign_tk ( PKI_X509_CERT *cert, PKI_TOKEN *tk, PKI_DIGEST_ALG *digest) { PKI_X509_KEYPAIR *kp = NULL; if( !cert || !cert->value || !tk ) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return PKI_ERR; }; if( PKI_TOKEN_login( tk ) == PKI_ERR ) { PKI_ERROR(PKI_ERR_HSM_LOGIN, NULL); return PKI_ERR; }; if((kp = PKI_TOKEN_get_keypair( tk )) == NULL ) { return PKI_ERR; }; return PKI_X509_CERT_sign ( cert, kp, digest ); };
static int is_p256_key(EVP_PKEY *private_key) { const EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(private_key); return ec_key != NULL && EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) == NID_X9_62_prime256v1; }
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; case ASN1_PKEY_CTRL_SET1_TLS_ENCPT: return EC_KEY_oct2key(EVP_PKEY_get0_EC_KEY(pkey), arg2, arg1, NULL); case ASN1_PKEY_CTRL_GET1_TLS_ENCPT: return EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(pkey), POINT_CONVERSION_UNCOMPRESSED, arg2, NULL); default: return -2; } }
static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, const char *keyfile, int keyform, int key_type, char *passinarg, int pkey_op, ENGINE *e, const int engine_impl, EVP_PKEY **ppkey) { EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; ENGINE *impl = NULL; char *passin = NULL; int rv = -1; X509 *x; if (((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT) || (pkey_op == EVP_PKEY_OP_DERIVE)) && (key_type != KEY_PRIVKEY && kdfalg == NULL)) { BIO_printf(bio_err, "A private key is needed for this operation\n"); goto end; } if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } switch (key_type) { case KEY_PRIVKEY: pkey = load_key(keyfile, keyform, 0, passin, e, "Private Key"); break; case KEY_PUBKEY: pkey = load_pubkey(keyfile, keyform, 0, NULL, e, "Public Key"); break; case KEY_CERT: x = load_cert(keyfile, keyform, "Certificate"); if (x) { pkey = X509_get_pubkey(x); X509_free(x); } break; case KEY_NONE: break; } #ifndef OPENSSL_NO_ENGINE if (engine_impl) impl = e; #endif if (kdfalg != NULL) { int kdfnid = OBJ_sn2nid(kdfalg); if (kdfnid == NID_undef) { kdfnid = OBJ_ln2nid(kdfalg); if (kdfnid == NID_undef) { BIO_printf(bio_err, "The given KDF \"%s\" is unknown.\n", kdfalg); goto end; } } ctx = EVP_PKEY_CTX_new_id(kdfnid, impl); } else { EC_KEY *eckey = NULL; const EC_GROUP *group = NULL; int nid; if (pkey == NULL) goto end; /* SM2 needs a special treatment */ if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { if ((eckey = EVP_PKEY_get0_EC_KEY(pkey)) == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || (nid = EC_GROUP_get_curve_name(group)) == 0) goto end; if (nid == NID_sm2) EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2); } *pkeysize = EVP_PKEY_size(pkey); ctx = EVP_PKEY_CTX_new(pkey, impl); if (ppkey != NULL) *ppkey = pkey; EVP_PKEY_free(pkey); } if (ctx == NULL) goto end; switch (pkey_op) { case EVP_PKEY_OP_SIGN: rv = EVP_PKEY_sign_init(ctx); break; case EVP_PKEY_OP_VERIFY: rv = EVP_PKEY_verify_init(ctx); break; case EVP_PKEY_OP_VERIFYRECOVER: rv = EVP_PKEY_verify_recover_init(ctx); break; case EVP_PKEY_OP_ENCRYPT: rv = EVP_PKEY_encrypt_init(ctx); break; case EVP_PKEY_OP_DECRYPT: rv = EVP_PKEY_decrypt_init(ctx); break; case EVP_PKEY_OP_DERIVE: rv = EVP_PKEY_derive_init(ctx); break; } if (rv <= 0) { EVP_PKEY_CTX_free(ctx); ctx = NULL; } end: OPENSSL_free(passin); return ctx; }
static int certfingerprint(char *file,void *out) { int r=FILEFAIL; int len; BIO *cert; X509 *x509; EVP_PKEY *key; RSA *rsa=NULL; EC_KEY *ec=NULL; unsigned char bfr[2048]; unsigned char *p=bfr; if(!(cert=BIO_new(BIO_s_file())))goto err1; if(BIO_read_filename(cert,file)<=0)goto err2; r=CRYPTOFAIL; if(!(x509=PEM_read_bio_X509_AUX(cert,NULL,NULL,NULL)))goto err2; if(!(key=X509_get_pubkey(x509)))goto err3; #if OPENSSL_VERSION_NUMBER >= 0x1010000fL if(EVP_PKEY_get0_RSA(key)) { if(!(rsa=EVP_PKEY_get1_RSA(key)))goto err4; if((len=i2d_RSA_PUBKEY(rsa,NULL))>sizeof(bfr))goto err5; if(i2d_RSA_PUBKEY(rsa,&p)!=len)goto err5; } else if(EVP_PKEY_get0_EC_KEY(key)) { if(!(ec=EVP_PKEY_get1_EC_KEY(key)))goto err4; if((len=i2d_EC_PUBKEY(ec,NULL))>sizeof(bfr))goto err5; if(i2d_EC_PUBKEY(ec,&p)!=len)goto err5; } else goto err4; #else switch(EVP_PKEY_type(key->type)) { case EVP_PKEY_RSA: if(!(rsa=EVP_PKEY_get1_RSA(key)))goto err4; if((len=i2d_RSA_PUBKEY(rsa,NULL))>sizeof(bfr))goto err5; if(i2d_RSA_PUBKEY(rsa,&p)!=len)goto err5; break; case EVP_PKEY_EC: if(!(ec=EVP_PKEY_get1_EC_KEY(key)))goto err4; if((len=i2d_EC_PUBKEY(ec,NULL))>sizeof(bfr))goto err5; if(i2d_EC_PUBKEY(ec,&p)!=len)goto err5; break; default:goto err4; } #endif if(out)sha256(bfr,len,out); r=OK; err5: if(rsa)RSA_free(rsa); if(ec)EC_KEY_free(ec); err4: EVP_PKEY_free(key); err3: X509_free(x509); err2: BIO_free(cert); err1: return r; }