Merge pull request #2735 from jareckib/master
[RRG-proxmark3.git] / common / mbedtls / pkparse.c
blob75222ffd7eb2a1db2f88d38dcf444c671b5c6293
1 /*
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.
20 #include "common.h"
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"
30 #include <string.h>
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
51 #if defined(MBEDTLS_PLATFORM_C)
52 #include "mbedtls/platform.h"
53 #else
54 #include <stdlib.h>
55 #define mbedtls_calloc calloc
56 #define mbedtls_free free
57 #endif
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) {
74 FILE *f;
75 long size;
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) {
86 fclose(f);
87 return (MBEDTLS_ERR_PK_FILE_IO_ERROR);
89 fseek(f, 0, SEEK_SET);
91 *n = (size_t) size;
93 if (*n + 1 == 0 ||
94 (*buf = mbedtls_calloc(1, *n + 1)) == NULL) {
95 fclose(f);
96 return (MBEDTLS_ERR_PK_ALLOC_FAILED);
99 if (fread(*buf, 1, *n, f) != *n) {
100 fclose(f);
102 mbedtls_platform_zeroize(*buf, *n);
103 mbedtls_free(*buf);
105 return (MBEDTLS_ERR_PK_FILE_IO_ERROR);
108 fclose(f);
110 (*buf)[*n] = '\0';
112 if (strstr((const char *) *buf, "-----BEGIN ") != NULL)
113 ++*n;
115 return (0);
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;
124 size_t n;
125 unsigned char *buf;
127 PK_VALIDATE_RET(ctx != NULL);
128 PK_VALIDATE_RET(path != NULL);
130 if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0)
131 return (ret);
133 if (pwd == NULL)
134 ret = mbedtls_pk_parse_key(ctx, buf, n, NULL, 0);
135 else
136 ret = mbedtls_pk_parse_key(ctx, buf, n,
137 (const unsigned char *) pwd, strlen(pwd));
139 mbedtls_platform_zeroize(buf, n);
140 mbedtls_free(buf);
142 return (ret);
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;
150 size_t n;
151 unsigned char *buf;
153 PK_VALIDATE_RET(ctx != NULL);
154 PK_VALIDATE_RET(path != NULL);
156 if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0)
157 return (ret);
159 ret = mbedtls_pk_parse_public_key(ctx, buf, n);
161 mbedtls_platform_zeroize(buf, n);
162 mbedtls_free(buf);
164 return (ret);
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;
181 if (end - *p < 1)
182 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
183 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
185 /* Tag may be either OID or SEQUENCE */
186 params->tag = **p;
187 if (params->tag != MBEDTLS_ASN1_OID
188 #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
189 && params->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)
190 #endif
192 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
193 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
196 if ((ret = mbedtls_asn1_get_tag(p, end, &params->len, params->tag)) != 0) {
197 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret);
200 params->p = *p;
201 *p += params->len;
203 if (*p != end)
204 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
205 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
207 return (0);
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}},
220 * curve Curve,
221 * base ECPoint,
222 * order INTEGER,
223 * cofactor INTEGER OPTIONAL,
224 * hash HashAlgorithm OPTIONAL,
225 * ...
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;
235 size_t len;
236 int ver;
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)
253 return (ret);
255 end_field = p + len;
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)
266 return (ret);
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);
273 p += len;
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);
281 if (p != end_field)
282 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
283 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
286 * Curve ::= SEQUENCE {
287 * a FieldElement,
288 * b FieldElement,
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)
296 return (ret);
298 end_curve = p + len;
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);
309 p += len;
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);
316 p += len;
318 /* Ignore seed BIT STRING OPTIONAL */
319 if ((ret = mbedtls_asn1_get_tag(&p, end_curve, &len, MBEDTLS_ASN1_BIT_STRING)) == 0)
320 p += len;
322 if (p != end_curve)
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);
348 p += len;
351 * order INTEGER
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.
362 return (0);
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) {
370 int ret = 0;
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)) {
391 break;
396 cleanup:
397 mbedtls_ecp_group_free(&ref);
399 *grp_id = *id;
401 if (ret == 0 && *id == MBEDTLS_ECP_DP_NONE)
402 ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
404 return (ret);
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)
418 goto cleanup;
420 ret = pk_group_id_from_group(&grp, grp_id);
422 cleanup:
423 mbedtls_ecp_group_free(&grp);
425 return (ret);
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);
444 } else {
445 #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
446 if ((ret = pk_group_id_from_specified(params, &grp_id)) != 0)
447 return (ret);
448 #else
449 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT);
450 #endif
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)
460 return (ret);
462 return (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;
486 return (ret);
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;
501 size_t len;
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);
507 if (*p + len != end)
508 return (MBEDTLS_ERR_PK_INVALID_PUBKEY +
509 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
511 /* Import N */
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);
519 *p += len;
521 /* Import E */
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);
529 *p += len;
531 if (mbedtls_rsa_complete(rsa) != 0 ||
532 mbedtls_rsa_check_pubkey(rsa) != 0) {
533 return (MBEDTLS_ERR_PK_INVALID_PUBKEY);
536 if (*p != end)
537 return (MBEDTLS_ERR_PK_INVALID_PUBKEY +
538 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
540 return (0);
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) ||
569 params->len != 0)) {
570 return (MBEDTLS_ERR_PK_INVALID_ALG);
573 return (0);
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;
584 size_t len;
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);
599 end = *p + len;
601 if ((ret = pk_get_pk_alg(p, end, &pk_alg, &alg_params)) != 0)
602 return (ret);
604 if ((ret = mbedtls_asn1_get_bitstring_null(p, end, &len)) != 0)
605 return (MBEDTLS_ERR_PK_INVALID_PUBKEY + ret);
607 if (*p + len != end)
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)
615 return (ret);
617 #if defined(MBEDTLS_RSA_C)
618 if (pk_alg == MBEDTLS_PK_RSA) {
619 ret = pk_get_rsapubkey(p, end, mbedtls_pk_rsa(*pk));
620 } else
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);
625 if (ret == 0)
626 ret = pk_get_ecpubkey(p, end, mbedtls_pk_ec(*pk));
627 } else
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;
635 if (ret != 0)
636 mbedtls_pk_free(pk);
638 return (ret);
641 #if defined(MBEDTLS_RSA_C)
643 * Wrapper around mbedtls_asn1_get_mpi() that rejects zero.
645 * The value zero is:
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,
654 mbedtls_mpi *X) {
655 int ret;
657 ret = mbedtls_asn1_get_mpi(p, end, X);
658 if (ret != 0)
659 return (ret);
661 if (mbedtls_mpi_cmp_int(X, 0) == 0)
662 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT);
664 return (0);
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,
672 size_t keylen) {
673 int ret, version;
674 size_t len;
675 unsigned char *p, *end;
677 mbedtls_mpi T;
678 mbedtls_mpi_init(&T);
680 p = (unsigned char *) key;
681 end = p + keylen;
684 * This function parses the RSAPrivateKey (PKCS#1)
686 * RSAPrivateKey ::= SEQUENCE {
687 * version Version,
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);
704 end = p + len;
706 if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0) {
707 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret);
710 if (version != 0) {
711 return (MBEDTLS_ERR_PK_KEY_INVALID_VERSION);
714 /* Import N */
715 if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
716 (ret = mbedtls_rsa_import(rsa, &T, NULL, NULL,
717 NULL, NULL)) != 0)
718 goto cleanup;
720 /* Import E */
721 if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
722 (ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL,
723 NULL, &T)) != 0)
724 goto cleanup;
726 /* Import D */
727 if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
728 (ret = mbedtls_rsa_import(rsa, NULL, NULL, NULL,
729 &T, NULL)) != 0)
730 goto cleanup;
732 /* Import P */
733 if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
734 (ret = mbedtls_rsa_import(rsa, NULL, &T, NULL,
735 NULL, NULL)) != 0)
736 goto cleanup;
738 /* Import Q */
739 if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
740 (ret = mbedtls_rsa_import(rsa, NULL, NULL, &T,
741 NULL, NULL)) != 0)
742 goto cleanup;
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.
756 /* Import DP */
757 if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
758 (ret = mbedtls_mpi_copy(&rsa->DP, &T)) != 0)
759 goto cleanup;
761 /* Import DQ */
762 if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
763 (ret = mbedtls_mpi_copy(&rsa->DQ, &T)) != 0)
764 goto cleanup;
766 /* Import QP */
767 if ((ret = asn1_get_nonzero_mpi(&p, end, &T)) != 0 ||
768 (ret = mbedtls_mpi_copy(&rsa->QP, &T)) != 0)
769 goto cleanup;
771 #else
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)
776 goto cleanup;
777 #endif
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) {
790 goto cleanup;
793 if (p != end) {
794 ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
795 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ;
798 cleanup:
800 mbedtls_mpi_free(&T);
802 if (ret != 0) {
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;
806 else
807 ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
809 mbedtls_rsa_free(rsa);
812 return (ret);
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,
822 size_t keylen) {
823 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
824 int version, pubkey_done;
825 size_t len;
826 mbedtls_asn1_buf params;
827 unsigned char *p = (unsigned char *) key;
828 unsigned char *end = p + keylen;
829 unsigned char *end2;
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);
846 end = p + len;
848 if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0)
849 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret);
851 if (version != 1)
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);
862 p += len;
864 pubkey_done = 0;
865 if (p != end) {
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, &params)) != 0 ||
872 (ret = pk_use_ecparams(&params, &eck->grp)) != 0) {
873 mbedtls_ecp_keypair_free(eck);
874 return (ret);
876 } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
877 mbedtls_ecp_keypair_free(eck);
878 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret);
882 if (p != end) {
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) {
889 end2 = p + len;
891 if ((ret = mbedtls_asn1_get_bitstring_null(&p, end2, &len)) != 0)
892 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret);
894 if (p + len != end2)
895 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
896 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
898 if ((ret = pk_get_ecpubkey(&p, end2, eck)) == 0)
899 pubkey_done = 1;
900 else {
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);
914 if (! pubkey_done &&
915 (ret = mbedtls_ecp_mul(&eck->grp, &eck->Q, &eck->d, &eck->grp.G,
916 NULL, NULL)) != 0) {
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);
923 return (ret);
926 return (0);
928 #endif /* MBEDTLS_ECP_C */
931 * Parse an unencrypted PKCS#8 encoded private key
933 * Notes:
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,
946 size_t keylen) {
947 int ret, version;
948 size_t len;
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 {
959 * version Version,
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);
976 end = p + len;
978 if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0)
979 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret);
981 if (version != 0)
982 return (MBEDTLS_ERR_PK_KEY_INVALID_VERSION + ret);
984 if ((ret = pk_get_pk_alg(&p, end, &pk_alg, &params)) != 0)
985 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret);
987 if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0)
988 return (MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret);
990 if (len < 1)
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)
998 return (ret);
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);
1004 return (ret);
1006 } else
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(&params, &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);
1013 return (ret);
1015 } else
1016 #endif /* MBEDTLS_ECP_C */
1017 return (MBEDTLS_ERR_PK_UNKNOWN_PK_ALG);
1019 return (0);
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;
1037 size_t len;
1038 unsigned char *buf;
1039 unsigned char *p, *end;
1040 mbedtls_asn1_buf pbe_alg_oid, pbe_params;
1041 #if defined(MBEDTLS_PKCS12_C)
1042 mbedtls_cipher_type_t cipher_alg;
1043 mbedtls_md_type_t md_alg;
1044 #endif
1046 p = key;
1047 end = p + keylen;
1049 if (pwdlen == 0)
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);
1072 end = p + len;
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);
1080 buf = p;
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,
1088 cipher_alg, md_alg,
1089 pwd, pwdlen, p, len, buf)) != 0) {
1090 if (ret == MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH)
1091 return (MBEDTLS_ERR_PK_PASSWORD_MISMATCH);
1093 return (ret);
1096 decrypted = 1;
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,
1100 pwd, pwdlen,
1101 p, len, buf)) != 0) {
1102 return (ret);
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);
1111 decrypted = 1;
1112 } else
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);
1121 return (ret);
1124 decrypted = 1;
1125 } else
1126 #endif /* MBEDTLS_PKCS5_C */
1128 ((void) pwd);
1131 if (decrypted == 0)
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)
1147 size_t len;
1148 mbedtls_pem_context pem;
1149 #endif
1151 PK_VALIDATE_RET(pk != NULL);
1152 if (keylen == 0)
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;
1163 else
1164 ret = mbedtls_pem_read_buffer(&pem,
1165 "-----BEGIN RSA PRIVATE KEY-----",
1166 "-----END RSA PRIVATE KEY-----",
1167 key, pwd, pwdlen, &len);
1169 if (ret == 0) {
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);
1178 return (ret);
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)
1184 return (ret);
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;
1191 else
1192 ret = mbedtls_pem_read_buffer(&pem,
1193 "-----BEGIN EC PRIVATE KEY-----",
1194 "-----END EC PRIVATE KEY-----",
1195 key, pwd, pwdlen, &len);
1196 if (ret == 0) {
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);
1206 return (ret);
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)
1212 return (ret);
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;
1218 else
1219 ret = mbedtls_pem_read_buffer(&pem,
1220 "-----BEGIN PRIVATE KEY-----",
1221 "-----END PRIVATE KEY-----",
1222 key, NULL, 0, &len);
1223 if (ret == 0) {
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);
1230 return (ret);
1231 } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT)
1232 return (ret);
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;
1238 else
1239 ret = mbedtls_pem_read_buffer(&pem,
1240 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
1241 "-----END ENCRYPTED PRIVATE KEY-----",
1242 key, NULL, 0, &len);
1243 if (ret == 0) {
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);
1251 return (ret);
1252 } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT)
1253 return (ret);
1254 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
1255 #else
1256 ((void) pwd);
1257 ((void) pwdlen);
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
1265 * error
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,
1277 pwd, pwdlen);
1279 mbedtls_platform_zeroize(key_copy, keylen);
1280 mbedtls_free(key_copy);
1283 if (ret == 0)
1284 return (0);
1286 mbedtls_pk_free(pk);
1287 mbedtls_pk_init(pk);
1289 if (ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH) {
1290 return (ret);
1292 #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
1294 if ((ret = pk_parse_key_pkcs8_unencrypted_der(pk, key, keylen)) == 0)
1295 return (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) {
1305 return (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) {
1317 return (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;
1341 unsigned char *p;
1342 #if defined(MBEDTLS_RSA_C)
1343 const mbedtls_pk_info_t *pk_info;
1344 #endif
1345 #if defined(MBEDTLS_PEM_PARSE_C)
1346 size_t len;
1347 mbedtls_pem_context pem;
1348 #endif
1350 PK_VALIDATE_RET(ctx != NULL);
1351 if (keylen == 0)
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;
1361 else
1362 ret = mbedtls_pem_read_buffer(&pem,
1363 "-----BEGIN RSA PUBLIC KEY-----",
1364 "-----END RSA PUBLIC KEY-----",
1365 key, NULL, 0, &len);
1367 if (ret == 0) {
1368 p = pem.buf;
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)
1373 return (ret);
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);
1379 return (ret);
1380 } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
1381 mbedtls_pem_free(&pem);
1382 return (ret);
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;
1389 else
1390 ret = mbedtls_pem_read_buffer(&pem,
1391 "-----BEGIN PUBLIC KEY-----",
1392 "-----END PUBLIC KEY-----",
1393 key, NULL, 0, &len);
1395 if (ret == 0) {
1397 * Was PEM encoded
1399 p = pem.buf;
1401 ret = mbedtls_pk_parse_subpubkey(&p, p + pem.buflen, ctx);
1402 mbedtls_pem_free(&pem);
1403 return (ret);
1404 } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
1405 mbedtls_pem_free(&pem);
1406 return (ret);
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)
1416 return (ret);
1418 p = (unsigned char *)key;
1419 ret = pk_get_rsapubkey(&p, p + keylen, mbedtls_pk_rsa(*ctx));
1420 if (ret == 0) {
1421 return (ret);
1423 mbedtls_pk_free(ctx);
1424 if (ret != (MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) {
1425 return (ret);
1427 #endif /* MBEDTLS_RSA_C */
1428 p = (unsigned char *) key;
1430 ret = mbedtls_pk_parse_subpubkey(&p, p + keylen, ctx);
1432 return (ret);
1435 #endif /* MBEDTLS_PK_PARSE_C */