2 * Public Key layer for parsing key files and structures
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #if defined(MBEDTLS_PK_PARSE_C)
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"
32 #if defined(MBEDTLS_RSA_C)
33 #include "mbedtls/rsa.h"
35 #if defined(MBEDTLS_ECP_C)
36 #include "mbedtls/ecp.h"
38 #if defined(MBEDTLS_ECDSA_C)
39 #include "mbedtls/ecdsa.h"
41 #if defined(MBEDTLS_PEM_PARSE_C)
42 #include "mbedtls/pem.h"
44 #if defined(MBEDTLS_PKCS5_C)
45 #include "mbedtls/pkcs5.h"
47 #if defined(MBEDTLS_PKCS12_C)
48 #include "mbedtls/pkcs12.h"
51 #if defined(MBEDTLS_PLATFORM_C)
52 #include "mbedtls/platform.h"
55 #define mbedtls_calloc calloc
56 #define mbedtls_free free
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 )
65 #if defined(MBEDTLS_FS_IO)
67 * Load all data from a file into a given buffer.
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.
73 int mbedtls_pk_load_file(const char *path
, unsigned char **buf
, size_t *n
) {
77 PK_VALIDATE_RET(path
!= NULL
);
78 PK_VALIDATE_RET(buf
!= NULL
);
79 PK_VALIDATE_RET(n
!= NULL
);
81 if ((f
= fopen(path
, "rb")) == NULL
)
82 return (MBEDTLS_ERR_PK_FILE_IO_ERROR
);
84 fseek(f
, 0, SEEK_END
);
85 if ((size
= ftell(f
)) == -1) {
87 return (MBEDTLS_ERR_PK_FILE_IO_ERROR
);
89 fseek(f
, 0, SEEK_SET
);
94 (*buf
= mbedtls_calloc(1, *n
+ 1)) == NULL
) {
96 return (MBEDTLS_ERR_PK_ALLOC_FAILED
);
99 if (fread(*buf
, 1, *n
, f
) != *n
) {
102 mbedtls_platform_zeroize(*buf
, *n
);
105 return (MBEDTLS_ERR_PK_FILE_IO_ERROR
);
112 if (strstr((const char *) *buf
, "-----BEGIN ") != NULL
)
119 * Load and parse a private key
121 int mbedtls_pk_parse_keyfile(mbedtls_pk_context
*ctx
,
122 const char *path
, const char *pwd
) {
123 int ret
= MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
;
127 PK_VALIDATE_RET(ctx
!= NULL
);
128 PK_VALIDATE_RET(path
!= NULL
);
130 if ((ret
= mbedtls_pk_load_file(path
, &buf
, &n
)) != 0)
134 ret
= mbedtls_pk_parse_key(ctx
, buf
, n
, NULL
, 0);
136 ret
= mbedtls_pk_parse_key(ctx
, buf
, n
,
137 (const unsigned char *) pwd
, strlen(pwd
));
139 mbedtls_platform_zeroize(buf
, n
);
146 * Load and parse a public key
148 int mbedtls_pk_parse_public_keyfile(mbedtls_pk_context
*ctx
, const char *path
) {
149 int ret
= MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
;
153 PK_VALIDATE_RET(ctx
!= NULL
);
154 PK_VALIDATE_RET(path
!= NULL
);
156 if ((ret
= mbedtls_pk_load_file(path
, &buf
, &n
)) != 0)
159 ret
= mbedtls_pk_parse_public_key(ctx
, buf
, n
);
161 mbedtls_platform_zeroize(buf
, n
);
166 #endif /* MBEDTLS_FS_IO */
168 #if defined(MBEDTLS_ECP_C)
169 /* Minimally parse an ECParameters buffer to and mbedtls_asn1_buf
171 * ECParameters ::= CHOICE {
172 * namedCurve OBJECT IDENTIFIER
173 * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... }
174 * -- implicitCurve NULL
177 static int pk_get_ecparams(unsigned char **p
, const unsigned char *end
,
178 mbedtls_asn1_buf
*params
) {
179 int ret
= MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
;
182 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
183 MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
185 /* Tag may be either OID or SEQUENCE */
187 if (params
->tag
!= MBEDTLS_ASN1_OID
188 #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
189 && params
->tag
!= (MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
)
192 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
193 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
);
196 if ((ret
= mbedtls_asn1_get_tag(p
, end
, ¶ms
->len
, params
->tag
)) != 0) {
197 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
204 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
205 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
210 #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
212 * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it.
213 * WARNING: the resulting group should only be used with
214 * pk_group_id_from_specified(), since its base point may not be set correctly
215 * if it was encoded compressed.
217 * SpecifiedECDomain ::= SEQUENCE {
218 * version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...),
219 * fieldID FieldID {{FieldTypes}},
223 * cofactor INTEGER OPTIONAL,
224 * hash HashAlgorithm OPTIONAL,
228 * We only support prime-field as field type, and ignore hash and cofactor.
230 static int pk_group_from_specified(const mbedtls_asn1_buf
*params
, mbedtls_ecp_group
*grp
) {
231 int ret
= MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
;
232 unsigned char *p
= params
->p
;
233 const unsigned char *const end
= params
->p
+ params
->len
;
234 const unsigned char *end_field
, *end_curve
;
238 /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */
239 if ((ret
= mbedtls_asn1_get_int(&p
, end
, &ver
)) != 0)
240 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
242 if (ver
< 1 || ver
> 3)
243 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
);
246 * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field
247 * fieldType FIELD-ID.&id({IOSet}),
248 * parameters FIELD-ID.&Type({IOSet}{@fieldType})
251 if ((ret
= mbedtls_asn1_get_tag(&p
, end
, &len
,
252 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
)) != 0)
258 * FIELD-ID ::= TYPE-IDENTIFIER
259 * FieldTypes FIELD-ID ::= {
260 * { Prime-p IDENTIFIED BY prime-field } |
261 * { Characteristic-two IDENTIFIED BY characteristic-two-field }
263 * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
265 if ((ret
= mbedtls_asn1_get_tag(&p
, end_field
, &len
, MBEDTLS_ASN1_OID
)) != 0)
268 if (len
!= MBEDTLS_OID_SIZE(MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD
) ||
269 memcmp(p
, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD
, len
) != 0) {
270 return (MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE
);
275 /* Prime-p ::= INTEGER -- Field of size p. */
276 if ((ret
= mbedtls_asn1_get_mpi(&p
, end_field
, &grp
->P
)) != 0)
277 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
279 grp
->pbits
= mbedtls_mpi_bitlen(&grp
->P
);
282 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
283 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
286 * Curve ::= SEQUENCE {
289 * seed BIT STRING OPTIONAL
290 * -- Shall be present if used in SpecifiedECDomain
291 * -- with version equal to ecdpVer2 or ecdpVer3
294 if ((ret
= mbedtls_asn1_get_tag(&p
, end
, &len
,
295 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
)) != 0)
301 * FieldElement ::= OCTET STRING
302 * containing an integer in the case of a prime field
304 if ((ret
= mbedtls_asn1_get_tag(&p
, end_curve
, &len
, MBEDTLS_ASN1_OCTET_STRING
)) != 0 ||
305 (ret
= mbedtls_mpi_read_binary(&grp
->A
, p
, len
)) != 0) {
306 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
311 if ((ret
= mbedtls_asn1_get_tag(&p
, end_curve
, &len
, MBEDTLS_ASN1_OCTET_STRING
)) != 0 ||
312 (ret
= mbedtls_mpi_read_binary(&grp
->B
, p
, len
)) != 0) {
313 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
318 /* Ignore seed BIT STRING OPTIONAL */
319 if ((ret
= mbedtls_asn1_get_tag(&p
, end_curve
, &len
, MBEDTLS_ASN1_BIT_STRING
)) == 0)
323 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
324 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
327 * ECPoint ::= OCTET STRING
329 if ((ret
= mbedtls_asn1_get_tag(&p
, end
, &len
, MBEDTLS_ASN1_OCTET_STRING
)) != 0)
330 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
332 if ((ret
= mbedtls_ecp_point_read_binary(grp
, &grp
->G
,
333 (const unsigned char *) p
, len
)) != 0) {
335 * If we can't read the point because it's compressed, cheat by
336 * reading only the X coordinate and the parity bit of Y.
338 if (ret
!= MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
||
339 (p
[0] != 0x02 && p
[0] != 0x03) ||
340 len
!= mbedtls_mpi_size(&grp
->P
) + 1 ||
341 mbedtls_mpi_read_binary(&grp
->G
.X
, p
+ 1, len
- 1) != 0 ||
342 mbedtls_mpi_lset(&grp
->G
.Y
, p
[0] - 2) != 0 ||
343 mbedtls_mpi_lset(&grp
->G
.Z
, 1) != 0) {
344 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
);
353 if ((ret
= mbedtls_asn1_get_mpi(&p
, end
, &grp
->N
)) != 0)
354 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
356 grp
->nbits
= mbedtls_mpi_bitlen(&grp
->N
);
359 * Allow optional elements by purposefully not enforcing p == end here.
366 * Find the group id associated with an (almost filled) group as generated by
367 * pk_group_from_specified(), or return an error if unknown.
369 static int pk_group_id_from_group(const mbedtls_ecp_group
*grp
, mbedtls_ecp_group_id
*grp_id
) {
371 mbedtls_ecp_group ref
;
372 const mbedtls_ecp_group_id
*id
;
374 mbedtls_ecp_group_init(&ref
);
376 for (id
= mbedtls_ecp_grp_id_list(); *id
!= MBEDTLS_ECP_DP_NONE
; id
++) {
377 /* Load the group associated to that id */
378 mbedtls_ecp_group_free(&ref
);
379 MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&ref
, *id
));
381 /* Compare to the group we were given, starting with easy tests */
382 if (grp
->pbits
== ref
.pbits
&& grp
->nbits
== ref
.nbits
&&
383 mbedtls_mpi_cmp_mpi(&grp
->P
, &ref
.P
) == 0 &&
384 mbedtls_mpi_cmp_mpi(&grp
->A
, &ref
.A
) == 0 &&
385 mbedtls_mpi_cmp_mpi(&grp
->B
, &ref
.B
) == 0 &&
386 mbedtls_mpi_cmp_mpi(&grp
->N
, &ref
.N
) == 0 &&
387 mbedtls_mpi_cmp_mpi(&grp
->G
.X
, &ref
.G
.X
) == 0 &&
388 mbedtls_mpi_cmp_mpi(&grp
->G
.Z
, &ref
.G
.Z
) == 0 &&
389 /* For Y we may only know the parity bit, so compare only that */
390 mbedtls_mpi_get_bit(&grp
->G
.Y
, 0) == mbedtls_mpi_get_bit(&ref
.G
.Y
, 0)) {
397 mbedtls_ecp_group_free(&ref
);
401 if (ret
== 0 && *id
== MBEDTLS_ECP_DP_NONE
)
402 ret
= MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
;
408 * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID
410 static int pk_group_id_from_specified(const mbedtls_asn1_buf
*params
,
411 mbedtls_ecp_group_id
*grp_id
) {
412 int ret
= MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
;
413 mbedtls_ecp_group grp
;
415 mbedtls_ecp_group_init(&grp
);
417 if ((ret
= pk_group_from_specified(params
, &grp
)) != 0)
420 ret
= pk_group_id_from_group(&grp
, grp_id
);
423 mbedtls_ecp_group_free(&grp
);
427 #endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */
430 * Use EC parameters to initialise an EC group
432 * ECParameters ::= CHOICE {
433 * namedCurve OBJECT IDENTIFIER
434 * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... }
435 * -- implicitCurve NULL
437 static int pk_use_ecparams(const mbedtls_asn1_buf
*params
, mbedtls_ecp_group
*grp
) {
438 int ret
= MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
;
439 mbedtls_ecp_group_id grp_id
;
441 if (params
->tag
== MBEDTLS_ASN1_OID
) {
442 if (mbedtls_oid_get_ec_grp(params
, &grp_id
) != 0)
443 return (MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE
);
445 #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
446 if ((ret
= pk_group_id_from_specified(params
, &grp_id
)) != 0)
449 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
);
454 * grp may already be initilialized; if so, make sure IDs match
456 if (grp
->id
!= MBEDTLS_ECP_DP_NONE
&& grp
->id
!= grp_id
)
457 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
);
459 if ((ret
= mbedtls_ecp_group_load(grp
, grp_id
)) != 0)
466 * EC public key is an EC point
468 * The caller is responsible for clearing the structure upon failure if
469 * desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE
470 * return code of mbedtls_ecp_point_read_binary() and leave p in a usable state.
472 static int pk_get_ecpubkey(unsigned char **p
, const unsigned char *end
,
473 mbedtls_ecp_keypair
*key
) {
474 int ret
= MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
;
476 if ((ret
= mbedtls_ecp_point_read_binary(&key
->grp
, &key
->Q
,
477 (const unsigned char *) *p
, end
- *p
)) == 0) {
478 ret
= mbedtls_ecp_check_pubkey(&key
->grp
, &key
->Q
);
482 * We know mbedtls_ecp_point_read_binary consumed all bytes or failed
484 *p
= (unsigned char *) end
;
488 #endif /* MBEDTLS_ECP_C */
490 #if defined(MBEDTLS_RSA_C)
492 * RSAPublicKey ::= SEQUENCE {
493 * modulus INTEGER, -- n
494 * publicExponent INTEGER -- e
497 static int pk_get_rsapubkey(unsigned char **p
,
498 const unsigned char *end
,
499 mbedtls_rsa_context
*rsa
) {
500 int ret
= MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
;
503 if ((ret
= mbedtls_asn1_get_tag(p
, end
, &len
,
504 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
)) != 0)
505 return (MBEDTLS_ERR_PK_INVALID_PUBKEY
+ ret
);
508 return (MBEDTLS_ERR_PK_INVALID_PUBKEY
+
509 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
512 if ((ret
= mbedtls_asn1_get_tag(p
, end
, &len
, MBEDTLS_ASN1_INTEGER
)) != 0)
513 return (MBEDTLS_ERR_PK_INVALID_PUBKEY
+ ret
);
515 if ((ret
= mbedtls_rsa_import_raw(rsa
, *p
, len
, NULL
, 0, NULL
, 0,
516 NULL
, 0, NULL
, 0)) != 0)
517 return (MBEDTLS_ERR_PK_INVALID_PUBKEY
);
522 if ((ret
= mbedtls_asn1_get_tag(p
, end
, &len
, MBEDTLS_ASN1_INTEGER
)) != 0)
523 return (MBEDTLS_ERR_PK_INVALID_PUBKEY
+ ret
);
525 if ((ret
= mbedtls_rsa_import_raw(rsa
, NULL
, 0, NULL
, 0, NULL
, 0,
526 NULL
, 0, *p
, len
)) != 0)
527 return (MBEDTLS_ERR_PK_INVALID_PUBKEY
);
531 if (mbedtls_rsa_complete(rsa
) != 0 ||
532 mbedtls_rsa_check_pubkey(rsa
) != 0) {
533 return (MBEDTLS_ERR_PK_INVALID_PUBKEY
);
537 return (MBEDTLS_ERR_PK_INVALID_PUBKEY
+
538 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
542 #endif /* MBEDTLS_RSA_C */
544 /* Get a PK algorithm identifier
546 * AlgorithmIdentifier ::= SEQUENCE {
547 * algorithm OBJECT IDENTIFIER,
548 * parameters ANY DEFINED BY algorithm OPTIONAL }
550 static int pk_get_pk_alg(unsigned char **p
,
551 const unsigned char *end
,
552 mbedtls_pk_type_t
*pk_alg
, mbedtls_asn1_buf
*params
) {
553 int ret
= MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
;
554 mbedtls_asn1_buf alg_oid
;
556 memset(params
, 0, sizeof(mbedtls_asn1_buf
));
558 if ((ret
= mbedtls_asn1_get_alg(p
, end
, &alg_oid
, params
)) != 0)
559 return (MBEDTLS_ERR_PK_INVALID_ALG
+ ret
);
561 if (mbedtls_oid_get_pk_alg(&alg_oid
, pk_alg
) != 0)
562 return (MBEDTLS_ERR_PK_UNKNOWN_PK_ALG
);
565 * No parameters with RSA (only for EC)
567 if (*pk_alg
== MBEDTLS_PK_RSA
&&
568 ((params
->tag
!= MBEDTLS_ASN1_NULL
&& params
->tag
!= 0) ||
570 return (MBEDTLS_ERR_PK_INVALID_ALG
);
577 * SubjectPublicKeyInfo ::= SEQUENCE {
578 * algorithm AlgorithmIdentifier,
579 * subjectPublicKey BIT STRING }
581 int mbedtls_pk_parse_subpubkey(unsigned char **p
, const unsigned char *end
,
582 mbedtls_pk_context
*pk
) {
583 int ret
= MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
;
585 mbedtls_asn1_buf alg_params
;
586 mbedtls_pk_type_t pk_alg
= MBEDTLS_PK_NONE
;
587 const mbedtls_pk_info_t
*pk_info
;
589 PK_VALIDATE_RET(p
!= NULL
);
590 PK_VALIDATE_RET(*p
!= NULL
);
591 PK_VALIDATE_RET(end
!= NULL
);
592 PK_VALIDATE_RET(pk
!= NULL
);
594 if ((ret
= mbedtls_asn1_get_tag(p
, end
, &len
,
595 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
)) != 0) {
596 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
601 if ((ret
= pk_get_pk_alg(p
, end
, &pk_alg
, &alg_params
)) != 0)
604 if ((ret
= mbedtls_asn1_get_bitstring_null(p
, end
, &len
)) != 0)
605 return (MBEDTLS_ERR_PK_INVALID_PUBKEY
+ ret
);
608 return (MBEDTLS_ERR_PK_INVALID_PUBKEY
+
609 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
611 if ((pk_info
= mbedtls_pk_info_from_type(pk_alg
)) == NULL
)
612 return (MBEDTLS_ERR_PK_UNKNOWN_PK_ALG
);
614 if ((ret
= mbedtls_pk_setup(pk
, pk_info
)) != 0)
617 #if defined(MBEDTLS_RSA_C)
618 if (pk_alg
== MBEDTLS_PK_RSA
) {
619 ret
= pk_get_rsapubkey(p
, end
, mbedtls_pk_rsa(*pk
));
621 #endif /* MBEDTLS_RSA_C */
622 #if defined(MBEDTLS_ECP_C)
623 if (pk_alg
== MBEDTLS_PK_ECKEY_DH
|| pk_alg
== MBEDTLS_PK_ECKEY
) {
624 ret
= pk_use_ecparams(&alg_params
, &mbedtls_pk_ec(*pk
)->grp
);
626 ret
= pk_get_ecpubkey(p
, end
, mbedtls_pk_ec(*pk
));
628 #endif /* MBEDTLS_ECP_C */
629 ret
= MBEDTLS_ERR_PK_UNKNOWN_PK_ALG
;
631 if (ret
== 0 && *p
!= end
)
632 ret
= MBEDTLS_ERR_PK_INVALID_PUBKEY
+
633 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
;
641 #if defined(MBEDTLS_RSA_C)
643 * Wrapper around mbedtls_asn1_get_mpi() that rejects zero.
646 * - never a valid value for an RSA parameter
647 * - interpreted as "omitted, please reconstruct" by mbedtls_rsa_complete().
649 * Since values can't be omitted in PKCS#1, passing a zero value to
650 * rsa_complete() would be incorrect, so reject zero values early.
652 static int asn1_get_nonzero_mpi(unsigned char **p
,
653 const unsigned char *end
,
657 ret
= mbedtls_asn1_get_mpi(p
, end
, X
);
661 if (mbedtls_mpi_cmp_int(X
, 0) == 0)
662 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
);
668 * Parse a PKCS#1 encoded private RSA key
670 static int pk_parse_key_pkcs1_der(mbedtls_rsa_context
*rsa
,
671 const unsigned char *key
,
675 unsigned char *p
, *end
;
678 mbedtls_mpi_init(&T
);
680 p
= (unsigned char *) key
;
684 * This function parses the RSAPrivateKey (PKCS#1)
686 * RSAPrivateKey ::= SEQUENCE {
688 * modulus INTEGER, -- n
689 * publicExponent INTEGER, -- e
690 * privateExponent INTEGER, -- d
691 * prime1 INTEGER, -- p
692 * prime2 INTEGER, -- q
693 * exponent1 INTEGER, -- d mod (p-1)
694 * exponent2 INTEGER, -- d mod (q-1)
695 * coefficient INTEGER, -- (inverse of q) mod p
696 * otherPrimeInfos OtherPrimeInfos OPTIONAL
699 if ((ret
= mbedtls_asn1_get_tag(&p
, end
, &len
,
700 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
)) != 0) {
701 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
706 if ((ret
= mbedtls_asn1_get_int(&p
, end
, &version
)) != 0) {
707 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
711 return (MBEDTLS_ERR_PK_KEY_INVALID_VERSION
);
715 if ((ret
= asn1_get_nonzero_mpi(&p
, end
, &T
)) != 0 ||
716 (ret
= mbedtls_rsa_import(rsa
, &T
, NULL
, NULL
,
721 if ((ret
= asn1_get_nonzero_mpi(&p
, end
, &T
)) != 0 ||
722 (ret
= mbedtls_rsa_import(rsa
, NULL
, NULL
, NULL
,
727 if ((ret
= asn1_get_nonzero_mpi(&p
, end
, &T
)) != 0 ||
728 (ret
= mbedtls_rsa_import(rsa
, NULL
, NULL
, NULL
,
733 if ((ret
= asn1_get_nonzero_mpi(&p
, end
, &T
)) != 0 ||
734 (ret
= mbedtls_rsa_import(rsa
, NULL
, &T
, NULL
,
739 if ((ret
= asn1_get_nonzero_mpi(&p
, end
, &T
)) != 0 ||
740 (ret
= mbedtls_rsa_import(rsa
, NULL
, NULL
, &T
,
744 #if !defined(MBEDTLS_RSA_NO_CRT) && !defined(MBEDTLS_RSA_ALT)
746 * The RSA CRT parameters DP, DQ and QP are nominally redundant, in
747 * that they can be easily recomputed from D, P and Q. However by
748 * parsing them from the PKCS1 structure it is possible to avoid
749 * recalculating them which both reduces the overhead of loading
750 * RSA private keys into memory and also avoids side channels which
751 * can arise when computing those values, since all of D, P, and Q
752 * are secret. See https://eprint.iacr.org/2020/055 for a
753 * description of one such attack.
757 if ((ret
= asn1_get_nonzero_mpi(&p
, end
, &T
)) != 0 ||
758 (ret
= mbedtls_mpi_copy(&rsa
->DP
, &T
)) != 0)
762 if ((ret
= asn1_get_nonzero_mpi(&p
, end
, &T
)) != 0 ||
763 (ret
= mbedtls_mpi_copy(&rsa
->DQ
, &T
)) != 0)
767 if ((ret
= asn1_get_nonzero_mpi(&p
, end
, &T
)) != 0 ||
768 (ret
= mbedtls_mpi_copy(&rsa
->QP
, &T
)) != 0)
772 /* Verify existance of the CRT params */
773 if ((ret
= asn1_get_nonzero_mpi(&p
, end
, &T
)) != 0 ||
774 (ret
= asn1_get_nonzero_mpi(&p
, end
, &T
)) != 0 ||
775 (ret
= asn1_get_nonzero_mpi(&p
, end
, &T
)) != 0)
779 /* rsa_complete() doesn't complete anything with the default
780 * implementation but is still called:
781 * - for the benefit of alternative implementation that may want to
782 * pre-compute stuff beyond what's provided (eg Montgomery factors)
783 * - as is also sanity-checks the key
785 * Furthermore, we also check the public part for consistency with
786 * mbedtls_pk_parse_pubkey(), as it includes size minima for example.
788 if ((ret
= mbedtls_rsa_complete(rsa
)) != 0 ||
789 (ret
= mbedtls_rsa_check_pubkey(rsa
)) != 0) {
794 ret
= MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
795 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
;
800 mbedtls_mpi_free(&T
);
803 /* Wrap error code if it's coming from a lower level */
804 if ((ret
& 0xff80) == 0)
805 ret
= MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
;
807 ret
= MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
;
809 mbedtls_rsa_free(rsa
);
814 #endif /* MBEDTLS_RSA_C */
816 #if defined(MBEDTLS_ECP_C)
818 * Parse a SEC1 encoded private EC key
820 static int pk_parse_key_sec1_der(mbedtls_ecp_keypair
*eck
,
821 const unsigned char *key
,
823 int ret
= MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
;
824 int version
, pubkey_done
;
826 mbedtls_asn1_buf params
;
827 unsigned char *p
= (unsigned char *) key
;
828 unsigned char *end
= p
+ keylen
;
832 * RFC 5915, or SEC1 Appendix C.4
834 * ECPrivateKey ::= SEQUENCE {
835 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
836 * privateKey OCTET STRING,
837 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
838 * publicKey [1] BIT STRING OPTIONAL
841 if ((ret
= mbedtls_asn1_get_tag(&p
, end
, &len
,
842 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
)) != 0) {
843 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
848 if ((ret
= mbedtls_asn1_get_int(&p
, end
, &version
)) != 0)
849 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
852 return (MBEDTLS_ERR_PK_KEY_INVALID_VERSION
);
854 if ((ret
= mbedtls_asn1_get_tag(&p
, end
, &len
, MBEDTLS_ASN1_OCTET_STRING
)) != 0)
855 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
857 if ((ret
= mbedtls_mpi_read_binary(&eck
->d
, p
, len
)) != 0) {
858 mbedtls_ecp_keypair_free(eck
);
859 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
867 * Is 'parameters' present?
869 if ((ret
= mbedtls_asn1_get_tag(&p
, end
, &len
,
870 MBEDTLS_ASN1_CONTEXT_SPECIFIC
| MBEDTLS_ASN1_CONSTRUCTED
| 0)) == 0) {
871 if ((ret
= pk_get_ecparams(&p
, p
+ len
, ¶ms
)) != 0 ||
872 (ret
= pk_use_ecparams(¶ms
, &eck
->grp
)) != 0) {
873 mbedtls_ecp_keypair_free(eck
);
876 } else if (ret
!= MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
) {
877 mbedtls_ecp_keypair_free(eck
);
878 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
884 * Is 'publickey' present? If not, or if we can't read it (eg because it
885 * is compressed), create it from the private key.
887 if ((ret
= mbedtls_asn1_get_tag(&p
, end
, &len
,
888 MBEDTLS_ASN1_CONTEXT_SPECIFIC
| MBEDTLS_ASN1_CONSTRUCTED
| 1)) == 0) {
891 if ((ret
= mbedtls_asn1_get_bitstring_null(&p
, end2
, &len
)) != 0)
892 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
895 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
896 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
);
898 if ((ret
= pk_get_ecpubkey(&p
, end2
, eck
)) == 0)
902 * The only acceptable failure mode of pk_get_ecpubkey() above
903 * is if the point format is not recognized.
905 if (ret
!= MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE
)
906 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
);
908 } else if (ret
!= MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
) {
909 mbedtls_ecp_keypair_free(eck
);
910 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
915 (ret
= mbedtls_ecp_mul(&eck
->grp
, &eck
->Q
, &eck
->d
, &eck
->grp
.G
,
917 mbedtls_ecp_keypair_free(eck
);
918 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
921 if ((ret
= mbedtls_ecp_check_privkey(&eck
->grp
, &eck
->d
)) != 0) {
922 mbedtls_ecp_keypair_free(eck
);
928 #endif /* MBEDTLS_ECP_C */
931 * Parse an unencrypted PKCS#8 encoded private key
935 * - This function does not own the key buffer. It is the
936 * responsibility of the caller to take care of zeroizing
937 * and freeing it after use.
939 * - The function is responsible for freeing the provided
940 * PK context on failure.
943 static int pk_parse_key_pkcs8_unencrypted_der(
944 mbedtls_pk_context
*pk
,
945 const unsigned char *key
,
949 mbedtls_asn1_buf params
;
950 unsigned char *p
= (unsigned char *) key
;
951 unsigned char *end
= p
+ keylen
;
952 mbedtls_pk_type_t pk_alg
= MBEDTLS_PK_NONE
;
953 const mbedtls_pk_info_t
*pk_info
;
956 * This function parses the PrivateKeyInfo object (PKCS#8 v1.2 = RFC 5208)
958 * PrivateKeyInfo ::= SEQUENCE {
960 * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
961 * privateKey PrivateKey,
962 * attributes [0] IMPLICIT Attributes OPTIONAL }
964 * Version ::= INTEGER
965 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
966 * PrivateKey ::= OCTET STRING
968 * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
971 if ((ret
= mbedtls_asn1_get_tag(&p
, end
, &len
,
972 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
)) != 0) {
973 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
978 if ((ret
= mbedtls_asn1_get_int(&p
, end
, &version
)) != 0)
979 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
982 return (MBEDTLS_ERR_PK_KEY_INVALID_VERSION
+ ret
);
984 if ((ret
= pk_get_pk_alg(&p
, end
, &pk_alg
, ¶ms
)) != 0)
985 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
987 if ((ret
= mbedtls_asn1_get_tag(&p
, end
, &len
, MBEDTLS_ASN1_OCTET_STRING
)) != 0)
988 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
991 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+
992 MBEDTLS_ERR_ASN1_OUT_OF_DATA
);
994 if ((pk_info
= mbedtls_pk_info_from_type(pk_alg
)) == NULL
)
995 return (MBEDTLS_ERR_PK_UNKNOWN_PK_ALG
);
997 if ((ret
= mbedtls_pk_setup(pk
, pk_info
)) != 0)
1000 #if defined(MBEDTLS_RSA_C)
1001 if (pk_alg
== MBEDTLS_PK_RSA
) {
1002 if ((ret
= pk_parse_key_pkcs1_der(mbedtls_pk_rsa(*pk
), p
, len
)) != 0) {
1003 mbedtls_pk_free(pk
);
1007 #endif /* MBEDTLS_RSA_C */
1008 #if defined(MBEDTLS_ECP_C)
1009 if (pk_alg
== MBEDTLS_PK_ECKEY
|| pk_alg
== MBEDTLS_PK_ECKEY_DH
) {
1010 if ((ret
= pk_use_ecparams(¶ms
, &mbedtls_pk_ec(*pk
)->grp
)) != 0 ||
1011 (ret
= pk_parse_key_sec1_der(mbedtls_pk_ec(*pk
), p
, len
)) != 0) {
1012 mbedtls_pk_free(pk
);
1016 #endif /* MBEDTLS_ECP_C */
1017 return (MBEDTLS_ERR_PK_UNKNOWN_PK_ALG
);
1023 * Parse an encrypted PKCS#8 encoded private key
1025 * To save space, the decryption happens in-place on the given key buffer.
1026 * Also, while this function may modify the keybuffer, it doesn't own it,
1027 * and instead it is the responsibility of the caller to zeroize and properly
1028 * free it after use.
1031 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
1032 static int pk_parse_key_pkcs8_encrypted_der(
1033 mbedtls_pk_context
*pk
,
1034 unsigned char *key
, size_t keylen
,
1035 const unsigned char *pwd
, size_t pwdlen
) {
1036 int ret
, decrypted
= 0;
1039 unsigned char *p
, *end
;
1040 mbedtls_asn1_buf pbe_alg_oid
, pbe_params
;
1041 #if defined(MBEDTLS_PKCS12_C)
1042 mbedtls_cipher_type_t cipher_alg
;
1043 mbedtls_md_type_t md_alg
;
1050 return (MBEDTLS_ERR_PK_PASSWORD_REQUIRED
);
1053 * This function parses the EncryptedPrivateKeyInfo object (PKCS#8)
1055 * EncryptedPrivateKeyInfo ::= SEQUENCE {
1056 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
1057 * encryptedData EncryptedData
1060 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
1062 * EncryptedData ::= OCTET STRING
1064 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
1067 if ((ret
= mbedtls_asn1_get_tag(&p
, end
, &len
,
1068 MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
)) != 0) {
1069 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
1074 if ((ret
= mbedtls_asn1_get_alg(&p
, end
, &pbe_alg_oid
, &pbe_params
)) != 0)
1075 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
1077 if ((ret
= mbedtls_asn1_get_tag(&p
, end
, &len
, MBEDTLS_ASN1_OCTET_STRING
)) != 0)
1078 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
+ ret
);
1083 * Decrypt EncryptedData with appropriate PBE
1085 #if defined(MBEDTLS_PKCS12_C)
1086 if (mbedtls_oid_get_pkcs12_pbe_alg(&pbe_alg_oid
, &md_alg
, &cipher_alg
) == 0) {
1087 if ((ret
= mbedtls_pkcs12_pbe(&pbe_params
, MBEDTLS_PKCS12_PBE_DECRYPT
,
1089 pwd
, pwdlen
, p
, len
, buf
)) != 0) {
1090 if (ret
== MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH
)
1091 return (MBEDTLS_ERR_PK_PASSWORD_MISMATCH
);
1097 } else if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128
, &pbe_alg_oid
) == 0) {
1098 if ((ret
= mbedtls_pkcs12_pbe_sha1_rc4_128(&pbe_params
,
1099 MBEDTLS_PKCS12_PBE_DECRYPT
,
1101 p
, len
, buf
)) != 0) {
1105 // Best guess for password mismatch when using RC4. If first tag is
1106 // not MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE
1108 if (*buf
!= (MBEDTLS_ASN1_CONSTRUCTED
| MBEDTLS_ASN1_SEQUENCE
))
1109 return (MBEDTLS_ERR_PK_PASSWORD_MISMATCH
);
1113 #endif /* MBEDTLS_PKCS12_C */
1114 #if defined(MBEDTLS_PKCS5_C)
1115 if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS5_PBES2
, &pbe_alg_oid
) == 0) {
1116 if ((ret
= mbedtls_pkcs5_pbes2(&pbe_params
, MBEDTLS_PKCS5_DECRYPT
, pwd
, pwdlen
,
1117 p
, len
, buf
)) != 0) {
1118 if (ret
== MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH
)
1119 return (MBEDTLS_ERR_PK_PASSWORD_MISMATCH
);
1126 #endif /* MBEDTLS_PKCS5_C */
1132 return (MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE
);
1134 return (pk_parse_key_pkcs8_unencrypted_der(pk
, buf
, len
));
1136 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
1139 * Parse a private key
1141 int mbedtls_pk_parse_key(mbedtls_pk_context
*pk
,
1142 const unsigned char *key
, size_t keylen
,
1143 const unsigned char *pwd
, size_t pwdlen
) {
1144 int ret
= MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
;
1145 const mbedtls_pk_info_t
*pk_info
;
1146 #if defined(MBEDTLS_PEM_PARSE_C)
1148 mbedtls_pem_context pem
;
1151 PK_VALIDATE_RET(pk
!= NULL
);
1153 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
);
1154 PK_VALIDATE_RET(key
!= NULL
);
1156 #if defined(MBEDTLS_PEM_PARSE_C)
1157 mbedtls_pem_init(&pem
);
1159 #if defined(MBEDTLS_RSA_C)
1160 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
1161 if (key
[keylen
- 1] != '\0')
1162 ret
= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
;
1164 ret
= mbedtls_pem_read_buffer(&pem
,
1165 "-----BEGIN RSA PRIVATE KEY-----",
1166 "-----END RSA PRIVATE KEY-----",
1167 key
, pwd
, pwdlen
, &len
);
1170 pk_info
= mbedtls_pk_info_from_type(MBEDTLS_PK_RSA
);
1171 if ((ret
= mbedtls_pk_setup(pk
, pk_info
)) != 0 ||
1172 (ret
= pk_parse_key_pkcs1_der(mbedtls_pk_rsa(*pk
),
1173 pem
.buf
, pem
.buflen
)) != 0) {
1174 mbedtls_pk_free(pk
);
1177 mbedtls_pem_free(&pem
);
1179 } else if (ret
== MBEDTLS_ERR_PEM_PASSWORD_MISMATCH
)
1180 return (MBEDTLS_ERR_PK_PASSWORD_MISMATCH
);
1181 else if (ret
== MBEDTLS_ERR_PEM_PASSWORD_REQUIRED
)
1182 return (MBEDTLS_ERR_PK_PASSWORD_REQUIRED
);
1183 else if (ret
!= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
)
1185 #endif /* MBEDTLS_RSA_C */
1187 #if defined(MBEDTLS_ECP_C)
1188 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
1189 if (key
[keylen
- 1] != '\0')
1190 ret
= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
;
1192 ret
= mbedtls_pem_read_buffer(&pem
,
1193 "-----BEGIN EC PRIVATE KEY-----",
1194 "-----END EC PRIVATE KEY-----",
1195 key
, pwd
, pwdlen
, &len
);
1197 pk_info
= mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY
);
1199 if ((ret
= mbedtls_pk_setup(pk
, pk_info
)) != 0 ||
1200 (ret
= pk_parse_key_sec1_der(mbedtls_pk_ec(*pk
),
1201 pem
.buf
, pem
.buflen
)) != 0) {
1202 mbedtls_pk_free(pk
);
1205 mbedtls_pem_free(&pem
);
1207 } else if (ret
== MBEDTLS_ERR_PEM_PASSWORD_MISMATCH
)
1208 return (MBEDTLS_ERR_PK_PASSWORD_MISMATCH
);
1209 else if (ret
== MBEDTLS_ERR_PEM_PASSWORD_REQUIRED
)
1210 return (MBEDTLS_ERR_PK_PASSWORD_REQUIRED
);
1211 else if (ret
!= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
)
1213 #endif /* MBEDTLS_ECP_C */
1215 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
1216 if (key
[keylen
- 1] != '\0')
1217 ret
= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
;
1219 ret
= mbedtls_pem_read_buffer(&pem
,
1220 "-----BEGIN PRIVATE KEY-----",
1221 "-----END PRIVATE KEY-----",
1222 key
, NULL
, 0, &len
);
1224 if ((ret
= pk_parse_key_pkcs8_unencrypted_der(pk
,
1225 pem
.buf
, pem
.buflen
)) != 0) {
1226 mbedtls_pk_free(pk
);
1229 mbedtls_pem_free(&pem
);
1231 } else if (ret
!= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
)
1234 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
1235 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
1236 if (key
[keylen
- 1] != '\0')
1237 ret
= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
;
1239 ret
= mbedtls_pem_read_buffer(&pem
,
1240 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
1241 "-----END ENCRYPTED PRIVATE KEY-----",
1242 key
, NULL
, 0, &len
);
1244 if ((ret
= pk_parse_key_pkcs8_encrypted_der(pk
,
1245 pem
.buf
, pem
.buflen
,
1246 pwd
, pwdlen
)) != 0) {
1247 mbedtls_pk_free(pk
);
1250 mbedtls_pem_free(&pem
);
1252 } else if (ret
!= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
)
1254 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
1258 #endif /* MBEDTLS_PEM_PARSE_C */
1261 * At this point we only know it's not a PEM formatted key. Could be any
1262 * of the known DER encoded private key formats
1264 * We try the different DER format parsers to see if one passes without
1267 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
1269 unsigned char *key_copy
;
1271 if ((key_copy
= mbedtls_calloc(1, keylen
)) == NULL
)
1272 return (MBEDTLS_ERR_PK_ALLOC_FAILED
);
1274 memcpy(key_copy
, key
, keylen
);
1276 ret
= pk_parse_key_pkcs8_encrypted_der(pk
, key_copy
, keylen
,
1279 mbedtls_platform_zeroize(key_copy
, keylen
);
1280 mbedtls_free(key_copy
);
1286 mbedtls_pk_free(pk
);
1287 mbedtls_pk_init(pk
);
1289 if (ret
== MBEDTLS_ERR_PK_PASSWORD_MISMATCH
) {
1292 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
1294 if ((ret
= pk_parse_key_pkcs8_unencrypted_der(pk
, key
, keylen
)) == 0)
1297 mbedtls_pk_free(pk
);
1298 mbedtls_pk_init(pk
);
1300 #if defined(MBEDTLS_RSA_C)
1302 pk_info
= mbedtls_pk_info_from_type(MBEDTLS_PK_RSA
);
1303 if (mbedtls_pk_setup(pk
, pk_info
) == 0 &&
1304 pk_parse_key_pkcs1_der(mbedtls_pk_rsa(*pk
), key
, keylen
) == 0) {
1308 mbedtls_pk_free(pk
);
1309 mbedtls_pk_init(pk
);
1310 #endif /* MBEDTLS_RSA_C */
1312 #if defined(MBEDTLS_ECP_C)
1313 pk_info
= mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY
);
1314 if (mbedtls_pk_setup(pk
, pk_info
) == 0 &&
1315 pk_parse_key_sec1_der(mbedtls_pk_ec(*pk
),
1316 key
, keylen
) == 0) {
1319 mbedtls_pk_free(pk
);
1320 #endif /* MBEDTLS_ECP_C */
1322 /* If MBEDTLS_RSA_C is defined but MBEDTLS_ECP_C isn't,
1323 * it is ok to leave the PK context initialized but not
1324 * freed: It is the caller's responsibility to call pk_init()
1325 * before calling this function, and to call pk_free()
1326 * when it fails. If MBEDTLS_ECP_C is defined but MBEDTLS_RSA_C
1327 * isn't, this leads to mbedtls_pk_free() being called
1328 * twice, once here and once by the caller, but this is
1329 * also ok and in line with the mbedtls_pk_free() calls
1330 * on failed PEM parsing attempts. */
1332 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
);
1336 * Parse a public key
1338 int mbedtls_pk_parse_public_key(mbedtls_pk_context
*ctx
,
1339 const unsigned char *key
, size_t keylen
) {
1340 int ret
= MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
;
1342 #if defined(MBEDTLS_RSA_C)
1343 const mbedtls_pk_info_t
*pk_info
;
1345 #if defined(MBEDTLS_PEM_PARSE_C)
1347 mbedtls_pem_context pem
;
1350 PK_VALIDATE_RET(ctx
!= NULL
);
1352 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT
);
1353 PK_VALIDATE_RET(key
!= NULL
|| keylen
== 0);
1355 #if defined(MBEDTLS_PEM_PARSE_C)
1356 mbedtls_pem_init(&pem
);
1357 #if defined(MBEDTLS_RSA_C)
1358 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
1359 if (key
[keylen
- 1] != '\0')
1360 ret
= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
;
1362 ret
= mbedtls_pem_read_buffer(&pem
,
1363 "-----BEGIN RSA PUBLIC KEY-----",
1364 "-----END RSA PUBLIC KEY-----",
1365 key
, NULL
, 0, &len
);
1369 if ((pk_info
= mbedtls_pk_info_from_type(MBEDTLS_PK_RSA
)) == NULL
)
1370 return (MBEDTLS_ERR_PK_UNKNOWN_PK_ALG
);
1372 if ((ret
= mbedtls_pk_setup(ctx
, pk_info
)) != 0)
1375 if ((ret
= pk_get_rsapubkey(&p
, p
+ pem
.buflen
, mbedtls_pk_rsa(*ctx
))) != 0)
1376 mbedtls_pk_free(ctx
);
1378 mbedtls_pem_free(&pem
);
1380 } else if (ret
!= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
) {
1381 mbedtls_pem_free(&pem
);
1384 #endif /* MBEDTLS_RSA_C */
1386 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
1387 if (key
[keylen
- 1] != '\0')
1388 ret
= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
;
1390 ret
= mbedtls_pem_read_buffer(&pem
,
1391 "-----BEGIN PUBLIC KEY-----",
1392 "-----END PUBLIC KEY-----",
1393 key
, NULL
, 0, &len
);
1401 ret
= mbedtls_pk_parse_subpubkey(&p
, p
+ pem
.buflen
, ctx
);
1402 mbedtls_pem_free(&pem
);
1404 } else if (ret
!= MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
) {
1405 mbedtls_pem_free(&pem
);
1408 mbedtls_pem_free(&pem
);
1409 #endif /* MBEDTLS_PEM_PARSE_C */
1411 #if defined(MBEDTLS_RSA_C)
1412 if ((pk_info
= mbedtls_pk_info_from_type(MBEDTLS_PK_RSA
)) == NULL
)
1413 return (MBEDTLS_ERR_PK_UNKNOWN_PK_ALG
);
1415 if ((ret
= mbedtls_pk_setup(ctx
, pk_info
)) != 0)
1418 p
= (unsigned char *)key
;
1419 ret
= pk_get_rsapubkey(&p
, p
+ keylen
, mbedtls_pk_rsa(*ctx
));
1423 mbedtls_pk_free(ctx
);
1424 if (ret
!= (MBEDTLS_ERR_PK_INVALID_PUBKEY
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
)) {
1427 #endif /* MBEDTLS_RSA_C */
1428 p
= (unsigned char *) key
;
1430 ret
= mbedtls_pk_parse_subpubkey(&p
, p
+ keylen
, ctx
);
1435 #endif /* MBEDTLS_PK_PARSE_C */