@@ -153,13 +153,33 @@ template int SSLWrap<TLSWrap>::SelectALPNCallback(
153153 unsigned int inlen,
154154 void * arg);
155155
156+ class PasswordCallbackInfo {
157+ public:
158+ explicit PasswordCallbackInfo (const char * passphrase)
159+ : passphrase_(passphrase) {}
160+
161+ inline const char * GetPassword () {
162+ needs_passphrase_ = true ;
163+ return passphrase_;
164+ }
165+
166+ inline bool CalledButEmpty () {
167+ return needs_passphrase_ && passphrase_ == nullptr ;
168+ }
169+
170+ private:
171+ const char * passphrase_;
172+ bool needs_passphrase_ = false ;
173+ };
156174
157175static int PasswordCallback (char * buf, int size, int rwflag, void * u) {
158- if (u) {
176+ PasswordCallbackInfo* info = static_cast <PasswordCallbackInfo*>(u);
177+ const char * passphrase = info->GetPassword ();
178+ if (passphrase != nullptr ) {
159179 size_t buflen = static_cast <size_t >(size);
160- size_t len = strlen (static_cast < const char *>(u) );
180+ size_t len = strlen (passphrase );
161181 len = len > buflen ? buflen : len;
162- memcpy (buf, u , len);
182+ memcpy (buf, passphrase , len);
163183 return len;
164184 }
165185
@@ -698,11 +718,12 @@ void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
698718
699719 node::Utf8Value passphrase (env->isolate (), args[1 ]);
700720
721+ PasswordCallbackInfo cb_info (len == 1 ? nullptr : *passphrase);
701722 EVPKeyPointer key (
702723 PEM_read_bio_PrivateKey (bio.get (),
703724 nullptr ,
704725 PasswordCallback,
705- len == 1 ? nullptr : *passphrase ));
726+ &cb_info ));
706727
707728 if (!key) {
708729 unsigned long err = ERR_get_error (); // NOLINT(runtime/int)
@@ -2899,13 +2920,14 @@ static bool IsSupportedAuthenticatedMode(const EVP_CIPHER_CTX* ctx) {
28992920 return IsSupportedAuthenticatedMode (cipher);
29002921}
29012922
2902- enum class ParsePublicKeyResult {
2903- kParsePublicOk ,
2904- kParsePublicNotRecognized ,
2905- kParsePublicFailed
2923+ enum class ParseKeyResult {
2924+ kParseKeyOk ,
2925+ kParseKeyNotRecognized ,
2926+ kParseKeyNeedPassphrase ,
2927+ kParseKeyFailed
29062928};
29072929
2908- static ParsePublicKeyResult TryParsePublicKey (
2930+ static ParseKeyResult TryParsePublicKey (
29092931 EVPKeyPointer* pkey,
29102932 const BIOPointer& bp,
29112933 const char * name,
@@ -2919,33 +2941,33 @@ static ParsePublicKeyResult TryParsePublicKey(
29192941 MarkPopErrorOnReturn mark_pop_error_on_return;
29202942 if (PEM_bytes_read_bio (&der_data, &der_len, nullptr , name,
29212943 bp.get (), nullptr , nullptr ) != 1 )
2922- return ParsePublicKeyResult:: kParsePublicNotRecognized ;
2944+ return ParseKeyResult:: kParseKeyNotRecognized ;
29232945 }
29242946
29252947 // OpenSSL might modify the pointer, so we need to make a copy before parsing.
29262948 const unsigned char * p = der_data;
29272949 pkey->reset (parse (&p, der_len));
29282950 OPENSSL_clear_free (der_data, der_len);
29292951
2930- return *pkey ? ParsePublicKeyResult:: kParsePublicOk :
2931- ParsePublicKeyResult:: kParsePublicFailed ;
2952+ return *pkey ? ParseKeyResult:: kParseKeyOk :
2953+ ParseKeyResult:: kParseKeyFailed ;
29322954}
29332955
2934- static ParsePublicKeyResult ParsePublicKeyPEM (EVPKeyPointer* pkey,
2935- const char * key_pem,
2936- int key_pem_len) {
2956+ static ParseKeyResult ParsePublicKeyPEM (EVPKeyPointer* pkey,
2957+ const char * key_pem,
2958+ int key_pem_len) {
29372959 BIOPointer bp (BIO_new_mem_buf (const_cast <char *>(key_pem), key_pem_len));
29382960 if (!bp)
2939- return ParsePublicKeyResult:: kParsePublicFailed ;
2961+ return ParseKeyResult:: kParseKeyFailed ;
29402962
2941- ParsePublicKeyResult ret;
2963+ ParseKeyResult ret;
29422964
29432965 // Try parsing as a SubjectPublicKeyInfo first.
29442966 ret = TryParsePublicKey (pkey, bp, " PUBLIC KEY" ,
29452967 [](const unsigned char ** p, long l) { // NOLINT(runtime/int)
29462968 return d2i_PUBKEY (nullptr , p, l);
29472969 });
2948- if (ret != ParsePublicKeyResult:: kParsePublicNotRecognized )
2970+ if (ret != ParseKeyResult:: kParseKeyNotRecognized )
29492971 return ret;
29502972
29512973 // Maybe it is PKCS#1.
@@ -2954,7 +2976,7 @@ static ParsePublicKeyResult ParsePublicKeyPEM(EVPKeyPointer* pkey,
29542976 [](const unsigned char ** p, long l) { // NOLINT(runtime/int)
29552977 return d2i_PublicKey (EVP_PKEY_RSA, nullptr , p, l);
29562978 });
2957- if (ret != ParsePublicKeyResult:: kParsePublicNotRecognized )
2979+ if (ret != ParseKeyResult:: kParseKeyNotRecognized )
29582980 return ret;
29592981
29602982 // X.509 fallback.
@@ -2966,25 +2988,25 @@ static ParsePublicKeyResult ParsePublicKeyPEM(EVPKeyPointer* pkey,
29662988 });
29672989}
29682990
2969- static bool ParsePublicKey (EVPKeyPointer* pkey,
2970- const PublicKeyEncodingConfig& config,
2971- const char * key,
2972- size_t key_len) {
2991+ static ParseKeyResult ParsePublicKey (EVPKeyPointer* pkey,
2992+ const PublicKeyEncodingConfig& config,
2993+ const char * key,
2994+ size_t key_len) {
29732995 if (config.format_ == kKeyFormatPEM ) {
2974- ParsePublicKeyResult r =
2975- ParsePublicKeyPEM (pkey, key, key_len);
2976- return r == ParsePublicKeyResult::kParsePublicOk ;
2996+ return ParsePublicKeyPEM (pkey, key, key_len);
29772997 } else {
29782998 CHECK_EQ (config.format_ , kKeyFormatDER );
2999+
29793000 const unsigned char * p = reinterpret_cast <const unsigned char *>(key);
29803001 if (config.type_ .ToChecked () == kKeyEncodingPKCS1 ) {
29813002 pkey->reset (d2i_PublicKey (EVP_PKEY_RSA, nullptr , &p, key_len));
2982- return pkey;
29833003 } else {
29843004 CHECK_EQ (config.type_ .ToChecked (), kKeyEncodingSPKI );
29853005 pkey->reset (d2i_PUBKEY (nullptr , &p, key_len));
2986- return pkey;
29873006 }
3007+
3008+ return *pkey ? ParseKeyResult::kParseKeyOk :
3009+ ParseKeyResult::kParseKeyFailed ;
29883010 }
29893011}
29903012
@@ -3099,56 +3121,59 @@ static bool IsEncryptedPrivateKeyInfo(const unsigned char* data, size_t size) {
30993121 data[offset] != 2 ;
31003122}
31013123
3102- static EVPKeyPointer ParsePrivateKey (const PrivateKeyEncodingConfig& config,
3103- const char * key,
3104- size_t key_len) {
3105- EVPKeyPointer pkey;
3124+ static ParseKeyResult ParsePrivateKey (EVPKeyPointer* pkey,
3125+ const PrivateKeyEncodingConfig& config,
3126+ const char * key,
3127+ size_t key_len) {
3128+ PasswordCallbackInfo pc_info (config.passphrase_ .get ());
31063129
31073130 if (config.format_ == kKeyFormatPEM ) {
31083131 BIOPointer bio (BIO_new_mem_buf (key, key_len));
31093132 if (!bio)
3110- return pkey ;
3133+ return ParseKeyResult:: kParseKeyFailed ;
31113134
3112- char * pass = const_cast <char *>(config.passphrase_ .get ());
3113- pkey.reset (PEM_read_bio_PrivateKey (bio.get (),
3114- nullptr ,
3115- PasswordCallback,
3116- pass));
3135+ pkey->reset (PEM_read_bio_PrivateKey (bio.get (),
3136+ nullptr ,
3137+ PasswordCallback,
3138+ &pc_info));
31173139 } else {
31183140 CHECK_EQ (config.format_ , kKeyFormatDER );
31193141
31203142 if (config.type_ .ToChecked () == kKeyEncodingPKCS1 ) {
31213143 const unsigned char * p = reinterpret_cast <const unsigned char *>(key);
3122- pkey. reset (d2i_PrivateKey (EVP_PKEY_RSA, nullptr , &p, key_len));
3144+ pkey-> reset (d2i_PrivateKey (EVP_PKEY_RSA, nullptr , &p, key_len));
31233145 } else if (config.type_ .ToChecked () == kKeyEncodingPKCS8 ) {
31243146 BIOPointer bio (BIO_new_mem_buf (key, key_len));
31253147 if (!bio)
3126- return pkey ;
3148+ return ParseKeyResult:: kParseKeyFailed ;
31273149
31283150 if (IsEncryptedPrivateKeyInfo (
31293151 reinterpret_cast <const unsigned char *>(key), key_len)) {
3130- char * pass = const_cast <char *>(config.passphrase_ .get ());
3131- pkey.reset (d2i_PKCS8PrivateKey_bio (bio.get (),
3132- nullptr ,
3133- PasswordCallback,
3134- pass));
3152+ pkey->reset (d2i_PKCS8PrivateKey_bio (bio.get (),
3153+ nullptr ,
3154+ PasswordCallback,
3155+ &pc_info));
31353156 } else {
31363157 PKCS8Pointer p8inf (d2i_PKCS8_PRIV_KEY_INFO_bio (bio.get (), nullptr ));
31373158 if (p8inf)
3138- pkey. reset (EVP_PKCS82PKEY (p8inf.get ()));
3159+ pkey-> reset (EVP_PKCS82PKEY (p8inf.get ()));
31393160 }
31403161 } else {
31413162 CHECK_EQ (config.type_ .ToChecked (), kKeyEncodingSEC1 );
31423163 const unsigned char * p = reinterpret_cast <const unsigned char *>(key);
3143- pkey. reset (d2i_PrivateKey (EVP_PKEY_EC, nullptr , &p, key_len));
3164+ pkey-> reset (d2i_PrivateKey (EVP_PKEY_EC, nullptr , &p, key_len));
31443165 }
31453166 }
31463167
31473168 // OpenSSL can fail to parse the key but still return a non-null pointer.
31483169 if (ERR_peek_error () != 0 )
3149- pkey. reset ();
3170+ pkey-> reset ();
31503171
3151- return pkey;
3172+ if (*pkey)
3173+ return ParseKeyResult::kParseKeyOk ;
3174+ if (pc_info.CalledButEmpty ())
3175+ return ParseKeyResult::kParseKeyNeedPassphrase ;
3176+ return ParseKeyResult::kParseKeyFailed ;
31523177}
31533178
31543179ByteSource::ByteSource (ByteSource&& other)
@@ -3284,6 +3309,25 @@ static PublicKeyEncodingConfig GetPublicKeyEncodingFromJs(
32843309 return result;
32853310}
32863311
3312+ static inline ManagedEVPPKey GetParsedKey (Environment* env,
3313+ EVPKeyPointer&& pkey,
3314+ ParseKeyResult ret,
3315+ const char * default_msg) {
3316+ switch (ret) {
3317+ case ParseKeyResult::kParseKeyOk :
3318+ CHECK (pkey);
3319+ break ;
3320+ case ParseKeyResult::kParseKeyNeedPassphrase :
3321+ THROW_ERR_MISSING_PASSPHRASE (env,
3322+ " Passphrase required for encrypted key" );
3323+ break ;
3324+ default :
3325+ ThrowCryptoError (env, ERR_get_error (), default_msg);
3326+ }
3327+
3328+ return ManagedEVPPKey (std::move (pkey));
3329+ }
3330+
32873331static NonCopyableMaybe<PrivateKeyEncodingConfig> GetPrivateKeyEncodingFromJs (
32883332 const FunctionCallbackInfo<Value>& args,
32893333 unsigned int * offset,
@@ -3339,11 +3383,12 @@ static ManagedEVPPKey GetPrivateKeyFromJs(
33393383 GetPrivateKeyEncodingFromJs (args, offset, kKeyContextInput );
33403384 if (config.IsEmpty ())
33413385 return ManagedEVPPKey ();
3342- EVPKeyPointer pkey =
3343- ParsePrivateKey (config.Release (), key.get (), key.size ());
3344- if (!pkey)
3345- ThrowCryptoError (env, ERR_get_error (), " Failed to read private key" );
3346- return ManagedEVPPKey (std::move (pkey));
3386+
3387+ EVPKeyPointer pkey;
3388+ ParseKeyResult ret =
3389+ ParsePrivateKey (&pkey, config.Release (), key.get (), key.size ());
3390+ return GetParsedKey (env, std::move (pkey), ret,
3391+ " Failed to read private key" );
33473392 } else {
33483393 CHECK (args[*offset]->IsObject () && allow_key_object);
33493394 KeyObject* key;
@@ -3364,15 +3409,16 @@ static ManagedEVPPKey GetPublicOrPrivateKeyFromJs(
33643409 GetPrivateKeyEncodingFromJs (args, offset, kKeyContextInput );
33653410 if (config_.IsEmpty ())
33663411 return ManagedEVPPKey ();
3412+
3413+ ParseKeyResult ret;
33673414 PrivateKeyEncodingConfig config = config_.Release ();
33683415 EVPKeyPointer pkey;
33693416 if (config.format_ == kKeyFormatPEM ) {
33703417 // For PEM, we can easily determine whether it is a public or private key
33713418 // by looking for the respective PEM tags.
3372- ParsePublicKeyResult ret = ParsePublicKeyPEM (&pkey, data.get (),
3373- data.size ());
3374- if (ret == ParsePublicKeyResult::kParsePublicNotRecognized ) {
3375- pkey = ParsePrivateKey (config, data.get (), data.size ());
3419+ ret = ParsePublicKeyPEM (&pkey, data.get (), data.size ());
3420+ if (ret == ParseKeyResult::kParseKeyNotRecognized ) {
3421+ ret = ParsePrivateKey (&pkey, config, data.get (), data.size ());
33763422 }
33773423 } else {
33783424 // For DER, the type determines how to parse it. SPKI, PKCS#8 and SEC1 are
@@ -3395,14 +3441,14 @@ static ManagedEVPPKey GetPublicOrPrivateKeyFromJs(
33953441 }
33963442
33973443 if (is_public) {
3398- ParsePublicKey (&pkey, config, data.get (), data.size ());
3444+ ret = ParsePublicKey (&pkey, config, data.get (), data.size ());
33993445 } else {
3400- pkey = ParsePrivateKey (config, data.get (), data.size ());
3446+ ret = ParsePrivateKey (&pkey, config, data.get (), data.size ());
34013447 }
34023448 }
3403- if (!pkey)
3404- ThrowCryptoError (env, ERR_get_error ( ), " Failed to read asymmetric key " );
3405- return ManagedEVPPKey ( std::move (pkey) );
3449+
3450+ return GetParsedKey (env, std::move (pkey ), ret,
3451+ " Failed to read asymmetric key " );
34063452 } else {
34073453 CHECK (args[*offset]->IsObject ());
34083454 KeyObject* key = Unwrap<KeyObject>(args[*offset].As <Object>());
@@ -3585,6 +3631,7 @@ KeyType KeyObject::GetKeyType() const {
35853631void KeyObject::Init (const FunctionCallbackInfo<Value>& args) {
35863632 KeyObject* key;
35873633 ASSIGN_OR_RETURN_UNWRAP (&key, args.Holder ());
3634+ MarkPopErrorOnReturn mark_pop_error_on_return;
35883635
35893636 unsigned int offset;
35903637 ManagedEVPPKey pkey;
@@ -4780,6 +4827,8 @@ void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
47804827 Sign* sign;
47814828 ASSIGN_OR_RETURN_UNWRAP (&sign, args.Holder ());
47824829
4830+ ClearErrorOnReturn clear_error_on_return;
4831+
47834832 unsigned int offset = 0 ;
47844833 ManagedEVPPKey key = GetPrivateKeyFromJs (args, &offset, true );
47854834 if (!key)
@@ -4791,8 +4840,6 @@ void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) {
47914840 CHECK (args[offset + 1 ]->IsInt32 ());
47924841 int salt_len = args[offset + 1 ].As <Int32>()->Value ();
47934842
4794- ClearErrorOnReturn clear_error_on_return;
4795-
47964843 SignResult ret = sign->SignFinal (
47974844 key,
47984845 padding,
0 commit comments