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