@@ -2821,6 +2821,59 @@ static MaybeLocal<Value> WritePublicKey(Environment* env,
2821
2821
return BIOToStringOrBuffer (env, bio.get (), config.format_ );
2822
2822
}
2823
2823
2824
+ static bool IsASN1Sequence (const unsigned char * data, size_t size,
2825
+ size_t * data_offset, size_t * data_size) {
2826
+ if (size < 2 || data[0 ] != 0x30 )
2827
+ return false ;
2828
+
2829
+ if (data[1 ] & 0x80 ) {
2830
+ // Long form.
2831
+ size_t n_bytes = data[1 ] & ~0x80 ;
2832
+ if (n_bytes + 2 > size || n_bytes > sizeof (size_t ))
2833
+ return false ;
2834
+ size_t length = 0 ;
2835
+ for (size_t i = 0 ; i < n_bytes; i++)
2836
+ length = (length << 8 ) | data[i + 2 ];
2837
+ *data_offset = 2 + n_bytes;
2838
+ *data_size = std::min (size - 2 - n_bytes, length);
2839
+ } else {
2840
+ // Short form.
2841
+ *data_offset = 2 ;
2842
+ *data_size = std::min<size_t >(size - 2 , data[1 ]);
2843
+ }
2844
+
2845
+ return true ;
2846
+ }
2847
+
2848
+ static bool IsRSAPrivateKey (const unsigned char * data, size_t size) {
2849
+ // Both RSAPrivateKey and RSAPublicKey structures start with a SEQUENCE.
2850
+ size_t offset, len;
2851
+ if (!IsASN1Sequence (data, size, &offset, &len))
2852
+ return false ;
2853
+
2854
+ // An RSAPrivateKey sequence always starts with a single-byte integer whose
2855
+ // value is either 0 or 1, whereas an RSAPublicKey starts with the modulus
2856
+ // (which is the product of two primes and therefore at least 4), so we can
2857
+ // decide the type of the structure based on the first three bytes of the
2858
+ // sequence.
2859
+ return len >= 3 &&
2860
+ data[offset] == 2 &&
2861
+ data[offset + 1 ] == 1 &&
2862
+ !(data[offset + 2 ] & 0xfe );
2863
+ }
2864
+
2865
+ static bool IsEncryptedPrivateKeyInfo (const unsigned char * data, size_t size) {
2866
+ // Both PrivateKeyInfo and EncryptedPrivateKeyInfo start with a SEQUENCE.
2867
+ size_t offset, len;
2868
+ if (!IsASN1Sequence (data, size, &offset, &len))
2869
+ return false ;
2870
+
2871
+ // A PrivateKeyInfo sequence always starts with an integer whereas an
2872
+ // EncryptedPrivateKeyInfo starts with an AlgorithmIdentifier.
2873
+ return len >= 1 &&
2874
+ data[offset] != 2 ;
2875
+ }
2876
+
2824
2877
static EVPKeyPointer ParsePrivateKey (const PrivateKeyEncodingConfig& config,
2825
2878
const char * key,
2826
2879
size_t key_len) {
@@ -2846,11 +2899,19 @@ static EVPKeyPointer ParsePrivateKey(const PrivateKeyEncodingConfig& config,
2846
2899
BIOPointer bio (BIO_new_mem_buf (key, key_len));
2847
2900
if (!bio)
2848
2901
return pkey;
2849
- char * pass = const_cast <char *>(config.passphrase_ .get ());
2850
- pkey.reset (d2i_PKCS8PrivateKey_bio (bio.get (),
2851
- nullptr ,
2852
- PasswordCallback,
2853
- pass));
2902
+
2903
+ if (IsEncryptedPrivateKeyInfo (
2904
+ reinterpret_cast <const unsigned char *>(key), key_len)) {
2905
+ char * pass = const_cast <char *>(config.passphrase_ .get ());
2906
+ pkey.reset (d2i_PKCS8PrivateKey_bio (bio.get (),
2907
+ nullptr ,
2908
+ PasswordCallback,
2909
+ pass));
2910
+ } else {
2911
+ PKCS8Pointer p8inf (d2i_PKCS8_PRIV_KEY_INFO_bio (bio.get (), nullptr ));
2912
+ if (p8inf)
2913
+ pkey.reset (EVP_PKCS82PKEY (p8inf.get ()));
2914
+ }
2854
2915
} else {
2855
2916
CHECK_EQ (config.type_ .ToChecked (), kKeyEncodingSEC1 );
2856
2917
const unsigned char * p = reinterpret_cast <const unsigned char *>(key);
@@ -3066,40 +3127,6 @@ static ManagedEVPPKey GetPrivateKeyFromJs(
3066
3127
}
3067
3128
}
3068
3129
3069
- static bool IsRSAPrivateKey (const unsigned char * data, size_t size) {
3070
- // Both RSAPrivateKey and RSAPublicKey structures start with a SEQUENCE.
3071
- if (size >= 2 && data[0 ] == 0x30 ) {
3072
- size_t offset;
3073
- if (data[1 ] & 0x80 ) {
3074
- // Long form.
3075
- size_t n_bytes = data[1 ] & ~0x80 ;
3076
- if (n_bytes + 2 > size || n_bytes > sizeof (size_t ))
3077
- return false ;
3078
- size_t i, length = 0 ;
3079
- for (i = 0 ; i < n_bytes; i++)
3080
- length = (length << 8 ) | data[i + 2 ];
3081
- offset = 2 + n_bytes;
3082
- size = std::min (size, length + 2 );
3083
- } else {
3084
- // Short form.
3085
- offset = 2 ;
3086
- size = std::min<size_t >(size, data[1 ] + 2 );
3087
- }
3088
-
3089
- // An RSAPrivateKey sequence always starts with a single-byte integer whose
3090
- // value is either 0 or 1, whereas an RSAPublicKey starts with the modulus
3091
- // (which is the product of two primes and therefore at least 4), so we can
3092
- // decide the type of the structure based on the first three bytes of the
3093
- // sequence.
3094
- return size - offset >= 3 &&
3095
- data[offset] == 2 &&
3096
- data[offset + 1 ] == 1 &&
3097
- !(data[offset + 2 ] & 0xfe );
3098
- }
3099
-
3100
- return false ;
3101
- }
3102
-
3103
3130
static ManagedEVPPKey GetPublicOrPrivateKeyFromJs (
3104
3131
const FunctionCallbackInfo<Value>& args,
3105
3132
unsigned int * offset,
0 commit comments