LCOV - code coverage report
Current view: top level - os_stub/mbedtlslib/mbedtls/library - x509write.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 59 0
Test Date: 2025-06-29 08:09:00 Functions: 0.0 % 1 0

            Line data    Source code
       1              : /*
       2              :  *  X.509 internal, common functions for writing
       3              :  *
       4              :  *  Copyright The Mbed TLS Contributors
       5              :  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
       6              :  */
       7              : #include "common.h"
       8              : #if defined(MBEDTLS_X509_CSR_WRITE_C) || defined(MBEDTLS_X509_CRT_WRITE_C)
       9              : 
      10              : #include "mbedtls/x509_crt.h"
      11              : #include "x509_internal.h"
      12              : #include "mbedtls/asn1write.h"
      13              : #include "mbedtls/error.h"
      14              : #include "mbedtls/oid.h"
      15              : #include "mbedtls/platform.h"
      16              : #include "mbedtls/platform_util.h"
      17              : 
      18              : #include <string.h>
      19              : #include <stdint.h>
      20              : 
      21              : #if defined(MBEDTLS_PEM_WRITE_C)
      22              : #include "mbedtls/pem.h"
      23              : #endif /* MBEDTLS_PEM_WRITE_C */
      24              : 
      25              : #if defined(MBEDTLS_USE_PSA_CRYPTO)
      26              : #include "psa/crypto.h"
      27              : #include "mbedtls/psa_util.h"
      28              : #include "md_psa.h"
      29              : #endif /* MBEDTLS_USE_PSA_CRYPTO */
      30              : 
      31              : #define CHECK_OVERFLOW_ADD(a, b) \
      32              :     do                         \
      33              :     {                           \
      34              :         if (a > SIZE_MAX - (b)) \
      35              :         { \
      36              :             return MBEDTLS_ERR_X509_BAD_INPUT_DATA; \
      37              :         }                            \
      38              :         a += b; \
      39              :     } while (0)
      40              : 
      41            0 : int mbedtls_x509_write_set_san_common(mbedtls_asn1_named_data **extensions,
      42              :                                       const mbedtls_x509_san_list *san_list)
      43              : {
      44            0 :     int ret = 0;
      45              :     const mbedtls_x509_san_list *cur;
      46              :     unsigned char *buf;
      47              :     unsigned char *p;
      48              :     size_t len;
      49            0 :     size_t buflen = 0;
      50              : 
      51              :     /* Determine the maximum size of the SubjectAltName list */
      52            0 :     for (cur = san_list; cur != NULL; cur = cur->next) {
      53              :         /* Calculate size of the required buffer */
      54            0 :         switch (cur->node.type) {
      55            0 :             case MBEDTLS_X509_SAN_DNS_NAME:
      56              :             case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
      57              :             case MBEDTLS_X509_SAN_IP_ADDRESS:
      58              :             case MBEDTLS_X509_SAN_RFC822_NAME:
      59              :                 /* length of value for each name entry,
      60              :                  * maximum 4 bytes for the length field,
      61              :                  * 1 byte for the tag/type.
      62              :                  */
      63            0 :                 CHECK_OVERFLOW_ADD(buflen, cur->node.san.unstructured_name.len);
      64            0 :                 CHECK_OVERFLOW_ADD(buflen, 4 + 1);
      65            0 :                 break;
      66            0 :             case MBEDTLS_X509_SAN_DIRECTORY_NAME:
      67              :             {
      68            0 :                 const mbedtls_asn1_named_data *chunk = &cur->node.san.directory_name;
      69            0 :                 while (chunk != NULL) {
      70              :                     // Max 4 bytes for length, +1 for tag,
      71              :                     // additional 4 max for length, +1 for tag.
      72              :                     // See x509_write_name for more information.
      73            0 :                     CHECK_OVERFLOW_ADD(buflen, 4 + 1 + 4 + 1);
      74            0 :                     CHECK_OVERFLOW_ADD(buflen, chunk->oid.len);
      75            0 :                     CHECK_OVERFLOW_ADD(buflen, chunk->val.len);
      76            0 :                     chunk = chunk->next;
      77              :                 }
      78            0 :                 CHECK_OVERFLOW_ADD(buflen, 4 + 1);
      79            0 :                 break;
      80              :             }
      81            0 :             default:
      82              :                 /* Not supported - return. */
      83            0 :                 return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
      84              :         }
      85              :     }
      86              : 
      87              :     /* Add the extra length field and tag */
      88            0 :     CHECK_OVERFLOW_ADD(buflen, 4 + 1);
      89              : 
      90              :     /* Allocate buffer */
      91            0 :     buf = mbedtls_calloc(1, buflen);
      92            0 :     if (buf == NULL) {
      93            0 :         return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
      94              :     }
      95            0 :     p = buf + buflen;
      96              : 
      97              :     /* Write ASN.1-based structure */
      98            0 :     cur = san_list;
      99            0 :     len = 0;
     100            0 :     while (cur != NULL) {
     101            0 :         size_t single_san_len = 0;
     102            0 :         switch (cur->node.type) {
     103            0 :             case MBEDTLS_X509_SAN_DNS_NAME:
     104              :             case MBEDTLS_X509_SAN_RFC822_NAME:
     105              :             case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
     106              :             case MBEDTLS_X509_SAN_IP_ADDRESS:
     107              :             {
     108            0 :                 const unsigned char *unstructured_name =
     109              :                     (const unsigned char *) cur->node.san.unstructured_name.p;
     110            0 :                 size_t unstructured_name_len = cur->node.san.unstructured_name.len;
     111              : 
     112            0 :                 MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
     113              :                                              mbedtls_asn1_write_raw_buffer(
     114              :                                                  &p, buf,
     115              :                                                  unstructured_name, unstructured_name_len));
     116            0 :                 MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len, mbedtls_asn1_write_len(
     117              :                                                  &p, buf, unstructured_name_len));
     118            0 :                 MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
     119              :                                              mbedtls_asn1_write_tag(
     120              :                                                  &p, buf,
     121              :                                                  MBEDTLS_ASN1_CONTEXT_SPECIFIC | cur->node.type));
     122              :             }
     123            0 :             break;
     124            0 :             case MBEDTLS_X509_SAN_DIRECTORY_NAME:
     125            0 :                 MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
     126              :                                              mbedtls_x509_write_names(&p, buf,
     127              :                                                                       (mbedtls_asn1_named_data *) &
     128              :                                                                       cur->node
     129              :                                                                       .san.directory_name));
     130            0 :                 MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
     131              :                                              mbedtls_asn1_write_len(&p, buf, single_san_len));
     132            0 :                 MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len,
     133              :                                              mbedtls_asn1_write_tag(&p, buf,
     134              :                                                                     MBEDTLS_ASN1_CONTEXT_SPECIFIC |
     135              :                                                                     MBEDTLS_ASN1_CONSTRUCTED |
     136              :                                                                     MBEDTLS_X509_SAN_DIRECTORY_NAME));
     137            0 :                 break;
     138            0 :             default:
     139              :                 /* Error out on an unsupported SAN */
     140            0 :                 ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
     141            0 :                 goto cleanup;
     142              :         }
     143            0 :         cur = cur->next;
     144              :         /* check for overflow */
     145            0 :         if (len > SIZE_MAX - single_san_len) {
     146            0 :             ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
     147            0 :             goto cleanup;
     148              :         }
     149            0 :         len += single_san_len;
     150              :     }
     151              : 
     152            0 :     MBEDTLS_ASN1_CHK_CLEANUP_ADD(len, mbedtls_asn1_write_len(&p, buf, len));
     153            0 :     MBEDTLS_ASN1_CHK_CLEANUP_ADD(len,
     154              :                                  mbedtls_asn1_write_tag(&p, buf,
     155              :                                                         MBEDTLS_ASN1_CONSTRUCTED |
     156              :                                                         MBEDTLS_ASN1_SEQUENCE));
     157              : 
     158            0 :     ret = mbedtls_x509_set_extension(extensions,
     159              :                                      MBEDTLS_OID_SUBJECT_ALT_NAME,
     160              :                                      MBEDTLS_OID_SIZE(MBEDTLS_OID_SUBJECT_ALT_NAME),
     161              :                                      0,
     162            0 :                                      buf + buflen - len, len);
     163              : 
     164              :     /* If we exceeded the allocated buffer it means that maximum size of the SubjectAltName list
     165              :      * was incorrectly calculated and memory is corrupted. */
     166            0 :     if (p < buf) {
     167            0 :         ret = MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
     168              :     }
     169            0 : cleanup:
     170            0 :     mbedtls_free(buf);
     171            0 :     return ret;
     172              : }
     173              : 
     174              : #endif /* MBEDTLS_X509_CSR_WRITE_C || MBEDTLS_X509_CRT_WRITE_C */
        

Generated by: LCOV version 2.0-1