xref: /reactos/dll/3rdparty/mbedtls/pkparse.c (revision 4561998a)
1 /*
2  *  Public Key layer for parsing key files and structures
3  *
4  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5  *  SPDX-License-Identifier: GPL-2.0
6  *
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.
11  *
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.
16  *
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.
20  *
21  *  This file is part of mbed TLS (https://tls.mbed.org)
22  */
23 
24 #if !defined(MBEDTLS_CONFIG_FILE)
25 #include "mbedtls/config.h"
26 #else
27 #include MBEDTLS_CONFIG_FILE
28 #endif
29 
30 #if defined(MBEDTLS_PK_PARSE_C)
31 
32 #include "mbedtls/pk.h"
33 #include "mbedtls/asn1.h"
34 #include "mbedtls/oid.h"
35 
36 #include <string.h>
37 
38 #if defined(MBEDTLS_RSA_C)
39 #include "mbedtls/rsa.h"
40 #endif
41 #if defined(MBEDTLS_ECP_C)
42 #include "mbedtls/ecp.h"
43 #endif
44 #if defined(MBEDTLS_ECDSA_C)
45 #include "mbedtls/ecdsa.h"
46 #endif
47 #if defined(MBEDTLS_PEM_PARSE_C)
48 #include "mbedtls/pem.h"
49 #endif
50 #if defined(MBEDTLS_PKCS5_C)
51 #include "mbedtls/pkcs5.h"
52 #endif
53 #if defined(MBEDTLS_PKCS12_C)
54 #include "mbedtls/pkcs12.h"
55 #endif
56 
57 #if defined(MBEDTLS_PLATFORM_C)
58 #include "mbedtls/platform.h"
59 #else
60 #include <stdlib.h>
61 #define mbedtls_calloc    calloc
62 #define mbedtls_free       free
63 #endif
64 
65 #if defined(MBEDTLS_FS_IO) || \
66     defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
67 /* Implementation that should never be optimized out by the compiler */
68 static void mbedtls_zeroize( void *v, size_t n ) {
69     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
70 }
71 #endif
72 
73 #if defined(MBEDTLS_FS_IO)
74 /*
75  * Load all data from a file into a given buffer.
76  *
77  * The file is expected to contain either PEM or DER encoded data.
78  * A terminating null byte is always appended. It is included in the announced
79  * length only if the data looks like it is PEM encoded.
80  */
81 int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n )
82 {
83     FILE *f;
84     long size;
85 
86     if( ( f = fopen( path, "rb" ) ) == NULL )
87         return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
88 
89     fseek( f, 0, SEEK_END );
90     if( ( size = ftell( f ) ) == -1 )
91     {
92         fclose( f );
93         return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
94     }
95     fseek( f, 0, SEEK_SET );
96 
97     *n = (size_t) size;
98 
99     if( *n + 1 == 0 ||
100         ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
101     {
102         fclose( f );
103         return( MBEDTLS_ERR_PK_ALLOC_FAILED );
104     }
105 
106     if( fread( *buf, 1, *n, f ) != *n )
107     {
108         fclose( f );
109 
110         mbedtls_zeroize( *buf, *n );
111         mbedtls_free( *buf );
112 
113         return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
114     }
115 
116     fclose( f );
117 
118     (*buf)[*n] = '\0';
119 
120     if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL )
121         ++*n;
122 
123     return( 0 );
124 }
125 
126 /*
127  * Load and parse a private key
128  */
129 int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
130                       const char *path, const char *pwd )
131 {
132     int ret;
133     size_t n;
134     unsigned char *buf;
135 
136     if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
137         return( ret );
138 
139     if( pwd == NULL )
140         ret = mbedtls_pk_parse_key( ctx, buf, n, NULL, 0 );
141     else
142         ret = mbedtls_pk_parse_key( ctx, buf, n,
143                 (const unsigned char *) pwd, strlen( pwd ) );
144 
145     mbedtls_zeroize( buf, n );
146     mbedtls_free( buf );
147 
148     return( ret );
149 }
150 
151 /*
152  * Load and parse a public key
153  */
154 int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path )
155 {
156     int ret;
157     size_t n;
158     unsigned char *buf;
159 
160     if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
161         return( ret );
162 
163     ret = mbedtls_pk_parse_public_key( ctx, buf, n );
164 
165     mbedtls_zeroize( buf, n );
166     mbedtls_free( buf );
167 
168     return( ret );
169 }
170 #endif /* MBEDTLS_FS_IO */
171 
172 #if defined(MBEDTLS_ECP_C)
173 /* Minimally parse an ECParameters buffer to and mbedtls_asn1_buf
174  *
175  * ECParameters ::= CHOICE {
176  *   namedCurve         OBJECT IDENTIFIER
177  *   specifiedCurve     SpecifiedECDomain -- = SEQUENCE { ... }
178  *   -- implicitCurve   NULL
179  * }
180  */
181 static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
182                             mbedtls_asn1_buf *params )
183 {
184     int ret;
185 
186     if ( end - *p < 1 )
187         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
188                 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
189 
190     /* Tag may be either OID or SEQUENCE */
191     params->tag = **p;
192     if( params->tag != MBEDTLS_ASN1_OID
193 #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
194             && params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE )
195 #endif
196             )
197     {
198         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
199                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
200     }
201 
202     if( ( ret = mbedtls_asn1_get_tag( p, end, &params->len, params->tag ) ) != 0 )
203     {
204         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
205     }
206 
207     params->p = *p;
208     *p += params->len;
209 
210     if( *p != end )
211         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
212                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
213 
214     return( 0 );
215 }
216 
217 #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
218 /*
219  * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it.
220  * WARNING: the resulting group should only be used with
221  * pk_group_id_from_specified(), since its base point may not be set correctly
222  * if it was encoded compressed.
223  *
224  *  SpecifiedECDomain ::= SEQUENCE {
225  *      version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...),
226  *      fieldID FieldID {{FieldTypes}},
227  *      curve Curve,
228  *      base ECPoint,
229  *      order INTEGER,
230  *      cofactor INTEGER OPTIONAL,
231  *      hash HashAlgorithm OPTIONAL,
232  *      ...
233  *  }
234  *
235  * We only support prime-field as field type, and ignore hash and cofactor.
236  */
237 static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp )
238 {
239     int ret;
240     unsigned char *p = params->p;
241     const unsigned char * const end = params->p + params->len;
242     const unsigned char *end_field, *end_curve;
243     size_t len;
244     int ver;
245 
246     /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */
247     if( ( ret = mbedtls_asn1_get_int( &p, end, &ver ) ) != 0 )
248         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
249 
250     if( ver < 1 || ver > 3 )
251         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
252 
253     /*
254      * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field
255      *       fieldType FIELD-ID.&id({IOSet}),
256      *       parameters FIELD-ID.&Type({IOSet}{@fieldType})
257      * }
258      */
259     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
260             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
261         return( ret );
262 
263     end_field = p + len;
264 
265     /*
266      * FIELD-ID ::= TYPE-IDENTIFIER
267      * FieldTypes FIELD-ID ::= {
268      *       { Prime-p IDENTIFIED BY prime-field } |
269      *       { Characteristic-two IDENTIFIED BY characteristic-two-field }
270      * }
271      * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
272      */
273     if( ( ret = mbedtls_asn1_get_tag( &p, end_field, &len, MBEDTLS_ASN1_OID ) ) != 0 )
274         return( ret );
275 
276     if( len != MBEDTLS_OID_SIZE( MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD ) ||
277         memcmp( p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 )
278     {
279         return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
280     }
281 
282     p += len;
283 
284     /* Prime-p ::= INTEGER -- Field of size p. */
285     if( ( ret = mbedtls_asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 )
286         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
287 
288     grp->pbits = mbedtls_mpi_bitlen( &grp->P );
289 
290     if( p != end_field )
291         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
292                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
293 
294     /*
295      * Curve ::= SEQUENCE {
296      *       a FieldElement,
297      *       b FieldElement,
298      *       seed BIT STRING OPTIONAL
299      *       -- Shall be present if used in SpecifiedECDomain
300      *       -- with version equal to ecdpVer2 or ecdpVer3
301      * }
302      */
303     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
304             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
305         return( ret );
306 
307     end_curve = p + len;
308 
309     /*
310      * FieldElement ::= OCTET STRING
311      * containing an integer in the case of a prime field
312      */
313     if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ||
314         ( ret = mbedtls_mpi_read_binary( &grp->A, p, len ) ) != 0 )
315     {
316         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
317     }
318 
319     p += len;
320 
321     if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ||
322         ( ret = mbedtls_mpi_read_binary( &grp->B, p, len ) ) != 0 )
323     {
324         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
325     }
326 
327     p += len;
328 
329     /* Ignore seed BIT STRING OPTIONAL */
330     if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_BIT_STRING ) ) == 0 )
331         p += len;
332 
333     if( p != end_curve )
334         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
335                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
336 
337     /*
338      * ECPoint ::= OCTET STRING
339      */
340     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
341         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
342 
343     if( ( ret = mbedtls_ecp_point_read_binary( grp, &grp->G,
344                                       ( const unsigned char *) p, len ) ) != 0 )
345     {
346         /*
347          * If we can't read the point because it's compressed, cheat by
348          * reading only the X coordinate and the parity bit of Y.
349          */
350         if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ||
351             ( p[0] != 0x02 && p[0] != 0x03 ) ||
352             len != mbedtls_mpi_size( &grp->P ) + 1 ||
353             mbedtls_mpi_read_binary( &grp->G.X, p + 1, len - 1 ) != 0 ||
354             mbedtls_mpi_lset( &grp->G.Y, p[0] - 2 ) != 0 ||
355             mbedtls_mpi_lset( &grp->G.Z, 1 ) != 0 )
356         {
357             return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
358         }
359     }
360 
361     p += len;
362 
363     /*
364      * order INTEGER
365      */
366     if( ( ret = mbedtls_asn1_get_mpi( &p, end, &grp->N ) ) != 0 )
367         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
368 
369     grp->nbits = mbedtls_mpi_bitlen( &grp->N );
370 
371     /*
372      * Allow optional elements by purposefully not enforcing p == end here.
373      */
374 
375     return( 0 );
376 }
377 
378 /*
379  * Find the group id associated with an (almost filled) group as generated by
380  * pk_group_from_specified(), or return an error if unknown.
381  */
382 static int pk_group_id_from_group( const mbedtls_ecp_group *grp, mbedtls_ecp_group_id *grp_id )
383 {
384     int ret = 0;
385     mbedtls_ecp_group ref;
386     const mbedtls_ecp_group_id *id;
387 
388     mbedtls_ecp_group_init( &ref );
389 
390     for( id = mbedtls_ecp_grp_id_list(); *id != MBEDTLS_ECP_DP_NONE; id++ )
391     {
392         /* Load the group associated to that id */
393         mbedtls_ecp_group_free( &ref );
394         MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ref, *id ) );
395 
396         /* Compare to the group we were given, starting with easy tests */
397         if( grp->pbits == ref.pbits && grp->nbits == ref.nbits &&
398             mbedtls_mpi_cmp_mpi( &grp->P, &ref.P ) == 0 &&
399             mbedtls_mpi_cmp_mpi( &grp->A, &ref.A ) == 0 &&
400             mbedtls_mpi_cmp_mpi( &grp->B, &ref.B ) == 0 &&
401             mbedtls_mpi_cmp_mpi( &grp->N, &ref.N ) == 0 &&
402             mbedtls_mpi_cmp_mpi( &grp->G.X, &ref.G.X ) == 0 &&
403             mbedtls_mpi_cmp_mpi( &grp->G.Z, &ref.G.Z ) == 0 &&
404             /* For Y we may only know the parity bit, so compare only that */
405             mbedtls_mpi_get_bit( &grp->G.Y, 0 ) == mbedtls_mpi_get_bit( &ref.G.Y, 0 ) )
406         {
407             break;
408         }
409 
410     }
411 
412 cleanup:
413     mbedtls_ecp_group_free( &ref );
414 
415     *grp_id = *id;
416 
417     if( ret == 0 && *id == MBEDTLS_ECP_DP_NONE )
418         ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
419 
420     return( ret );
421 }
422 
423 /*
424  * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID
425  */
426 static int pk_group_id_from_specified( const mbedtls_asn1_buf *params,
427                                        mbedtls_ecp_group_id *grp_id )
428 {
429     int ret;
430     mbedtls_ecp_group grp;
431 
432     mbedtls_ecp_group_init( &grp );
433 
434     if( ( ret = pk_group_from_specified( params, &grp ) ) != 0 )
435         goto cleanup;
436 
437     ret = pk_group_id_from_group( &grp, grp_id );
438 
439 cleanup:
440     mbedtls_ecp_group_free( &grp );
441 
442     return( ret );
443 }
444 #endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */
445 
446 /*
447  * Use EC parameters to initialise an EC group
448  *
449  * ECParameters ::= CHOICE {
450  *   namedCurve         OBJECT IDENTIFIER
451  *   specifiedCurve     SpecifiedECDomain -- = SEQUENCE { ... }
452  *   -- implicitCurve   NULL
453  */
454 static int pk_use_ecparams( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp )
455 {
456     int ret;
457     mbedtls_ecp_group_id grp_id;
458 
459     if( params->tag == MBEDTLS_ASN1_OID )
460     {
461         if( mbedtls_oid_get_ec_grp( params, &grp_id ) != 0 )
462             return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE );
463     }
464     else
465     {
466 #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
467         if( ( ret = pk_group_id_from_specified( params, &grp_id ) ) != 0 )
468             return( ret );
469 #else
470         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
471 #endif
472     }
473 
474     /*
475      * grp may already be initilialized; if so, make sure IDs match
476      */
477     if( grp->id != MBEDTLS_ECP_DP_NONE && grp->id != grp_id )
478         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
479 
480     if( ( ret = mbedtls_ecp_group_load( grp, grp_id ) ) != 0 )
481         return( ret );
482 
483     return( 0 );
484 }
485 
486 /*
487  * EC public key is an EC point
488  *
489  * The caller is responsible for clearing the structure upon failure if
490  * desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE
491  * return code of mbedtls_ecp_point_read_binary() and leave p in a usable state.
492  */
493 static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end,
494                             mbedtls_ecp_keypair *key )
495 {
496     int ret;
497 
498     if( ( ret = mbedtls_ecp_point_read_binary( &key->grp, &key->Q,
499                     (const unsigned char *) *p, end - *p ) ) == 0 )
500     {
501         ret = mbedtls_ecp_check_pubkey( &key->grp, &key->Q );
502     }
503 
504     /*
505      * We know mbedtls_ecp_point_read_binary consumed all bytes or failed
506      */
507     *p = (unsigned char *) end;
508 
509     return( ret );
510 }
511 #endif /* MBEDTLS_ECP_C */
512 
513 #if defined(MBEDTLS_RSA_C)
514 /*
515  *  RSAPublicKey ::= SEQUENCE {
516  *      modulus           INTEGER,  -- n
517  *      publicExponent    INTEGER   -- e
518  *  }
519  */
520 static int pk_get_rsapubkey( unsigned char **p,
521                              const unsigned char *end,
522                              mbedtls_rsa_context *rsa )
523 {
524     int ret;
525     size_t len;
526 
527     if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
528             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
529         return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
530 
531     if( *p + len != end )
532         return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
533                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
534 
535     /* Import N */
536     if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
537         return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
538 
539     if( ( ret = mbedtls_rsa_import_raw( rsa, *p, len, NULL, 0, NULL, 0,
540                                         NULL, 0, NULL, 0 ) ) != 0 )
541         return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
542 
543     *p += len;
544 
545     /* Import E */
546     if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
547         return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
548 
549     if( ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
550                                         NULL, 0, *p, len ) ) != 0 )
551         return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
552 
553     *p += len;
554 
555     if( mbedtls_rsa_complete( rsa ) != 0 ||
556         mbedtls_rsa_check_pubkey( rsa ) != 0 )
557     {
558         return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
559     }
560 
561     if( *p != end )
562         return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
563                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
564 
565     return( 0 );
566 }
567 #endif /* MBEDTLS_RSA_C */
568 
569 /* Get a PK algorithm identifier
570  *
571  *  AlgorithmIdentifier  ::=  SEQUENCE  {
572  *       algorithm               OBJECT IDENTIFIER,
573  *       parameters              ANY DEFINED BY algorithm OPTIONAL  }
574  */
575 static int pk_get_pk_alg( unsigned char **p,
576                           const unsigned char *end,
577                           mbedtls_pk_type_t *pk_alg, mbedtls_asn1_buf *params )
578 {
579     int ret;
580     mbedtls_asn1_buf alg_oid;
581 
582     memset( params, 0, sizeof(mbedtls_asn1_buf) );
583 
584     if( ( ret = mbedtls_asn1_get_alg( p, end, &alg_oid, params ) ) != 0 )
585         return( MBEDTLS_ERR_PK_INVALID_ALG + ret );
586 
587     if( mbedtls_oid_get_pk_alg( &alg_oid, pk_alg ) != 0 )
588         return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
589 
590     /*
591      * No parameters with RSA (only for EC)
592      */
593     if( *pk_alg == MBEDTLS_PK_RSA &&
594             ( ( params->tag != MBEDTLS_ASN1_NULL && params->tag != 0 ) ||
595                 params->len != 0 ) )
596     {
597         return( MBEDTLS_ERR_PK_INVALID_ALG );
598     }
599 
600     return( 0 );
601 }
602 
603 /*
604  *  SubjectPublicKeyInfo  ::=  SEQUENCE  {
605  *       algorithm            AlgorithmIdentifier,
606  *       subjectPublicKey     BIT STRING }
607  */
608 int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
609                         mbedtls_pk_context *pk )
610 {
611     int ret;
612     size_t len;
613     mbedtls_asn1_buf alg_params;
614     mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
615     const mbedtls_pk_info_t *pk_info;
616 
617     if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
618                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
619     {
620         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
621     }
622 
623     end = *p + len;
624 
625     if( ( ret = pk_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 )
626         return( ret );
627 
628     if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 )
629         return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
630 
631     if( *p + len != end )
632         return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
633                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
634 
635     if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL )
636         return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
637 
638     if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 )
639         return( ret );
640 
641 #if defined(MBEDTLS_RSA_C)
642     if( pk_alg == MBEDTLS_PK_RSA )
643     {
644         ret = pk_get_rsapubkey( p, end, mbedtls_pk_rsa( *pk ) );
645     } else
646 #endif /* MBEDTLS_RSA_C */
647 #if defined(MBEDTLS_ECP_C)
648     if( pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY )
649     {
650         ret = pk_use_ecparams( &alg_params, &mbedtls_pk_ec( *pk )->grp );
651         if( ret == 0 )
652             ret = pk_get_ecpubkey( p, end, mbedtls_pk_ec( *pk ) );
653     } else
654 #endif /* MBEDTLS_ECP_C */
655         ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;
656 
657     if( ret == 0 && *p != end )
658         ret = MBEDTLS_ERR_PK_INVALID_PUBKEY
659               MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
660 
661     if( ret != 0 )
662         mbedtls_pk_free( pk );
663 
664     return( ret );
665 }
666 
667 #if defined(MBEDTLS_RSA_C)
668 /*
669  * Parse a PKCS#1 encoded private RSA key
670  */
671 static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
672                                    const unsigned char *key,
673                                    size_t keylen )
674 {
675     int ret, version;
676     size_t len;
677     unsigned char *p, *end;
678 
679     mbedtls_mpi T;
680     mbedtls_mpi_init( &T );
681 
682     p = (unsigned char *) key;
683     end = p + keylen;
684 
685     /*
686      * This function parses the RSAPrivateKey (PKCS#1)
687      *
688      *  RSAPrivateKey ::= SEQUENCE {
689      *      version           Version,
690      *      modulus           INTEGER,  -- n
691      *      publicExponent    INTEGER,  -- e
692      *      privateExponent   INTEGER,  -- d
693      *      prime1            INTEGER,  -- p
694      *      prime2            INTEGER,  -- q
695      *      exponent1         INTEGER,  -- d mod (p-1)
696      *      exponent2         INTEGER,  -- d mod (q-1)
697      *      coefficient       INTEGER,  -- (inverse of q) mod p
698      *      otherPrimeInfos   OtherPrimeInfos OPTIONAL
699      *  }
700      */
701     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
702             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
703     {
704         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
705     }
706 
707     end = p + len;
708 
709     if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
710     {
711         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
712     }
713 
714     if( version != 0 )
715     {
716         return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION );
717     }
718 
719     /* Import N */
720     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
721                                       MBEDTLS_ASN1_INTEGER ) ) != 0 ||
722         ( ret = mbedtls_rsa_import_raw( rsa, p, len, NULL, 0, NULL, 0,
723                                         NULL, 0, NULL, 0 ) ) != 0 )
724         goto cleanup;
725     p += len;
726 
727     /* Import E */
728     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
729                                       MBEDTLS_ASN1_INTEGER ) ) != 0 ||
730         ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
731                                         NULL, 0, p, len ) ) != 0 )
732         goto cleanup;
733     p += len;
734 
735     /* Import D */
736     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
737                                       MBEDTLS_ASN1_INTEGER ) ) != 0 ||
738         ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
739                                         p, len, NULL, 0 ) ) != 0 )
740         goto cleanup;
741     p += len;
742 
743     /* Import P */
744     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
745                                       MBEDTLS_ASN1_INTEGER ) ) != 0 ||
746         ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, p, len, NULL, 0,
747                                         NULL, 0, NULL, 0 ) ) != 0 )
748         goto cleanup;
749     p += len;
750 
751     /* Import Q */
752     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
753                                       MBEDTLS_ASN1_INTEGER ) ) != 0 ||
754         ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, p, len,
755                                         NULL, 0, NULL, 0 ) ) != 0 )
756         goto cleanup;
757     p += len;
758 
759     /* Complete the RSA private key */
760     if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 )
761         goto cleanup;
762 
763     /* Check optional parameters */
764     if( ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ||
765         ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 ||
766         ( ret = mbedtls_asn1_get_mpi( &p, end, &T ) ) != 0 )
767         goto cleanup;
768 
769     if( p != end )
770     {
771         ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
772               MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ;
773     }
774 
775 cleanup:
776 
777     mbedtls_mpi_free( &T );
778 
779     if( ret != 0 )
780     {
781         /* Wrap error code if it's coming from a lower level */
782         if( ( ret & 0xff80 ) == 0 )
783             ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret;
784         else
785             ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
786 
787         mbedtls_rsa_free( rsa );
788     }
789 
790     return( ret );
791 }
792 #endif /* MBEDTLS_RSA_C */
793 
794 #if defined(MBEDTLS_ECP_C)
795 /*
796  * Parse a SEC1 encoded private EC key
797  */
798 static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
799                                   const unsigned char *key,
800                                   size_t keylen )
801 {
802     int ret;
803     int version, pubkey_done;
804     size_t len;
805     mbedtls_asn1_buf params;
806     unsigned char *p = (unsigned char *) key;
807     unsigned char *end = p + keylen;
808     unsigned char *end2;
809 
810     /*
811      * RFC 5915, or SEC1 Appendix C.4
812      *
813      * ECPrivateKey ::= SEQUENCE {
814      *      version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
815      *      privateKey     OCTET STRING,
816      *      parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
817      *      publicKey  [1] BIT STRING OPTIONAL
818      *    }
819      */
820     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
821             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
822     {
823         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
824     }
825 
826     end = p + len;
827 
828     if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
829         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
830 
831     if( version != 1 )
832         return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION );
833 
834     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
835         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
836 
837     if( ( ret = mbedtls_mpi_read_binary( &eck->d, p, len ) ) != 0 )
838     {
839         mbedtls_ecp_keypair_free( eck );
840         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
841     }
842 
843     p += len;
844 
845     pubkey_done = 0;
846     if( p != end )
847     {
848         /*
849          * Is 'parameters' present?
850          */
851         if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
852                         MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 )
853         {
854             if( ( ret = pk_get_ecparams( &p, p + len, &params) ) != 0 ||
855                 ( ret = pk_use_ecparams( &params, &eck->grp )  ) != 0 )
856             {
857                 mbedtls_ecp_keypair_free( eck );
858                 return( ret );
859             }
860         }
861         else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
862         {
863             mbedtls_ecp_keypair_free( eck );
864             return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
865         }
866     }
867 
868     if( p != end )
869     {
870         /*
871          * Is 'publickey' present? If not, or if we can't read it (eg because it
872          * is compressed), create it from the private key.
873          */
874         if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
875                         MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 )
876         {
877             end2 = p + len;
878 
879             if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end2, &len ) ) != 0 )
880                 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
881 
882             if( p + len != end2 )
883                 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
884                         MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
885 
886             if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 )
887                 pubkey_done = 1;
888             else
889             {
890                 /*
891                  * The only acceptable failure mode of pk_get_ecpubkey() above
892                  * is if the point format is not recognized.
893                  */
894                 if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE )
895                     return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
896             }
897         }
898         else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
899         {
900             mbedtls_ecp_keypair_free( eck );
901             return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
902         }
903     }
904 
905     if( ! pubkey_done &&
906         ( ret = mbedtls_ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G,
907                                                       NULL, NULL ) ) != 0 )
908     {
909         mbedtls_ecp_keypair_free( eck );
910         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
911     }
912 
913     if( ( ret = mbedtls_ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
914     {
915         mbedtls_ecp_keypair_free( eck );
916         return( ret );
917     }
918 
919     return( 0 );
920 }
921 #endif /* MBEDTLS_ECP_C */
922 
923 /*
924  * Parse an unencrypted PKCS#8 encoded private key
925  *
926  * Notes:
927  *
928  * - This function does not own the key buffer. It is the
929  *   responsibility of the caller to take care of zeroizing
930  *   and freeing it after use.
931  *
932  * - The function is responsible for freeing the provided
933  *   PK context on failure.
934  *
935  */
936 static int pk_parse_key_pkcs8_unencrypted_der(
937                                     mbedtls_pk_context *pk,
938                                     const unsigned char* key,
939                                     size_t keylen )
940 {
941     int ret, version;
942     size_t len;
943     mbedtls_asn1_buf params;
944     unsigned char *p = (unsigned char *) key;
945     unsigned char *end = p + keylen;
946     mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
947     const mbedtls_pk_info_t *pk_info;
948 
949     /*
950      * This function parses the PrivateKeyInfo object (PKCS#8 v1.2 = RFC 5208)
951      *
952      *    PrivateKeyInfo ::= SEQUENCE {
953      *      version                   Version,
954      *      privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
955      *      privateKey                PrivateKey,
956      *      attributes           [0]  IMPLICIT Attributes OPTIONAL }
957      *
958      *    Version ::= INTEGER
959      *    PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
960      *    PrivateKey ::= OCTET STRING
961      *
962      *  The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
963      */
964 
965     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
966             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
967     {
968         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
969     }
970 
971     end = p + len;
972 
973     if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
974         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
975 
976     if( version != 0 )
977         return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION + ret );
978 
979     if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &params ) ) != 0 )
980         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
981 
982     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
983         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
984 
985     if( len < 1 )
986         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
987                 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
988 
989     if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL )
990         return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
991 
992     if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 )
993         return( ret );
994 
995 #if defined(MBEDTLS_RSA_C)
996     if( pk_alg == MBEDTLS_PK_RSA )
997     {
998         if( ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), p, len ) ) != 0 )
999         {
1000             mbedtls_pk_free( pk );
1001             return( ret );
1002         }
1003     } else
1004 #endif /* MBEDTLS_RSA_C */
1005 #if defined(MBEDTLS_ECP_C)
1006     if( pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH )
1007     {
1008         if( ( ret = pk_use_ecparams( &params, &mbedtls_pk_ec( *pk )->grp ) ) != 0 ||
1009             ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), p, len )  ) != 0 )
1010         {
1011             mbedtls_pk_free( pk );
1012             return( ret );
1013         }
1014     } else
1015 #endif /* MBEDTLS_ECP_C */
1016         return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
1017 
1018     return( 0 );
1019 }
1020 
1021 /*
1022  * Parse an encrypted PKCS#8 encoded private key
1023  *
1024  * To save space, the decryption happens in-place on the given key buffer.
1025  * Also, while this function may modify the keybuffer, it doesn't own it,
1026  * and instead it is the responsibility of the caller to zeroize and properly
1027  * free it after use.
1028  *
1029  */
1030 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
1031 static int pk_parse_key_pkcs8_encrypted_der(
1032                                     mbedtls_pk_context *pk,
1033                                     unsigned char *key, size_t keylen,
1034                                     const unsigned char *pwd, size_t pwdlen )
1035 {
1036     int ret, decrypted = 0;
1037     size_t len;
1038     unsigned char *buf;
1039     unsigned char *p, *end;
1040     mbedtls_asn1_buf pbe_alg_oid, pbe_params;
1041 #if defined(MBEDTLS_PKCS12_C)
1042     mbedtls_cipher_type_t cipher_alg;
1043     mbedtls_md_type_t md_alg;
1044 #endif
1045 
1046     p = key;
1047     end = p + keylen;
1048 
1049     if( pwdlen == 0 )
1050         return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED );
1051 
1052     /*
1053      * This function parses the EncryptedPrivateKeyInfo object (PKCS#8)
1054      *
1055      *  EncryptedPrivateKeyInfo ::= SEQUENCE {
1056      *    encryptionAlgorithm  EncryptionAlgorithmIdentifier,
1057      *    encryptedData        EncryptedData
1058      *  }
1059      *
1060      *  EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
1061      *
1062      *  EncryptedData ::= OCTET STRING
1063      *
1064      *  The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
1065      *
1066      */
1067     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
1068             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
1069     {
1070         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
1071     }
1072 
1073     end = p + len;
1074 
1075     if( ( ret = mbedtls_asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
1076         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
1077 
1078     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
1079         return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
1080 
1081     buf = p;
1082 
1083     /*
1084      * Decrypt EncryptedData with appropriate PBE
1085      */
1086 #if defined(MBEDTLS_PKCS12_C)
1087     if( mbedtls_oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
1088     {
1089         if( ( ret = mbedtls_pkcs12_pbe( &pbe_params, MBEDTLS_PKCS12_PBE_DECRYPT,
1090                                 cipher_alg, md_alg,
1091                                 pwd, pwdlen, p, len, buf ) ) != 0 )
1092         {
1093             if( ret == MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH )
1094                 return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
1095 
1096             return( ret );
1097         }
1098 
1099         decrypted = 1;
1100     }
1101     else if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) == 0 )
1102     {
1103         if( ( ret = mbedtls_pkcs12_pbe_sha1_rc4_128( &pbe_params,
1104                                              MBEDTLS_PKCS12_PBE_DECRYPT,
1105                                              pwd, pwdlen,
1106                                              p, len, buf ) ) != 0 )
1107         {
1108             return( ret );
1109         }
1110 
1111         // Best guess for password mismatch when using RC4. If first tag is
1112         // not MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE
1113         //
1114         if( *buf != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
1115             return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
1116 
1117         decrypted = 1;
1118     }
1119     else
1120 #endif /* MBEDTLS_PKCS12_C */
1121 #if defined(MBEDTLS_PKCS5_C)
1122     if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBES2, &pbe_alg_oid ) == 0 )
1123     {
1124         if( ( ret = mbedtls_pkcs5_pbes2( &pbe_params, MBEDTLS_PKCS5_DECRYPT, pwd, pwdlen,
1125                                   p, len, buf ) ) != 0 )
1126         {
1127             if( ret == MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH )
1128                 return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
1129 
1130             return( ret );
1131         }
1132 
1133         decrypted = 1;
1134     }
1135     else
1136 #endif /* MBEDTLS_PKCS5_C */
1137     {
1138         ((void) pwd);
1139     }
1140 
1141     if( decrypted == 0 )
1142         return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
1143 
1144     return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) );
1145 }
1146 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
1147 
1148 /*
1149  * Parse a private key
1150  */
1151 int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
1152                   const unsigned char *key, size_t keylen,
1153                   const unsigned char *pwd, size_t pwdlen )
1154 {
1155     int ret;
1156     const mbedtls_pk_info_t *pk_info;
1157 
1158 #if defined(MBEDTLS_PEM_PARSE_C)
1159     size_t len;
1160     mbedtls_pem_context pem;
1161 
1162     mbedtls_pem_init( &pem );
1163 
1164 #if defined(MBEDTLS_RSA_C)
1165     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
1166     if( keylen == 0 || key[keylen - 1] != '\0' )
1167         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
1168     else
1169         ret = mbedtls_pem_read_buffer( &pem,
1170                                "-----BEGIN RSA PRIVATE KEY-----",
1171                                "-----END RSA PRIVATE KEY-----",
1172                                key, pwd, pwdlen, &len );
1173 
1174     if( ret == 0 )
1175     {
1176         pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA );
1177         if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
1178             ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ),
1179                                             pem.buf, pem.buflen ) ) != 0 )
1180         {
1181             mbedtls_pk_free( pk );
1182         }
1183 
1184         mbedtls_pem_free( &pem );
1185         return( ret );
1186     }
1187     else if( ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH )
1188         return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
1189     else if( ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED )
1190         return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED );
1191     else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1192         return( ret );
1193 #endif /* MBEDTLS_RSA_C */
1194 
1195 #if defined(MBEDTLS_ECP_C)
1196     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
1197     if( keylen == 0 || key[keylen - 1] != '\0' )
1198         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
1199     else
1200         ret = mbedtls_pem_read_buffer( &pem,
1201                                "-----BEGIN EC PRIVATE KEY-----",
1202                                "-----END EC PRIVATE KEY-----",
1203                                key, pwd, pwdlen, &len );
1204     if( ret == 0 )
1205     {
1206         pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY );
1207 
1208         if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
1209             ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
1210                                            pem.buf, pem.buflen ) ) != 0 )
1211         {
1212             mbedtls_pk_free( pk );
1213         }
1214 
1215         mbedtls_pem_free( &pem );
1216         return( ret );
1217     }
1218     else if( ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH )
1219         return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
1220     else if( ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED )
1221         return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED );
1222     else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1223         return( ret );
1224 #endif /* MBEDTLS_ECP_C */
1225 
1226     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
1227     if( keylen == 0 || key[keylen - 1] != '\0' )
1228         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
1229     else
1230         ret = mbedtls_pem_read_buffer( &pem,
1231                                "-----BEGIN PRIVATE KEY-----",
1232                                "-----END PRIVATE KEY-----",
1233                                key, NULL, 0, &len );
1234     if( ret == 0 )
1235     {
1236         if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk,
1237                                                 pem.buf, pem.buflen ) ) != 0 )
1238         {
1239             mbedtls_pk_free( pk );
1240         }
1241 
1242         mbedtls_pem_free( &pem );
1243         return( ret );
1244     }
1245     else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1246         return( ret );
1247 
1248 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
1249     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
1250     if( keylen == 0 || key[keylen - 1] != '\0' )
1251         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
1252     else
1253         ret = mbedtls_pem_read_buffer( &pem,
1254                                "-----BEGIN ENCRYPTED PRIVATE KEY-----",
1255                                "-----END ENCRYPTED PRIVATE KEY-----",
1256                                key, NULL, 0, &len );
1257     if( ret == 0 )
1258     {
1259         if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk,
1260                                                       pem.buf, pem.buflen,
1261                                                       pwd, pwdlen ) ) != 0 )
1262         {
1263             mbedtls_pk_free( pk );
1264         }
1265 
1266         mbedtls_pem_free( &pem );
1267         return( ret );
1268     }
1269     else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1270         return( ret );
1271 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
1272 #else
1273     ((void) pwd);
1274     ((void) pwdlen);
1275 #endif /* MBEDTLS_PEM_PARSE_C */
1276 
1277     /*
1278      * At this point we only know it's not a PEM formatted key. Could be any
1279      * of the known DER encoded private key formats
1280      *
1281      * We try the different DER format parsers to see if one passes without
1282      * error
1283      */
1284 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
1285     {
1286         unsigned char *key_copy;
1287 
1288         if( keylen == 0 )
1289             return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
1290 
1291         if( ( key_copy = mbedtls_calloc( 1, keylen ) ) == NULL )
1292             return( MBEDTLS_ERR_PK_ALLOC_FAILED );
1293 
1294         memcpy( key_copy, key, keylen );
1295 
1296         ret = pk_parse_key_pkcs8_encrypted_der( pk, key_copy, keylen,
1297                                                 pwd, pwdlen );
1298 
1299         mbedtls_zeroize( key_copy, keylen );
1300         mbedtls_free( key_copy );
1301     }
1302 
1303     if( ret == 0 )
1304         return( 0 );
1305 
1306     mbedtls_pk_free( pk );
1307     mbedtls_pk_init( pk );
1308 
1309     if( ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH )
1310     {
1311         return( ret );
1312     }
1313 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
1314 
1315     if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 )
1316         return( 0 );
1317 
1318     mbedtls_pk_free( pk );
1319     mbedtls_pk_init( pk );
1320 
1321 #if defined(MBEDTLS_RSA_C)
1322 
1323     pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA );
1324     if( mbedtls_pk_setup( pk, pk_info ) == 0 &&
1325         pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), key, keylen ) == 0 )
1326     {
1327         return( 0 );
1328     }
1329 
1330     mbedtls_pk_free( pk );
1331     mbedtls_pk_init( pk );
1332 #endif /* MBEDTLS_RSA_C */
1333 
1334 #if defined(MBEDTLS_ECP_C)
1335     pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY );
1336     if( mbedtls_pk_setup( pk, pk_info ) == 0 &&
1337         pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
1338                                key, keylen ) == 0 )
1339     {
1340         return( 0 );
1341     }
1342     mbedtls_pk_free( pk );
1343 #endif /* MBEDTLS_ECP_C */
1344 
1345     /* If MBEDTLS_RSA_C is defined but MBEDTLS_ECP_C isn't,
1346      * it is ok to leave the PK context initialized but not
1347      * freed: It is the caller's responsibility to call pk_init()
1348      * before calling this function, and to call pk_free()
1349      * when it fails. If MBEDTLS_ECP_C is defined but MBEDTLS_RSA_C
1350      * isn't, this leads to mbedtls_pk_free() being called
1351      * twice, once here and once by the caller, but this is
1352      * also ok and in line with the mbedtls_pk_free() calls
1353      * on failed PEM parsing attempts. */
1354 
1355     return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
1356 }
1357 
1358 /*
1359  * Parse a public key
1360  */
1361 int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
1362                          const unsigned char *key, size_t keylen )
1363 {
1364     int ret;
1365     unsigned char *p;
1366 #if defined(MBEDTLS_PEM_PARSE_C)
1367     size_t len;
1368     mbedtls_pem_context pem;
1369 
1370     mbedtls_pem_init( &pem );
1371 
1372     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
1373     if( keylen == 0 || key[keylen - 1] != '\0' )
1374         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
1375     else
1376         ret = mbedtls_pem_read_buffer( &pem,
1377                 "-----BEGIN PUBLIC KEY-----",
1378                 "-----END PUBLIC KEY-----",
1379                 key, NULL, 0, &len );
1380 
1381     if( ret == 0 )
1382     {
1383         /*
1384          * Was PEM encoded
1385          */
1386         key = pem.buf;
1387         keylen = pem.buflen;
1388     }
1389     else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1390     {
1391         mbedtls_pem_free( &pem );
1392         return( ret );
1393     }
1394 #endif /* MBEDTLS_PEM_PARSE_C */
1395     p = (unsigned char *) key;
1396 
1397     ret = mbedtls_pk_parse_subpubkey( &p, p + keylen, ctx );
1398 
1399 #if defined(MBEDTLS_PEM_PARSE_C)
1400     mbedtls_pem_free( &pem );
1401 #endif
1402 
1403     return( ret );
1404 }
1405 
1406 #endif /* MBEDTLS_PK_PARSE_C */
1407