quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

pkparse.c (43503B)


      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 */
     66 static 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 */
     73 static 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  */
     85 static 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  */
    109 static 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  */
    260 static 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 
    287 cleanup:
    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  */
    302 static 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 
    316 cleanup:
    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  */
    348 static 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, &params->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  */
    389 static 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  */
    413 static 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  */
    429 static 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  */
    471 static 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  */
    517 int 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  */
    604 static 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, &params)) != 0 ||
    662                 (ret = pk_use_ecparams(&params, 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  */
    742 static 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, &params, &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(&params, 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(&params, 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)
    865 MBEDTLS_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  */
    973 int 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  */
   1180 int 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  */
   1298 int 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  */
   1347 int 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  */
   1374 int 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 */