LCOV - code coverage report
Current view: top level - os_stub/mbedtlslib/mbedtls/library - pkparse.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 45.5 % 301 137
Test Date: 2025-06-29 08:09:00 Functions: 58.3 % 12 7

            Line data    Source code
       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            0 : static int pk_ecc_tag_is_specified_ec_domain(int tag)
      67              : {
      68              :     (void) tag;
      69            0 :     return 0;
      70              : }
      71              : 
      72              : /* See the "real" version for documentation */
      73            0 : 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            0 :     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            0 : static int pk_get_ecparams(unsigned char **p, const unsigned char *end,
     349              :                            mbedtls_asn1_buf *params)
     350              : {
     351            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     352              : 
     353            0 :     if (end - *p < 1) {
     354            0 :         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            0 :     params->tag = **p;
     360            0 :     if (params->tag != MBEDTLS_ASN1_OID &&
     361            0 :         !pk_ecc_tag_is_specified_ec_domain(params->tag)) {
     362            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
     363              :                                  MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
     364              :     }
     365              : 
     366            0 :     if ((ret = mbedtls_asn1_get_tag(p, end, &params->len, params->tag)) != 0) {
     367            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
     368              :     }
     369              : 
     370            0 :     params->p = *p;
     371            0 :     *p += params->len;
     372              : 
     373            0 :     if (*p != end) {
     374            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
     375              :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     376              :     }
     377              : 
     378            0 :     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        11650 : static int pk_use_ecparams(const mbedtls_asn1_buf *params, mbedtls_pk_context *pk)
     390              : {
     391        11650 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     392              :     mbedtls_ecp_group_id grp_id;
     393              : 
     394        11650 :     if (params->tag == MBEDTLS_ASN1_OID) {
     395        11650 :         if (mbedtls_oid_get_ec_grp(params, &grp_id) != 0) {
     396            0 :             return MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE;
     397              :         }
     398              :     } else {
     399            0 :         ret = pk_ecc_group_id_from_specified(params, &grp_id);
     400            0 :         if (ret != 0) {
     401            0 :             return ret;
     402              :         }
     403              :     }
     404              : 
     405        11650 :     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            0 : 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            0 :     if (params->tag != 0 || params->len != 0) {
     418            0 :         return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
     419              :     }
     420              : 
     421            0 :     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            0 : 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            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     434              :     size_t len;
     435              : 
     436            0 :     if ((ret = mbedtls_asn1_get_tag(&key, (key + keylen), &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) {
     437            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
     438              :     }
     439              : 
     440            0 :     if (key + len != end) {
     441            0 :         return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
     442              :     }
     443              : 
     444              :     /*
     445              :      * Load the private key
     446              :      */
     447            0 :     ret = mbedtls_pk_ecc_set_key(pk, key, len);
     448            0 :     if (ret != 0) {
     449            0 :         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            0 :     if ((ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, key, len, f_rng, p_rng)) != 0) {
     456            0 :         return ret;
     457              :     }
     458              : 
     459            0 :     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        13001 : 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        13001 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     477              :     mbedtls_asn1_buf alg_oid;
     478              : 
     479        13001 :     memset(params, 0, sizeof(mbedtls_asn1_buf));
     480              : 
     481        13001 :     if ((ret = mbedtls_asn1_get_alg(p, end, &alg_oid, params)) != 0) {
     482            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_ALG, ret);
     483              :     }
     484              : 
     485        13001 :     ret = mbedtls_oid_get_pk_alg(&alg_oid, pk_alg);
     486              : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
     487        13001 :     if (ret == MBEDTLS_ERR_OID_NOT_FOUND) {
     488            0 :         ret = mbedtls_oid_get_ec_grp_algid(&alg_oid, ec_grp_id);
     489            0 :         if (ret == 0) {
     490            0 :             *pk_alg = MBEDTLS_PK_ECKEY;
     491              :         }
     492              :     }
     493              : #else
     494              :     (void) ec_grp_id;
     495              : #endif
     496        13001 :     if (ret != 0) {
     497            0 :         return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;
     498              :     }
     499              : 
     500              :     /*
     501              :      * No parameters with RSA (only for EC)
     502              :      */
     503        13001 :     if (*pk_alg == MBEDTLS_PK_RSA &&
     504         1351 :         ((params->tag != MBEDTLS_ASN1_NULL && params->tag != 0) ||
     505         1351 :          params->len != 0)) {
     506            0 :         return MBEDTLS_ERR_PK_INVALID_ALG;
     507              :     }
     508              : 
     509        13001 :     return 0;
     510              : }
     511              : 
     512              : /*
     513              :  *  SubjectPublicKeyInfo  ::=  SEQUENCE  {
     514              :  *       algorithm            AlgorithmIdentifier,
     515              :  *       subjectPublicKey     BIT STRING }
     516              :  */
     517        12820 : int mbedtls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end,
     518              :                                mbedtls_pk_context *pk)
     519              : {
     520        12820 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     521              :     size_t len;
     522              :     mbedtls_asn1_buf alg_params;
     523        12820 :     mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
     524        12820 :     mbedtls_ecp_group_id ec_grp_id = MBEDTLS_ECP_DP_NONE;
     525              :     const mbedtls_pk_info_t *pk_info;
     526              : 
     527        12820 :     if ((ret = mbedtls_asn1_get_tag(p, end, &len,
     528              :                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
     529            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
     530              :     }
     531              : 
     532        12820 :     end = *p + len;
     533              : 
     534        12820 :     if ((ret = pk_get_pk_alg(p, end, &pk_alg, &alg_params, &ec_grp_id)) != 0) {
     535            0 :         return ret;
     536              :     }
     537              : 
     538        12820 :     if ((ret = mbedtls_asn1_get_bitstring_null(p, end, &len)) != 0) {
     539            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret);
     540              :     }
     541              : 
     542        12820 :     if (*p + len != end) {
     543            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY,
     544              :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     545              :     }
     546              : 
     547        12820 :     if ((pk_info = mbedtls_pk_info_from_type(pk_alg)) == NULL) {
     548            0 :         return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;
     549              :     }
     550              : 
     551        12820 :     if ((ret = mbedtls_pk_setup(pk, pk_info)) != 0) {
     552            0 :         return ret;
     553              :     }
     554              : 
     555              : #if defined(MBEDTLS_RSA_C)
     556        12820 :     if (pk_alg == MBEDTLS_PK_RSA) {
     557         1315 :         ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*pk), *p, (size_t) (end - *p));
     558         1315 :         if (ret == 0) {
     559              :             /* On success all the input has been consumed by the parsing function. */
     560         1315 :             *p += end - *p;
     561            0 :         } 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            0 :             ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY, ret);
     565              :         } else {
     566            0 :             ret = MBEDTLS_ERR_PK_INVALID_PUBKEY;
     567              :         }
     568              :     } else
     569              : #endif /* MBEDTLS_RSA_C */
     570              : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
     571        11505 :     if (pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY) {
     572              : #if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
     573        11505 :         if (MBEDTLS_PK_IS_RFC8410_GROUP_ID(ec_grp_id)) {
     574            0 :             ret = pk_use_ecparams_rfc8410(&alg_params, ec_grp_id, pk);
     575              :         } else
     576              : #endif
     577              :         {
     578        11505 :             ret = pk_use_ecparams(&alg_params, pk);
     579              :         }
     580        11505 :         if (ret == 0) {
     581        11505 :             ret = mbedtls_pk_ecc_set_pubkey(pk, *p, (size_t) (end - *p));
     582        11505 :             *p += end - *p;
     583              :         }
     584              :     } else
     585              : #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
     586            0 :     ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;
     587              : 
     588        12820 :     if (ret == 0 && *p != end) {
     589            0 :         ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_INVALID_PUBKEY,
     590              :                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     591              :     }
     592              : 
     593        12820 :     if (ret != 0) {
     594            0 :         mbedtls_pk_free(pk);
     595              :     }
     596              : 
     597        12820 :     return ret;
     598              : }
     599              : 
     600              : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
     601              : /*
     602              :  * Parse a SEC1 encoded private EC key
     603              :  */
     604          145 : 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          145 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     609              :     int version, pubkey_done;
     610              :     size_t len, d_len;
     611          145 :     mbedtls_asn1_buf params = { 0, 0, NULL };
     612          145 :     unsigned char *p = (unsigned char *) key;
     613              :     unsigned char *d;
     614          145 :     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          145 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
     628              :                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
     629            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
     630              :     }
     631              : 
     632          145 :     end = p + len;
     633              : 
     634          145 :     if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0) {
     635            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
     636              :     }
     637              : 
     638          145 :     if (version != 1) {
     639            0 :         return MBEDTLS_ERR_PK_KEY_INVALID_VERSION;
     640              :     }
     641              : 
     642          145 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) {
     643            0 :         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          145 :     d = p;
     649          145 :     d_len = len;
     650              : 
     651          145 :     p += len;
     652              : 
     653          145 :     pubkey_done = 0;
     654          145 :     if (p != end) {
     655              :         /*
     656              :          * Is 'parameters' present?
     657              :          */
     658          145 :         if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
     659              :                                         MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
     660              :                                         0)) == 0) {
     661            0 :             if ((ret = pk_get_ecparams(&p, p + len, &params)) != 0 ||
     662            0 :                 (ret = pk_use_ecparams(&params, pk)) != 0) {
     663            0 :                 return ret;
     664              :             }
     665          145 :         } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
     666            0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
     667              :         }
     668              :     }
     669              : 
     670              :     /*
     671              :      * Load the private key
     672              :      */
     673          145 :     ret = mbedtls_pk_ecc_set_key(pk, d, d_len);
     674          145 :     if (ret != 0) {
     675            0 :         return ret;
     676              :     }
     677              : 
     678          145 :     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          145 :         if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
     684              :                                         MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
     685              :                                         1)) == 0) {
     686          145 :             end2 = p + len;
     687              : 
     688          145 :             if ((ret = mbedtls_asn1_get_bitstring_null(&p, end2, &len)) != 0) {
     689            0 :                 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
     690              :             }
     691              : 
     692          145 :             if (p + len != end2) {
     693            0 :                 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
     694              :                                          MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     695              :             }
     696              : 
     697          145 :             if ((ret = mbedtls_pk_ecc_set_pubkey(pk, p, (size_t) (end2 - p))) == 0) {
     698          145 :                 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            0 :                 if (ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) {
     705            0 :                     return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
     706              :                 }
     707              :             }
     708            0 :         } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
     709            0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
     710              :         }
     711              :     }
     712              : 
     713          145 :     if (!pubkey_done) {
     714            0 :         if ((ret = mbedtls_pk_ecc_set_pubkey_from_prv(pk, d, d_len, f_rng, p_rng)) != 0) {
     715            0 :             return ret;
     716              :         }
     717              :     }
     718              : 
     719          145 :     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          181 : 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          181 :     unsigned char *p = (unsigned char *) key;
     751          181 :     unsigned char *end = p + keylen;
     752          181 :     mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
     753          181 :     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          181 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
     778              :                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
     779            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
     780              :     }
     781              : 
     782          181 :     end = p + len;
     783              : 
     784          181 :     if ((ret = mbedtls_asn1_get_int(&p, end, &version)) != 0) {
     785            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
     786              :     }
     787              : 
     788          181 :     if (version != 0) {
     789            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_VERSION, ret);
     790              :     }
     791              : 
     792          181 :     if ((ret = pk_get_pk_alg(&p, end, &pk_alg, &params, &ec_grp_id)) != 0) {
     793            0 :         return ret;
     794              :     }
     795              : 
     796          181 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING)) != 0) {
     797            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret);
     798              :     }
     799              : 
     800          181 :     if (len < 1) {
     801            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
     802              :                                  MBEDTLS_ERR_ASN1_OUT_OF_DATA);
     803              :     }
     804              : 
     805          181 :     if ((pk_info = mbedtls_pk_info_from_type(pk_alg)) == NULL) {
     806            0 :         return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;
     807              :     }
     808              : 
     809          181 :     if ((ret = mbedtls_pk_setup(pk, pk_info)) != 0) {
     810            0 :         return ret;
     811              :     }
     812              : 
     813              : #if defined(MBEDTLS_RSA_C)
     814          181 :     if (pk_alg == MBEDTLS_PK_RSA) {
     815           36 :         if ((ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), p, len)) != 0) {
     816            0 :             mbedtls_pk_free(pk);
     817            0 :             return ret;
     818              :         }
     819              :     } else
     820              : #endif /* MBEDTLS_RSA_C */
     821              : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
     822          145 :     if (pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH) {
     823              : #if defined(MBEDTLS_PK_HAVE_RFC8410_CURVES)
     824          145 :         if (MBEDTLS_PK_IS_RFC8410_GROUP_ID(ec_grp_id)) {
     825            0 :             if ((ret =
     826            0 :                      pk_use_ecparams_rfc8410(&params, ec_grp_id, pk)) != 0 ||
     827              :                 (ret =
     828            0 :                      pk_parse_key_rfc8410_der(pk, p, len, end, f_rng,
     829              :                                               p_rng)) != 0) {
     830            0 :                 mbedtls_pk_free(pk);
     831            0 :                 return ret;
     832              :             }
     833              :         } else
     834              : #endif
     835              :         {
     836          290 :             if ((ret = pk_use_ecparams(&params, pk)) != 0 ||
     837          145 :                 (ret = pk_parse_key_sec1_der(pk, p, len, f_rng, p_rng)) != 0) {
     838            0 :                 mbedtls_pk_free(pk);
     839            0 :                 return ret;
     840              :             }
     841              :         }
     842              :     } else
     843              : #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
     844            0 :     return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;
     845              : 
     846          181 :     end = p + len;
     847          181 :     if (end != (key + keylen)) {
     848            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
     849              :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     850              :     }
     851              : 
     852          181 :     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          181 : 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          181 :     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          181 :     if (keylen == 0) {
     986            0 :         return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
     987              :     }
     988              : 
     989              : #if defined(MBEDTLS_PEM_PARSE_C)
     990          181 :     mbedtls_pem_init(&pem);
     991              : 
     992              : #if defined(MBEDTLS_RSA_C)
     993              :     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
     994          181 :     if (key[keylen - 1] != '\0') {
     995            0 :         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
     996              :     } else {
     997          181 :         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          181 :     if (ret == 0) {
    1003            0 :         pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
    1004            0 :         if ((ret = mbedtls_pk_setup(pk, pk_info)) != 0 ||
    1005            0 :             (ret = mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk),
    1006            0 :                                          pem.buf, pem.buflen)) != 0) {
    1007            0 :             mbedtls_pk_free(pk);
    1008              :         }
    1009              : 
    1010            0 :         mbedtls_pem_free(&pem);
    1011            0 :         return ret;
    1012          181 :     } else if (ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) {
    1013            0 :         return MBEDTLS_ERR_PK_PASSWORD_MISMATCH;
    1014          181 :     } else if (ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) {
    1015            0 :         return MBEDTLS_ERR_PK_PASSWORD_REQUIRED;
    1016          181 :     } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
    1017            0 :         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          181 :     if (key[keylen - 1] != '\0') {
    1024            0 :         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
    1025              :     } else {
    1026          181 :         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          181 :     if (ret == 0) {
    1032            0 :         pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);
    1033              : 
    1034            0 :         if ((ret = mbedtls_pk_setup(pk, pk_info)) != 0 ||
    1035            0 :             (ret = pk_parse_key_sec1_der(pk,
    1036            0 :                                          pem.buf, pem.buflen,
    1037              :                                          f_rng, p_rng)) != 0) {
    1038            0 :             mbedtls_pk_free(pk);
    1039              :         }
    1040              : 
    1041            0 :         mbedtls_pem_free(&pem);
    1042            0 :         return ret;
    1043          181 :     } else if (ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) {
    1044            0 :         return MBEDTLS_ERR_PK_PASSWORD_MISMATCH;
    1045          181 :     } else if (ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) {
    1046            0 :         return MBEDTLS_ERR_PK_PASSWORD_REQUIRED;
    1047          181 :     } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
    1048            0 :         return ret;
    1049              :     }
    1050              : #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
    1051              : 
    1052              :     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
    1053          181 :     if (key[keylen - 1] != '\0') {
    1054            0 :         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
    1055              :     } else {
    1056          181 :         ret = mbedtls_pem_read_buffer(&pem,
    1057              :                                       PEM_BEGIN_PRIVATE_KEY_PKCS8, PEM_END_PRIVATE_KEY_PKCS8,
    1058              :                                       key, NULL, 0, &len);
    1059              :     }
    1060          181 :     if (ret == 0) {
    1061          181 :         if ((ret = pk_parse_key_pkcs8_unencrypted_der(pk,
    1062          181 :                                                       pem.buf, pem.buflen, f_rng, p_rng)) != 0) {
    1063            0 :             mbedtls_pk_free(pk);
    1064              :         }
    1065              : 
    1066          181 :         mbedtls_pem_free(&pem);
    1067          181 :         return ret;
    1068            0 :     } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
    1069            0 :         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            0 :     ret = pk_parse_key_pkcs8_unencrypted_der(pk, key, keylen, f_rng, p_rng);
    1135            0 :     if (ret == 0) {
    1136            0 :         return 0;
    1137              :     }
    1138              : 
    1139            0 :     mbedtls_pk_free(pk);
    1140            0 :     mbedtls_pk_init(pk);
    1141              : 
    1142              : #if defined(MBEDTLS_RSA_C)
    1143              : 
    1144            0 :     pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA);
    1145            0 :     if (mbedtls_pk_setup(pk, pk_info) == 0 &&
    1146            0 :         mbedtls_rsa_parse_key(mbedtls_pk_rsa(*pk), key, keylen) == 0) {
    1147            0 :         return 0;
    1148              :     }
    1149              : 
    1150            0 :     mbedtls_pk_free(pk);
    1151            0 :     mbedtls_pk_init(pk);
    1152              : #endif /* MBEDTLS_RSA_C */
    1153              : 
    1154              : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
    1155            0 :     pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);
    1156            0 :     if (mbedtls_pk_setup(pk, pk_info) == 0 &&
    1157            0 :         pk_parse_key_sec1_der(pk,
    1158              :                               key, keylen, f_rng, p_rng) == 0) {
    1159            0 :         return 0;
    1160              :     }
    1161            0 :     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            0 :     return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
    1175              : }
    1176              : 
    1177              : /*
    1178              :  * Parse a public key
    1179              :  */
    1180           10 : int mbedtls_pk_parse_public_key(mbedtls_pk_context *ctx,
    1181              :                                 const unsigned char *key, size_t keylen)
    1182              : {
    1183           10 :     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           10 :     if (keylen == 0) {
    1194            0 :         return MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
    1195              :     }
    1196              : 
    1197              : #if defined(MBEDTLS_PEM_PARSE_C)
    1198           10 :     mbedtls_pem_init(&pem);
    1199              : #if defined(MBEDTLS_RSA_C)
    1200              :     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
    1201           10 :     if (key[keylen - 1] != '\0') {
    1202           10 :         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
    1203              :     } else {
    1204            0 :         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           10 :     if (ret == 0) {
    1210            0 :         p = pem.buf;
    1211            0 :         if ((pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == NULL) {
    1212            0 :             mbedtls_pem_free(&pem);
    1213            0 :             return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;
    1214              :         }
    1215              : 
    1216            0 :         if ((ret = mbedtls_pk_setup(ctx, pk_info)) != 0) {
    1217            0 :             mbedtls_pem_free(&pem);
    1218            0 :             return ret;
    1219              :         }
    1220              : 
    1221            0 :         if ((ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*ctx), p, pem.buflen)) != 0) {
    1222            0 :             mbedtls_pk_free(ctx);
    1223              :         }
    1224              : 
    1225            0 :         mbedtls_pem_free(&pem);
    1226            0 :         return ret;
    1227           10 :     } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
    1228            0 :         mbedtls_pem_free(&pem);
    1229            0 :         return ret;
    1230              :     }
    1231              : #endif /* MBEDTLS_RSA_C */
    1232              : 
    1233              :     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
    1234           10 :     if (key[keylen - 1] != '\0') {
    1235           10 :         ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
    1236              :     } else {
    1237            0 :         ret = mbedtls_pem_read_buffer(&pem,
    1238              :                                       PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY,
    1239              :                                       key, NULL, 0, &len);
    1240              :     }
    1241              : 
    1242           10 :     if (ret == 0) {
    1243              :         /*
    1244              :          * Was PEM encoded
    1245              :          */
    1246            0 :         p = pem.buf;
    1247              : 
    1248            0 :         ret = mbedtls_pk_parse_subpubkey(&p, p + pem.buflen, ctx);
    1249            0 :         mbedtls_pem_free(&pem);
    1250            0 :         return ret;
    1251           10 :     } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
    1252            0 :         mbedtls_pem_free(&pem);
    1253            0 :         return ret;
    1254              :     }
    1255           10 :     mbedtls_pem_free(&pem);
    1256              : #endif /* MBEDTLS_PEM_PARSE_C */
    1257              : 
    1258              : #if defined(MBEDTLS_RSA_C)
    1259           10 :     if ((pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA)) == NULL) {
    1260            0 :         return MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;
    1261              :     }
    1262              : 
    1263           10 :     if ((ret = mbedtls_pk_setup(ctx, pk_info)) != 0) {
    1264            0 :         return ret;
    1265              :     }
    1266              : 
    1267           10 :     p = (unsigned char *) key;
    1268           10 :     ret = mbedtls_rsa_parse_pubkey(mbedtls_pk_rsa(*ctx), p, keylen);
    1269           10 :     if (ret == 0) {
    1270            0 :         return ret;
    1271              :     }
    1272           10 :     mbedtls_pk_free(ctx);
    1273           10 :     if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
    1274            0 :         return ret;
    1275              :     }
    1276              : #endif /* MBEDTLS_RSA_C */
    1277           10 :     p = (unsigned char *) key;
    1278              : 
    1279           10 :     ret = mbedtls_pk_parse_subpubkey(&p, p + keylen, ctx);
    1280              : 
    1281           10 :     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 */
        

Generated by: LCOV version 2.0-1