LCOV - code coverage report
Current view: top level - os_stub/cryptlib_mbedtls/pem - pem.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 60.9 % 87 53
Test Date: 2025-06-29 08:09:00 Functions: 40.0 % 5 2

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2021-2024 DMTF. All rights reserved.
       4              :  *  License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
       5              :  **/
       6              : 
       7              : /** @file
       8              :  * PEM (Privacy Enhanced Mail) format Handler Wrapper Implementation.
       9              :  **/
      10              : 
      11              : #include "internal_crypt_lib.h"
      12              : #include <mbedtls/pem.h>
      13              : #include <mbedtls/pk.h>
      14              : #include <mbedtls/rsa.h>
      15              : #include <mbedtls/ecp.h>
      16              : #include <mbedtls/ecdh.h>
      17              : #include <mbedtls/ecdsa.h>
      18              : 
      19            0 : static size_t ascii_str_len(const char *string)
      20              : {
      21              :     size_t length;
      22              : 
      23            0 :     LIBSPDM_ASSERT(string != NULL);
      24            0 :     if (string == NULL) {
      25            0 :         return 0;
      26              :     }
      27              : 
      28            0 :     for (length = 0; *string != '\0'; string++, length++) {
      29              :         ;
      30              :     }
      31            0 :     return length;
      32              : }
      33              : 
      34              : #if (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT)
      35              : /**
      36              :  * Retrieve the RSA Private key from the password-protected PEM key data.
      37              :  *
      38              :  * @param[in]  pem_data      Pointer to the PEM-encoded key data to be retrieved.
      39              :  * @param[in]  pem_size      size of the PEM key data in bytes.
      40              :  * @param[in]  password     NULL-terminated passphrase used for encrypted PEM key data.
      41              :  * @param[out] rsa_context   Pointer to newly generated RSA context which contain the retrieved
      42              :  *                         RSA private key component. Use libspdm_rsa_free() function to free the
      43              :  *                         resource.
      44              :  *
      45              :  * If pem_data is NULL, then return false.
      46              :  * If rsa_context is NULL, then return false.
      47              :  *
      48              :  * @retval  true   RSA Private key was retrieved successfully.
      49              :  * @retval  false  Invalid PEM key data or incorrect password.
      50              :  *
      51              :  **/
      52           36 : bool libspdm_rsa_get_private_key_from_pem(const uint8_t *pem_data,
      53              :                                           size_t pem_size,
      54              :                                           const char *password,
      55              :                                           void **rsa_context)
      56              : {
      57              :     int ret;
      58              :     mbedtls_pk_context pk;
      59              :     mbedtls_rsa_context *rsa;
      60              :     uint8_t *new_pem_data;
      61              :     size_t password_len;
      62              : 
      63           36 :     if (pem_data == NULL || rsa_context == NULL || pem_size > INT_MAX) {
      64            0 :         return false;
      65              :     }
      66              : 
      67           36 :     new_pem_data = NULL;
      68           36 :     if (pem_data[pem_size - 1] != 0) {
      69           36 :         new_pem_data = allocate_pool(pem_size + 1);
      70           36 :         if (new_pem_data == NULL) {
      71            0 :             return false;
      72              :         }
      73           36 :         libspdm_copy_mem(new_pem_data, pem_size + 1, pem_data, pem_size);
      74           36 :         new_pem_data[pem_size] = 0;
      75           36 :         pem_data = new_pem_data;
      76           36 :         pem_size += 1;
      77              :     }
      78              : 
      79           36 :     mbedtls_pk_init(&pk);
      80              : 
      81           36 :     if (password != NULL) {
      82            0 :         password_len = ascii_str_len(password);
      83              :     } else {
      84           36 :         password_len = 0;
      85              :     }
      86              : 
      87           36 :     ret = mbedtls_pk_parse_key(&pk, pem_data, pem_size,
      88              :                                (const uint8_t *)password, password_len,
      89              :                                libspdm_myrand, NULL);
      90              : 
      91           36 :     if (new_pem_data != NULL) {
      92           36 :         free_pool(new_pem_data);
      93           36 :         new_pem_data = NULL;
      94              :     }
      95              : 
      96           36 :     if (ret != 0) {
      97            0 :         mbedtls_pk_free(&pk);
      98            0 :         return false;
      99              :     }
     100              : 
     101           36 :     if (mbedtls_pk_get_type(&pk) != MBEDTLS_PK_RSA) {
     102            0 :         mbedtls_pk_free(&pk);
     103            0 :         return false;
     104              :     }
     105              : 
     106           36 :     rsa = libspdm_rsa_new();
     107           36 :     if (rsa == NULL) {
     108            0 :         return false;
     109              :     }
     110           36 :     ret = mbedtls_rsa_copy(rsa, mbedtls_pk_rsa(pk));
     111           36 :     if (ret != 0) {
     112            0 :         libspdm_rsa_free(rsa);
     113            0 :         mbedtls_pk_free(&pk);
     114            0 :         return false;
     115              :     }
     116           36 :     mbedtls_pk_free(&pk);
     117              : 
     118           36 :     *rsa_context = rsa;
     119           36 :     return true;
     120              : }
     121              : #endif /* (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT) */
     122              : 
     123              : /**
     124              :  * Retrieve the EC Private key from the password-protected PEM key data.
     125              :  *
     126              :  * @param[in]  pem_data      Pointer to the PEM-encoded key data to be retrieved.
     127              :  * @param[in]  pem_size      size of the PEM key data in bytes.
     128              :  * @param[in]  password     NULL-terminated passphrase used for encrypted PEM key data.
     129              :  * @param[out] ec_context    Pointer to newly generated EC DSA context which contain the retrieved
     130              :  *                         EC private key component. Use libspdm_ec_free() function to free the
     131              :  *                         resource.
     132              :  *
     133              :  * If pem_data is NULL, then return false.
     134              :  * If ec_context is NULL, then return false.
     135              :  *
     136              :  * @retval  true   EC Private key was retrieved successfully.
     137              :  * @retval  false  Invalid PEM key data or incorrect password.
     138              :  *
     139              :  **/
     140          145 : bool libspdm_ec_get_private_key_from_pem(const uint8_t *pem_data, size_t pem_size,
     141              :                                          const char *password,
     142              :                                          void **ec_context)
     143              : {
     144              :     int ret;
     145              :     mbedtls_pk_context pk;
     146              :     mbedtls_ecdh_context *ecdh;
     147              :     uint8_t *new_pem_data;
     148              :     size_t password_len;
     149              : 
     150          145 :     if (pem_data == NULL || ec_context == NULL || pem_size > INT_MAX) {
     151            0 :         return false;
     152              :     }
     153              : 
     154          145 :     new_pem_data = NULL;
     155          145 :     if (pem_data[pem_size - 1] != 0) {
     156          145 :         new_pem_data = allocate_pool(pem_size + 1);
     157          145 :         if (new_pem_data == NULL) {
     158            0 :             return false;
     159              :         }
     160          145 :         libspdm_copy_mem(new_pem_data, pem_size + 1, pem_data, pem_size);
     161          145 :         new_pem_data[pem_size] = 0;
     162          145 :         pem_data = new_pem_data;
     163          145 :         pem_size += 1;
     164              :     }
     165              : 
     166          145 :     mbedtls_pk_init(&pk);
     167              : 
     168          145 :     if (password != NULL) {
     169            0 :         password_len = ascii_str_len(password);
     170              :     } else {
     171          145 :         password_len = 0;
     172              :     }
     173              : 
     174          145 :     ret = mbedtls_pk_parse_key(&pk, pem_data, pem_size,
     175              :                                (const uint8_t *)password, password_len,
     176              :                                libspdm_myrand, NULL);
     177              : 
     178          145 :     if (new_pem_data != NULL) {
     179          145 :         free_pool(new_pem_data);
     180          145 :         new_pem_data = NULL;
     181              :     }
     182              : 
     183          145 :     if (ret != 0) {
     184            0 :         mbedtls_pk_free(&pk);
     185            0 :         return false;
     186              :     }
     187              : 
     188          145 :     if (mbedtls_pk_get_type(&pk) != MBEDTLS_PK_ECKEY) {
     189            0 :         mbedtls_pk_free(&pk);
     190            0 :         return false;
     191              :     }
     192              : 
     193          145 :     ecdh = allocate_zero_pool(sizeof(mbedtls_ecdh_context));
     194          145 :     if (ecdh == NULL) {
     195            0 :         mbedtls_pk_free(&pk);
     196            0 :         return false;
     197              :     }
     198          145 :     mbedtls_ecdh_init(ecdh);
     199              : 
     200          145 :     ret = mbedtls_ecdh_get_params(ecdh, mbedtls_pk_ec(pk),
     201              :                                   MBEDTLS_ECDH_OURS);
     202          145 :     if (ret != 0) {
     203            0 :         mbedtls_ecdh_free(ecdh);
     204            0 :         free_pool(ecdh);
     205            0 :         mbedtls_pk_free(&pk);
     206            0 :         return false;
     207              :     }
     208          145 :     mbedtls_pk_free(&pk);
     209              : 
     210          145 :     *ec_context = ecdh;
     211          145 :     return true;
     212              : }
     213              : 
     214              : /**
     215              :  * Retrieve the Ed Private key from the password-protected PEM key data.
     216              :  *
     217              :  * @param[in]  pem_data      Pointer to the PEM-encoded key data to be retrieved.
     218              :  * @param[in]  pem_size      size of the PEM key data in bytes.
     219              :  * @param[in]  password     NULL-terminated passphrase used for encrypted PEM key data.
     220              :  * @param[out] ecd_context    Pointer to newly generated Ed DSA context which contain the retrieved
     221              :  *                         Ed private key component. Use libspdm_ecd_free() function to free the
     222              :  *                         resource.
     223              :  *
     224              :  * If pem_data is NULL, then return false.
     225              :  * If ecd_context is NULL, then return false.
     226              :  *
     227              :  * @retval  true   Ed Private key was retrieved successfully.
     228              :  * @retval  false  Invalid PEM key data or incorrect password.
     229              :  *
     230              :  **/
     231            0 : bool libspdm_ecd_get_private_key_from_pem(const uint8_t *pem_data,
     232              :                                           size_t pem_size,
     233              :                                           const char *password,
     234              :                                           void **ecd_context)
     235              : {
     236            0 :     return false;
     237              : }
     238              : 
     239              : /**
     240              :  * Retrieve the sm2 Private key from the password-protected PEM key data.
     241              :  *
     242              :  * @param[in]  pem_data      Pointer to the PEM-encoded key data to be retrieved.
     243              :  * @param[in]  pem_size      size of the PEM key data in bytes.
     244              :  * @param[in]  password     NULL-terminated passphrase used for encrypted PEM key data.
     245              :  * @param[out] sm2_context   Pointer to newly generated sm2 context which contain the retrieved
     246              :  *                         sm2 private key component. Use sm2_free() function to free the
     247              :  *                         resource.
     248              :  *
     249              :  * If pem_data is NULL, then return false.
     250              :  * If sm2_context is NULL, then return false.
     251              :  *
     252              :  * @retval  true   sm2 Private key was retrieved successfully.
     253              :  * @retval  false  Invalid PEM key data or incorrect password.
     254              :  *
     255              :  **/
     256            0 : bool libspdm_sm2_get_private_key_from_pem(const uint8_t *pem_data,
     257              :                                           size_t pem_size,
     258              :                                           const char *password,
     259              :                                           void **sm2_context)
     260              : {
     261            0 :     return false;
     262              : }
        

Generated by: LCOV version 2.0-1