@@ -2848,6 +2848,59 @@ static MaybeLocal<Value> WritePublicKey(Environment* env,
2848
2848
return BIOToStringOrBuffer (env, bio.get (), config.format_ );
2849
2849
}
2850
2850
2851
+ static bool IsASN1Sequence (const unsigned char * data, size_t size,
2852
+ size_t * data_offset, size_t * data_size) {
2853
+ if (size < 2 || data[0 ] != 0x30 )
2854
+ return false ;
2855
+
2856
+ if (data[1 ] & 0x80 ) {
2857
+ // Long form.
2858
+ size_t n_bytes = data[1 ] & ~0x80 ;
2859
+ if (n_bytes + 2 > size || n_bytes > sizeof (size_t ))
2860
+ return false ;
2861
+ size_t length = 0 ;
2862
+ for (size_t i = 0 ; i < n_bytes; i++)
2863
+ length = (length << 8 ) | data[i + 2 ];
2864
+ *data_offset = 2 + n_bytes;
2865
+ *data_size = std::min (size - 2 - n_bytes, length);
2866
+ } else {
2867
+ // Short form.
2868
+ *data_offset = 2 ;
2869
+ *data_size = std::min<size_t >(size - 2 , data[1 ]);
2870
+ }
2871
+
2872
+ return true ;
2873
+ }
2874
+
2875
+ static bool IsRSAPrivateKey (const unsigned char * data, size_t size) {
2876
+ // Both RSAPrivateKey and RSAPublicKey structures start with a SEQUENCE.
2877
+ size_t offset, len;
2878
+ if (!IsASN1Sequence (data, size, &offset, &len))
2879
+ return false ;
2880
+
2881
+ // An RSAPrivateKey sequence always starts with a single-byte integer whose
2882
+ // value is either 0 or 1, whereas an RSAPublicKey starts with the modulus
2883
+ // (which is the product of two primes and therefore at least 4), so we can
2884
+ // decide the type of the structure based on the first three bytes of the
2885
+ // sequence.
2886
+ return len >= 3 &&
2887
+ data[offset] == 2 &&
2888
+ data[offset + 1 ] == 1 &&
2889
+ !(data[offset + 2 ] & 0xfe );
2890
+ }
2891
+
2892
+ static bool IsEncryptedPrivateKeyInfo (const unsigned char * data, size_t size) {
2893
+ // Both PrivateKeyInfo and EncryptedPrivateKeyInfo start with a SEQUENCE.
2894
+ size_t offset, len;
2895
+ if (!IsASN1Sequence (data, size, &offset, &len))
2896
+ return false ;
2897
+
2898
+ // A PrivateKeyInfo sequence always starts with an integer whereas an
2899
+ // EncryptedPrivateKeyInfo starts with an AlgorithmIdentifier.
2900
+ return len >= 1 &&
2901
+ data[offset] != 2 ;
2902
+ }
2903
+
2851
2904
static EVPKeyPointer ParsePrivateKey (const PrivateKeyEncodingConfig& config,
2852
2905
const char * key,
2853
2906
size_t key_len) {
@@ -2873,11 +2926,19 @@ static EVPKeyPointer ParsePrivateKey(const PrivateKeyEncodingConfig& config,
2873
2926
BIOPointer bio (BIO_new_mem_buf (key, key_len));
2874
2927
if (!bio)
2875
2928
return pkey;
2876
- char * pass = const_cast <char *>(config.passphrase_ .get ());
2877
- pkey.reset (d2i_PKCS8PrivateKey_bio (bio.get (),
2878
- nullptr ,
2879
- PasswordCallback,
2880
- pass));
2929
+
2930
+ if (IsEncryptedPrivateKeyInfo (
2931
+ reinterpret_cast <const unsigned char *>(key), key_len)) {
2932
+ char * pass = const_cast <char *>(config.passphrase_ .get ());
2933
+ pkey.reset (d2i_PKCS8PrivateKey_bio (bio.get (),
2934
+ nullptr ,
2935
+ PasswordCallback,
2936
+ pass));
2937
+ } else {
2938
+ PKCS8Pointer p8inf (d2i_PKCS8_PRIV_KEY_INFO_bio (bio.get (), nullptr ));
2939
+ if (p8inf)
2940
+ pkey.reset (EVP_PKCS82PKEY (p8inf.get ()));
2941
+ }
2881
2942
} else {
2882
2943
CHECK_EQ (config.type_ .ToChecked (), kKeyEncodingSEC1 );
2883
2944
const unsigned char * p = reinterpret_cast <const unsigned char *>(key);
@@ -3093,40 +3154,6 @@ static ManagedEVPPKey GetPrivateKeyFromJs(
3093
3154
}
3094
3155
}
3095
3156
3096
- static bool IsRSAPrivateKey (const unsigned char * data, size_t size) {
3097
- // Both RSAPrivateKey and RSAPublicKey structures start with a SEQUENCE.
3098
- if (size >= 2 && data[0 ] == 0x30 ) {
3099
- size_t offset;
3100
- if (data[1 ] & 0x80 ) {
3101
- // Long form.
3102
- size_t n_bytes = data[1 ] & ~0x80 ;
3103
- if (n_bytes + 2 > size || n_bytes > sizeof (size_t ))
3104
- return false ;
3105
- size_t i, length = 0 ;
3106
- for (i = 0 ; i < n_bytes; i++)
3107
- length = (length << 8 ) | data[i + 2 ];
3108
- offset = 2 + n_bytes;
3109
- size = std::min (size, length + 2 );
3110
- } else {
3111
- // Short form.
3112
- offset = 2 ;
3113
- size = std::min<size_t >(size, data[1 ] + 2 );
3114
- }
3115
-
3116
- // An RSAPrivateKey sequence always starts with a single-byte integer whose
3117
- // value is either 0 or 1, whereas an RSAPublicKey starts with the modulus
3118
- // (which is the product of two primes and therefore at least 4), so we can
3119
- // decide the type of the structure based on the first three bytes of the
3120
- // sequence.
3121
- return size - offset >= 3 &&
3122
- data[offset] == 2 &&
3123
- data[offset + 1 ] == 1 &&
3124
- !(data[offset + 2 ] & 0xfe );
3125
- }
3126
-
3127
- return false ;
3128
- }
3129
-
3130
3157
static ManagedEVPPKey GetPublicOrPrivateKeyFromJs (
3131
3158
const FunctionCallbackInfo<Value>& args,
3132
3159
unsigned int * offset,
0 commit comments