@@ -3651,6 +3651,45 @@ void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
3651
3651
args.GetReturnValue ().Set (rc);
3652
3652
}
3653
3653
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
+ }
3654
3693
3655
3694
void Verify::Initialize (Environment* env, v8::Local<Object> target) {
3656
3695
Local<FunctionTemplate> t = env->NewFunctionTemplate (New);
@@ -3711,34 +3750,7 @@ SignBase::Error Verify::VerifyFinal(const char* key_pem,
3711
3750
*verify_result = false ;
3712
3751
EVPMDPointer mdctx = std::move (mdctx_);
3713
3752
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 )
3742
3754
return kSignPublicKey ;
3743
3755
3744
3756
if (!EVP_DigestFinal_ex (mdctx.get (), m, &m_len))
@@ -3808,40 +3820,25 @@ bool PublicKeyCipher::Cipher(const char* key_pem,
3808
3820
size_t * out_len) {
3809
3821
EVPKeyPointer pkey;
3810
3822
3811
- BIOPointer bp (BIO_new_mem_buf (const_cast <char *>(key_pem), key_pem_len));
3812
- if (!bp)
3813
- return false ;
3814
-
3815
3823
// Check if this is a PKCS#8 or RSA public key before trying as X.509 and
3816
3824
// 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)
3834
3834
return false ;
3835
-
3836
- pkey.reset (X509_get_pubkey (x509.get ()));
3837
- } else {
3838
3835
pkey.reset (PEM_read_bio_PrivateKey (bp.get (),
3839
3836
nullptr ,
3840
3837
PasswordCallback,
3841
3838
const_cast <char *>(passphrase)));
3839
+ if (!pkey)
3840
+ return false ;
3842
3841
}
3843
- if (!pkey)
3844
- return false ;
3845
3842
3846
3843
EVPKeyCtxPointer ctx (EVP_PKEY_CTX_new (pkey.get (), nullptr ));
3847
3844
if (!ctx)
0 commit comments