/src/libspdm/os_stub/mbedtlslib/mbedtls/library/x509write.c
Line | Count | Source (jump to first uncovered line) |
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 | 0 | do \ |
33 | 0 | { \ |
34 | 0 | if (a > SIZE_MAX - (b)) \ |
35 | 0 | { \ |
36 | 0 | return MBEDTLS_ERR_X509_BAD_INPUT_DATA; \ |
37 | 0 | } \ |
38 | 0 | a += b; \ |
39 | 0 | } while (0) |
40 | | |
41 | | int mbedtls_x509_write_set_san_common(mbedtls_asn1_named_data **extensions, |
42 | | const mbedtls_x509_san_list *san_list) |
43 | 0 | { |
44 | 0 | int ret = 0; |
45 | 0 | const mbedtls_x509_san_list *cur; |
46 | 0 | unsigned char *buf; |
47 | 0 | unsigned char *p; |
48 | 0 | 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 | 0 | case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: |
57 | 0 | case MBEDTLS_X509_SAN_IP_ADDRESS: |
58 | 0 | 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 | 0 | { |
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 | 0 | } |
78 | 0 | CHECK_OVERFLOW_ADD(buflen, 4 + 1); |
79 | 0 | break; |
80 | 0 | } |
81 | 0 | default: |
82 | | /* Not supported - return. */ |
83 | 0 | return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; |
84 | 0 | } |
85 | 0 | } |
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 | 0 | } |
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 | 0 | case MBEDTLS_X509_SAN_RFC822_NAME: |
105 | 0 | case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER: |
106 | 0 | case MBEDTLS_X509_SAN_IP_ADDRESS: |
107 | 0 | { |
108 | 0 | const unsigned char *unstructured_name = |
109 | 0 | (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 | 0 | mbedtls_asn1_write_raw_buffer( |
114 | 0 | &p, buf, |
115 | 0 | unstructured_name, unstructured_name_len)); |
116 | 0 | MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len, mbedtls_asn1_write_len( |
117 | 0 | &p, buf, unstructured_name_len)); |
118 | 0 | MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len, |
119 | 0 | mbedtls_asn1_write_tag( |
120 | 0 | &p, buf, |
121 | 0 | MBEDTLS_ASN1_CONTEXT_SPECIFIC | cur->node.type)); |
122 | 0 | } |
123 | 0 | break; |
124 | 0 | case MBEDTLS_X509_SAN_DIRECTORY_NAME: |
125 | 0 | MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len, |
126 | 0 | mbedtls_x509_write_names(&p, buf, |
127 | 0 | (mbedtls_asn1_named_data *) & |
128 | 0 | cur->node |
129 | 0 | .san.directory_name)); |
130 | 0 | MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len, |
131 | 0 | mbedtls_asn1_write_len(&p, buf, single_san_len)); |
132 | 0 | MBEDTLS_ASN1_CHK_CLEANUP_ADD(single_san_len, |
133 | 0 | mbedtls_asn1_write_tag(&p, buf, |
134 | 0 | MBEDTLS_ASN1_CONTEXT_SPECIFIC | |
135 | 0 | MBEDTLS_ASN1_CONSTRUCTED | |
136 | 0 | 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 | 0 | } |
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 | 0 | } |
149 | 0 | len += single_san_len; |
150 | 0 | } |
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 | 0 | mbedtls_asn1_write_tag(&p, buf, |
155 | 0 | MBEDTLS_ASN1_CONSTRUCTED | |
156 | 0 | MBEDTLS_ASN1_SEQUENCE)); |
157 | | |
158 | 0 | ret = mbedtls_x509_set_extension(extensions, |
159 | 0 | MBEDTLS_OID_SUBJECT_ALT_NAME, |
160 | 0 | MBEDTLS_OID_SIZE(MBEDTLS_OID_SUBJECT_ALT_NAME), |
161 | 0 | 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 | 0 | } |
169 | 0 | cleanup: |
170 | 0 | mbedtls_free(buf); |
171 | 0 | return ret; |
172 | 0 | } |
173 | | |
174 | | #endif /* MBEDTLS_X509_CSR_WRITE_C || MBEDTLS_X509_CRT_WRITE_C */ |