@@ -14,6 +14,9 @@ typedef struct aws_rsa_key_pair *(aws_rsa_key_pair_new_from_public_pkcs1_fn)(str
1414typedef struct aws_rsa_key_pair * (aws_rsa_key_pair_new_from_private_pkcs1_fn )(struct aws_allocator * allocator ,
1515 struct aws_byte_cursor private_key );
1616
17+ typedef struct aws_rsa_key_pair * (aws_rsa_key_pair_new_from_private_pkcs8_fn )(struct aws_allocator * allocator ,
18+ struct aws_byte_cursor private_key );
19+
1720#ifndef BYO_CRYPTO
1821
1922extern struct aws_rsa_key_pair * aws_rsa_key_pair_new_from_public_key_pkcs1_impl (
@@ -24,6 +27,10 @@ extern struct aws_rsa_key_pair *aws_rsa_key_pair_new_from_private_key_pkcs1_impl
2427 struct aws_allocator * allocator ,
2528 struct aws_byte_cursor private_key );
2629
30+ struct aws_rsa_key_pair * aws_rsa_key_pair_new_from_private_key_pkcs8_impl (
31+ struct aws_allocator * allocator ,
32+ struct aws_byte_cursor private_key );
33+
2734#else /* BYO_CRYPTO */
2835
2936struct aws_rsa_key_pair * aws_rsa_key_pair_new_from_public_key_pkcs1_impl (
@@ -41,6 +48,14 @@ struct aws_rsa_key_pair *aws_rsa_key_pair_new_from_private_key_pkcs1_impl(
4148 (void )private_key ;
4249 abort ();
4350}
51+
52+ struct aws_rsa_key_pair * aws_rsa_key_pair_new_from_private_key_pkcs8_impl (
53+ struct aws_allocator * allocator ,
54+ struct aws_byte_cursor private_key ) {
55+ (void )allocator ;
56+ (void )private_key ;
57+ abort ();
58+ }
4459#endif /* BYO_CRYPTO */
4560
4661static aws_rsa_key_pair_new_from_public_pkcs1_fn * s_rsa_key_pair_new_from_public_key_pkcs1_fn =
@@ -49,6 +64,9 @@ static aws_rsa_key_pair_new_from_public_pkcs1_fn *s_rsa_key_pair_new_from_public
4964static aws_rsa_key_pair_new_from_private_pkcs1_fn * s_rsa_key_pair_new_from_private_key_pkcs1_fn =
5065 aws_rsa_key_pair_new_from_private_key_pkcs1_impl ;
5166
67+ static aws_rsa_key_pair_new_from_private_pkcs8_fn * s_rsa_key_pair_new_from_private_key_pkcs8_fn =
68+ aws_rsa_key_pair_new_from_private_key_pkcs8_impl ;
69+
5270struct aws_rsa_key_pair * aws_rsa_key_pair_new_from_public_key_pkcs1 (
5371 struct aws_allocator * allocator ,
5472 struct aws_byte_cursor public_key ) {
@@ -61,6 +79,12 @@ struct aws_rsa_key_pair *aws_rsa_key_pair_new_from_private_key_pkcs1(
6179 return s_rsa_key_pair_new_from_private_key_pkcs1_fn (allocator , private_key );
6280}
6381
82+ AWS_CAL_API struct aws_rsa_key_pair * aws_rsa_key_pair_new_from_private_key_pkcs8 (
83+ struct aws_allocator * allocator ,
84+ struct aws_byte_cursor key ) {
85+ return s_rsa_key_pair_new_from_private_key_pkcs8_fn (allocator , key );
86+ }
87+
6488void aws_rsa_key_pair_base_clean_up (struct aws_rsa_key_pair * key_pair ) {
6589 aws_byte_buf_clean_up_secure (& key_pair -> priv );
6690 aws_byte_buf_clean_up_secure (& key_pair -> pub );
@@ -286,3 +310,107 @@ int is_valid_rsa_key_size(size_t key_size_in_bits) {
286310
287311 return AWS_OP_SUCCESS ;
288312}
313+
314+ #ifndef BYO_CRYPTO
315+
316+ static uint8_t s_rsa_encryption_oid [] = {0x2a , 0x86 , 0x48 , 0x86 , 0xf7 , 0x0d , 0x01 , 0x01 , 0x01 };
317+
318+ /**
319+ * There are likely tens of algo specifiers for rsa out there.
320+ * But in practice mostly everyone uses rsaEncryption oid for key at rest.
321+ * So for now just support that and we can add other ones later if needed.
322+ * Even though its technically encryption oid, most crypto libs are lax
323+ * and allow the key to be used for all operations.
324+ */
325+ static struct aws_byte_cursor s_rsa_encryption_oid_cur = {
326+ .ptr = (s_rsa_encryption_oid ),
327+ .len = sizeof (s_rsa_encryption_oid ),
328+ };
329+
330+ /**
331+ * Win and Mac dont provide native support for loading pkcs8 keys, so
332+ * for simplicity and consistency just parse pkcs1 key from pkcs8 and
333+ * use it with existing pkcs1 loader.
334+ */
335+ struct aws_rsa_key_pair * aws_rsa_key_pair_new_from_private_key_pkcs8_impl (
336+ struct aws_allocator * allocator ,
337+ struct aws_byte_cursor private_key ) {
338+
339+ struct aws_der_decoder * decoder = aws_der_decoder_new (allocator , private_key );
340+
341+ if (decoder == NULL ) {
342+ return NULL ;
343+ }
344+
345+ /**
346+ * Format of pkcs8 is as follows.
347+ * PrivateKeyInfo ::= SEQUENCE {
348+ * version Version, -- INTEGER (0)
349+ * algorithm AlgorithmIdentifier,
350+ * privateKey OCTET STRING, -- contains DER encoded key
351+ * attributes [0] IMPLICIT SET OF Attribute OPTIONAL
352+ * }
353+ * AlgorithmIdentifier ::= SEQUENCE {
354+ * algorithm OBJECT IDENTIFIER,
355+ * parameters ANY DEFINED BY algorithm OPTIONAL
356+ * }
357+ */
358+
359+ struct aws_rsa_key_pair * key_pair = NULL ;
360+
361+ if (!aws_der_decoder_next (decoder ) || aws_der_decoder_tlv_type (decoder ) != AWS_DER_SEQUENCE ) {
362+ aws_raise_error (AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED );
363+ goto on_done ;
364+ }
365+
366+ /* version */
367+ struct aws_byte_cursor version_cur ;
368+ if (!aws_der_decoder_next (decoder ) || aws_der_decoder_tlv_unsigned_integer (decoder , & version_cur )) {
369+ aws_raise_error (AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED );
370+ goto on_done ;
371+ }
372+
373+ if (version_cur .len != 1 || version_cur .ptr [0 ] != 0 ) {
374+ aws_raise_error (AWS_ERROR_CAL_UNSUPPORTED_KEY_FORMAT );
375+ goto on_done ;
376+ }
377+
378+ /* oid */
379+ struct aws_byte_cursor oid_cur ;
380+ if (!aws_der_decoder_next (decoder ) || aws_der_decoder_tlv_type (decoder ) != AWS_DER_SEQUENCE ) {
381+ aws_raise_error (AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED );
382+ goto on_done ;
383+ }
384+
385+ if (!aws_der_decoder_next (decoder ) || aws_der_decoder_tlv_type (decoder ) != AWS_DER_OBJECT_IDENTIFIER ||
386+ aws_der_decoder_tlv_blob (decoder , & oid_cur )) {
387+ aws_raise_error (AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED );
388+ goto on_done ;
389+ }
390+
391+ if (!aws_byte_cursor_eq (& s_rsa_encryption_oid_cur , & oid_cur )) {
392+ aws_raise_error (AWS_ERROR_CAL_UNSUPPORTED_KEY_FORMAT );
393+ goto on_done ;
394+ }
395+
396+ /* skip additional params */
397+ if (!aws_der_decoder_next (decoder )) {
398+ aws_raise_error (AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED );
399+ goto on_done ;
400+ }
401+
402+ /* key */
403+ struct aws_byte_cursor key ;
404+ if (!aws_der_decoder_next (decoder ) || aws_der_decoder_tlv_string (decoder , & key )) {
405+ aws_raise_error (AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED );
406+ goto on_done ;
407+ }
408+
409+ key_pair = aws_rsa_key_pair_new_from_private_key_pkcs1 (allocator , key );
410+
411+ on_done :
412+ aws_der_decoder_destroy (decoder );
413+ return key_pair ;
414+ }
415+
416+ #endif
0 commit comments