@@ -3651,6 +3651,45 @@ void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
36513651 args.GetReturnValue ().Set (rc);
36523652}
36533653
3654+ enum ParsePublicKeyResult {
3655+ kParsePublicOk ,
3656+ kParsePublicNotRecognized ,
3657+ kParsePublicFailed
3658+ };
3659+
3660+ static ParsePublicKeyResult ParsePublicKey (EVPKeyPointer* pkey,
3661+ const char * key_pem,
3662+ int key_pem_len) {
3663+ BIOPointer bp (BIO_new_mem_buf (const_cast <char *>(key_pem), key_pem_len));
3664+ if (!bp)
3665+ return kParsePublicFailed ;
3666+
3667+ // Check if this is a PKCS#8 or RSA public key before trying as X.509.
3668+ if (strncmp (key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0 ) {
3669+ pkey->reset (
3670+ PEM_read_bio_PUBKEY (bp.get (), nullptr , NoPasswordCallback, nullptr ));
3671+ } else if (strncmp (key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0 ) {
3672+ RSAPointer rsa (PEM_read_bio_RSAPublicKey (
3673+ bp.get (), nullptr , PasswordCallback, nullptr ));
3674+ if (rsa) {
3675+ pkey->reset (EVP_PKEY_new ());
3676+ if (*pkey)
3677+ EVP_PKEY_set1_RSA (pkey->get (), rsa.get ());
3678+ }
3679+ } else if (strncmp (key_pem, CERTIFICATE_PFX, CERTIFICATE_PFX_LEN) == 0 ) {
3680+ // X.509 fallback
3681+ X509Pointer x509 (PEM_read_bio_X509 (
3682+ bp.get (), nullptr , NoPasswordCallback, nullptr ));
3683+ if (!x509)
3684+ return kParsePublicFailed ;
3685+
3686+ pkey->reset (X509_get_pubkey (x509.get ()));
3687+ } else {
3688+ return kParsePublicNotRecognized ;
3689+ }
3690+
3691+ return *pkey ? kParsePublicOk : kParsePublicFailed ;
3692+ }
36543693
36553694void Verify::Initialize (Environment* env, v8::Local<Object> target) {
36563695 Local<FunctionTemplate> t = env->NewFunctionTemplate (New);
@@ -3711,34 +3750,7 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem,
37113750 *verify_result = false ;
37123751 EVPMDPointer mdctx = std::move (mdctx_);
37133752
3714- BIOPointer bp (BIO_new_mem_buf (const_cast <char *>(key_pem), key_pem_len));
3715- if (!bp)
3716- return kSignPublicKey ;
3717-
3718- // Check if this is a PKCS#8 or RSA public key before trying as X.509.
3719- // Split this out into a separate function once we have more than one
3720- // consumer of public keys.
3721- if (strncmp (key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0 ) {
3722- pkey.reset (
3723- PEM_read_bio_PUBKEY (bp.get (), nullptr , NoPasswordCallback, nullptr ));
3724- } else if (strncmp (key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0 ) {
3725- RSAPointer rsa (PEM_read_bio_RSAPublicKey (
3726- bp.get (), nullptr , PasswordCallback, nullptr ));
3727- if (rsa) {
3728- pkey.reset (EVP_PKEY_new ());
3729- if (pkey)
3730- EVP_PKEY_set1_RSA (pkey.get (), rsa.get ());
3731- }
3732- } else {
3733- // X.509 fallback
3734- X509Pointer x509 (PEM_read_bio_X509 (
3735- bp.get (), nullptr , NoPasswordCallback, nullptr ));
3736- if (!x509)
3737- return kSignPublicKey ;
3738-
3739- pkey.reset (X509_get_pubkey (x509.get ()));
3740- }
3741- if (!pkey)
3753+ if (ParsePublicKey (&pkey, key_pem, key_pem_len) != kParsePublicOk )
37423754 return kSignPublicKey ;
37433755
37443756 if (!EVP_DigestFinal_ex (mdctx.get (), m, &m_len))
@@ -3808,40 +3820,25 @@ bool PublicKeyCipher::Cipher(const char* key_pem,
38083820 size_t * out_len) {
38093821 EVPKeyPointer pkey;
38103822
3811- BIOPointer bp (BIO_new_mem_buf (const_cast <char *>(key_pem), key_pem_len));
3812- if (!bp)
3813- return false ;
3814-
38153823 // Check if this is a PKCS#8 or RSA public key before trying as X.509 and
38163824 // private key.
3817- if (operation == kPublic &&
3818- strncmp (key_pem, PUBLIC_KEY_PFX, PUBLIC_KEY_PFX_LEN) == 0 ) {
3819- pkey.reset (PEM_read_bio_PUBKEY (bp.get (), nullptr , nullptr , nullptr ));
3820- } else if (operation == kPublic &&
3821- strncmp (key_pem, PUBRSA_KEY_PFX, PUBRSA_KEY_PFX_LEN) == 0 ) {
3822- RSAPointer rsa (
3823- PEM_read_bio_RSAPublicKey (bp.get (), nullptr , nullptr , nullptr ));
3824- if (rsa) {
3825- pkey.reset (EVP_PKEY_new ());
3826- if (pkey)
3827- EVP_PKEY_set1_RSA (pkey.get (), rsa.get ());
3828- }
3829- } else if (operation == kPublic &&
3830- strncmp (key_pem, CERTIFICATE_PFX, CERTIFICATE_PFX_LEN) == 0 ) {
3831- X509Pointer x509 (
3832- PEM_read_bio_X509 (bp.get (), nullptr , NoPasswordCallback, nullptr ));
3833- if (!x509)
3825+ if (operation == kPublic ) {
3826+ ParsePublicKeyResult pkeyres = ParsePublicKey (&pkey, key_pem, key_pem_len);
3827+ if (pkeyres == kParsePublicFailed )
3828+ return false ;
3829+ }
3830+ if (!pkey) {
3831+ // Private key fallback.
3832+ BIOPointer bp (BIO_new_mem_buf (const_cast <char *>(key_pem), key_pem_len));
3833+ if (!bp)
38343834 return false ;
3835-
3836- pkey.reset (X509_get_pubkey (x509.get ()));
3837- } else {
38383835 pkey.reset (PEM_read_bio_PrivateKey (bp.get (),
38393836 nullptr ,
38403837 PasswordCallback,
38413838 const_cast <char *>(passphrase)));
3839+ if (!pkey)
3840+ return false ;
38423841 }
3843- if (!pkey)
3844- return false ;
38453842
38463843 EVPKeyCtxPointer ctx (EVP_PKEY_CTX_new (pkey.get (), nullptr ));
38473844 if (!ctx)
0 commit comments