int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type) { if (pkey->type == type) { return 1; /* it already is that type */ } /* * The application is requesting to alias this to a different pkey type, * but not one that resolves to the base type. */ if (EVP_PKEY_type(type) != EVP_PKEY_base_id(pkey)) { EVPerr(EVP_F_EVP_PKEY_SET_ALIAS_TYPE, EVP_R_UNSUPPORTED_ALGORITHM); return 0; } pkey->type = type; return 1; }
VALUE ossl_ec_new(EVP_PKEY *pkey) { VALUE obj; if (!pkey) { obj = ec_instance(cEC, EC_KEY_new()); } else { if (EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) { ossl_raise(rb_eTypeError, "Not a EC key!"); } WrapPKey(cEC, obj, pkey); } if (obj == Qfalse) { ossl_raise(eECError, NULL); } return obj; }
QString pki_key::getTypeString() { QString type; switch (EVP_PKEY_type(key->type)) { case EVP_PKEY_RSA: type = "RSA"; break; case EVP_PKEY_DSA: type = "DSA"; break; case EVP_PKEY_EC: type = "EC"; break; default: type = "---"; } return type; }
/* static */ Key* Key::ImportKey(const AuthorizationSet& key_description, keymaster_key_format_t key_format, const uint8_t* key_data, size_t key_data_length, const Logger& logger, keymaster_error_t* error) { *error = KM_ERROR_OK; if (key_data == NULL || key_data_length <= 0) { *error = KM_ERROR_INVALID_KEY_BLOB; return NULL; } if (key_format != KM_KEY_FORMAT_PKCS8) { *error = KM_ERROR_UNSUPPORTED_KEY_FORMAT; return NULL; } UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> pkcs8( d2i_PKCS8_PRIV_KEY_INFO(NULL, &key_data, key_data_length)); if (pkcs8.get() == NULL) { *error = KM_ERROR_MEMORY_ALLOCATION_FAILED; return NULL; } UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKCS82PKEY(pkcs8.get())); if (pkey.get() == NULL) { *error = KM_ERROR_INVALID_KEY_BLOB; return NULL; } UniquePtr<Key> key; switch (EVP_PKEY_type(pkey->type)) { case EVP_PKEY_RSA: return RsaKey::ImportKey(key_description, pkey.get(), logger, error); case EVP_PKEY_DSA: return DsaKey::ImportKey(key_description, pkey.get(), logger, error); case EVP_PKEY_EC: return EcdsaKey::ImportKey(key_description, pkey.get(), logger, error); default: *error = KM_ERROR_UNSUPPORTED_ALGORITHM; return NULL; } *error = KM_ERROR_UNIMPLEMENTED; return NULL; }
VALUE ossl_dh_new(EVP_PKEY *pkey) { VALUE obj; if (!pkey) { obj = dh_instance(cDH, DH_new()); } else { if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DH) { ossl_raise(rb_eTypeError, "Not a DH key!"); } WrapPKey(cDH, obj, pkey); } if (obj == Qfalse) { ossl_raise(eDHError, NULL); } return obj; }
int load_and_print_pubkey(FILE* pemFile, int version) { assert(pemFile); EVP_PKEY* pubkey = PEM_read_PUBKEY(pemFile, NULL, NULL, NULL); if (!pubkey) { fprintf(stderr, "error: PEM_read_PUBKEY() failed.\n"); return 1; } if (EVP_PKEY_type(pubkey->type) != EVP_PKEY_EC) { fprintf(stderr, "error: PEM does not contain an EC key.\n"); EVP_PKEY_free(pubkey); return 1; } int result = extract_and_print_eckey(pubkey, version); EVP_PKEY_free(pubkey); return result; }
SEXP PKI_sign_RSA(SEXP what, SEXP sMD, SEXP sKey) { SEXP res; int md = asInteger(sMD), type; EVP_PKEY *key; RSA *rsa; unsigned int siglen = sizeof(buf); switch (md) { case PKI_MD5: type = NID_md5; break; case PKI_SHA1: type = NID_sha1; break; case PKI_SHA256: type = NID_sha256; break; default: Rf_error("unsupported hash type"); } if (TYPEOF(what) != RAWSXP || (md == PKI_MD5 && LENGTH(what) != MD5_DIGEST_LENGTH) || (md == PKI_SHA1 && LENGTH(what) != SHA_DIGEST_LENGTH) || (md == PKI_SHA256 && LENGTH(what) != SHA256_DIGEST_LENGTH)) Rf_error("invalid hash"); if (!inherits(sKey, "private.key")) Rf_error("key must be RSA private key"); key = (EVP_PKEY*) R_ExternalPtrAddr(sKey); if (!key) Rf_error("NULL key"); PKI_init(); if (EVP_PKEY_type(key->type) != EVP_PKEY_RSA) Rf_error("key must be RSA private key"); rsa = EVP_PKEY_get1_RSA(key); if (!rsa) Rf_error("%s", ERR_error_string(ERR_get_error(), NULL)); if (RSA_sign(type, (const unsigned char*) RAW(what), LENGTH(what), (unsigned char *) buf, &siglen, rsa) != 1) Rf_error("%s", ERR_error_string(ERR_get_error(), NULL)); res = allocVector(RAWSXP, siglen); memcpy(RAW(res), buf, siglen); return res; }
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; ret->save_type=type; ret->type=EVP_PKEY_type(type); switch (ret->type) { #ifndef OPENSSL_NO_RSA case EVP_PKEY_RSA: if ((ret->pkey.rsa=d2i_RSAPublicKey(NULL, (const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */ { 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; /* break; */ } if (a != NULL) (*a)=ret; return(ret); err: if ((ret != NULL) && ((a == NULL) || (*a != ret))) EVP_PKEY_free(ret); return(NULL); }
/** * Extract public key in PEM format. */ static int meth_pubkey(lua_State* L) { char* data; long bytes; int ret = 1; X509* cert = lsec_checkx509(L, 1); BIO *bio = BIO_new(BIO_s_mem()); EVP_PKEY *pkey = X509_get_pubkey(cert); if(PEM_write_bio_PUBKEY(bio, pkey)) { bytes = BIO_get_mem_data(bio, &data); if (bytes > 0) { lua_pushlstring(L, data, bytes); switch(EVP_PKEY_type(pkey->type)) { case EVP_PKEY_RSA: lua_pushstring(L, "RSA"); break; case EVP_PKEY_DSA: lua_pushstring(L, "DSA"); break; case EVP_PKEY_DH: lua_pushstring(L, "DH"); break; case EVP_PKEY_EC: lua_pushstring(L, "EC"); break; default: lua_pushstring(L, "Unknown"); break; } lua_pushinteger(L, EVP_PKEY_bits(pkey)); ret = 3; } else lua_pushnil(L); } else lua_pushnil(L); /* Cleanup */ BIO_free(bio); EVP_PKEY_free(pkey); return ret; }
int syslog_sign_init() { SSL *ssl; sign_global_conf = EVP_MD_CTX_create(); EVP_MD_CTX_init(sign_global_conf); if (ssl = SSL_new(ssl_global_conf)) { dprintf("Try to get keys from TLS X.509 cert...\n"); if (!(xcert = SSL_get_certificate(ssl))) { logerror("SSL_get_certificate() failed"); SSL_free(ssl); return EXIT_FAILURE; } if (!(eprivkey = SSL_get_privatekey(ssl))) { logerror("SSL_get_privatekey() failed"); SSL_free(ssl); return EXIT_FAILURE; } if (!(epubkey = X509_get_pubkey(xcert))) { logerror("X509_get_pubkey() failed"); SSL_free(ssl); return EXIT_FAILURE; } } SSL_free(ssl); if (EVP_PKEY_DSA != EVP_PKEY_type(epubkey->type)) { dprintf("X.509 cert has no DSA key\n"); EVP_PKEY_free(epubkey); eprivkey = NULL; epubkey = NULL; } else { dprintf("Got public and private key " "from X.509 --> use type PKIX\n"); sign_method = EVP_dss1(); } }
PKI_ALGOR * PKI_X509_KEYPAIR_VALUE_get_algor ( PKI_X509_KEYPAIR_VALUE *pVal ) { PKI_ALGOR *ret = NULL; int size = -1; int algId = -1; size = PKI_X509_KEYPAIR_VALUE_get_size(pVal); if (size <= 0) PKI_ERROR(PKI_ERR_GENERAL, "Key size is 0!"); switch (EVP_PKEY_type(pVal->type)) { case EVP_PKEY_DSA: algId = PKI_ALGOR_DSA_SHA1; break; case EVP_PKEY_RSA: algId = PKI_ALGOR_RSA_SHA256; break; #ifdef ENABLE_ECDSA case EVP_PKEY_EC: if ( size < 256 ) { algId = PKI_ALGOR_ECDSA_SHA1; } else if ( size < 384 ) { algId = PKI_ALGOR_ECDSA_SHA256; } else if ( size < 512 ) { algId = PKI_ALGOR_ECDSA_SHA384; } else { algId = PKI_ALGOR_ECDSA_SHA512; }; break; #endif default: return ret; }; if( algId > 0 ) ret = PKI_ALGOR_get ( algId ); return ret; };
int getPrivKeyType(EVP_PKEY *pkey) { int rValue = CERT_OBJECT_MAX_OBJECT; switch (EVP_PKEY_type(pkey->type)) { case EVP_PKEY_RSA: rValue = CERT_OBJECT_RSA_PRIVATE_KEY; break; case EVP_PKEY_DSA: rValue = CERT_OBJECT_DSA_PRIVATE_KEY; break; case EVP_PKEY_EC: rValue = CERT_OBJECT_EC_PRIVATE_KEY; break; } return rValue; }
TEST_P(KeymasterGenerateECTest, GenerateKeyPair_EC_Success) { keymaster_keypair_t key_type = TYPE_EC; keymaster_ec_keygen_params_t params = { .field_size = GetParam(), }; uint8_t* key_blob; size_t key_blob_length; ASSERT_EQ(0, sDevice->generate_keypair(sDevice, key_type, ¶ms, &key_blob, &key_blob_length)) << "Should generate an EC key with " << GetParam() << " field size"; UniqueKey key(&sDevice, key_blob, key_blob_length); uint8_t* x509_data = NULL; size_t x509_data_length; ASSERT_EQ(0, sDevice->get_keypair_public(sDevice, key_blob, key_blob_length, &x509_data, &x509_data_length)) << "Should be able to retrieve EC public key successfully"; UniqueBlob x509_blob(x509_data, x509_data_length); ASSERT_FALSE(x509_blob.get() == NULL) << "X509 data should be allocated"; const unsigned char *tmp = static_cast<const unsigned char*>(x509_blob.get()); Unique_EVP_PKEY actual(d2i_PUBKEY((EVP_PKEY**) NULL, &tmp, static_cast<long>(x509_blob.length()))); ASSERT_EQ(EVP_PKEY_EC, EVP_PKEY_type(actual.get()->type)) << "Generated key type should be of type EC"; Unique_EC_KEY ecKey(EVP_PKEY_get1_EC_KEY(actual.get())); ASSERT_FALSE(ecKey.get() == NULL) << "Should be able to extract EC key from EVP_PKEY"; ASSERT_FALSE(EC_KEY_get0_group(ecKey.get()) == NULL) << "EC key should have a EC_GROUP"; ASSERT_TRUE(EC_KEY_check_key(ecKey.get())) << "EC key should check correctly"; }
SEXP PKI_verify_RSA(SEXP what, SEXP sMD, SEXP sKey, SEXP sig) { int md = asInteger(sMD), type; EVP_PKEY *key; RSA *rsa; switch (md) { case PKI_MD5: type = NID_md5; break; case PKI_SHA1: type = NID_sha1; break; case PKI_SHA256: type = NID_sha256; break; default: Rf_error("unsupported hash type"); } if (TYPEOF(what) != RAWSXP || (md == PKI_MD5 && LENGTH(what) != MD5_DIGEST_LENGTH) || (md == PKI_SHA1 && LENGTH(what) != SHA_DIGEST_LENGTH) || (md == PKI_SHA256 && LENGTH(what) != SHA256_DIGEST_LENGTH)) Rf_error("invalid hash"); if (!inherits(sKey, "public.key") && !inherits(sKey, "private.key")) Rf_error("key must be RSA public or private key"); key = (EVP_PKEY*) R_ExternalPtrAddr(sKey); if (!key) Rf_error("NULL key"); if (EVP_PKEY_type(key->type) != EVP_PKEY_RSA) Rf_error("key must be RSA public or private key"); rsa = EVP_PKEY_get1_RSA(key); if (!rsa) Rf_error("%s", ERR_error_string(ERR_get_error(), NULL)); return ScalarLogical( /* FIXME: sig is not const in RSA_verify - that is odd so in theory in may modify sig ... */ (RSA_verify(type, (const unsigned char*) RAW(what), LENGTH(what), (unsigned char *) RAW(sig), LENGTH(sig), rsa) == 1) ? TRUE : FALSE); }
QSslKey SafetPKCS12::keyFromEVP( EVP_PKEY * evp ) { EVP_PKEY *key = (EVP_PKEY*)evp; unsigned char *data = NULL; int len = 0; QSsl::KeyAlgorithm alg; QSsl::KeyType type; switch( EVP_PKEY_type( key->type ) ) { case EVP_PKEY_RSA: { RSA *rsa = EVP_PKEY_get1_RSA( key ); alg = QSsl::Rsa; type = rsa->d ? QSsl::PrivateKey : QSsl::PublicKey; len = rsa->d ? i2d_RSAPrivateKey( rsa, &data ) : i2d_RSAPublicKey( rsa, &data ); RSA_free( rsa ); break; } case EVP_PKEY_DSA: { DSA *dsa = EVP_PKEY_get1_DSA( key ); alg = QSsl::Dsa; type = dsa->priv_key ? QSsl::PrivateKey : QSsl::PublicKey; len = dsa->priv_key ? i2d_DSAPrivateKey( dsa, &data ) : i2d_DSAPublicKey( dsa, &data ); DSA_free( dsa ); break; } default: break; } QSslKey k; if( len > 0 ) k = QSslKey( QByteArray( (char*)data, len ), alg, QSsl::Der, type ); OPENSSL_free( data ); return k; }
__attribute__((visibility("default"))) int openssl_sign_data( const keymaster0_device_t*, const void* params, const uint8_t* keyBlob, const size_t keyBlobLength, const uint8_t* data, const size_t dataLength, uint8_t** signedData, size_t* signedDataLength) { if (data == NULL) { ALOGW("input data to sign == NULL"); return -1; } else if (signedData == NULL || signedDataLength == NULL) { ALOGW("output signature buffer == NULL"); return -1; } Unique_EVP_PKEY pkey(unwrap_key(keyBlob, keyBlobLength)); if (pkey.get() == NULL) { return -1; } int type = EVP_PKEY_type(pkey->type); if (type == EVP_PKEY_DSA) { const keymaster_dsa_sign_params_t* sign_params = reinterpret_cast<const keymaster_dsa_sign_params_t*>(params); return sign_dsa(pkey.get(), const_cast<keymaster_dsa_sign_params_t*>(sign_params), data, dataLength, signedData, signedDataLength); } else if (type == EVP_PKEY_EC) { const keymaster_ec_sign_params_t* sign_params = reinterpret_cast<const keymaster_ec_sign_params_t*>(params); return sign_ec(pkey.get(), const_cast<keymaster_ec_sign_params_t*>(sign_params), data, dataLength, signedData, signedDataLength); } else if (type == EVP_PKEY_RSA) { const keymaster_rsa_sign_params_t* sign_params = reinterpret_cast<const keymaster_rsa_sign_params_t*>(params); return sign_rsa(pkey.get(), const_cast<keymaster_rsa_sign_params_t*>(sign_params), data, dataLength, signedData, signedDataLength); } else { ALOGW("Unsupported key type"); return -1; } }
int ep_crypto_keytype_fromkey(EP_CRYPTO_KEY *key) { int i = EVP_PKEY_type(key->type); switch (i) { case EVP_PKEY_RSA: return EP_CRYPTO_KEYTYPE_RSA; case EVP_PKEY_DSA: return EP_CRYPTO_KEYTYPE_DSA; case EVP_PKEY_DH: return EP_CRYPTO_KEYTYPE_DH; case EVP_PKEY_EC: return EP_CRYPTO_KEYTYPE_EC; default: return EP_CRYPTO_KEYTYPE_UNKNOWN; } }
static int ldns_pkey_is_ecdsa(EVP_PKEY* pkey) { EC_KEY* ec; const EC_GROUP* g; if(EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) return 0; ec = EVP_PKEY_get1_EC_KEY(pkey); g = EC_KEY_get0_group(ec); if(!g) { EC_KEY_free(ec); return 0; } if(EC_GROUP_get_curve_name(g) == NID_secp224r1 || EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1 || EC_GROUP_get_curve_name(g) == NID_secp384r1) { EC_KEY_free(ec); return 1; } /* downref the eckey, the original is still inside the pkey */ EC_KEY_free(ec); return 0; }
/** * Verify signature with RSA public key from X.509 certificate. * * @param digestMethod digest method (e.g NID_sha1 for SHA1, see openssl/obj_mac.h). * @param digest digest value, this value is compared with the digest value decrypted from the <code>signature</code>. * @param signature signature value, this value is decrypted to get the digest and compared with * the digest value provided in <code>digest</code>. * @return returns <code>true</code> if the signature value matches with the digest, otherwise <code>false</code> * is returned. * @throws IOException throws exception if X.509 certificate is not missing or does not have a RSA public key. */ bool digidoc::RSACrypt::verify(int digestMethod, std::vector<unsigned char> digest, std::vector<unsigned char> signature) throw(IOException) { // Check that X.509 certificate is set. if(cert == NULL) { THROW_IOEXCEPTION("X.509 certificate parameter is not set in RSACrypt, can not verify signature."); } // Extract RSA public key from X.509 certificate. X509Cert x509(cert); EVP_PKEY* key = x509.getPublicKey(); if(EVP_PKEY_type(key->type) != EVP_PKEY_RSA) { EVP_PKEY_free(key); THROW_IOEXCEPTION("Certificate '%s' does not have a RSA public key, can not verify signature.", x509.getSubject().c_str()); } RSA* publicKey = EVP_PKEY_get1_RSA(key); // Verify signature with RSA public key. int result = RSA_verify(digestMethod, &digest[0], digest.size(), &signature[0], signature.size(), publicKey); RSA_free(publicKey); EVP_PKEY_free(key); return (result == 1); }
SEXP PKI_decrypt(SEXP what, SEXP sKey) { SEXP res; EVP_PKEY *key; RSA *rsa; int len; if (TYPEOF(what) != RAWSXP) Rf_error("invalid payload to sign - must be a raw vector"); if (!inherits(sKey, "private.key")) Rf_error("invalid key object"); key = (EVP_PKEY*) R_ExternalPtrAddr(sKey); if (!key) Rf_error("NULL key"); if (EVP_PKEY_type(key->type) != EVP_PKEY_RSA) Rf_error("Sorry only RSA keys are supported at this point"); rsa = EVP_PKEY_get1_RSA(key); if (!rsa) Rf_error("%s", ERR_error_string(ERR_get_error(), NULL)); len = RSA_private_decrypt(LENGTH(what), RAW(what), (unsigned char*) buf, rsa, RSA_PKCS1_PADDING); if (len < 0) Rf_error("%s", ERR_error_string(ERR_get_error(), NULL)); res = allocVector(RAWSXP, len); memcpy(RAW(res), buf, len); return res; }
static LUA_FUNCTION(openssl_pkey_parse) { EVP_PKEY *pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); if (pkey->pkey.ptr) { lua_newtable(L); AUXILIAR_SET(L, -1, "bits", EVP_PKEY_bits(pkey), integer); AUXILIAR_SET(L, -1, "size", EVP_PKEY_size(pkey), integer); switch (EVP_PKEY_type(pkey->type)) { case EVP_PKEY_RSA: case EVP_PKEY_RSA2: { RSA* rsa = EVP_PKEY_get1_RSA(pkey); PUSH_OBJECT(rsa, "openssl.rsa"); lua_setfield(L, -2, "rsa"); AUXILIAR_SET(L, -1, "type", "rsa", string); } break; case EVP_PKEY_DSA: case EVP_PKEY_DSA2: case EVP_PKEY_DSA3: case EVP_PKEY_DSA4: { DSA* dsa = EVP_PKEY_get1_DSA(pkey); PUSH_OBJECT(dsa, "openssl.dsa"); lua_setfield(L, -2, "dsa"); AUXILIAR_SET(L, -1, "type", "dsa", string); } break; case EVP_PKEY_DH: { DH* dh = EVP_PKEY_get1_DH(pkey); PUSH_OBJECT(dh, "openssl.dh"); lua_rawseti(L, -2, 0); AUXILIAR_SET(L, -1, "type", "dh", string); } break; #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: { const EC_KEY* ec = EVP_PKEY_get1_EC_KEY(pkey); PUSH_OBJECT(ec, "openssl.ec_key"); lua_setfield(L, -2, "ec"); AUXILIAR_SET(L, -1, "type", "ec", string); } break; #endif default: break; }; return 1; } else luaL_argerror(L, 1, "not assign any keypair"); return 0; };
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) { EVP_PKEY *ret=NULL; long j; int type; const unsigned char *p; #if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA) const unsigned char *cp; X509_ALGOR *a; #endif if (key == NULL) goto err; if (key->pkey != NULL) { CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); return(key->pkey); } if (key->public_key == NULL) goto err; type=OBJ_obj2nid(key->algor->algorithm); if ((ret = EVP_PKEY_new()) == NULL) { X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); goto err; } ret->type = EVP_PKEY_type(type); /* the parameters must be extracted before the public key (ECDSA!) */ #if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA) a=key->algor; #endif if (0) ; #ifndef OPENSSL_NO_DSA else if (ret->type == EVP_PKEY_DSA) { if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) { if ((ret->pkey.dsa = DSA_new()) == NULL) { X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); goto err; } ret->pkey.dsa->write_params=0; cp=p=a->parameter->value.sequence->data; j=a->parameter->value.sequence->length; if (!d2i_DSAparams(&ret->pkey.dsa, &cp, (long)j)) goto err; } ret->save_parameters=1; } #endif #ifndef OPENSSL_NO_EC else if (ret->type == EVP_PKEY_EC) { if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) { /* type == V_ASN1_SEQUENCE => we have explicit parameters * (e.g. parameters in the X9_62_EC_PARAMETERS-structure ) */ if ((ret->pkey.ec= EC_KEY_new()) == NULL) { X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); goto err; } cp = p = a->parameter->value.sequence->data; j = a->parameter->value.sequence->length; if (!d2i_ECParameters(&ret->pkey.ec, &cp, (long)j)) { X509err(X509_F_X509_PUBKEY_GET, ERR_R_EC_LIB); goto err; } } else if (a->parameter && (a->parameter->type == V_ASN1_OBJECT)) { /* type == V_ASN1_OBJECT => the parameters are given * by an asn1 OID */ EC_KEY *ec_key; EC_GROUP *group; if (ret->pkey.ec == NULL) ret->pkey.ec = EC_KEY_new(); ec_key = ret->pkey.ec; if (ec_key == NULL) goto err; group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object)); if (group == NULL) goto err; EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); if (EC_KEY_set_group(ec_key, group) == 0) goto err; EC_GROUP_free(group); } /* the case implicitlyCA is currently not implemented */ ret->save_parameters = 1; } #endif p=key->public_key->data; j=key->public_key->length; if (!d2i_PublicKey(type, &ret, &p, (long)j)) { X509err(X509_F_X509_PUBKEY_GET, X509_R_ERR_ASN1_LIB); goto err; } key->pkey = ret; CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY); return(ret); err: if (ret != NULL) EVP_PKEY_free(ret); return(NULL); }
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken) { PKCS8_PRIV_KEY_INFO *p8; if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) { EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE); return NULL; } p8->broken = broken; if (!ASN1_INTEGER_set(p8->version, 0)) { EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE); PKCS8_PRIV_KEY_INFO_free (p8); return NULL; } if (!(p8->pkeyalg->parameter = ASN1_TYPE_new ())) { EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE); PKCS8_PRIV_KEY_INFO_free (p8); return NULL; } p8->pkey->type = V_ASN1_OCTET_STRING; switch (EVP_PKEY_type(pkey->type)) { #ifndef OPENSSL_NO_RSA case EVP_PKEY_RSA: if(p8->broken == PKCS8_NO_OCTET) p8->pkey->type = V_ASN1_SEQUENCE; p8->pkeyalg->algorithm = OBJ_nid2obj(NID_rsaEncryption); p8->pkeyalg->parameter->type = V_ASN1_NULL; if (!ASN1_pack_string_of (EVP_PKEY,pkey, i2d_PrivateKey, &p8->pkey->value.octet_string)) { EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE); PKCS8_PRIV_KEY_INFO_free (p8); return NULL; } break; #endif #ifndef OPENSSL_NO_DSA case EVP_PKEY_DSA: if(!dsa_pkey2pkcs8(p8, pkey)) { PKCS8_PRIV_KEY_INFO_free (p8); return NULL; } break; #endif #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: if (!eckey_pkey2pkcs8(p8, pkey)) { PKCS8_PRIV_KEY_INFO_free(p8); return(NULL); } break; #endif default: EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); PKCS8_PRIV_KEY_INFO_free (p8); return NULL; } RAND_add(p8->pkey->value.octet_string->data, p8->pkey->value.octet_string->length, 0.0); return p8; }
int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) { EVP_MD_CTX ctx; unsigned char *buf_in=NULL; int ret= -1,inl; int mdnid, pknid; if (!pkey) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER); return -1; } EVP_MD_CTX_init(&ctx); /* Convert signature OID into digest and public key OIDs */ if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); goto err; } if (mdnid == NID_undef) { if (!pkey->ameth || !pkey->ameth->item_verify) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); goto err; } ret = pkey->ameth->item_verify(&ctx, it, asn, a, signature, pkey); /* Return value of 2 means carry on, anything else means we * exit straight away: either a fatal error of the underlying * verification routine handles all verification. */ if (ret != 2) goto err; ret = -1; } else { const EVP_MD *type; type=EVP_get_digestbynid(mdnid); if (type == NULL) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); goto err; } /* Check public key OID matches public key type */ if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_WRONG_PUBLIC_KEY_TYPE); goto err; } if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey)) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB); ret=0; goto err; } } inl = ASN1_item_i2d(asn, &buf_in, it); if (buf_in == NULL) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_MALLOC_FAILURE); goto err; } if (!EVP_DigestVerifyUpdate(&ctx,buf_in,inl)) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB); ret=0; goto err; } OPENSSL_cleanse(buf_in,(unsigned int)inl); OPENSSL_free(buf_in); if (EVP_DigestVerifyFinal(&ctx,signature->data, (size_t)signature->length) <= 0) { ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB); ret=0; goto err; } /* we don't need to zero the 'ctx' because we just checked * public information */ /* memset(&ctx,0,sizeof(ctx)); */ ret=1; err: EVP_MD_CTX_cleanup(&ctx); return(ret); }
DVT_STATUS CERTIFICATE_CLASS::generateFiles(LOG_CLASS* logger_ptr, const char* signerCredentialsFile_ptr, const char* credentialsPassword_ptr, const char* keyPassword_ptr, const char* keyFile_ptr, const char* certificateFile_ptr) // DESCRIPTION : Generate a certificate and key files from this class. // PRECONDITIONS : // POSTCONDITIONS : // EXCEPTIONS : // NOTES : If signerCredentialsFile_ptr is NULL, a self signed // : certificate will be generated. // : // : Returns: MSG_OK, MSG_LIB_NOT_EXIST, MSG_FILE_NOT_EXIST, // : MSG_ERROR, MSG_INVALID_PASSWORD //<<=========================================================================== { DVT_STATUS ret = MSG_ERROR; unsigned long err; OPENSSL_CLASS* openSsl_ptr; BIO* caBio_ptr = NULL; EVP_PKEY* caPrivateKey_ptr = NULL; X509* caCertificate_ptr = NULL; EVP_PKEY* key_ptr = NULL; X509* cert_ptr = NULL; X509_NAME* name_ptr; time_t effectiveTime; time_t expirationTime; EVP_PKEY* tmpKey_ptr; const EVP_MD *digest_ptr; BIO* pkBio_ptr = NULL; const EVP_CIPHER *cipher_ptr; BIO* certBio_ptr = NULL; // check for the existence of the OpenSSL DLLs openSsl_ptr = OPENSSL_CLASS::getInstance(); if (openSsl_ptr == NULL) { return MSG_LIB_NOT_EXIST; } // clear the error queue ERR_clear_error(); if (signerCredentialsFile_ptr != NULL) { // open the credentials file caBio_ptr = BIO_new(BIO_s_file_internal()); if (caBio_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting up to read CA credentials file"); goto end; } if (BIO_read_filename(caBio_ptr, signerCredentialsFile_ptr) <= 0) { err = ERR_peek_error(); if ((ERR_GET_LIB(err) == ERR_LIB_SYS) && (ERR_GET_REASON(err) == ERROR_FILE_NOT_FOUND)) { // file does not exist ERR_clear_error(); // eat any errors ret = MSG_FILE_NOT_EXIST; } else { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "opening CA credentials file for reading"); } goto end; } // read the certificate authority's private key caPrivateKey_ptr = PEM_read_bio_PrivateKey(caBio_ptr, NULL, NULL, (void*)credentialsPassword_ptr); if (caPrivateKey_ptr == NULL) { err = ERR_peek_error(); if ((ERR_GET_LIB(err) == ERR_LIB_EVP) && (ERR_GET_REASON(err) == EVP_R_BAD_DECRYPT)) { // bad password ERR_clear_error(); // eat any errors ret = MSG_INVALID_PASSWORD; } else { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "reading private key from CA credentials file"); } goto end; } // read the certificate authority's certificate caCertificate_ptr = PEM_read_bio_X509(caBio_ptr, NULL, NULL, (void*)credentialsPassword_ptr); if (caCertificate_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "reading CA certificate from CA credentials file"); goto end; } } // generate the new private/public key pair if (signatureAlgorithmM.compare("RSA") == 0) { // RSA key RSA* rsa_key; rsa_key = RSA_generate_key(signatureKeyLengthM, RSA_3, NULL, 0); if (rsa_key == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "generating RSA key"); goto end; } key_ptr = EVP_PKEY_new(); if (key_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "creating RSA key"); RSA_free(rsa_key); goto end; } EVP_PKEY_assign_RSA(key_ptr, rsa_key); } else { // DSA key DSA* dsa_key; dsa_key = DSA_generate_parameters(signatureKeyLengthM, NULL, 0, NULL, NULL, NULL, 0); if (dsa_key == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "generating DSA parameters"); goto end; } if (DSA_generate_key(dsa_key) == 0) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "generating DSA key"); DSA_free(dsa_key); goto end; } key_ptr = EVP_PKEY_new(); if (key_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "creating DSA key"); DSA_free(dsa_key); goto end; } EVP_PKEY_assign_DSA(key_ptr, dsa_key); } // create the certificate cert_ptr = X509_new(); if (cert_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "creating certificate object"); goto end; } // version if (X509_set_version(cert_ptr, (versionM - 1)) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting certificate version"); goto end; } // subject name_ptr = openSsl_ptr->onelineName2Name(subjectM.c_str()); if (name_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "parsing owner name"); goto end; } if (X509_set_subject_name(cert_ptr, name_ptr) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting owner name in certificate"); goto end; } // issuer if (signerCredentialsFile_ptr != NULL) { // CA signed name_ptr = X509_get_subject_name(caCertificate_ptr); if (name_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "getting name from CA certificate"); goto end; } if (X509_set_issuer_name(cert_ptr, name_ptr) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting issuer name in certificate"); goto end; } } else { // self signed name_ptr = X509_NAME_dup(name_ptr); // duplicate the name so it can be used again if (name_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "duplicating owner name"); goto end; } if (X509_set_issuer_name(cert_ptr, name_ptr) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting issuer name in certificate"); goto end; } } // public key if (X509_set_pubkey(cert_ptr, key_ptr) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting public key in certificate"); goto end; } // valid dates effectiveTime = mktime(&effectiveDateM); expirationTime = mktime(&expirationDateM); if ((X509_time_adj(X509_get_notBefore(cert_ptr), 0, &effectiveTime) == NULL) || (X509_time_adj(X509_get_notAfter(cert_ptr), 0, &expirationTime) == NULL)) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting valid dates in certificate"); goto end; } // serial number, use the current time_t ASN1_INTEGER_set(X509_get_serialNumber(cert_ptr), (unsigned)time(NULL)); // sign the certificate if (signerCredentialsFile_ptr != NULL) { // CA signed tmpKey_ptr = caPrivateKey_ptr; } else { // self signed tmpKey_ptr = key_ptr; } if (EVP_PKEY_type(tmpKey_ptr->type) == EVP_PKEY_RSA) { digest_ptr = EVP_sha1(); } else if (EVP_PKEY_type(tmpKey_ptr->type) == EVP_PKEY_DSA) { digest_ptr = EVP_dss1(); } else { if (logger_ptr) { logger_ptr->text(LOG_ERROR, 1, "Unsupported key type in CA private key"); } goto end; } if (!X509_sign(cert_ptr, tmpKey_ptr, digest_ptr)) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "signing certificate"); goto end; } // write out the private key // open the private key file pkBio_ptr = BIO_new(BIO_s_file_internal()); if (pkBio_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting up to write private key file"); goto end; } if (BIO_write_filename(pkBio_ptr, (void *)keyFile_ptr) <= 0) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "opening to write private key file"); goto end; } if ((keyPassword_ptr != NULL) && (strlen(keyPassword_ptr) > 0)) { // we have a password, use 3DES to encrypt the key cipher_ptr = EVP_des_ede3_cbc(); } else { // there is no password, don't encrypt the key cipher_ptr = NULL; } // write out the private key if (PEM_write_bio_PKCS8PrivateKey(pkBio_ptr, key_ptr, cipher_ptr, NULL, 0, NULL, (void *)keyPassword_ptr) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing private key"); goto end; } // write the certificate file // open the certificate file certBio_ptr = BIO_new(BIO_s_file_internal()); if (certBio_ptr == NULL) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting up to write certificate file"); goto end; } if (BIO_write_filename(certBio_ptr, (void *)certificateFile_ptr) <= 0) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "opening to write certificate file"); goto end; } // write the new certificate if (PEM_write_bio_X509(certBio_ptr, cert_ptr) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing certificate"); goto end; } // write the new certificate into the credential file if (PEM_write_bio_X509(pkBio_ptr, cert_ptr) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing certificate"); goto end; } if (signerCredentialsFile_ptr != NULL) { // write the CA certificate if (PEM_write_bio_X509(certBio_ptr, caCertificate_ptr) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing CA certificate"); goto end; } // loop reading certificates from the CA credentials file and writing them to the certificate file X509_free(caCertificate_ptr); while ((caCertificate_ptr = PEM_read_bio_X509(caBio_ptr, NULL, NULL, (void*)credentialsPassword_ptr)) != NULL) { // write the certificate if (PEM_write_bio_X509(certBio_ptr, caCertificate_ptr) != 1) { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing certificate chain"); goto end; } X509_free(caCertificate_ptr); } // check the error err = ERR_peek_error(); if ((ERR_GET_LIB(err) == ERR_LIB_PEM) && (ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) { // end of data - this is normal ERR_clear_error(); } else { openSsl_ptr->printError(logger_ptr, LOG_ERROR, "reading certificates from CA credentials file"); goto end; } } ret = MSG_OK; end: if (certBio_ptr != NULL) BIO_free(certBio_ptr); if (pkBio_ptr != NULL) BIO_free(pkBio_ptr); if (cert_ptr != NULL) X509_free(cert_ptr); if (key_ptr != NULL) EVP_PKEY_free(key_ptr); if (caCertificate_ptr != NULL) X509_free(caCertificate_ptr); if (caPrivateKey_ptr != NULL) EVP_PKEY_free(caPrivateKey_ptr); if (caBio_ptr != NULL) BIO_free(caBio_ptr); return ret; }
/** * @retval 1 equal * @retval 0 not equal * @retval -1 error */ static int CompareCertToRSA(X509 *cert, RSA *rsa_key) { int ret; int retval = -1; /* ERROR */ EVP_PKEY *cert_pkey = X509_get_pubkey(cert); if (cert_pkey == NULL) { Log(LOG_LEVEL_ERR, "X509_get_pubkey: %s", TLSErrorString(ERR_get_error())); goto ret1; } if (EVP_PKEY_type(cert_pkey->type) != EVP_PKEY_RSA) { Log(LOG_LEVEL_ERR, "Received key of unknown type, only RSA currently supported!"); goto ret2; } RSA *cert_rsa_key = EVP_PKEY_get1_RSA(cert_pkey); if (cert_rsa_key == NULL) { Log(LOG_LEVEL_ERR, "TLSVerifyPeer: EVP_PKEY_get1_RSA failed!"); goto ret2; } EVP_PKEY *rsa_pkey = EVP_PKEY_new(); if (rsa_pkey == NULL) { Log(LOG_LEVEL_ERR, "TLSVerifyPeer: EVP_PKEY_new allocation failed!"); goto ret3; } ret = EVP_PKEY_set1_RSA(rsa_pkey, rsa_key); if (ret == 0) { Log(LOG_LEVEL_ERR, "TLSVerifyPeer: EVP_PKEY_set1_RSA failed!"); goto ret4; } ret = EVP_PKEY_cmp(cert_pkey, rsa_pkey); if (ret == 1) { Log(LOG_LEVEL_DEBUG, "Public key to certificate compare equal"); retval = 1; /* EQUAL */ } else if (ret == 0 || ret == -1) { Log(LOG_LEVEL_DEBUG, "Public key to certificate compare different"); retval = 0; /* NOT EQUAL */ } else { Log(LOG_LEVEL_ERR, "OpenSSL EVP_PKEY_cmp: %d %s", ret, TLSErrorString(ERR_get_error())); } ret4: EVP_PKEY_free(rsa_pkey); ret3: RSA_free(cert_rsa_key); ret2: EVP_PKEY_free(cert_pkey); ret1: return retval; }
static LUA_FUNCTION(openssl_pkey_export) { EVP_PKEY * key; int ispriv = 0; int exraw = 0; int expem = 1; size_t passphrase_len = 0; BIO * bio_out = NULL; int ret = 0; const EVP_CIPHER * cipher; const char * passphrase = NULL; key = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); ispriv = openssl_pkey_is_private(key); if (!lua_isnoneornil(L, 2)) expem = lua_toboolean(L, 2); if (expem) { if (!lua_isnoneornil(L, 3)) exraw = lua_toboolean(L, 3); passphrase = luaL_optlstring(L, 4, NULL, &passphrase_len); } else { passphrase = luaL_optlstring(L, 3, NULL, &passphrase_len); } if (passphrase) { cipher = (EVP_CIPHER *) EVP_des_ede3_cbc(); } else { cipher = NULL; } bio_out = BIO_new(BIO_s_mem()); if (expem) { if (exraw==0) { ret = ispriv ? PEM_write_bio_PrivateKey(bio_out, key, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) : PEM_write_bio_PUBKEY(bio_out, key); } else { /* export raw key format */ switch (EVP_PKEY_type(key->type)) { case EVP_PKEY_RSA: case EVP_PKEY_RSA2: ret = ispriv ? PEM_write_bio_RSAPrivateKey(bio_out, key->pkey.rsa, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) : PEM_write_bio_RSAPublicKey(bio_out, key->pkey.rsa); break; case EVP_PKEY_DSA: case EVP_PKEY_DSA2: case EVP_PKEY_DSA3: case EVP_PKEY_DSA4: { ret = ispriv ? PEM_write_bio_DSAPrivateKey(bio_out, key->pkey.dsa, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) : PEM_write_bio_DSA_PUBKEY(bio_out, key->pkey.dsa); } break; case EVP_PKEY_DH: ret = PEM_write_bio_DHparams(bio_out, key->pkey.dh); break; #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: ret = ispriv ? PEM_write_bio_ECPrivateKey(bio_out, key->pkey.ec, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) : PEM_write_bio_EC_PUBKEY(bio_out, key->pkey.ec); break; #endif default: ret = 0; break; } } } else { if (ispriv) { if (passphrase == NULL) { ret = i2d_PrivateKey_bio(bio_out, key); } else { ret = i2d_PKCS8PrivateKey_bio(bio_out, key, cipher, (char *)passphrase, passphrase_len, NULL, NULL); } } else { int l; l = i2d_PublicKey(key, NULL); if (l > 0) { unsigned char* p = malloc(l); unsigned char* pp = p; l = i2d_PublicKey(key, &pp); if (l > 0) { BIO_write(bio_out, p, l); ret = 1; } else ret = 0; free(p); } else ret = 0; } } if (ret) { char * bio_mem_ptr; long bio_mem_len; bio_mem_len = BIO_get_mem_data(bio_out, &bio_mem_ptr); lua_pushlstring(L, bio_mem_ptr, bio_mem_len); ret = 1; } if (bio_out) { BIO_free(bio_out); } return ret; }
int EVP_PKEY_base_id(const EVP_PKEY *pkey) { return EVP_PKEY_type(pkey->type); }
int PKI_X509_KEYPAIR_get_curve ( PKI_X509_KEYPAIR *kp ) { #ifdef ENABLE_ECDSA PKI_X509_KEYPAIR_VALUE *pVal = NULL; const EC_GROUP *gr; EC_GROUP *gr2; EC_KEY *ec = NULL; EC_POINT *point = NULL; BN_CTX *ctx = NULL; int ret = PKI_ID_UNKNOWN; EC_builtin_curve *curves = NULL; size_t num_curves = 0; int i; BIGNUM *order; unsigned long long keyBits = 0; unsigned long long curveBits = 0; pVal = kp->value; if (!pVal ) return PKI_ID_UNKNOWN; ctx = BN_CTX_new(); switch (EVP_PKEY_type(pVal->type)) { case EVP_PKEY_EC: ec = pVal->pkey.ec; break; default: return PKI_ID_UNKNOWN; break; }; if (!ec) { return PKI_ID_UNKNOWN; }; if((gr = EC_KEY_get0_group(ec)) == NULL) { return PKI_ID_UNKNOWN; }; order = BN_new(); if (EC_GROUP_get_order(gr, order, NULL)) { keyBits = (unsigned long long) BN_num_bits(order); } BN_free( order ); order = NULL; if((point = EC_POINT_new( gr )) == NULL ) { PKI_log_err("Can not generate a new point in Key's Group"); return PKI_ID_UNKNOWN; }; /* Get the number of availabe ECDSA curves in OpenSSL */ if ((num_curves = EC_get_builtin_curves(NULL, 0)) < 1 ) { /* No curves available! */ return PKI_ID_UNKNOWN; } /* Alloc the needed memory */ curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * (int) num_curves); if (curves == NULL) { return PKI_ID_UNKNOWN; }; /* Get the builtin curves */ if (!EC_get_builtin_curves(curves, num_curves)) { if( curves ) free (curves); return PKI_ID_UNKNOWN; } order = BN_new(); /* Cycle through the curves and display the names */ for( i = 0; i < num_curves; i++ ) { int nid; nid = curves[i].nid; if(( gr2 = EC_GROUP_new_by_curve_name( nid )) == NULL) { PKI_log_err("Can not get default curve [%d]", i); break; }; if (EC_GROUP_get_order(gr2, order, NULL)) { curveBits = (unsigned long long) BN_num_bits(order); }; if ( curveBits == keyBits ) { if( EC_POINT_is_on_curve( gr2, point, ctx ) ) { ret = nid; break; }; }; if( gr2 ) EC_GROUP_free ( gr2 ); }; if ( order ) BN_free ( order ); if( curves ) free ( curves ); BN_CTX_free ( ctx ); return ret; #else return PKI_ID_UNKNOWN; #endif };
RTDECL(int) RTCrPkixPubKeyVerifySignature(PCRTASN1OBJID pAlgorithm, PCRTASN1DYNTYPE pParameters, PCRTASN1BITSTRING pPublicKey, PCRTASN1BITSTRING pSignatureValue, const void *pvData, size_t cbData, PRTERRINFO pErrInfo) { /* * Valid input. */ AssertPtrReturn(pAlgorithm, VERR_INVALID_POINTER); AssertReturn(RTAsn1ObjId_IsPresent(pAlgorithm), VERR_INVALID_POINTER); if (pParameters) { AssertPtrReturn(pParameters, VERR_INVALID_POINTER); if (pParameters->enmType == RTASN1TYPE_NULL) pParameters = NULL; } AssertPtrReturn(pPublicKey, VERR_INVALID_POINTER); AssertReturn(RTAsn1BitString_IsPresent(pPublicKey), VERR_INVALID_POINTER); AssertPtrReturn(pSignatureValue, VERR_INVALID_POINTER); AssertReturn(RTAsn1BitString_IsPresent(pSignatureValue), VERR_INVALID_POINTER); AssertPtrReturn(pvData, VERR_INVALID_POINTER); AssertReturn(cbData > 0, VERR_INVALID_PARAMETER); /* * Parameters are not currently supported (openssl code path). */ if (pParameters) return RTErrInfoSet(pErrInfo, VERR_CR_PKIX_CIPHER_ALGO_PARAMS_NOT_IMPL, "Cipher algorithm parameters are not yet supported."); /* * Validate using IPRT. */ RTCRPKIXSIGNATURE hSignature; int rcIprt = RTCrPkixSignatureCreateByObjId(&hSignature, pAlgorithm, false /*fSigning*/, pPublicKey, pParameters); if (RT_FAILURE(rcIprt)) return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_CIPHER_ALGO_NOT_KNOWN, "Unknown public key algorithm [IPRT]: %s", pAlgorithm->szObjId); RTCRDIGEST hDigest; rcIprt = RTCrDigestCreateByObjId(&hDigest, pAlgorithm); if (RT_SUCCESS(rcIprt)) { /* Calculate the digest. */ rcIprt = RTCrDigestUpdate(hDigest, pvData, cbData); if (RT_SUCCESS(rcIprt)) { rcIprt = RTCrPkixSignatureVerifyBitString(hSignature, hDigest, pSignatureValue); if (RT_FAILURE(rcIprt)) RTErrInfoSet(pErrInfo, rcIprt, "RTCrPkixSignatureVerifyBitString failed"); } else RTErrInfoSet(pErrInfo, rcIprt, "RTCrDigestUpdate failed"); RTCrDigestRelease(hDigest); } else RTErrInfoSetF(pErrInfo, rcIprt, "Unknown digest algorithm [IPRT]: %s", pAlgorithm->szObjId); RTCrPkixSignatureRelease(hSignature); #ifdef IPRT_WITH_OPENSSL /* * Validate using OpenSSL EVP. */ rtCrOpenSslInit(); /* Translate the algorithm ID into a EVP message digest type pointer. */ int iAlgoNid = OBJ_txt2nid(pAlgorithm->szObjId); if (iAlgoNid == NID_undef) return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN, "Unknown public key algorithm [OpenSSL]: %s", pAlgorithm->szObjId); const char *pszAlogSn = OBJ_nid2sn(iAlgoNid); const EVP_MD *pEvpMdType = EVP_get_digestbyname(pszAlogSn); if (!pEvpMdType) return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALGO_NOT_KNOWN_EVP, "EVP_get_digestbyname failed on %s (%s)", pszAlogSn, pAlgorithm->szObjId); /* Initialize the EVP message digest context. */ EVP_MD_CTX EvpMdCtx; EVP_MD_CTX_init(&EvpMdCtx); if (!EVP_VerifyInit_ex(&EvpMdCtx, pEvpMdType, NULL /*engine*/)) return RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_CIPHER_ALOG_INIT_FAILED, "EVP_VerifyInit_ex failed (algorithm type is %s / %s)", pszAlogSn, pAlgorithm->szObjId); /* Create an EVP public key. */ int rcOssl; EVP_PKEY *pEvpPublicKey = EVP_PKEY_new(); if (pEvpPublicKey) { pEvpPublicKey->type = EVP_PKEY_type(pEvpMdType->required_pkey_type[0]); if (pEvpPublicKey->type != NID_undef) { const unsigned char *puchPublicKey = RTASN1BITSTRING_GET_BIT0_PTR(pPublicKey); if (d2i_PublicKey(pEvpPublicKey->type, &pEvpPublicKey, &puchPublicKey, RTASN1BITSTRING_GET_BYTE_SIZE(pPublicKey))) { /* Digest the data. */ EVP_VerifyUpdate(&EvpMdCtx, pvData, cbData); /* Verify the signature. */ if (EVP_VerifyFinal(&EvpMdCtx, RTASN1BITSTRING_GET_BIT0_PTR(pSignatureValue), RTASN1BITSTRING_GET_BYTE_SIZE(pSignatureValue), pEvpPublicKey) > 0) rcOssl = VINF_SUCCESS; else rcOssl = RTErrInfoSet(pErrInfo, VERR_CR_PKIX_OSSL_VERIFY_FINAL_FAILED, "EVP_VerifyFinal failed"); } else rcOssl = RTErrInfoSet(pErrInfo, VERR_CR_PKIX_OSSL_D2I_PUBLIC_KEY_FAILED, "d2i_PublicKey failed"); } else rcOssl = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_OSSL_EVP_PKEY_TYPE_ERROR, "EVP_PKEY_type(%d) failed", pEvpMdType->required_pkey_type[0]); /* Cleanup and return.*/ EVP_PKEY_free(pEvpPublicKey); } else rcOssl = RTErrInfoSetF(pErrInfo, VERR_NO_MEMORY, "EVP_PKEY_new(%d) failed", pEvpMdType->required_pkey_type[0]); EVP_MD_CTX_cleanup(&EvpMdCtx); /* * Check the result. */ if (RT_SUCCESS(rcIprt) && RT_SUCCESS(rcOssl)) return VINF_SUCCESS; if (RT_FAILURE_NP(rcIprt) && RT_FAILURE_NP(rcOssl)) return rcIprt; AssertMsgFailed(("rcIprt=%Rrc rcOssl=%Rrc\n", rcIprt, rcOssl)); if (RT_FAILURE_NP(rcOssl)) return rcOssl; #endif /* IPRT_WITH_OPENSSL */ return rcIprt; }