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