blob: 09219bcf4daac98015f5619293ff14eb2534c9db [file] [log] [blame]
Edison Aic6672fd2018-02-28 15:01:47 +08001// SPDX-License-Identifier: Apache-2.0
Jens Wiklander817466c2018-05-22 13:49:31 +02002/*
3 * Public Key layer for parsing key files and structures
4 *
5 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Jens Wiklander817466c2018-05-22 13:49:31 +02006 *
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 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22#if !defined(MBEDTLS_CONFIG_FILE)
23#include "mbedtls/config.h"
24#else
25#include MBEDTLS_CONFIG_FILE
26#endif
27
28#if defined(MBEDTLS_PK_PARSE_C)
29
30#include "mbedtls/pk.h"
31#include "mbedtls/asn1.h"
32#include "mbedtls/oid.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010033#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020034#include "mbedtls/error.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020035
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
Jens Wiklander3d3b0592019-03-20 15:30:29 +010065/* Parameter validation macros based on platform_util.h */
66#define PK_VALIDATE_RET( cond ) \
67 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_PK_BAD_INPUT_DATA )
68#define PK_VALIDATE( cond ) \
69 MBEDTLS_INTERNAL_VALIDATE( cond )
Jens Wiklander817466c2018-05-22 13:49:31 +020070
Jens Wiklander3d3b0592019-03-20 15:30:29 +010071#if defined(MBEDTLS_FS_IO)
Jens Wiklander817466c2018-05-22 13:49:31 +020072/*
73 * Load all data from a file into a given buffer.
74 *
75 * The file is expected to contain either PEM or DER encoded data.
76 * A terminating null byte is always appended. It is included in the announced
77 * length only if the data looks like it is PEM encoded.
78 */
79int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n )
80{
81 FILE *f;
82 long size;
83
Jens Wiklander3d3b0592019-03-20 15:30:29 +010084 PK_VALIDATE_RET( path != NULL );
85 PK_VALIDATE_RET( buf != NULL );
86 PK_VALIDATE_RET( n != NULL );
87
Jens Wiklander817466c2018-05-22 13:49:31 +020088 if( ( f = fopen( path, "rb" ) ) == NULL )
89 return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
90
91 fseek( f, 0, SEEK_END );
92 if( ( size = ftell( f ) ) == -1 )
93 {
94 fclose( f );
95 return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
96 }
97 fseek( f, 0, SEEK_SET );
98
99 *n = (size_t) size;
100
101 if( *n + 1 == 0 ||
102 ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
103 {
104 fclose( f );
105 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
106 }
107
108 if( fread( *buf, 1, *n, f ) != *n )
109 {
110 fclose( f );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100111
112 mbedtls_platform_zeroize( *buf, *n );
Jens Wiklander817466c2018-05-22 13:49:31 +0200113 mbedtls_free( *buf );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100114
Jens Wiklander817466c2018-05-22 13:49:31 +0200115 return( MBEDTLS_ERR_PK_FILE_IO_ERROR );
116 }
117
118 fclose( f );
119
120 (*buf)[*n] = '\0';
121
122 if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL )
123 ++*n;
124
125 return( 0 );
126}
127
128/*
129 * Load and parse a private key
130 */
131int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
132 const char *path, const char *pwd )
133{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200134 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200135 size_t n;
136 unsigned char *buf;
137
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100138 PK_VALIDATE_RET( ctx != NULL );
139 PK_VALIDATE_RET( path != NULL );
140
Jens Wiklander817466c2018-05-22 13:49:31 +0200141 if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
142 return( ret );
143
144 if( pwd == NULL )
145 ret = mbedtls_pk_parse_key( ctx, buf, n, NULL, 0 );
146 else
147 ret = mbedtls_pk_parse_key( ctx, buf, n,
148 (const unsigned char *) pwd, strlen( pwd ) );
149
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100150 mbedtls_platform_zeroize( buf, n );
Jens Wiklander817466c2018-05-22 13:49:31 +0200151 mbedtls_free( buf );
152
153 return( ret );
154}
155
156/*
157 * Load and parse a public key
158 */
159int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path )
160{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200161 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200162 size_t n;
163 unsigned char *buf;
164
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100165 PK_VALIDATE_RET( ctx != NULL );
166 PK_VALIDATE_RET( path != NULL );
167
Jens Wiklander817466c2018-05-22 13:49:31 +0200168 if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
169 return( ret );
170
171 ret = mbedtls_pk_parse_public_key( ctx, buf, n );
172
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100173 mbedtls_platform_zeroize( buf, n );
Jens Wiklander817466c2018-05-22 13:49:31 +0200174 mbedtls_free( buf );
175
176 return( ret );
177}
178#endif /* MBEDTLS_FS_IO */
179
180#if defined(MBEDTLS_ECP_C)
181/* Minimally parse an ECParameters buffer to and mbedtls_asn1_buf
182 *
183 * ECParameters ::= CHOICE {
184 * namedCurve OBJECT IDENTIFIER
185 * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... }
186 * -- implicitCurve NULL
187 * }
188 */
189static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
190 mbedtls_asn1_buf *params )
191{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200192 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200193
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100194 if ( end - *p < 1 )
195 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
196 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
197
Jens Wiklander817466c2018-05-22 13:49:31 +0200198 /* Tag may be either OID or SEQUENCE */
199 params->tag = **p;
200 if( params->tag != MBEDTLS_ASN1_OID
201#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
202 && params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE )
203#endif
204 )
205 {
206 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
207 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
208 }
209
210 if( ( ret = mbedtls_asn1_get_tag( p, end, &params->len, params->tag ) ) != 0 )
211 {
212 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
213 }
214
215 params->p = *p;
216 *p += params->len;
217
218 if( *p != end )
219 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
220 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
221
222 return( 0 );
223}
224
225#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
226/*
227 * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it.
228 * WARNING: the resulting group should only be used with
229 * pk_group_id_from_specified(), since its base point may not be set correctly
230 * if it was encoded compressed.
231 *
232 * SpecifiedECDomain ::= SEQUENCE {
233 * version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...),
234 * fieldID FieldID {{FieldTypes}},
235 * curve Curve,
236 * base ECPoint,
237 * order INTEGER,
238 * cofactor INTEGER OPTIONAL,
239 * hash HashAlgorithm OPTIONAL,
240 * ...
241 * }
242 *
243 * We only support prime-field as field type, and ignore hash and cofactor.
244 */
245static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp )
246{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200247 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200248 unsigned char *p = params->p;
249 const unsigned char * const end = params->p + params->len;
250 const unsigned char *end_field, *end_curve;
251 size_t len;
252 int ver;
253
254 /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */
255 if( ( ret = mbedtls_asn1_get_int( &p, end, &ver ) ) != 0 )
256 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
257
258 if( ver < 1 || ver > 3 )
259 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
260
261 /*
262 * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field
263 * fieldType FIELD-ID.&id({IOSet}),
264 * parameters FIELD-ID.&Type({IOSet}{@fieldType})
265 * }
266 */
267 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
268 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
269 return( ret );
270
271 end_field = p + len;
272
273 /*
274 * FIELD-ID ::= TYPE-IDENTIFIER
275 * FieldTypes FIELD-ID ::= {
276 * { Prime-p IDENTIFIED BY prime-field } |
277 * { Characteristic-two IDENTIFIED BY characteristic-two-field }
278 * }
279 * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
280 */
281 if( ( ret = mbedtls_asn1_get_tag( &p, end_field, &len, MBEDTLS_ASN1_OID ) ) != 0 )
282 return( ret );
283
284 if( len != MBEDTLS_OID_SIZE( MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD ) ||
285 memcmp( p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 )
286 {
287 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
288 }
289
290 p += len;
291
292 /* Prime-p ::= INTEGER -- Field of size p. */
293 if( ( ret = mbedtls_asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 )
294 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
295
296 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
297
298 if( p != end_field )
299 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
300 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
301
302 /*
303 * Curve ::= SEQUENCE {
304 * a FieldElement,
305 * b FieldElement,
306 * seed BIT STRING OPTIONAL
307 * -- Shall be present if used in SpecifiedECDomain
308 * -- with version equal to ecdpVer2 or ecdpVer3
309 * }
310 */
311 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
312 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
313 return( ret );
314
315 end_curve = p + len;
316
317 /*
318 * FieldElement ::= OCTET STRING
319 * containing an integer in the case of a prime field
320 */
321 if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ||
322 ( ret = mbedtls_mpi_read_binary( &grp->A, p, len ) ) != 0 )
323 {
324 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
325 }
326
327 p += len;
328
329 if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ||
330 ( ret = mbedtls_mpi_read_binary( &grp->B, p, len ) ) != 0 )
331 {
332 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
333 }
334
335 p += len;
336
337 /* Ignore seed BIT STRING OPTIONAL */
338 if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_BIT_STRING ) ) == 0 )
339 p += len;
340
341 if( p != end_curve )
342 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
343 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
344
345 /*
346 * ECPoint ::= OCTET STRING
347 */
348 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
349 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
350
351 if( ( ret = mbedtls_ecp_point_read_binary( grp, &grp->G,
352 ( const unsigned char *) p, len ) ) != 0 )
353 {
354 /*
355 * If we can't read the point because it's compressed, cheat by
356 * reading only the X coordinate and the parity bit of Y.
357 */
358 if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ||
359 ( p[0] != 0x02 && p[0] != 0x03 ) ||
360 len != mbedtls_mpi_size( &grp->P ) + 1 ||
361 mbedtls_mpi_read_binary( &grp->G.X, p + 1, len - 1 ) != 0 ||
362 mbedtls_mpi_lset( &grp->G.Y, p[0] - 2 ) != 0 ||
363 mbedtls_mpi_lset( &grp->G.Z, 1 ) != 0 )
364 {
365 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
366 }
367 }
368
369 p += len;
370
371 /*
372 * order INTEGER
373 */
374 if( ( ret = mbedtls_asn1_get_mpi( &p, end, &grp->N ) ) != 0 )
375 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
376
377 grp->nbits = mbedtls_mpi_bitlen( &grp->N );
378
379 /*
380 * Allow optional elements by purposefully not enforcing p == end here.
381 */
382
383 return( 0 );
384}
385
386/*
387 * Find the group id associated with an (almost filled) group as generated by
388 * pk_group_from_specified(), or return an error if unknown.
389 */
390static int pk_group_id_from_group( const mbedtls_ecp_group *grp, mbedtls_ecp_group_id *grp_id )
391{
392 int ret = 0;
393 mbedtls_ecp_group ref;
394 const mbedtls_ecp_group_id *id;
395
396 mbedtls_ecp_group_init( &ref );
397
398 for( id = mbedtls_ecp_grp_id_list(); *id != MBEDTLS_ECP_DP_NONE; id++ )
399 {
400 /* Load the group associated to that id */
401 mbedtls_ecp_group_free( &ref );
402 MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ref, *id ) );
403
404 /* Compare to the group we were given, starting with easy tests */
405 if( grp->pbits == ref.pbits && grp->nbits == ref.nbits &&
406 mbedtls_mpi_cmp_mpi( &grp->P, &ref.P ) == 0 &&
407 mbedtls_mpi_cmp_mpi( &grp->A, &ref.A ) == 0 &&
408 mbedtls_mpi_cmp_mpi( &grp->B, &ref.B ) == 0 &&
409 mbedtls_mpi_cmp_mpi( &grp->N, &ref.N ) == 0 &&
410 mbedtls_mpi_cmp_mpi( &grp->G.X, &ref.G.X ) == 0 &&
411 mbedtls_mpi_cmp_mpi( &grp->G.Z, &ref.G.Z ) == 0 &&
412 /* For Y we may only know the parity bit, so compare only that */
413 mbedtls_mpi_get_bit( &grp->G.Y, 0 ) == mbedtls_mpi_get_bit( &ref.G.Y, 0 ) )
414 {
415 break;
416 }
417
418 }
419
420cleanup:
421 mbedtls_ecp_group_free( &ref );
422
423 *grp_id = *id;
424
425 if( ret == 0 && *id == MBEDTLS_ECP_DP_NONE )
426 ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
427
428 return( ret );
429}
430
431/*
432 * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID
433 */
434static int pk_group_id_from_specified( const mbedtls_asn1_buf *params,
435 mbedtls_ecp_group_id *grp_id )
436{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200437 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200438 mbedtls_ecp_group grp;
439
440 mbedtls_ecp_group_init( &grp );
441
442 if( ( ret = pk_group_from_specified( params, &grp ) ) != 0 )
443 goto cleanup;
444
445 ret = pk_group_id_from_group( &grp, grp_id );
446
447cleanup:
448 mbedtls_ecp_group_free( &grp );
449
450 return( ret );
451}
452#endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */
453
454/*
455 * Use EC parameters to initialise an EC group
456 *
457 * ECParameters ::= CHOICE {
458 * namedCurve OBJECT IDENTIFIER
459 * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... }
460 * -- implicitCurve NULL
461 */
462static int pk_use_ecparams( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp )
463{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200464 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200465 mbedtls_ecp_group_id grp_id;
466
467 if( params->tag == MBEDTLS_ASN1_OID )
468 {
469 if( mbedtls_oid_get_ec_grp( params, &grp_id ) != 0 )
470 return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE );
471 }
472 else
473 {
474#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
475 if( ( ret = pk_group_id_from_specified( params, &grp_id ) ) != 0 )
476 return( ret );
477#else
478 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
479#endif
480 }
481
482 /*
483 * grp may already be initilialized; if so, make sure IDs match
484 */
485 if( grp->id != MBEDTLS_ECP_DP_NONE && grp->id != grp_id )
486 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
487
488 if( ( ret = mbedtls_ecp_group_load( grp, grp_id ) ) != 0 )
489 return( ret );
490
491 return( 0 );
492}
493
494/*
495 * EC public key is an EC point
496 *
497 * The caller is responsible for clearing the structure upon failure if
498 * desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE
499 * return code of mbedtls_ecp_point_read_binary() and leave p in a usable state.
500 */
501static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end,
502 mbedtls_ecp_keypair *key )
503{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200504 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200505
506 if( ( ret = mbedtls_ecp_point_read_binary( &key->grp, &key->Q,
507 (const unsigned char *) *p, end - *p ) ) == 0 )
508 {
509 ret = mbedtls_ecp_check_pubkey( &key->grp, &key->Q );
510 }
511
512 /*
513 * We know mbedtls_ecp_point_read_binary consumed all bytes or failed
514 */
515 *p = (unsigned char *) end;
516
517 return( ret );
518}
519#endif /* MBEDTLS_ECP_C */
520
521#if defined(MBEDTLS_RSA_C)
522/*
523 * RSAPublicKey ::= SEQUENCE {
524 * modulus INTEGER, -- n
525 * publicExponent INTEGER -- e
526 * }
527 */
528static int pk_get_rsapubkey( unsigned char **p,
529 const unsigned char *end,
530 mbedtls_rsa_context *rsa )
531{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200532 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200533 size_t len;
534
535 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
536 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
537 return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
538
539 if( *p + len != end )
540 return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
541 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
542
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100543 /* Import N */
544 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200545 return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
546
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100547 if( ( ret = mbedtls_rsa_import_raw( rsa, *p, len, NULL, 0, NULL, 0,
548 NULL, 0, NULL, 0 ) ) != 0 )
549 return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
550
551 *p += len;
552
553 /* Import E */
554 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
555 return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
556
557 if( ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
558 NULL, 0, *p, len ) ) != 0 )
559 return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
560
561 *p += len;
562
563 if( mbedtls_rsa_complete( rsa ) != 0 ||
564 mbedtls_rsa_check_pubkey( rsa ) != 0 )
565 {
566 return( MBEDTLS_ERR_PK_INVALID_PUBKEY );
567 }
568
Jens Wiklander817466c2018-05-22 13:49:31 +0200569 if( *p != end )
570 return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
571 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
572
Jens Wiklander817466c2018-05-22 13:49:31 +0200573 return( 0 );
574}
575#endif /* MBEDTLS_RSA_C */
576
577/* Get a PK algorithm identifier
578 *
579 * AlgorithmIdentifier ::= SEQUENCE {
580 * algorithm OBJECT IDENTIFIER,
581 * parameters ANY DEFINED BY algorithm OPTIONAL }
582 */
583static int pk_get_pk_alg( unsigned char **p,
584 const unsigned char *end,
585 mbedtls_pk_type_t *pk_alg, mbedtls_asn1_buf *params )
586{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200587 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200588 mbedtls_asn1_buf alg_oid;
589
590 memset( params, 0, sizeof(mbedtls_asn1_buf) );
591
592 if( ( ret = mbedtls_asn1_get_alg( p, end, &alg_oid, params ) ) != 0 )
593 return( MBEDTLS_ERR_PK_INVALID_ALG + ret );
594
595 if( mbedtls_oid_get_pk_alg( &alg_oid, pk_alg ) != 0 )
596 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
597
598 /*
599 * No parameters with RSA (only for EC)
600 */
601 if( *pk_alg == MBEDTLS_PK_RSA &&
602 ( ( params->tag != MBEDTLS_ASN1_NULL && params->tag != 0 ) ||
603 params->len != 0 ) )
604 {
605 return( MBEDTLS_ERR_PK_INVALID_ALG );
606 }
607
608 return( 0 );
609}
610
611/*
612 * SubjectPublicKeyInfo ::= SEQUENCE {
613 * algorithm AlgorithmIdentifier,
614 * subjectPublicKey BIT STRING }
615 */
616int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
617 mbedtls_pk_context *pk )
618{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200619 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200620 size_t len;
621 mbedtls_asn1_buf alg_params;
622 mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
623 const mbedtls_pk_info_t *pk_info;
624
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100625 PK_VALIDATE_RET( p != NULL );
626 PK_VALIDATE_RET( *p != NULL );
627 PK_VALIDATE_RET( end != NULL );
628 PK_VALIDATE_RET( pk != NULL );
629
Jens Wiklander817466c2018-05-22 13:49:31 +0200630 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
631 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
632 {
633 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
634 }
635
636 end = *p + len;
637
638 if( ( ret = pk_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 )
639 return( ret );
640
641 if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 )
642 return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
643
644 if( *p + len != end )
645 return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
646 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
647
648 if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL )
649 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
650
651 if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 )
652 return( ret );
653
654#if defined(MBEDTLS_RSA_C)
655 if( pk_alg == MBEDTLS_PK_RSA )
656 {
657 ret = pk_get_rsapubkey( p, end, mbedtls_pk_rsa( *pk ) );
658 } else
659#endif /* MBEDTLS_RSA_C */
660#if defined(MBEDTLS_ECP_C)
661 if( pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY )
662 {
663 ret = pk_use_ecparams( &alg_params, &mbedtls_pk_ec( *pk )->grp );
664 if( ret == 0 )
665 ret = pk_get_ecpubkey( p, end, mbedtls_pk_ec( *pk ) );
666 } else
667#endif /* MBEDTLS_ECP_C */
668 ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;
669
670 if( ret == 0 && *p != end )
671 ret = MBEDTLS_ERR_PK_INVALID_PUBKEY
672 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
673
674 if( ret != 0 )
675 mbedtls_pk_free( pk );
676
677 return( ret );
678}
679
680#if defined(MBEDTLS_RSA_C)
681/*
Jerome Forissier5b25c762020-04-07 11:18:49 +0200682 * Wrapper around mbedtls_asn1_get_mpi() that rejects zero.
683 *
684 * The value zero is:
685 * - never a valid value for an RSA parameter
686 * - interpreted as "omitted, please reconstruct" by mbedtls_rsa_complete().
687 *
688 * Since values can't be omitted in PKCS#1, passing a zero value to
689 * rsa_complete() would be incorrect, so reject zero values early.
690 */
691static int asn1_get_nonzero_mpi( unsigned char **p,
692 const unsigned char *end,
693 mbedtls_mpi *X )
694{
695 int ret;
696
697 ret = mbedtls_asn1_get_mpi( p, end, X );
698 if( ret != 0 )
699 return( ret );
700
701 if( mbedtls_mpi_cmp_int( X, 0 ) == 0 )
702 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
703
704 return( 0 );
705}
706
707/*
Jens Wiklander817466c2018-05-22 13:49:31 +0200708 * Parse a PKCS#1 encoded private RSA key
709 */
710static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
711 const unsigned char *key,
712 size_t keylen )
713{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100714 int ret, version;
Jens Wiklander817466c2018-05-22 13:49:31 +0200715 size_t len;
716 unsigned char *p, *end;
717
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100718 mbedtls_mpi T;
719 mbedtls_mpi_init( &T );
720
Jens Wiklander817466c2018-05-22 13:49:31 +0200721 p = (unsigned char *) key;
722 end = p + keylen;
723
724 /*
725 * This function parses the RSAPrivateKey (PKCS#1)
726 *
727 * RSAPrivateKey ::= SEQUENCE {
728 * version Version,
729 * modulus INTEGER, -- n
730 * publicExponent INTEGER, -- e
731 * privateExponent INTEGER, -- d
732 * prime1 INTEGER, -- p
733 * prime2 INTEGER, -- q
734 * exponent1 INTEGER, -- d mod (p-1)
735 * exponent2 INTEGER, -- d mod (q-1)
736 * coefficient INTEGER, -- (inverse of q) mod p
737 * otherPrimeInfos OtherPrimeInfos OPTIONAL
738 * }
739 */
740 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
741 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
742 {
743 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
744 }
745
746 end = p + len;
747
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100748 if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200749 {
750 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
751 }
752
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100753 if( version != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200754 {
755 return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION );
756 }
757
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100758 /* Import N */
Jerome Forissier5b25c762020-04-07 11:18:49 +0200759 if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
760 ( ret = mbedtls_rsa_import( rsa, &T, NULL, NULL,
761 NULL, NULL ) ) != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100762 goto cleanup;
Jens Wiklander817466c2018-05-22 13:49:31 +0200763
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100764 /* Import E */
Jerome Forissier5b25c762020-04-07 11:18:49 +0200765 if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
766 ( ret = mbedtls_rsa_import( rsa, NULL, NULL, NULL,
767 NULL, &T ) ) != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100768 goto cleanup;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100769
770 /* Import D */
Jerome Forissier5b25c762020-04-07 11:18:49 +0200771 if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
772 ( ret = mbedtls_rsa_import( rsa, NULL, NULL, NULL,
773 &T, NULL ) ) != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100774 goto cleanup;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100775
776 /* Import P */
Jerome Forissier5b25c762020-04-07 11:18:49 +0200777 if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
778 ( ret = mbedtls_rsa_import( rsa, NULL, &T, NULL,
779 NULL, NULL ) ) != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100780 goto cleanup;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100781
782 /* Import Q */
Jerome Forissier5b25c762020-04-07 11:18:49 +0200783 if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
784 ( ret = mbedtls_rsa_import( rsa, NULL, NULL, &T,
785 NULL, NULL ) ) != 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100786 goto cleanup;
787
Jerome Forissier5b25c762020-04-07 11:18:49 +0200788#if !defined(MBEDTLS_RSA_NO_CRT) && !defined(MBEDTLS_RSA_ALT)
789 /*
790 * The RSA CRT parameters DP, DQ and QP are nominally redundant, in
791 * that they can be easily recomputed from D, P and Q. However by
792 * parsing them from the PKCS1 structure it is possible to avoid
793 * recalculating them which both reduces the overhead of loading
794 * RSA private keys into memory and also avoids side channels which
795 * can arise when computing those values, since all of D, P, and Q
796 * are secret. See https://eprint.iacr.org/2020/055 for a
797 * description of one such attack.
798 */
799
800 /* Import DP */
801 if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
802 ( ret = mbedtls_mpi_copy( &rsa->DP, &T ) ) != 0 )
803 goto cleanup;
804
805 /* Import DQ */
806 if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
807 ( ret = mbedtls_mpi_copy( &rsa->DQ, &T ) ) != 0 )
808 goto cleanup;
809
810 /* Import QP */
811 if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
812 ( ret = mbedtls_mpi_copy( &rsa->QP, &T ) ) != 0 )
813 goto cleanup;
814
815#else
816 /* Verify existance of the CRT params */
817 if( ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
818 ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 ||
819 ( ret = asn1_get_nonzero_mpi( &p, end, &T ) ) != 0 )
820 goto cleanup;
821#endif
822
823 /* rsa_complete() doesn't complete anything with the default
824 * implementation but is still called:
825 * - for the benefit of alternative implementation that may want to
826 * pre-compute stuff beyond what's provided (eg Montgomery factors)
827 * - as is also sanity-checks the key
828 *
829 * Furthermore, we also check the public part for consistency with
830 * mbedtls_pk_parse_pubkey(), as it includes size minima for example.
831 */
832 if( ( ret = mbedtls_rsa_complete( rsa ) ) != 0 ||
833 ( ret = mbedtls_rsa_check_pubkey( rsa ) ) != 0 )
834 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100835 goto cleanup;
Jerome Forissier5b25c762020-04-07 11:18:49 +0200836 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200837
838 if( p != end )
839 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100840 ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
841 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ;
Jens Wiklander817466c2018-05-22 13:49:31 +0200842 }
843
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100844cleanup:
845
846 mbedtls_mpi_free( &T );
847
848 if( ret != 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200849 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100850 /* Wrap error code if it's coming from a lower level */
851 if( ( ret & 0xff80 ) == 0 )
852 ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret;
853 else
854 ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
855
Jens Wiklander817466c2018-05-22 13:49:31 +0200856 mbedtls_rsa_free( rsa );
Jens Wiklander817466c2018-05-22 13:49:31 +0200857 }
858
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100859 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +0200860}
861#endif /* MBEDTLS_RSA_C */
862
863#if defined(MBEDTLS_ECP_C)
864/*
865 * Parse a SEC1 encoded private EC key
866 */
867static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
868 const unsigned char *key,
869 size_t keylen )
870{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200871 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200872 int version, pubkey_done;
873 size_t len;
874 mbedtls_asn1_buf params;
875 unsigned char *p = (unsigned char *) key;
876 unsigned char *end = p + keylen;
877 unsigned char *end2;
878
879 /*
880 * RFC 5915, or SEC1 Appendix C.4
881 *
882 * ECPrivateKey ::= SEQUENCE {
883 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
884 * privateKey OCTET STRING,
885 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
886 * publicKey [1] BIT STRING OPTIONAL
887 * }
888 */
889 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
890 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
891 {
892 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
893 }
894
895 end = p + len;
896
897 if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
898 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
899
900 if( version != 1 )
901 return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION );
902
903 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
904 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
905
906 if( ( ret = mbedtls_mpi_read_binary( &eck->d, p, len ) ) != 0 )
907 {
908 mbedtls_ecp_keypair_free( eck );
909 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
910 }
911
912 p += len;
913
914 pubkey_done = 0;
915 if( p != end )
916 {
917 /*
918 * Is 'parameters' present?
919 */
920 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
921 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 )
922 {
923 if( ( ret = pk_get_ecparams( &p, p + len, &params) ) != 0 ||
924 ( ret = pk_use_ecparams( &params, &eck->grp ) ) != 0 )
925 {
926 mbedtls_ecp_keypair_free( eck );
927 return( ret );
928 }
929 }
930 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
931 {
932 mbedtls_ecp_keypair_free( eck );
933 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
934 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100935 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200936
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100937 if( p != end )
938 {
Jens Wiklander817466c2018-05-22 13:49:31 +0200939 /*
940 * Is 'publickey' present? If not, or if we can't read it (eg because it
941 * is compressed), create it from the private key.
942 */
943 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
944 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 )
945 {
946 end2 = p + len;
947
948 if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end2, &len ) ) != 0 )
949 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
950
951 if( p + len != end2 )
952 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
953 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
954
955 if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 )
956 pubkey_done = 1;
957 else
958 {
959 /*
960 * The only acceptable failure mode of pk_get_ecpubkey() above
961 * is if the point format is not recognized.
962 */
963 if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE )
964 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
965 }
966 }
967 else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
968 {
969 mbedtls_ecp_keypair_free( eck );
970 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
971 }
972 }
973
974 if( ! pubkey_done &&
975 ( ret = mbedtls_ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G,
976 NULL, NULL ) ) != 0 )
977 {
978 mbedtls_ecp_keypair_free( eck );
979 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
980 }
981
982 if( ( ret = mbedtls_ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
983 {
984 mbedtls_ecp_keypair_free( eck );
985 return( ret );
986 }
987
988 return( 0 );
989}
990#endif /* MBEDTLS_ECP_C */
991
992/*
993 * Parse an unencrypted PKCS#8 encoded private key
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100994 *
995 * Notes:
996 *
997 * - This function does not own the key buffer. It is the
998 * responsibility of the caller to take care of zeroizing
999 * and freeing it after use.
1000 *
1001 * - The function is responsible for freeing the provided
1002 * PK context on failure.
1003 *
Jens Wiklander817466c2018-05-22 13:49:31 +02001004 */
1005static int pk_parse_key_pkcs8_unencrypted_der(
1006 mbedtls_pk_context *pk,
1007 const unsigned char* key,
1008 size_t keylen )
1009{
1010 int ret, version;
1011 size_t len;
1012 mbedtls_asn1_buf params;
1013 unsigned char *p = (unsigned char *) key;
1014 unsigned char *end = p + keylen;
1015 mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
1016 const mbedtls_pk_info_t *pk_info;
1017
1018 /*
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001019 * This function parses the PrivateKeyInfo object (PKCS#8 v1.2 = RFC 5208)
Jens Wiklander817466c2018-05-22 13:49:31 +02001020 *
1021 * PrivateKeyInfo ::= SEQUENCE {
1022 * version Version,
1023 * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
1024 * privateKey PrivateKey,
1025 * attributes [0] IMPLICIT Attributes OPTIONAL }
1026 *
1027 * Version ::= INTEGER
1028 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
1029 * PrivateKey ::= OCTET STRING
1030 *
1031 * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
1032 */
1033
1034 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
1035 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
1036 {
1037 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
1038 }
1039
1040 end = p + len;
1041
1042 if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
1043 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
1044
1045 if( version != 0 )
1046 return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION + ret );
1047
1048 if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &params ) ) != 0 )
1049 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
1050
1051 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
1052 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
1053
1054 if( len < 1 )
1055 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
1056 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
1057
1058 if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL )
1059 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
1060
1061 if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 )
1062 return( ret );
1063
1064#if defined(MBEDTLS_RSA_C)
1065 if( pk_alg == MBEDTLS_PK_RSA )
1066 {
1067 if( ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), p, len ) ) != 0 )
1068 {
1069 mbedtls_pk_free( pk );
1070 return( ret );
1071 }
1072 } else
1073#endif /* MBEDTLS_RSA_C */
1074#if defined(MBEDTLS_ECP_C)
1075 if( pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH )
1076 {
1077 if( ( ret = pk_use_ecparams( &params, &mbedtls_pk_ec( *pk )->grp ) ) != 0 ||
1078 ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), p, len ) ) != 0 )
1079 {
1080 mbedtls_pk_free( pk );
1081 return( ret );
1082 }
1083 } else
1084#endif /* MBEDTLS_ECP_C */
1085 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
1086
1087 return( 0 );
1088}
1089
1090/*
1091 * Parse an encrypted PKCS#8 encoded private key
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001092 *
1093 * To save space, the decryption happens in-place on the given key buffer.
1094 * Also, while this function may modify the keybuffer, it doesn't own it,
1095 * and instead it is the responsibility of the caller to zeroize and properly
1096 * free it after use.
1097 *
Jens Wiklander817466c2018-05-22 13:49:31 +02001098 */
1099#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
1100static int pk_parse_key_pkcs8_encrypted_der(
1101 mbedtls_pk_context *pk,
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001102 unsigned char *key, size_t keylen,
Jens Wiklander817466c2018-05-22 13:49:31 +02001103 const unsigned char *pwd, size_t pwdlen )
1104{
1105 int ret, decrypted = 0;
1106 size_t len;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001107 unsigned char *buf;
Jens Wiklander817466c2018-05-22 13:49:31 +02001108 unsigned char *p, *end;
1109 mbedtls_asn1_buf pbe_alg_oid, pbe_params;
1110#if defined(MBEDTLS_PKCS12_C)
1111 mbedtls_cipher_type_t cipher_alg;
1112 mbedtls_md_type_t md_alg;
1113#endif
1114
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001115 p = key;
Jens Wiklander817466c2018-05-22 13:49:31 +02001116 end = p + keylen;
1117
1118 if( pwdlen == 0 )
1119 return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED );
1120
1121 /*
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001122 * This function parses the EncryptedPrivateKeyInfo object (PKCS#8)
Jens Wiklander817466c2018-05-22 13:49:31 +02001123 *
1124 * EncryptedPrivateKeyInfo ::= SEQUENCE {
1125 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
1126 * encryptedData EncryptedData
1127 * }
1128 *
1129 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
1130 *
1131 * EncryptedData ::= OCTET STRING
1132 *
1133 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001134 *
Jens Wiklander817466c2018-05-22 13:49:31 +02001135 */
1136 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
1137 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
1138 {
1139 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
1140 }
1141
1142 end = p + len;
1143
1144 if( ( ret = mbedtls_asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
1145 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
1146
1147 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
1148 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
1149
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001150 buf = p;
Jens Wiklander817466c2018-05-22 13:49:31 +02001151
1152 /*
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001153 * Decrypt EncryptedData with appropriate PBE
Jens Wiklander817466c2018-05-22 13:49:31 +02001154 */
1155#if defined(MBEDTLS_PKCS12_C)
1156 if( mbedtls_oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
1157 {
1158 if( ( ret = mbedtls_pkcs12_pbe( &pbe_params, MBEDTLS_PKCS12_PBE_DECRYPT,
1159 cipher_alg, md_alg,
1160 pwd, pwdlen, p, len, buf ) ) != 0 )
1161 {
1162 if( ret == MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH )
1163 return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
1164
1165 return( ret );
1166 }
1167
1168 decrypted = 1;
1169 }
1170 else if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) == 0 )
1171 {
1172 if( ( ret = mbedtls_pkcs12_pbe_sha1_rc4_128( &pbe_params,
1173 MBEDTLS_PKCS12_PBE_DECRYPT,
1174 pwd, pwdlen,
1175 p, len, buf ) ) != 0 )
1176 {
1177 return( ret );
1178 }
1179
1180 // Best guess for password mismatch when using RC4. If first tag is
1181 // not MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE
1182 //
1183 if( *buf != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
1184 return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
1185
1186 decrypted = 1;
1187 }
1188 else
1189#endif /* MBEDTLS_PKCS12_C */
1190#if defined(MBEDTLS_PKCS5_C)
1191 if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBES2, &pbe_alg_oid ) == 0 )
1192 {
1193 if( ( ret = mbedtls_pkcs5_pbes2( &pbe_params, MBEDTLS_PKCS5_DECRYPT, pwd, pwdlen,
1194 p, len, buf ) ) != 0 )
1195 {
1196 if( ret == MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH )
1197 return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
1198
1199 return( ret );
1200 }
1201
1202 decrypted = 1;
1203 }
1204 else
1205#endif /* MBEDTLS_PKCS5_C */
1206 {
1207 ((void) pwd);
1208 }
1209
1210 if( decrypted == 0 )
1211 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
1212
1213 return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) );
1214}
1215#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
1216
1217/*
1218 * Parse a private key
1219 */
1220int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
1221 const unsigned char *key, size_t keylen,
1222 const unsigned char *pwd, size_t pwdlen )
1223{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001224 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001225 const mbedtls_pk_info_t *pk_info;
Jens Wiklander817466c2018-05-22 13:49:31 +02001226#if defined(MBEDTLS_PEM_PARSE_C)
1227 size_t len;
1228 mbedtls_pem_context pem;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001229#endif
Jens Wiklander817466c2018-05-22 13:49:31 +02001230
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001231 PK_VALIDATE_RET( pk != NULL );
1232 if( keylen == 0 )
1233 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
1234 PK_VALIDATE_RET( key != NULL );
1235
1236#if defined(MBEDTLS_PEM_PARSE_C)
1237 mbedtls_pem_init( &pem );
Jens Wiklander817466c2018-05-22 13:49:31 +02001238
1239#if defined(MBEDTLS_RSA_C)
1240 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001241 if( key[keylen - 1] != '\0' )
Jens Wiklander817466c2018-05-22 13:49:31 +02001242 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
1243 else
1244 ret = mbedtls_pem_read_buffer( &pem,
1245 "-----BEGIN RSA PRIVATE KEY-----",
1246 "-----END RSA PRIVATE KEY-----",
1247 key, pwd, pwdlen, &len );
1248
1249 if( ret == 0 )
1250 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001251 pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA );
1252 if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
Jens Wiklander817466c2018-05-22 13:49:31 +02001253 ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ),
1254 pem.buf, pem.buflen ) ) != 0 )
1255 {
1256 mbedtls_pk_free( pk );
1257 }
1258
1259 mbedtls_pem_free( &pem );
1260 return( ret );
1261 }
1262 else if( ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH )
1263 return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
1264 else if( ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED )
1265 return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED );
1266 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1267 return( ret );
1268#endif /* MBEDTLS_RSA_C */
1269
1270#if defined(MBEDTLS_ECP_C)
1271 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001272 if( key[keylen - 1] != '\0' )
Jens Wiklander817466c2018-05-22 13:49:31 +02001273 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
1274 else
1275 ret = mbedtls_pem_read_buffer( &pem,
1276 "-----BEGIN EC PRIVATE KEY-----",
1277 "-----END EC PRIVATE KEY-----",
1278 key, pwd, pwdlen, &len );
1279 if( ret == 0 )
1280 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001281 pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY );
Jens Wiklander817466c2018-05-22 13:49:31 +02001282
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001283 if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ||
Jens Wiklander817466c2018-05-22 13:49:31 +02001284 ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
1285 pem.buf, pem.buflen ) ) != 0 )
1286 {
1287 mbedtls_pk_free( pk );
1288 }
1289
1290 mbedtls_pem_free( &pem );
1291 return( ret );
1292 }
1293 else if( ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH )
1294 return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH );
1295 else if( ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED )
1296 return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED );
1297 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1298 return( ret );
1299#endif /* MBEDTLS_ECP_C */
1300
1301 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001302 if( key[keylen - 1] != '\0' )
Jens Wiklander817466c2018-05-22 13:49:31 +02001303 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
1304 else
1305 ret = mbedtls_pem_read_buffer( &pem,
1306 "-----BEGIN PRIVATE KEY-----",
1307 "-----END PRIVATE KEY-----",
1308 key, NULL, 0, &len );
1309 if( ret == 0 )
1310 {
1311 if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk,
1312 pem.buf, pem.buflen ) ) != 0 )
1313 {
1314 mbedtls_pk_free( pk );
1315 }
1316
1317 mbedtls_pem_free( &pem );
1318 return( ret );
1319 }
1320 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1321 return( ret );
1322
1323#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
1324 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001325 if( key[keylen - 1] != '\0' )
Jens Wiklander817466c2018-05-22 13:49:31 +02001326 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
1327 else
1328 ret = mbedtls_pem_read_buffer( &pem,
1329 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
1330 "-----END ENCRYPTED PRIVATE KEY-----",
1331 key, NULL, 0, &len );
1332 if( ret == 0 )
1333 {
1334 if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk,
1335 pem.buf, pem.buflen,
1336 pwd, pwdlen ) ) != 0 )
1337 {
1338 mbedtls_pk_free( pk );
1339 }
1340
1341 mbedtls_pem_free( &pem );
1342 return( ret );
1343 }
1344 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1345 return( ret );
1346#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
1347#else
Jens Wiklander817466c2018-05-22 13:49:31 +02001348 ((void) pwd);
1349 ((void) pwdlen);
1350#endif /* MBEDTLS_PEM_PARSE_C */
1351
1352 /*
1353 * At this point we only know it's not a PEM formatted key. Could be any
1354 * of the known DER encoded private key formats
1355 *
1356 * We try the different DER format parsers to see if one passes without
1357 * error
1358 */
1359#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
Jens Wiklander817466c2018-05-22 13:49:31 +02001360 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001361 unsigned char *key_copy;
1362
1363 if( ( key_copy = mbedtls_calloc( 1, keylen ) ) == NULL )
1364 return( MBEDTLS_ERR_PK_ALLOC_FAILED );
1365
1366 memcpy( key_copy, key, keylen );
1367
1368 ret = pk_parse_key_pkcs8_encrypted_der( pk, key_copy, keylen,
1369 pwd, pwdlen );
1370
1371 mbedtls_platform_zeroize( key_copy, keylen );
1372 mbedtls_free( key_copy );
Jens Wiklander817466c2018-05-22 13:49:31 +02001373 }
1374
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001375 if( ret == 0 )
1376 return( 0 );
1377
Jens Wiklander817466c2018-05-22 13:49:31 +02001378 mbedtls_pk_free( pk );
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001379 mbedtls_pk_init( pk );
Jens Wiklander817466c2018-05-22 13:49:31 +02001380
1381 if( ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH )
1382 {
1383 return( ret );
1384 }
1385#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
1386
1387 if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 )
1388 return( 0 );
1389
1390 mbedtls_pk_free( pk );
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001391 mbedtls_pk_init( pk );
Jens Wiklander817466c2018-05-22 13:49:31 +02001392
1393#if defined(MBEDTLS_RSA_C)
Jens Wiklander817466c2018-05-22 13:49:31 +02001394
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001395 pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA );
1396 if( mbedtls_pk_setup( pk, pk_info ) == 0 &&
1397 pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), key, keylen ) == 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +02001398 {
1399 return( 0 );
1400 }
1401
1402 mbedtls_pk_free( pk );
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001403 mbedtls_pk_init( pk );
Jens Wiklander817466c2018-05-22 13:49:31 +02001404#endif /* MBEDTLS_RSA_C */
1405
1406#if defined(MBEDTLS_ECP_C)
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001407 pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY );
1408 if( mbedtls_pk_setup( pk, pk_info ) == 0 &&
1409 pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ),
1410 key, keylen ) == 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +02001411 {
1412 return( 0 );
1413 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001414 mbedtls_pk_free( pk );
1415#endif /* MBEDTLS_ECP_C */
1416
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001417 /* If MBEDTLS_RSA_C is defined but MBEDTLS_ECP_C isn't,
1418 * it is ok to leave the PK context initialized but not
1419 * freed: It is the caller's responsibility to call pk_init()
1420 * before calling this function, and to call pk_free()
1421 * when it fails. If MBEDTLS_ECP_C is defined but MBEDTLS_RSA_C
1422 * isn't, this leads to mbedtls_pk_free() being called
1423 * twice, once here and once by the caller, but this is
1424 * also ok and in line with the mbedtls_pk_free() calls
1425 * on failed PEM parsing attempts. */
1426
Jens Wiklander817466c2018-05-22 13:49:31 +02001427 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
1428}
1429
1430/*
1431 * Parse a public key
1432 */
1433int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
1434 const unsigned char *key, size_t keylen )
1435{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001436 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001437 unsigned char *p;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001438#if defined(MBEDTLS_RSA_C)
1439 const mbedtls_pk_info_t *pk_info;
1440#endif
Jens Wiklander817466c2018-05-22 13:49:31 +02001441#if defined(MBEDTLS_PEM_PARSE_C)
1442 size_t len;
1443 mbedtls_pem_context pem;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001444#endif
Jens Wiklander817466c2018-05-22 13:49:31 +02001445
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001446 PK_VALIDATE_RET( ctx != NULL );
1447 if( keylen == 0 )
1448 return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
1449 PK_VALIDATE_RET( key != NULL || keylen == 0 );
1450
1451#if defined(MBEDTLS_PEM_PARSE_C)
Jens Wiklander817466c2018-05-22 13:49:31 +02001452 mbedtls_pem_init( &pem );
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001453#if defined(MBEDTLS_RSA_C)
1454 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
1455 if( key[keylen - 1] != '\0' )
1456 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
1457 else
1458 ret = mbedtls_pem_read_buffer( &pem,
1459 "-----BEGIN RSA PUBLIC KEY-----",
1460 "-----END RSA PUBLIC KEY-----",
1461 key, NULL, 0, &len );
1462
1463 if( ret == 0 )
1464 {
1465 p = pem.buf;
1466 if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
1467 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
1468
1469 if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 )
1470 return( ret );
1471
1472 if ( ( ret = pk_get_rsapubkey( &p, p + pem.buflen, mbedtls_pk_rsa( *ctx ) ) ) != 0 )
1473 mbedtls_pk_free( ctx );
1474
1475 mbedtls_pem_free( &pem );
1476 return( ret );
1477 }
1478 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1479 {
1480 mbedtls_pem_free( &pem );
1481 return( ret );
1482 }
1483#endif /* MBEDTLS_RSA_C */
Jens Wiklander817466c2018-05-22 13:49:31 +02001484
1485 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001486 if( key[keylen - 1] != '\0' )
Jens Wiklander817466c2018-05-22 13:49:31 +02001487 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
1488 else
1489 ret = mbedtls_pem_read_buffer( &pem,
1490 "-----BEGIN PUBLIC KEY-----",
1491 "-----END PUBLIC KEY-----",
1492 key, NULL, 0, &len );
1493
1494 if( ret == 0 )
1495 {
1496 /*
1497 * Was PEM encoded
1498 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001499 p = pem.buf;
1500
1501 ret = mbedtls_pk_parse_subpubkey( &p, p + pem.buflen, ctx );
1502 mbedtls_pem_free( &pem );
1503 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +02001504 }
1505 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1506 {
1507 mbedtls_pem_free( &pem );
1508 return( ret );
1509 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001510 mbedtls_pem_free( &pem );
Jens Wiklander817466c2018-05-22 13:49:31 +02001511#endif /* MBEDTLS_PEM_PARSE_C */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001512
1513#if defined(MBEDTLS_RSA_C)
1514 if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL )
1515 return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
1516
1517 if( ( ret = mbedtls_pk_setup( ctx, pk_info ) ) != 0 )
1518 return( ret );
1519
1520 p = (unsigned char *)key;
1521 ret = pk_get_rsapubkey( &p, p + keylen, mbedtls_pk_rsa( *ctx ) );
1522 if( ret == 0 )
1523 {
1524 return( ret );
1525 }
1526 mbedtls_pk_free( ctx );
1527 if( ret != ( MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
1528 {
1529 return( ret );
1530 }
1531#endif /* MBEDTLS_RSA_C */
Jens Wiklander817466c2018-05-22 13:49:31 +02001532 p = (unsigned char *) key;
1533
1534 ret = mbedtls_pk_parse_subpubkey( &p, p + keylen, ctx );
1535
Jens Wiklander817466c2018-05-22 13:49:31 +02001536 return( ret );
1537}
1538
1539#endif /* MBEDTLS_PK_PARSE_C */