2 * Public Key layer for parsing key files and structures
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: GPL-2.0
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 * This file is part of mbed TLS (https://tls.mbed.org)
24 #if !defined(MBEDTLS_CONFIG_FILE)
25 #include "mbedtls/config.h"
27 #include MBEDTLS_CONFIG_FILE
30 #if defined(MBEDTLS_PK_PARSE_C)
32 #include "mbedtls/pk.h"
33 #include "mbedtls/asn1.h"
34 #include "mbedtls/oid.h"
38 #if defined(MBEDTLS_RSA_C)
39 #include "mbedtls/rsa.h"
41 #if defined(MBEDTLS_ECP_C)
42 #include "mbedtls/ecp.h"
44 #if defined(MBEDTLS_ECDSA_C)
45 #include "mbedtls/ecdsa.h"
47 #if defined(MBEDTLS_PEM_PARSE_C)
48 #include "mbedtls/pem.h"
50 #if defined(MBEDTLS_PKCS5_C)
51 #include "mbedtls/pkcs5.h"
53 #if defined(MBEDTLS_PKCS12_C)
54 #include "mbedtls/pkcs12.h"
57 #if defined(MBEDTLS_PLATFORM_C)
58 #include "mbedtls/platform.h"
61 #define mbedtls_calloc calloc
62 #define mbedtls_free free
65 #if defined(MBEDTLS_FS_IO)
66 /* Implementation that should never be optimized out by the compiler */
67 static void mbedtls_zeroize( void *v
, size_t n
) {
68 volatile unsigned char *p
= v
; while( n
-- ) *p
++ = 0;
72 * Load all data from a file into a given buffer.
74 * The file is expected to contain either PEM or DER encoded data.
75 * A terminating null byte is always appended. It is included in the announced
76 * length only if the data looks like it is PEM encoded.
78 int mbedtls_pk_load_file( const char *path
, unsigned char **buf
, size_t *n
)
83 if( ( f
= fopen( path
, "rb" ) ) == NULL
)
84 return( MBEDTLS_ERR_PK_FILE_IO_ERROR
);
86 fseek( f
, 0, SEEK_END
);
87 if( ( size
= ftell( f
) ) == -1 )
90 return( MBEDTLS_ERR_PK_FILE_IO_ERROR
);
92 fseek( f
, 0, SEEK_SET
);
97 ( *buf
= mbedtls_calloc( 1, *n
+ 1 ) ) == NULL
)
100 return( MBEDTLS_ERR_PK_ALLOC_FAILED
);
103 if( fread( *buf
, 1, *n
, f
) != *n
)
106 mbedtls_free( *buf
);
107 return( MBEDTLS_ERR_PK_FILE_IO_ERROR
);
114 if( strstr( (const char *) *buf
, "-----BEGIN " ) != NULL
)
121 * Load and parse a private key
123 int mbedtls_pk_parse_keyfile( mbedtls_pk_context
*ctx
,
124 const char *path
, const char *pwd
)
130 if( ( ret
= mbedtls_pk_load_file( path
, &buf
, &n
) ) != 0 )
134 ret
= mbedtls_pk_parse_key( ctx
, buf
, n
, NULL
, 0 );
136 ret
= mbedtls_pk_parse_key( ctx
, buf
, n
,
137 (const unsigned char *) pwd
, strlen( pwd
) );
139 mbedtls_zeroize( buf
, n
);
146 * Load and parse a public key
148 int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context
*ctx
, const char *path
)
154 if( ( ret
= mbedtls_pk_load_file( path
, &buf
, &n
) ) != 0 )
157 ret
= mbedtls_pk_parse_public_key( ctx
, buf
, n
);
159 mbedtls_zeroize( buf
, n
);
164 #endif /* MBEDTLS_FS_IO */
166 #if defined(MBEDTLS_ECP_C)
167 /* Minimally parse an ECParameters buffer to and mbedtls_asn1_buf
169 * ECParameters ::= CHOICE {
170 * namedCurve OBJECT IDENTIFIER
171 * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... }
172 * -- implicitCurve NULL
175 static int pk_get_ecparams( unsigned char **p
, const unsigned char *end
,
176 mbedtls_asn1_buf
*params
)
180 /* Tag may be either OID or SEQUENCE */
182 if( params
->tag
!= MBEDTLS_ASN1_OID
183 #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
184 && params
->tag
!= ( MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
)
188 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
189 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
);
192 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, ¶ms
->len
, params
->tag
) ) != 0 )
194 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
201 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
202 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
207 #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
209 * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it.
210 * WARNING: the resulting group should only be used with
211 * pk_group_id_from_specified(), since its base point may not be set correctly
212 * if it was encoded compressed.
214 * SpecifiedECDomain ::= SEQUENCE {
215 * version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...),
216 * fieldID FieldID {{FieldTypes}},
220 * cofactor INTEGER OPTIONAL,
221 * hash HashAlgorithm OPTIONAL,
225 * We only support prime-field as field type, and ignore hash and cofactor.
227 static int pk_group_from_specified( const mbedtls_asn1_buf
*params
, mbedtls_ecp_group
*grp
)
230 unsigned char *p
= params
->p
;
231 const unsigned char * const end
= params
->p
+ params
->len
;
232 const unsigned char *end_field
, *end_curve
;
236 /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */
237 if( ( ret
= mbedtls_asn1_get_int( &p
, end
, &ver
) ) != 0 )
238 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
240 if( ver
< 1 || ver
> 3 )
241 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
);
244 * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field
245 * fieldType FIELD-ID.&id({IOSet}),
246 * parameters FIELD-ID.&Type({IOSet}{@fieldType})
249 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
250 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
256 * FIELD-ID ::= TYPE-IDENTIFIER
257 * FieldTypes FIELD-ID ::= {
258 * { Prime-p IDENTIFIED BY prime-field } |
259 * { Characteristic-two IDENTIFIED BY characteristic-two-field }
261 * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
263 if( ( ret
= mbedtls_asn1_get_tag( &p
, end_field
, &len
, MBEDTLS_ASN1_OID
) ) != 0 )
266 if( len
!= MBEDTLS_OID_SIZE( MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD
) ||
267 memcmp( p
, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD
, len
) != 0 )
269 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE
);
274 /* Prime-p ::= INTEGER -- Field of size p. */
275 if( ( ret
= mbedtls_asn1_get_mpi( &p
, end_field
, &grp
->P
) ) != 0 )
276 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
278 grp
->pbits
= mbedtls_mpi_bitlen( &grp
->P
);
281 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
282 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
285 * Curve ::= SEQUENCE {
288 * seed BIT STRING OPTIONAL
289 * -- Shall be present if used in SpecifiedECDomain
290 * -- with version equal to ecdpVer2 or ecdpVer3
293 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
294 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
300 * FieldElement ::= OCTET STRING
301 * containing an integer in the case of a prime field
303 if( ( ret
= mbedtls_asn1_get_tag( &p
, end_curve
, &len
, MBEDTLS_ASN1_OCTET_STRING
) ) != 0 ||
304 ( ret
= mbedtls_mpi_read_binary( &grp
->A
, p
, len
) ) != 0 )
306 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
311 if( ( ret
= mbedtls_asn1_get_tag( &p
, end_curve
, &len
, MBEDTLS_ASN1_OCTET_STRING
) ) != 0 ||
312 ( ret
= mbedtls_mpi_read_binary( &grp
->B
, p
, len
) ) != 0 )
314 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
319 /* Ignore seed BIT STRING OPTIONAL */
320 if( ( ret
= mbedtls_asn1_get_tag( &p
, end_curve
, &len
, MBEDTLS_ASN1_BIT_STRING
) ) == 0 )
324 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
325 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
328 * ECPoint ::= OCTET STRING
330 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
, MBEDTLS_ASN1_OCTET_STRING
) ) != 0 )
331 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
333 if( ( ret
= mbedtls_ecp_point_read_binary( grp
, &grp
->G
,
334 ( const unsigned char *) p
, len
) ) != 0 )
337 * If we can't read the point because it's compressed, cheat by
338 * reading only the X coordinate and the parity bit of Y.
340 if( ret
!= MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
||
341 ( p
[0] != 0x02 && p
[0] != 0x03 ) ||
342 len
!= mbedtls_mpi_size( &grp
->P
) + 1 ||
343 mbedtls_mpi_read_binary( &grp
->G
.X
, p
+ 1, len
- 1 ) != 0 ||
344 mbedtls_mpi_lset( &grp
->G
.Y
, p
[0] - 2 ) != 0 ||
345 mbedtls_mpi_lset( &grp
->G
.Z
, 1 ) != 0 )
347 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
);
356 if( ( ret
= mbedtls_asn1_get_mpi( &p
, end
, &grp
->N
) ) != 0 )
357 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
359 grp
->nbits
= mbedtls_mpi_bitlen( &grp
->N
);
362 * Allow optional elements by purposefully not enforcing p == end here.
369 * Find the group id associated with an (almost filled) group as generated by
370 * pk_group_from_specified(), or return an error if unknown.
372 static int pk_group_id_from_group( const mbedtls_ecp_group
*grp
, mbedtls_ecp_group_id
*grp_id
)
375 mbedtls_ecp_group ref
;
376 const mbedtls_ecp_group_id
*id
;
378 mbedtls_ecp_group_init( &ref
);
380 for( id
= mbedtls_ecp_grp_id_list(); *id
!= MBEDTLS_ECP_DP_NONE
; id
++ )
382 /* Load the group associated to that id */
383 mbedtls_ecp_group_free( &ref
);
384 MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ref
, *id
) );
386 /* Compare to the group we were given, starting with easy tests */
387 if( grp
->pbits
== ref
.pbits
&& grp
->nbits
== ref
.nbits
&&
388 mbedtls_mpi_cmp_mpi( &grp
->P
, &ref
.P
) == 0 &&
389 mbedtls_mpi_cmp_mpi( &grp
->A
, &ref
.A
) == 0 &&
390 mbedtls_mpi_cmp_mpi( &grp
->B
, &ref
.B
) == 0 &&
391 mbedtls_mpi_cmp_mpi( &grp
->N
, &ref
.N
) == 0 &&
392 mbedtls_mpi_cmp_mpi( &grp
->G
.X
, &ref
.G
.X
) == 0 &&
393 mbedtls_mpi_cmp_mpi( &grp
->G
.Z
, &ref
.G
.Z
) == 0 &&
394 /* For Y we may only know the parity bit, so compare only that */
395 mbedtls_mpi_get_bit( &grp
->G
.Y
, 0 ) == mbedtls_mpi_get_bit( &ref
.G
.Y
, 0 ) )
403 mbedtls_ecp_group_free( &ref
);
407 if( ret
== 0 && *id
== MBEDTLS_ECP_DP_NONE
)
408 ret
= MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
;
414 * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID
416 static int pk_group_id_from_specified( const mbedtls_asn1_buf
*params
,
417 mbedtls_ecp_group_id
*grp_id
)
420 mbedtls_ecp_group grp
;
422 mbedtls_ecp_group_init( &grp
);
424 if( ( ret
= pk_group_from_specified( params
, &grp
) ) != 0 )
427 ret
= pk_group_id_from_group( &grp
, grp_id
);
430 mbedtls_ecp_group_free( &grp
);
434 #endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */
437 * Use EC parameters to initialise an EC group
439 * ECParameters ::= CHOICE {
440 * namedCurve OBJECT IDENTIFIER
441 * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... }
442 * -- implicitCurve NULL
444 static int pk_use_ecparams( const mbedtls_asn1_buf
*params
, mbedtls_ecp_group
*grp
)
447 mbedtls_ecp_group_id grp_id
;
449 if( params
->tag
== MBEDTLS_ASN1_OID
)
451 if( mbedtls_oid_get_ec_grp( params
, &grp_id
) != 0 )
452 return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE
);
456 #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
457 if( ( ret
= pk_group_id_from_specified( params
, &grp_id
) ) != 0 )
460 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
);
465 * grp may already be initilialized; if so, make sure IDs match
467 if( grp
->id
!= MBEDTLS_ECP_DP_NONE
&& grp
->id
!= grp_id
)
468 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
);
470 if( ( ret
= mbedtls_ecp_group_load( grp
, grp_id
) ) != 0 )
477 * EC public key is an EC point
479 * The caller is responsible for clearing the structure upon failure if
480 * desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE
481 * return code of mbedtls_ecp_point_read_binary() and leave p in a usable state.
483 static int pk_get_ecpubkey( unsigned char **p
, const unsigned char *end
,
484 mbedtls_ecp_keypair
*key
)
488 if( ( ret
= mbedtls_ecp_point_read_binary( &key
->grp
, &key
->Q
,
489 (const unsigned char *) *p
, end
- *p
) ) == 0 )
491 ret
= mbedtls_ecp_check_pubkey( &key
->grp
, &key
->Q
);
495 * We know mbedtls_ecp_point_read_binary consumed all bytes or failed
497 *p
= (unsigned char *) end
;
501 #endif /* MBEDTLS_ECP_C */
503 #if defined(MBEDTLS_RSA_C)
505 * RSAPublicKey ::= SEQUENCE {
506 * modulus INTEGER, -- n
507 * publicExponent INTEGER -- e
510 static int pk_get_rsapubkey( unsigned char **p
,
511 const unsigned char *end
,
512 mbedtls_rsa_context
*rsa
)
517 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
,
518 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
519 return( MBEDTLS_ERR_PK_INVALID_PUBKEY
+ ret
);
521 if( *p
+ len
!= end
)
522 return( MBEDTLS_ERR_PK_INVALID_PUBKEY
+
523 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
525 if( ( ret
= mbedtls_asn1_get_mpi( p
, end
, &rsa
->N
) ) != 0 ||
526 ( ret
= mbedtls_asn1_get_mpi( p
, end
, &rsa
->E
) ) != 0 )
527 return( MBEDTLS_ERR_PK_INVALID_PUBKEY
+ ret
);
530 return( MBEDTLS_ERR_PK_INVALID_PUBKEY
+
531 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
533 if( ( ret
= mbedtls_rsa_check_pubkey( rsa
) ) != 0 )
534 return( MBEDTLS_ERR_PK_INVALID_PUBKEY
);
536 rsa
->len
= mbedtls_mpi_size( &rsa
->N
);
540 #endif /* MBEDTLS_RSA_C */
542 /* Get a PK algorithm identifier
544 * AlgorithmIdentifier ::= SEQUENCE {
545 * algorithm OBJECT IDENTIFIER,
546 * parameters ANY DEFINED BY algorithm OPTIONAL }
548 static int pk_get_pk_alg( unsigned char **p
,
549 const unsigned char *end
,
550 mbedtls_pk_type_t
*pk_alg
, mbedtls_asn1_buf
*params
)
553 mbedtls_asn1_buf alg_oid
;
555 memset( params
, 0, sizeof(mbedtls_asn1_buf
) );
557 if( ( ret
= mbedtls_asn1_get_alg( p
, end
, &alg_oid
, params
) ) != 0 )
558 return( MBEDTLS_ERR_PK_INVALID_ALG
+ ret
);
560 if( mbedtls_oid_get_pk_alg( &alg_oid
, pk_alg
) != 0 )
561 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG
);
564 * No parameters with RSA (only for EC)
566 if( *pk_alg
== MBEDTLS_PK_RSA
&&
567 ( ( params
->tag
!= MBEDTLS_ASN1_NULL
&& params
->tag
!= 0 ) ||
570 return( MBEDTLS_ERR_PK_INVALID_ALG
);
577 * SubjectPublicKeyInfo ::= SEQUENCE {
578 * algorithm AlgorithmIdentifier,
579 * subjectPublicKey BIT STRING }
581 int mbedtls_pk_parse_subpubkey( unsigned char **p
, const unsigned char *end
,
582 mbedtls_pk_context
*pk
)
586 mbedtls_asn1_buf alg_params
;
587 mbedtls_pk_type_t pk_alg
= MBEDTLS_PK_NONE
;
588 const mbedtls_pk_info_t
*pk_info
;
590 if( ( ret
= mbedtls_asn1_get_tag( p
, end
, &len
,
591 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
593 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
598 if( ( ret
= pk_get_pk_alg( p
, end
, &pk_alg
, &alg_params
) ) != 0 )
601 if( ( ret
= mbedtls_asn1_get_bitstring_null( p
, end
, &len
) ) != 0 )
602 return( MBEDTLS_ERR_PK_INVALID_PUBKEY
+ ret
);
604 if( *p
+ len
!= end
)
605 return( MBEDTLS_ERR_PK_INVALID_PUBKEY
+
606 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
608 if( ( pk_info
= mbedtls_pk_info_from_type( pk_alg
) ) == NULL
)
609 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG
);
611 if( ( ret
= mbedtls_pk_setup( pk
, pk_info
) ) != 0 )
614 #if defined(MBEDTLS_RSA_C)
615 if( pk_alg
== MBEDTLS_PK_RSA
)
617 ret
= pk_get_rsapubkey( p
, end
, mbedtls_pk_rsa( *pk
) );
619 #endif /* MBEDTLS_RSA_C */
620 #if defined(MBEDTLS_ECP_C)
621 if( pk_alg
== MBEDTLS_PK_ECKEY_DH
|| pk_alg
== MBEDTLS_PK_ECKEY
)
623 ret
= pk_use_ecparams( &alg_params
, &mbedtls_pk_ec( *pk
)->grp
);
625 ret
= pk_get_ecpubkey( p
, end
, mbedtls_pk_ec( *pk
) );
627 #endif /* MBEDTLS_ECP_C */
628 ret
= MBEDTLS_ERR_PK_UNKNOWN_PK_ALG
;
630 if( ret
== 0 && *p
!= end
)
631 ret
= MBEDTLS_ERR_PK_INVALID_PUBKEY
632 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
;
635 mbedtls_pk_free( pk
);
640 #if defined(MBEDTLS_RSA_C)
642 * Parse a PKCS#1 encoded private RSA key
644 static int pk_parse_key_pkcs1_der( mbedtls_rsa_context
*rsa
,
645 const unsigned char *key
,
650 unsigned char *p
, *end
;
652 p
= (unsigned char *) key
;
656 * This function parses the RSAPrivateKey (PKCS#1)
658 * RSAPrivateKey ::= SEQUENCE {
660 * modulus INTEGER, -- n
661 * publicExponent INTEGER, -- e
662 * privateExponent INTEGER, -- d
663 * prime1 INTEGER, -- p
664 * prime2 INTEGER, -- q
665 * exponent1 INTEGER, -- d mod (p-1)
666 * exponent2 INTEGER, -- d mod (q-1)
667 * coefficient INTEGER, -- (inverse of q) mod p
668 * otherPrimeInfos OtherPrimeInfos OPTIONAL
671 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
672 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
674 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
679 if( ( ret
= mbedtls_asn1_get_int( &p
, end
, &rsa
->ver
) ) != 0 )
681 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
686 return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION
);
689 if( ( ret
= mbedtls_asn1_get_mpi( &p
, end
, &rsa
->N
) ) != 0 ||
690 ( ret
= mbedtls_asn1_get_mpi( &p
, end
, &rsa
->E
) ) != 0 ||
691 ( ret
= mbedtls_asn1_get_mpi( &p
, end
, &rsa
->D
) ) != 0 ||
692 ( ret
= mbedtls_asn1_get_mpi( &p
, end
, &rsa
->P
) ) != 0 ||
693 ( ret
= mbedtls_asn1_get_mpi( &p
, end
, &rsa
->Q
) ) != 0 ||
694 ( ret
= mbedtls_asn1_get_mpi( &p
, end
, &rsa
->DP
) ) != 0 ||
695 ( ret
= mbedtls_asn1_get_mpi( &p
, end
, &rsa
->DQ
) ) != 0 ||
696 ( ret
= mbedtls_asn1_get_mpi( &p
, end
, &rsa
->QP
) ) != 0 )
698 mbedtls_rsa_free( rsa
);
699 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
702 rsa
->len
= mbedtls_mpi_size( &rsa
->N
);
706 mbedtls_rsa_free( rsa
);
707 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
708 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
711 if( ( ret
= mbedtls_rsa_check_privkey( rsa
) ) != 0 )
713 mbedtls_rsa_free( rsa
);
719 #endif /* MBEDTLS_RSA_C */
721 #if defined(MBEDTLS_ECP_C)
723 * Parse a SEC1 encoded private EC key
725 static int pk_parse_key_sec1_der( mbedtls_ecp_keypair
*eck
,
726 const unsigned char *key
,
730 int version
, pubkey_done
;
732 mbedtls_asn1_buf params
;
733 unsigned char *p
= (unsigned char *) key
;
734 unsigned char *end
= p
+ keylen
;
738 * RFC 5915, or SEC1 Appendix C.4
740 * ECPrivateKey ::= SEQUENCE {
741 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
742 * privateKey OCTET STRING,
743 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
744 * publicKey [1] BIT STRING OPTIONAL
747 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
748 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
750 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
755 if( ( ret
= mbedtls_asn1_get_int( &p
, end
, &version
) ) != 0 )
756 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
759 return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION
);
761 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
, MBEDTLS_ASN1_OCTET_STRING
) ) != 0 )
762 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
764 if( ( ret
= mbedtls_mpi_read_binary( &eck
->d
, p
, len
) ) != 0 )
766 mbedtls_ecp_keypair_free( eck
);
767 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
776 * Is 'parameters' present?
778 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
779 MBEDTLS_ASN1_CONTEXT_SPECIFIC
| MBEDTLS_ASN1_CONSTRUCTED
| 0 ) ) == 0 )
781 if( ( ret
= pk_get_ecparams( &p
, p
+ len
, ¶ms
) ) != 0 ||
782 ( ret
= pk_use_ecparams( ¶ms
, &eck
->grp
) ) != 0 )
784 mbedtls_ecp_keypair_free( eck
);
788 else if( ret
!= MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
)
790 mbedtls_ecp_keypair_free( eck
);
791 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
795 * Is 'publickey' present? If not, or if we can't read it (eg because it
796 * is compressed), create it from the private key.
798 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
799 MBEDTLS_ASN1_CONTEXT_SPECIFIC
| MBEDTLS_ASN1_CONSTRUCTED
| 1 ) ) == 0 )
803 if( ( ret
= mbedtls_asn1_get_bitstring_null( &p
, end2
, &len
) ) != 0 )
804 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
806 if( p
+ len
!= end2
)
807 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
808 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
810 if( ( ret
= pk_get_ecpubkey( &p
, end2
, eck
) ) == 0 )
815 * The only acceptable failure mode of pk_get_ecpubkey() above
816 * is if the point format is not recognized.
818 if( ret
!= MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
)
819 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
);
822 else if( ret
!= MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
)
824 mbedtls_ecp_keypair_free( eck
);
825 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
830 ( ret
= mbedtls_ecp_mul( &eck
->grp
, &eck
->Q
, &eck
->d
, &eck
->grp
.G
,
831 NULL
, NULL
) ) != 0 )
833 mbedtls_ecp_keypair_free( eck
);
834 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
837 if( ( ret
= mbedtls_ecp_check_privkey( &eck
->grp
, &eck
->d
) ) != 0 )
839 mbedtls_ecp_keypair_free( eck
);
845 #endif /* MBEDTLS_ECP_C */
848 * Parse an unencrypted PKCS#8 encoded private key
850 static int pk_parse_key_pkcs8_unencrypted_der(
851 mbedtls_pk_context
*pk
,
852 const unsigned char* key
,
857 mbedtls_asn1_buf params
;
858 unsigned char *p
= (unsigned char *) key
;
859 unsigned char *end
= p
+ keylen
;
860 mbedtls_pk_type_t pk_alg
= MBEDTLS_PK_NONE
;
861 const mbedtls_pk_info_t
*pk_info
;
864 * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208)
866 * PrivateKeyInfo ::= SEQUENCE {
868 * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
869 * privateKey PrivateKey,
870 * attributes [0] IMPLICIT Attributes OPTIONAL }
872 * Version ::= INTEGER
873 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
874 * PrivateKey ::= OCTET STRING
876 * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
879 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
880 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
882 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
887 if( ( ret
= mbedtls_asn1_get_int( &p
, end
, &version
) ) != 0 )
888 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
891 return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION
+ ret
);
893 if( ( ret
= pk_get_pk_alg( &p
, end
, &pk_alg
, ¶ms
) ) != 0 )
894 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
896 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
, MBEDTLS_ASN1_OCTET_STRING
) ) != 0 )
897 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
900 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
901 MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
903 if( ( pk_info
= mbedtls_pk_info_from_type( pk_alg
) ) == NULL
)
904 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG
);
906 if( ( ret
= mbedtls_pk_setup( pk
, pk_info
) ) != 0 )
909 #if defined(MBEDTLS_RSA_C)
910 if( pk_alg
== MBEDTLS_PK_RSA
)
912 if( ( ret
= pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk
), p
, len
) ) != 0 )
914 mbedtls_pk_free( pk
);
918 #endif /* MBEDTLS_RSA_C */
919 #if defined(MBEDTLS_ECP_C)
920 if( pk_alg
== MBEDTLS_PK_ECKEY
|| pk_alg
== MBEDTLS_PK_ECKEY_DH
)
922 if( ( ret
= pk_use_ecparams( ¶ms
, &mbedtls_pk_ec( *pk
)->grp
) ) != 0 ||
923 ( ret
= pk_parse_key_sec1_der( mbedtls_pk_ec( *pk
), p
, len
) ) != 0 )
925 mbedtls_pk_free( pk
);
929 #endif /* MBEDTLS_ECP_C */
930 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG
);
936 * Parse an encrypted PKCS#8 encoded private key
938 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
939 static int pk_parse_key_pkcs8_encrypted_der(
940 mbedtls_pk_context
*pk
,
941 const unsigned char *key
, size_t keylen
,
942 const unsigned char *pwd
, size_t pwdlen
)
944 int ret
, decrypted
= 0;
946 unsigned char buf
[2048];
947 unsigned char *p
, *end
;
948 mbedtls_asn1_buf pbe_alg_oid
, pbe_params
;
949 #if defined(MBEDTLS_PKCS12_C)
950 mbedtls_cipher_type_t cipher_alg
;
951 mbedtls_md_type_t md_alg
;
954 memset( buf
, 0, sizeof( buf
) );
956 p
= (unsigned char *) key
;
960 return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED
);
963 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
965 * EncryptedPrivateKeyInfo ::= SEQUENCE {
966 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
967 * encryptedData EncryptedData
970 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
972 * EncryptedData ::= OCTET STRING
974 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
976 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
,
977 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) ) != 0 )
979 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
984 if( ( ret
= mbedtls_asn1_get_alg( &p
, end
, &pbe_alg_oid
, &pbe_params
) ) != 0 )
985 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
987 if( ( ret
= mbedtls_asn1_get_tag( &p
, end
, &len
, MBEDTLS_ASN1_OCTET_STRING
) ) != 0 )
988 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
990 if( len
> sizeof( buf
) )
991 return( MBEDTLS_ERR_PK_BAD_INPUT_DATA
);
994 * Decrypt EncryptedData with appropriate PDE
996 #if defined(MBEDTLS_PKCS12_C)
997 if( mbedtls_oid_get_pkcs12_pbe_alg( &pbe_alg_oid
, &md_alg
, &cipher_alg
) == 0 )
999 if( ( ret
= mbedtls_pkcs12_pbe( &pbe_params
, MBEDTLS_PKCS12_PBE_DECRYPT
,
1001 pwd
, pwdlen
, p
, len
, buf
) ) != 0 )
1003 if( ret
== MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH
)
1004 return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH
);
1011 else if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128
, &pbe_alg_oid
) == 0 )
1013 if( ( ret
= mbedtls_pkcs12_pbe_sha1_rc4_128( &pbe_params
,
1014 MBEDTLS_PKCS12_PBE_DECRYPT
,
1016 p
, len
, buf
) ) != 0 )
1021 // Best guess for password mismatch when using RC4. If first tag is
1022 // not MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE
1024 if( *buf
!= ( MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
) )
1025 return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH
);
1030 #endif /* MBEDTLS_PKCS12_C */
1031 #if defined(MBEDTLS_PKCS5_C)
1032 if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBES2
, &pbe_alg_oid
) == 0 )
1034 if( ( ret
= mbedtls_pkcs5_pbes2( &pbe_params
, MBEDTLS_PKCS5_DECRYPT
, pwd
, pwdlen
,
1035 p
, len
, buf
) ) != 0 )
1037 if( ret
== MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH
)
1038 return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH
);
1046 #endif /* MBEDTLS_PKCS5_C */
1051 if( decrypted
== 0 )
1052 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE
);
1054 return( pk_parse_key_pkcs8_unencrypted_der( pk
, buf
, len
) );
1056 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
1059 * Parse a private key
1061 int mbedtls_pk_parse_key( mbedtls_pk_context
*pk
,
1062 const unsigned char *key
, size_t keylen
,
1063 const unsigned char *pwd
, size_t pwdlen
)
1066 const mbedtls_pk_info_t
*pk_info
;
1068 #if defined(MBEDTLS_PEM_PARSE_C)
1070 mbedtls_pem_context pem
;
1072 mbedtls_pem_init( &pem
);
1074 #if defined(MBEDTLS_RSA_C)
1075 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
1076 if( keylen
== 0 || key
[keylen
- 1] != '\0' )
1077 ret
= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
;
1079 ret
= mbedtls_pem_read_buffer( &pem
,
1080 "-----BEGIN RSA PRIVATE KEY-----",
1081 "-----END RSA PRIVATE KEY-----",
1082 key
, pwd
, pwdlen
, &len
);
1086 if( ( pk_info
= mbedtls_pk_info_from_type( MBEDTLS_PK_RSA
) ) == NULL
)
1087 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG
);
1089 if( ( ret
= mbedtls_pk_setup( pk
, pk_info
) ) != 0 ||
1090 ( ret
= pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk
),
1091 pem
.buf
, pem
.buflen
) ) != 0 )
1093 mbedtls_pk_free( pk
);
1096 mbedtls_pem_free( &pem
);
1099 else if( ret
== MBEDTLS_ERR_PEM_PASSWORD_MISMATCH
)
1100 return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH
);
1101 else if( ret
== MBEDTLS_ERR_PEM_PASSWORD_REQUIRED
)
1102 return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED
);
1103 else if( ret
!= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
)
1105 #endif /* MBEDTLS_RSA_C */
1107 #if defined(MBEDTLS_ECP_C)
1108 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
1109 if( keylen
== 0 || key
[keylen
- 1] != '\0' )
1110 ret
= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
;
1112 ret
= mbedtls_pem_read_buffer( &pem
,
1113 "-----BEGIN EC PRIVATE KEY-----",
1114 "-----END EC PRIVATE KEY-----",
1115 key
, pwd
, pwdlen
, &len
);
1118 if( ( pk_info
= mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY
) ) == NULL
)
1119 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG
);
1121 if( ( ret
= mbedtls_pk_setup( pk
, pk_info
) ) != 0 ||
1122 ( ret
= pk_parse_key_sec1_der( mbedtls_pk_ec( *pk
),
1123 pem
.buf
, pem
.buflen
) ) != 0 )
1125 mbedtls_pk_free( pk
);
1128 mbedtls_pem_free( &pem
);
1131 else if( ret
== MBEDTLS_ERR_PEM_PASSWORD_MISMATCH
)
1132 return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH
);
1133 else if( ret
== MBEDTLS_ERR_PEM_PASSWORD_REQUIRED
)
1134 return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED
);
1135 else if( ret
!= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
)
1137 #endif /* MBEDTLS_ECP_C */
1139 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
1140 if( keylen
== 0 || key
[keylen
- 1] != '\0' )
1141 ret
= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
;
1143 ret
= mbedtls_pem_read_buffer( &pem
,
1144 "-----BEGIN PRIVATE KEY-----",
1145 "-----END PRIVATE KEY-----",
1146 key
, NULL
, 0, &len
);
1149 if( ( ret
= pk_parse_key_pkcs8_unencrypted_der( pk
,
1150 pem
.buf
, pem
.buflen
) ) != 0 )
1152 mbedtls_pk_free( pk
);
1155 mbedtls_pem_free( &pem
);
1158 else if( ret
!= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
)
1161 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
1162 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
1163 if( keylen
== 0 || key
[keylen
- 1] != '\0' )
1164 ret
= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
;
1166 ret
= mbedtls_pem_read_buffer( &pem
,
1167 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
1168 "-----END ENCRYPTED PRIVATE KEY-----",
1169 key
, NULL
, 0, &len
);
1172 if( ( ret
= pk_parse_key_pkcs8_encrypted_der( pk
,
1173 pem
.buf
, pem
.buflen
,
1174 pwd
, pwdlen
) ) != 0 )
1176 mbedtls_pk_free( pk
);
1179 mbedtls_pem_free( &pem
);
1182 else if( ret
!= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
)
1184 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
1189 #endif /* MBEDTLS_PEM_PARSE_C */
1192 * At this point we only know it's not a PEM formatted key. Could be any
1193 * of the known DER encoded private key formats
1195 * We try the different DER format parsers to see if one passes without
1198 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
1199 if( ( ret
= pk_parse_key_pkcs8_encrypted_der( pk
, key
, keylen
,
1200 pwd
, pwdlen
) ) == 0 )
1205 mbedtls_pk_free( pk
);
1207 if( ret
== MBEDTLS_ERR_PK_PASSWORD_MISMATCH
)
1211 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
1213 if( ( ret
= pk_parse_key_pkcs8_unencrypted_der( pk
, key
, keylen
) ) == 0 )
1216 mbedtls_pk_free( pk
);
1218 #if defined(MBEDTLS_RSA_C)
1219 if( ( pk_info
= mbedtls_pk_info_from_type( MBEDTLS_PK_RSA
) ) == NULL
)
1220 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG
);
1222 if( ( ret
= mbedtls_pk_setup( pk
, pk_info
) ) != 0 ||
1223 ( ret
= pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk
), key
, keylen
) ) == 0 )
1228 mbedtls_pk_free( pk
);
1229 #endif /* MBEDTLS_RSA_C */
1231 #if defined(MBEDTLS_ECP_C)
1232 if( ( pk_info
= mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY
) ) == NULL
)
1233 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG
);
1235 if( ( ret
= mbedtls_pk_setup( pk
, pk_info
) ) != 0 ||
1236 ( ret
= pk_parse_key_sec1_der( mbedtls_pk_ec( *pk
), key
, keylen
) ) == 0 )
1241 mbedtls_pk_free( pk
);
1242 #endif /* MBEDTLS_ECP_C */
1244 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
);
1248 * Parse a public key
1250 int mbedtls_pk_parse_public_key( mbedtls_pk_context
*ctx
,
1251 const unsigned char *key
, size_t keylen
)
1255 #if defined(MBEDTLS_PEM_PARSE_C)
1257 mbedtls_pem_context pem
;
1259 mbedtls_pem_init( &pem
);
1261 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
1262 if( keylen
== 0 || key
[keylen
- 1] != '\0' )
1263 ret
= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
;
1265 ret
= mbedtls_pem_read_buffer( &pem
,
1266 "-----BEGIN PUBLIC KEY-----",
1267 "-----END PUBLIC KEY-----",
1268 key
, NULL
, 0, &len
);
1276 keylen
= pem
.buflen
;
1278 else if( ret
!= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
)
1280 mbedtls_pem_free( &pem
);
1283 #endif /* MBEDTLS_PEM_PARSE_C */
1284 p
= (unsigned char *) key
;
1286 ret
= mbedtls_pk_parse_subpubkey( &p
, p
+ keylen
, ctx
);
1288 #if defined(MBEDTLS_PEM_PARSE_C)
1289 mbedtls_pem_free( &pem
);
1295 #endif /* MBEDTLS_PK_PARSE_C */