1a8e1175bSopenharmony_ci/* BEGIN_HEADER */
2a8e1175bSopenharmony_ci#include "mbedtls/bignum.h"
3a8e1175bSopenharmony_ci#include "mbedtls/x509_crt.h"
4a8e1175bSopenharmony_ci#include "mbedtls/x509_csr.h"
5a8e1175bSopenharmony_ci#include "x509_internal.h"
6a8e1175bSopenharmony_ci#include "mbedtls/pem.h"
7a8e1175bSopenharmony_ci#include "mbedtls/oid.h"
8a8e1175bSopenharmony_ci#include "mbedtls/rsa.h"
9a8e1175bSopenharmony_ci#include "mbedtls/asn1write.h"
10a8e1175bSopenharmony_ci#include "mbedtls/pk.h"
11a8e1175bSopenharmony_ci#include "mbedtls/psa_util.h"
12a8e1175bSopenharmony_ci
13a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C)
14a8e1175bSopenharmony_ciint mbedtls_rsa_decrypt_func(void *ctx, size_t *olen,
15a8e1175bSopenharmony_ci                             const unsigned char *input, unsigned char *output,
16a8e1175bSopenharmony_ci                             size_t output_max_len)
17a8e1175bSopenharmony_ci{
18a8e1175bSopenharmony_ci    return mbedtls_rsa_pkcs1_decrypt((mbedtls_rsa_context *) ctx, NULL, NULL,
19a8e1175bSopenharmony_ci                                     olen, input, output, output_max_len);
20a8e1175bSopenharmony_ci}
21a8e1175bSopenharmony_ciint mbedtls_rsa_sign_func(void *ctx,
22a8e1175bSopenharmony_ci                          int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
23a8e1175bSopenharmony_ci                          mbedtls_md_type_t md_alg, unsigned int hashlen,
24a8e1175bSopenharmony_ci                          const unsigned char *hash, unsigned char *sig)
25a8e1175bSopenharmony_ci{
26a8e1175bSopenharmony_ci    return mbedtls_rsa_pkcs1_sign((mbedtls_rsa_context *) ctx, f_rng, p_rng,
27a8e1175bSopenharmony_ci                                  md_alg, hashlen, hash, sig);
28a8e1175bSopenharmony_ci}
29a8e1175bSopenharmony_cisize_t mbedtls_rsa_key_len_func(void *ctx)
30a8e1175bSopenharmony_ci{
31a8e1175bSopenharmony_ci    return ((const mbedtls_rsa_context *) ctx)->len;
32a8e1175bSopenharmony_ci}
33a8e1175bSopenharmony_ci#endif /* MBEDTLS_RSA_C */
34a8e1175bSopenharmony_ci
35a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
36a8e1175bSopenharmony_ci    defined(MBEDTLS_PEM_WRITE_C) && defined(MBEDTLS_X509_CSR_WRITE_C)
37a8e1175bSopenharmony_cistatic int x509_crt_verifycsr(const unsigned char *buf, size_t buflen)
38a8e1175bSopenharmony_ci{
39a8e1175bSopenharmony_ci    unsigned char hash[PSA_HASH_MAX_SIZE];
40a8e1175bSopenharmony_ci    mbedtls_x509_csr csr;
41a8e1175bSopenharmony_ci    int ret = 0;
42a8e1175bSopenharmony_ci
43a8e1175bSopenharmony_ci    mbedtls_x509_csr_init(&csr);
44a8e1175bSopenharmony_ci
45a8e1175bSopenharmony_ci    if (mbedtls_x509_csr_parse(&csr, buf, buflen) != 0) {
46a8e1175bSopenharmony_ci        ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
47a8e1175bSopenharmony_ci        goto cleanup;
48a8e1175bSopenharmony_ci    }
49a8e1175bSopenharmony_ci
50a8e1175bSopenharmony_ci    psa_algorithm_t psa_alg = mbedtls_md_psa_alg_from_type(csr.sig_md);
51a8e1175bSopenharmony_ci    size_t hash_size = 0;
52a8e1175bSopenharmony_ci    psa_status_t status = psa_hash_compute(psa_alg, csr.cri.p, csr.cri.len,
53a8e1175bSopenharmony_ci                                           hash, PSA_HASH_MAX_SIZE, &hash_size);
54a8e1175bSopenharmony_ci
55a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
56a8e1175bSopenharmony_ci        /* Note: this can't happen except after an internal error */
57a8e1175bSopenharmony_ci        ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
58a8e1175bSopenharmony_ci        goto cleanup;
59a8e1175bSopenharmony_ci    }
60a8e1175bSopenharmony_ci
61a8e1175bSopenharmony_ci    if (mbedtls_pk_verify_ext(csr.sig_pk, csr.sig_opts, &csr.pk,
62a8e1175bSopenharmony_ci                              csr.sig_md, hash, mbedtls_md_get_size_from_type(csr.sig_md),
63a8e1175bSopenharmony_ci                              csr.sig.p, csr.sig.len) != 0) {
64a8e1175bSopenharmony_ci        ret = MBEDTLS_ERR_X509_CERT_VERIFY_FAILED;
65a8e1175bSopenharmony_ci        goto cleanup;
66a8e1175bSopenharmony_ci    }
67a8e1175bSopenharmony_ci
68a8e1175bSopenharmony_cicleanup:
69a8e1175bSopenharmony_ci
70a8e1175bSopenharmony_ci    mbedtls_x509_csr_free(&csr);
71a8e1175bSopenharmony_ci    return ret;
72a8e1175bSopenharmony_ci}
73a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_PEM_WRITE_C && MBEDTLS_X509_CSR_WRITE_C */
74a8e1175bSopenharmony_ci
75a8e1175bSopenharmony_ci#if defined(MBEDTLS_X509_CSR_WRITE_C)
76a8e1175bSopenharmony_ci
77a8e1175bSopenharmony_ci/*
78a8e1175bSopenharmony_ci * The size of this temporary buffer is given by the sequence of functions
79a8e1175bSopenharmony_ci * called hereinafter:
80a8e1175bSopenharmony_ci * - mbedtls_asn1_write_oid()
81a8e1175bSopenharmony_ci *     - 8 bytes for MBEDTLS_OID_EXTENDED_KEY_USAGE raw value
82a8e1175bSopenharmony_ci *     - 1 byte for MBEDTLS_OID_EXTENDED_KEY_USAGE length
83a8e1175bSopenharmony_ci *     - 1 byte for MBEDTLS_ASN1_OID tag
84a8e1175bSopenharmony_ci * - mbedtls_asn1_write_len()
85a8e1175bSopenharmony_ci *     - 1 byte since we're dealing with sizes which are less than 0x80
86a8e1175bSopenharmony_ci * - mbedtls_asn1_write_tag()
87a8e1175bSopenharmony_ci *     - 1 byte
88a8e1175bSopenharmony_ci *
89a8e1175bSopenharmony_ci * This length is fine as long as this function is called using the
90a8e1175bSopenharmony_ci * MBEDTLS_OID_SERVER_AUTH OID. If this is changed in the future, then this
91a8e1175bSopenharmony_ci * buffer's length should be adjusted accordingly.
92a8e1175bSopenharmony_ci * Unfortunately there's no predefined max size for OIDs which can be used
93a8e1175bSopenharmony_ci * to set an overall upper boundary which is always guaranteed.
94a8e1175bSopenharmony_ci */
95a8e1175bSopenharmony_ci#define EXT_KEY_USAGE_TMP_BUF_MAX_LENGTH    12
96a8e1175bSopenharmony_ci
97a8e1175bSopenharmony_cistatic int csr_set_extended_key_usage(mbedtls_x509write_csr *ctx,
98a8e1175bSopenharmony_ci                                      const char *oid, size_t oid_len)
99a8e1175bSopenharmony_ci{
100a8e1175bSopenharmony_ci    unsigned char buf[EXT_KEY_USAGE_TMP_BUF_MAX_LENGTH] = { 0 };
101a8e1175bSopenharmony_ci    unsigned char *p = buf + sizeof(buf);
102a8e1175bSopenharmony_ci    int ret;
103a8e1175bSopenharmony_ci    size_t len = 0;
104a8e1175bSopenharmony_ci
105a8e1175bSopenharmony_ci    /*
106a8e1175bSopenharmony_ci     * Following functions fail anyway if the temporary buffer is not large,
107a8e1175bSopenharmony_ci     * but we set an extra check here to emphasize a possible source of errors
108a8e1175bSopenharmony_ci     */
109a8e1175bSopenharmony_ci    if (oid_len > EXT_KEY_USAGE_TMP_BUF_MAX_LENGTH) {
110a8e1175bSopenharmony_ci        return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
111a8e1175bSopenharmony_ci    }
112a8e1175bSopenharmony_ci
113a8e1175bSopenharmony_ci    MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(&p, buf, oid, oid_len));
114a8e1175bSopenharmony_ci    MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, buf, ret));
115a8e1175bSopenharmony_ci    MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, buf,
116a8e1175bSopenharmony_ci                                                     MBEDTLS_ASN1_CONSTRUCTED |
117a8e1175bSopenharmony_ci                                                     MBEDTLS_ASN1_SEQUENCE));
118a8e1175bSopenharmony_ci
119a8e1175bSopenharmony_ci    ret = mbedtls_x509write_csr_set_extension(ctx,
120a8e1175bSopenharmony_ci                                              MBEDTLS_OID_EXTENDED_KEY_USAGE,
121a8e1175bSopenharmony_ci                                              MBEDTLS_OID_SIZE(MBEDTLS_OID_EXTENDED_KEY_USAGE),
122a8e1175bSopenharmony_ci                                              0,
123a8e1175bSopenharmony_ci                                              p,
124a8e1175bSopenharmony_ci                                              len);
125a8e1175bSopenharmony_ci
126a8e1175bSopenharmony_ci    return ret;
127a8e1175bSopenharmony_ci}
128a8e1175bSopenharmony_ci#endif  /* MBEDTLS_X509_CSR_WRITE_C */
129a8e1175bSopenharmony_ci
130a8e1175bSopenharmony_ci/* Due to inconsistencies in the input size limits applied by different
131a8e1175bSopenharmony_ci * library functions, some write-parse tests may fail. */
132a8e1175bSopenharmony_ci#define MAY_FAIL_GET_NAME       0x0001
133a8e1175bSopenharmony_ci#define MAY_FAIL_DN_GETS        0x0002
134a8e1175bSopenharmony_ci
135a8e1175bSopenharmony_ci/* END_HEADER */
136a8e1175bSopenharmony_ci
137a8e1175bSopenharmony_ci/* BEGIN_DEPENDENCIES
138a8e1175bSopenharmony_ci * depends_on:MBEDTLS_FS_IO:MBEDTLS_PK_PARSE_C
139a8e1175bSopenharmony_ci * END_DEPENDENCIES
140a8e1175bSopenharmony_ci */
141a8e1175bSopenharmony_ci
142a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_PEM_WRITE_C:MBEDTLS_X509_CSR_WRITE_C */
143a8e1175bSopenharmony_civoid x509_csr_check(char *key_file, char *cert_req_check_file, int md_type,
144a8e1175bSopenharmony_ci                    int key_usage, int set_key_usage, int cert_type,
145a8e1175bSopenharmony_ci                    int set_cert_type, int set_extension)
146a8e1175bSopenharmony_ci{
147a8e1175bSopenharmony_ci    mbedtls_pk_context key;
148a8e1175bSopenharmony_ci    mbedtls_x509write_csr req;
149a8e1175bSopenharmony_ci    unsigned char buf[4096];
150a8e1175bSopenharmony_ci    int ret;
151a8e1175bSopenharmony_ci#if !defined(MBEDTLS_USE_PSA_CRYPTO)
152a8e1175bSopenharmony_ci    unsigned char check_buf[4000];
153a8e1175bSopenharmony_ci    FILE *f;
154a8e1175bSopenharmony_ci    size_t olen = 0;
155a8e1175bSopenharmony_ci#endif /* !MBEDTLS_USE_PSA_CRYPTO */
156a8e1175bSopenharmony_ci    size_t pem_len = 0, buf_index;
157a8e1175bSopenharmony_ci    int der_len = -1;
158a8e1175bSopenharmony_ci    const char *subject_name = "C=NL,O=PolarSSL,CN=PolarSSL Server 1";
159a8e1175bSopenharmony_ci    mbedtls_test_rnd_pseudo_info rnd_info;
160a8e1175bSopenharmony_ci    mbedtls_x509_san_list san_ip;
161a8e1175bSopenharmony_ci    mbedtls_x509_san_list san_dns;
162a8e1175bSopenharmony_ci    mbedtls_x509_san_list san_uri;
163a8e1175bSopenharmony_ci    mbedtls_x509_san_list san_mail;
164a8e1175bSopenharmony_ci    mbedtls_x509_san_list san_dn;
165a8e1175bSopenharmony_ci    mbedtls_x509_san_list *san_list = NULL;
166a8e1175bSopenharmony_ci    mbedtls_asn1_named_data *ext_san_dirname = NULL;
167a8e1175bSopenharmony_ci
168a8e1175bSopenharmony_ci    const char san_ip_name[] = { 0x7f, 0x00, 0x00, 0x01 }; // 127.0.0.1
169a8e1175bSopenharmony_ci    const char *san_dns_name = "example.com";
170a8e1175bSopenharmony_ci    const char *san_dn_name = "C=UK,O=Mbed TLS,CN=Mbed TLS directoryName SAN";
171a8e1175bSopenharmony_ci    const char *san_mail_name = "mail@example.com";
172a8e1175bSopenharmony_ci    const char *san_uri_name = "http://pki.example.com";
173a8e1175bSopenharmony_ci
174a8e1175bSopenharmony_ci    san_mail.node.type = MBEDTLS_X509_SAN_RFC822_NAME;
175a8e1175bSopenharmony_ci    san_mail.node.san.unstructured_name.p = (unsigned char *) san_mail_name;
176a8e1175bSopenharmony_ci    san_mail.node.san.unstructured_name.len = strlen(san_mail_name);
177a8e1175bSopenharmony_ci    san_mail.next = NULL;
178a8e1175bSopenharmony_ci
179a8e1175bSopenharmony_ci    san_dns.node.type = MBEDTLS_X509_SAN_DNS_NAME;
180a8e1175bSopenharmony_ci    san_dns.node.san.unstructured_name.p = (unsigned char *) san_dns_name;
181a8e1175bSopenharmony_ci    san_dns.node.san.unstructured_name.len = strlen(san_dns_name);
182a8e1175bSopenharmony_ci    san_dns.next = &san_mail;
183a8e1175bSopenharmony_ci
184a8e1175bSopenharmony_ci    san_dn.node.type = MBEDTLS_X509_SAN_DIRECTORY_NAME;
185a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_x509_string_to_names(&ext_san_dirname,
186a8e1175bSopenharmony_ci                                             san_dn_name) == 0);
187a8e1175bSopenharmony_ci    san_dn.node.san.directory_name = *ext_san_dirname;
188a8e1175bSopenharmony_ci    san_dn.next = &san_dns;
189a8e1175bSopenharmony_ci
190a8e1175bSopenharmony_ci    san_ip.node.type = MBEDTLS_X509_SAN_IP_ADDRESS;
191a8e1175bSopenharmony_ci    san_ip.node.san.unstructured_name.p = (unsigned char *) san_ip_name;
192a8e1175bSopenharmony_ci    san_ip.node.san.unstructured_name.len = sizeof(san_ip_name);
193a8e1175bSopenharmony_ci    san_ip.next = &san_dn;
194a8e1175bSopenharmony_ci
195a8e1175bSopenharmony_ci    san_uri.node.type = MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER;
196a8e1175bSopenharmony_ci    san_uri.node.san.unstructured_name.p = (unsigned char *) san_uri_name;
197a8e1175bSopenharmony_ci    san_uri.node.san.unstructured_name.len = strlen(san_uri_name);
198a8e1175bSopenharmony_ci    san_uri.next = &san_ip;
199a8e1175bSopenharmony_ci
200a8e1175bSopenharmony_ci    san_list = &san_uri;
201a8e1175bSopenharmony_ci
202a8e1175bSopenharmony_ci    memset(&rnd_info, 0x2a, sizeof(mbedtls_test_rnd_pseudo_info));
203a8e1175bSopenharmony_ci
204a8e1175bSopenharmony_ci    mbedtls_x509write_csr_init(&req);
205a8e1175bSopenharmony_ci    mbedtls_pk_init(&key);
206a8e1175bSopenharmony_ci    MD_OR_USE_PSA_INIT();
207a8e1175bSopenharmony_ci
208a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_pk_parse_keyfile(&key, key_file, NULL,
209a8e1175bSopenharmony_ci                                         mbedtls_test_rnd_std_rand, NULL) == 0);
210a8e1175bSopenharmony_ci
211a8e1175bSopenharmony_ci    mbedtls_x509write_csr_set_md_alg(&req, md_type);
212a8e1175bSopenharmony_ci    mbedtls_x509write_csr_set_key(&req, &key);
213a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_x509write_csr_set_subject_name(&req, subject_name) == 0);
214a8e1175bSopenharmony_ci    if (set_key_usage != 0) {
215a8e1175bSopenharmony_ci        TEST_ASSERT(mbedtls_x509write_csr_set_key_usage(&req, key_usage) == 0);
216a8e1175bSopenharmony_ci    }
217a8e1175bSopenharmony_ci    if (set_cert_type != 0) {
218a8e1175bSopenharmony_ci        TEST_ASSERT(mbedtls_x509write_csr_set_ns_cert_type(&req, cert_type) == 0);
219a8e1175bSopenharmony_ci    }
220a8e1175bSopenharmony_ci    if (set_extension != 0) {
221a8e1175bSopenharmony_ci        TEST_ASSERT(csr_set_extended_key_usage(&req, MBEDTLS_OID_SERVER_AUTH,
222a8e1175bSopenharmony_ci                                               MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH)) == 0);
223a8e1175bSopenharmony_ci
224a8e1175bSopenharmony_ci        TEST_ASSERT(mbedtls_x509write_csr_set_subject_alternative_name(&req, san_list) == 0);
225a8e1175bSopenharmony_ci    }
226a8e1175bSopenharmony_ci
227a8e1175bSopenharmony_ci    ret = mbedtls_x509write_csr_pem(&req, buf, sizeof(buf),
228a8e1175bSopenharmony_ci                                    mbedtls_test_rnd_pseudo_rand, &rnd_info);
229a8e1175bSopenharmony_ci    TEST_ASSERT(ret == 0);
230a8e1175bSopenharmony_ci
231a8e1175bSopenharmony_ci    pem_len = strlen((char *) buf);
232a8e1175bSopenharmony_ci
233a8e1175bSopenharmony_ci    for (buf_index = pem_len; buf_index < sizeof(buf); ++buf_index) {
234a8e1175bSopenharmony_ci        TEST_ASSERT(buf[buf_index] == 0);
235a8e1175bSopenharmony_ci    }
236a8e1175bSopenharmony_ci
237a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
238a8e1175bSopenharmony_ci    // When using PSA crypto, RNG isn't controllable, so cert_req_check_file can't be used
239a8e1175bSopenharmony_ci    (void) cert_req_check_file;
240a8e1175bSopenharmony_ci    buf[pem_len] = '\0';
241a8e1175bSopenharmony_ci    TEST_ASSERT(x509_crt_verifycsr(buf, pem_len + 1) == 0);
242a8e1175bSopenharmony_ci#else
243a8e1175bSopenharmony_ci    f = fopen(cert_req_check_file, "r");
244a8e1175bSopenharmony_ci    TEST_ASSERT(f != NULL);
245a8e1175bSopenharmony_ci    olen = fread(check_buf, 1, sizeof(check_buf), f);
246a8e1175bSopenharmony_ci    fclose(f);
247a8e1175bSopenharmony_ci
248a8e1175bSopenharmony_ci    TEST_ASSERT(olen >= pem_len - 1);
249a8e1175bSopenharmony_ci    TEST_ASSERT(memcmp(buf, check_buf, pem_len - 1) == 0);
250a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
251a8e1175bSopenharmony_ci
252a8e1175bSopenharmony_ci    der_len = mbedtls_x509write_csr_der(&req, buf, sizeof(buf),
253a8e1175bSopenharmony_ci                                        mbedtls_test_rnd_pseudo_rand,
254a8e1175bSopenharmony_ci                                        &rnd_info);
255a8e1175bSopenharmony_ci    TEST_ASSERT(der_len >= 0);
256a8e1175bSopenharmony_ci
257a8e1175bSopenharmony_ci    if (der_len == 0) {
258a8e1175bSopenharmony_ci        goto exit;
259a8e1175bSopenharmony_ci    }
260a8e1175bSopenharmony_ci
261a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
262a8e1175bSopenharmony_ci    // When using PSA crypto, RNG isn't controllable, result length isn't
263a8e1175bSopenharmony_ci    // deterministic over multiple runs, removing a single byte isn't enough to
264a8e1175bSopenharmony_ci    // go into the MBEDTLS_ERR_ASN1_BUF_TOO_SMALL error case
265a8e1175bSopenharmony_ci    der_len /= 2;
266a8e1175bSopenharmony_ci#else
267a8e1175bSopenharmony_ci    der_len -= 1;
268a8e1175bSopenharmony_ci#endif
269a8e1175bSopenharmony_ci    ret = mbedtls_x509write_csr_der(&req, buf, (size_t) (der_len),
270a8e1175bSopenharmony_ci                                    mbedtls_test_rnd_pseudo_rand, &rnd_info);
271a8e1175bSopenharmony_ci    TEST_ASSERT(ret == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
272a8e1175bSopenharmony_ci
273a8e1175bSopenharmony_ciexit:
274a8e1175bSopenharmony_ci    mbedtls_asn1_free_named_data_list(&ext_san_dirname);
275a8e1175bSopenharmony_ci    mbedtls_x509write_csr_free(&req);
276a8e1175bSopenharmony_ci    mbedtls_pk_free(&key);
277a8e1175bSopenharmony_ci    MD_OR_USE_PSA_DONE();
278a8e1175bSopenharmony_ci}
279a8e1175bSopenharmony_ci/* END_CASE */
280a8e1175bSopenharmony_ci
281a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_PEM_WRITE_C:MBEDTLS_X509_CSR_WRITE_C:MBEDTLS_USE_PSA_CRYPTO */
282a8e1175bSopenharmony_civoid x509_csr_check_opaque(char *key_file, int md_type, int key_usage,
283a8e1175bSopenharmony_ci                           int cert_type)
284a8e1175bSopenharmony_ci{
285a8e1175bSopenharmony_ci    mbedtls_pk_context key;
286a8e1175bSopenharmony_ci    mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
287a8e1175bSopenharmony_ci    psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
288a8e1175bSopenharmony_ci    mbedtls_x509write_csr req;
289a8e1175bSopenharmony_ci    unsigned char buf[4096];
290a8e1175bSopenharmony_ci    int ret;
291a8e1175bSopenharmony_ci    size_t pem_len = 0;
292a8e1175bSopenharmony_ci    const char *subject_name = "C=NL,O=PolarSSL,CN=PolarSSL Server 1";
293a8e1175bSopenharmony_ci    mbedtls_test_rnd_pseudo_info rnd_info;
294a8e1175bSopenharmony_ci
295a8e1175bSopenharmony_ci    mbedtls_x509write_csr_init(&req);
296a8e1175bSopenharmony_ci    MD_OR_USE_PSA_INIT();
297a8e1175bSopenharmony_ci
298a8e1175bSopenharmony_ci    memset(&rnd_info, 0x2a, sizeof(mbedtls_test_rnd_pseudo_info));
299a8e1175bSopenharmony_ci
300a8e1175bSopenharmony_ci    mbedtls_pk_init(&key);
301a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_pk_parse_keyfile(&key, key_file, NULL,
302a8e1175bSopenharmony_ci                                         mbedtls_test_rnd_std_rand, NULL) == 0);
303a8e1175bSopenharmony_ci
304a8e1175bSopenharmony_ci    /* Turn the PK context into an opaque one. */
305a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_pk_get_psa_attributes(&key, PSA_KEY_USAGE_SIGN_HASH, &key_attr), 0);
306a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_pk_import_into_psa(&key, &key_attr, &key_id), 0);
307a8e1175bSopenharmony_ci    mbedtls_pk_free(&key);
308a8e1175bSopenharmony_ci    mbedtls_pk_init(&key);
309a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_pk_setup_opaque(&key, key_id), 0);
310a8e1175bSopenharmony_ci
311a8e1175bSopenharmony_ci    mbedtls_x509write_csr_set_md_alg(&req, md_type);
312a8e1175bSopenharmony_ci    mbedtls_x509write_csr_set_key(&req, &key);
313a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_x509write_csr_set_subject_name(&req, subject_name) == 0);
314a8e1175bSopenharmony_ci    if (key_usage != 0) {
315a8e1175bSopenharmony_ci        TEST_ASSERT(mbedtls_x509write_csr_set_key_usage(&req, key_usage) == 0);
316a8e1175bSopenharmony_ci    }
317a8e1175bSopenharmony_ci    if (cert_type != 0) {
318a8e1175bSopenharmony_ci        TEST_ASSERT(mbedtls_x509write_csr_set_ns_cert_type(&req, cert_type) == 0);
319a8e1175bSopenharmony_ci    }
320a8e1175bSopenharmony_ci
321a8e1175bSopenharmony_ci    ret = mbedtls_x509write_csr_pem(&req, buf, sizeof(buf) - 1,
322a8e1175bSopenharmony_ci                                    mbedtls_test_rnd_pseudo_rand, &rnd_info);
323a8e1175bSopenharmony_ci
324a8e1175bSopenharmony_ci    TEST_ASSERT(ret == 0);
325a8e1175bSopenharmony_ci
326a8e1175bSopenharmony_ci    pem_len = strlen((char *) buf);
327a8e1175bSopenharmony_ci    buf[pem_len] = '\0';
328a8e1175bSopenharmony_ci    TEST_ASSERT(x509_crt_verifycsr(buf, pem_len + 1) == 0);
329a8e1175bSopenharmony_ci
330a8e1175bSopenharmony_ci
331a8e1175bSopenharmony_ciexit:
332a8e1175bSopenharmony_ci    mbedtls_x509write_csr_free(&req);
333a8e1175bSopenharmony_ci    mbedtls_pk_free(&key);
334a8e1175bSopenharmony_ci    psa_destroy_key(key_id);
335a8e1175bSopenharmony_ci    MD_OR_USE_PSA_DONE();
336a8e1175bSopenharmony_ci}
337a8e1175bSopenharmony_ci/* END_CASE */
338a8e1175bSopenharmony_ci
339a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_PEM_WRITE_C:MBEDTLS_X509_CRT_WRITE_C:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_MD_CAN_SHA1 */
340a8e1175bSopenharmony_civoid x509_crt_check(char *subject_key_file, char *subject_pwd,
341a8e1175bSopenharmony_ci                    char *subject_name, char *issuer_key_file,
342a8e1175bSopenharmony_ci                    char *issuer_pwd, char *issuer_name,
343a8e1175bSopenharmony_ci                    data_t *serial_arg, char *not_before, char *not_after,
344a8e1175bSopenharmony_ci                    int md_type, int key_usage, int set_key_usage,
345a8e1175bSopenharmony_ci                    char *ext_key_usage,
346a8e1175bSopenharmony_ci                    int cert_type, int set_cert_type, int auth_ident,
347a8e1175bSopenharmony_ci                    int ver, char *cert_check_file, int pk_wrap, int is_ca,
348a8e1175bSopenharmony_ci                    char *cert_verify_file, int set_subjectAltNames)
349a8e1175bSopenharmony_ci{
350a8e1175bSopenharmony_ci    mbedtls_pk_context subject_key, issuer_key, issuer_key_alt;
351a8e1175bSopenharmony_ci    mbedtls_pk_context *key = &issuer_key;
352a8e1175bSopenharmony_ci
353a8e1175bSopenharmony_ci    mbedtls_x509write_cert crt;
354a8e1175bSopenharmony_ci    unsigned char buf[4096];
355a8e1175bSopenharmony_ci    unsigned char check_buf[5000];
356a8e1175bSopenharmony_ci    unsigned char *p, *end;
357a8e1175bSopenharmony_ci    unsigned char tag, sz;
358a8e1175bSopenharmony_ci#if defined(MBEDTLS_TEST_DEPRECATED) && defined(MBEDTLS_BIGNUM_C)
359a8e1175bSopenharmony_ci    mbedtls_mpi serial_mpi;
360a8e1175bSopenharmony_ci#endif
361a8e1175bSopenharmony_ci    int ret, before_tag, after_tag;
362a8e1175bSopenharmony_ci    size_t olen = 0, pem_len = 0, buf_index = 0;
363a8e1175bSopenharmony_ci    int der_len = -1;
364a8e1175bSopenharmony_ci    FILE *f;
365a8e1175bSopenharmony_ci    mbedtls_test_rnd_pseudo_info rnd_info;
366a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
367a8e1175bSopenharmony_ci    mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
368a8e1175bSopenharmony_ci    psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
369a8e1175bSopenharmony_ci#endif
370a8e1175bSopenharmony_ci    mbedtls_pk_type_t issuer_key_type;
371a8e1175bSopenharmony_ci    mbedtls_x509_san_list san_ip;
372a8e1175bSopenharmony_ci    mbedtls_x509_san_list san_dns;
373a8e1175bSopenharmony_ci    mbedtls_x509_san_list san_uri;
374a8e1175bSopenharmony_ci    mbedtls_x509_san_list san_mail;
375a8e1175bSopenharmony_ci    mbedtls_x509_san_list san_dn;
376a8e1175bSopenharmony_ci    mbedtls_asn1_named_data *ext_san_dirname = NULL;
377a8e1175bSopenharmony_ci    const char san_ip_name[] = { 0x01, 0x02, 0x03, 0x04 };
378a8e1175bSopenharmony_ci    const char *san_dns_name = "example.com";
379a8e1175bSopenharmony_ci    const char *san_dn_name = "C=UK,O=Mbed TLS,CN=SubjectAltName test";
380a8e1175bSopenharmony_ci    const char *san_mail_name = "mail@example.com";
381a8e1175bSopenharmony_ci    const char *san_uri_name = "http://pki.example.com";
382a8e1175bSopenharmony_ci    mbedtls_x509_san_list *san_list = NULL;
383a8e1175bSopenharmony_ci
384a8e1175bSopenharmony_ci    if (set_subjectAltNames) {
385a8e1175bSopenharmony_ci        san_mail.node.type = MBEDTLS_X509_SAN_RFC822_NAME;
386a8e1175bSopenharmony_ci        san_mail.node.san.unstructured_name.p = (unsigned char *) san_mail_name;
387a8e1175bSopenharmony_ci        san_mail.node.san.unstructured_name.len = strlen(san_mail_name);
388a8e1175bSopenharmony_ci        san_mail.next = NULL;
389a8e1175bSopenharmony_ci
390a8e1175bSopenharmony_ci        san_dns.node.type = MBEDTLS_X509_SAN_DNS_NAME;
391a8e1175bSopenharmony_ci        san_dns.node.san.unstructured_name.p = (unsigned char *) san_dns_name;
392a8e1175bSopenharmony_ci        san_dns.node.san.unstructured_name.len = strlen(san_dns_name);
393a8e1175bSopenharmony_ci        san_dns.next = &san_mail;
394a8e1175bSopenharmony_ci
395a8e1175bSopenharmony_ci        san_dn.node.type = MBEDTLS_X509_SAN_DIRECTORY_NAME;
396a8e1175bSopenharmony_ci        TEST_ASSERT(mbedtls_x509_string_to_names(&ext_san_dirname,
397a8e1175bSopenharmony_ci                                                 san_dn_name) == 0);
398a8e1175bSopenharmony_ci        san_dn.node.san.directory_name = *ext_san_dirname;
399a8e1175bSopenharmony_ci        san_dn.next = &san_dns;
400a8e1175bSopenharmony_ci
401a8e1175bSopenharmony_ci        san_ip.node.type = MBEDTLS_X509_SAN_IP_ADDRESS;
402a8e1175bSopenharmony_ci        san_ip.node.san.unstructured_name.p = (unsigned char *) san_ip_name;
403a8e1175bSopenharmony_ci        san_ip.node.san.unstructured_name.len = sizeof(san_ip_name);
404a8e1175bSopenharmony_ci        san_ip.next = &san_dn;
405a8e1175bSopenharmony_ci
406a8e1175bSopenharmony_ci        san_uri.node.type = MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER;
407a8e1175bSopenharmony_ci        san_uri.node.san.unstructured_name.p = (unsigned char *) san_uri_name;
408a8e1175bSopenharmony_ci        san_uri.node.san.unstructured_name.len = strlen(san_uri_name);
409a8e1175bSopenharmony_ci        san_uri.next = &san_ip;
410a8e1175bSopenharmony_ci
411a8e1175bSopenharmony_ci        san_list = &san_uri;
412a8e1175bSopenharmony_ci    }
413a8e1175bSopenharmony_ci
414a8e1175bSopenharmony_ci    memset(&rnd_info, 0x2a, sizeof(mbedtls_test_rnd_pseudo_info));
415a8e1175bSopenharmony_ci#if defined(MBEDTLS_TEST_DEPRECATED) && defined(MBEDTLS_BIGNUM_C)
416a8e1175bSopenharmony_ci    mbedtls_mpi_init(&serial_mpi);
417a8e1175bSopenharmony_ci#endif
418a8e1175bSopenharmony_ci
419a8e1175bSopenharmony_ci    mbedtls_pk_init(&subject_key);
420a8e1175bSopenharmony_ci    mbedtls_pk_init(&issuer_key);
421a8e1175bSopenharmony_ci    mbedtls_pk_init(&issuer_key_alt);
422a8e1175bSopenharmony_ci    mbedtls_x509write_crt_init(&crt);
423a8e1175bSopenharmony_ci    MD_OR_USE_PSA_INIT();
424a8e1175bSopenharmony_ci
425a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_pk_parse_keyfile(&subject_key, subject_key_file,
426a8e1175bSopenharmony_ci                                         subject_pwd, mbedtls_test_rnd_std_rand, NULL) == 0);
427a8e1175bSopenharmony_ci
428a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_pk_parse_keyfile(&issuer_key, issuer_key_file,
429a8e1175bSopenharmony_ci                                         issuer_pwd, mbedtls_test_rnd_std_rand, NULL) == 0);
430a8e1175bSopenharmony_ci
431a8e1175bSopenharmony_ci    issuer_key_type = mbedtls_pk_get_type(&issuer_key);
432a8e1175bSopenharmony_ci
433a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
434a8e1175bSopenharmony_ci    /* For RSA PK contexts, create a copy as an alternative RSA context. */
435a8e1175bSopenharmony_ci    if (pk_wrap == 1 && issuer_key_type == MBEDTLS_PK_RSA) {
436a8e1175bSopenharmony_ci        TEST_ASSERT(mbedtls_pk_setup_rsa_alt(&issuer_key_alt,
437a8e1175bSopenharmony_ci                                             mbedtls_pk_rsa(issuer_key),
438a8e1175bSopenharmony_ci                                             mbedtls_rsa_decrypt_func,
439a8e1175bSopenharmony_ci                                             mbedtls_rsa_sign_func,
440a8e1175bSopenharmony_ci                                             mbedtls_rsa_key_len_func) == 0);
441a8e1175bSopenharmony_ci
442a8e1175bSopenharmony_ci        key = &issuer_key_alt;
443a8e1175bSopenharmony_ci    }
444a8e1175bSopenharmony_ci#endif
445a8e1175bSopenharmony_ci
446a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
447a8e1175bSopenharmony_ci    /* Turn the issuer PK context into an opaque one. */
448a8e1175bSopenharmony_ci    if (pk_wrap == 2) {
449a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_pk_get_psa_attributes(&issuer_key, PSA_KEY_USAGE_SIGN_HASH,
450a8e1175bSopenharmony_ci                                                 &key_attr), 0);
451a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_pk_import_into_psa(&issuer_key, &key_attr, &key_id), 0);
452a8e1175bSopenharmony_ci        mbedtls_pk_free(&issuer_key);
453a8e1175bSopenharmony_ci        mbedtls_pk_init(&issuer_key);
454a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_pk_setup_opaque(&issuer_key, key_id), 0);
455a8e1175bSopenharmony_ci    }
456a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
457a8e1175bSopenharmony_ci
458a8e1175bSopenharmony_ci    if (pk_wrap == 2) {
459a8e1175bSopenharmony_ci        TEST_ASSERT(mbedtls_pk_get_type(&issuer_key) == MBEDTLS_PK_OPAQUE);
460a8e1175bSopenharmony_ci    }
461a8e1175bSopenharmony_ci
462a8e1175bSopenharmony_ci    if (ver != -1) {
463a8e1175bSopenharmony_ci        mbedtls_x509write_crt_set_version(&crt, ver);
464a8e1175bSopenharmony_ci    }
465a8e1175bSopenharmony_ci
466a8e1175bSopenharmony_ci#if defined(MBEDTLS_TEST_DEPRECATED) && defined(MBEDTLS_BIGNUM_C)
467a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_mpi_read_binary(&serial_mpi, serial_arg->x,
468a8e1175bSopenharmony_ci                                        serial_arg->len) == 0);
469a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_x509write_crt_set_serial(&crt, &serial_mpi) == 0);
470a8e1175bSopenharmony_ci#else
471a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_x509write_crt_set_serial_raw(&crt, serial_arg->x,
472a8e1175bSopenharmony_ci                                                     serial_arg->len) == 0);
473a8e1175bSopenharmony_ci#endif
474a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_x509write_crt_set_validity(&crt, not_before,
475a8e1175bSopenharmony_ci                                                   not_after) == 0);
476a8e1175bSopenharmony_ci    mbedtls_x509write_crt_set_md_alg(&crt, md_type);
477a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_x509write_crt_set_issuer_name(&crt, issuer_name) == 0);
478a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_x509write_crt_set_subject_name(&crt, subject_name) == 0);
479a8e1175bSopenharmony_ci    mbedtls_x509write_crt_set_subject_key(&crt, &subject_key);
480a8e1175bSopenharmony_ci
481a8e1175bSopenharmony_ci    mbedtls_x509write_crt_set_issuer_key(&crt, key);
482a8e1175bSopenharmony_ci
483a8e1175bSopenharmony_ci    if (crt.version >= MBEDTLS_X509_CRT_VERSION_3) {
484a8e1175bSopenharmony_ci        /* For the CA case, a path length of -1 means unlimited. */
485a8e1175bSopenharmony_ci        TEST_ASSERT(mbedtls_x509write_crt_set_basic_constraints(&crt, is_ca,
486a8e1175bSopenharmony_ci                                                                (is_ca ? -1 : 0)) == 0);
487a8e1175bSopenharmony_ci        TEST_ASSERT(mbedtls_x509write_crt_set_subject_key_identifier(&crt) == 0);
488a8e1175bSopenharmony_ci        if (auth_ident) {
489a8e1175bSopenharmony_ci            TEST_ASSERT(mbedtls_x509write_crt_set_authority_key_identifier(&crt) == 0);
490a8e1175bSopenharmony_ci        }
491a8e1175bSopenharmony_ci        if (set_key_usage != 0) {
492a8e1175bSopenharmony_ci            TEST_ASSERT(mbedtls_x509write_crt_set_key_usage(&crt, key_usage) == 0);
493a8e1175bSopenharmony_ci        }
494a8e1175bSopenharmony_ci        if (set_cert_type != 0) {
495a8e1175bSopenharmony_ci            TEST_ASSERT(mbedtls_x509write_crt_set_ns_cert_type(&crt, cert_type) == 0);
496a8e1175bSopenharmony_ci        }
497a8e1175bSopenharmony_ci        if (strcmp(ext_key_usage, "NULL") != 0) {
498a8e1175bSopenharmony_ci            mbedtls_asn1_sequence exts[2];
499a8e1175bSopenharmony_ci            memset(exts, 0, sizeof(exts));
500a8e1175bSopenharmony_ci
501a8e1175bSopenharmony_ci#define SET_OID(x, oid)                \
502a8e1175bSopenharmony_ci    do {                               \
503a8e1175bSopenharmony_ci        x.len = MBEDTLS_OID_SIZE(oid); \
504a8e1175bSopenharmony_ci        x.p   = (unsigned char *) oid;   \
505a8e1175bSopenharmony_ci        x.tag = MBEDTLS_ASN1_OID;      \
506a8e1175bSopenharmony_ci    }                                  \
507a8e1175bSopenharmony_ci    while (0)
508a8e1175bSopenharmony_ci
509a8e1175bSopenharmony_ci            if (strcmp(ext_key_usage, "serverAuth") == 0) {
510a8e1175bSopenharmony_ci                SET_OID(exts[0].buf, MBEDTLS_OID_SERVER_AUTH);
511a8e1175bSopenharmony_ci            } else if (strcmp(ext_key_usage, "codeSigning,timeStamping") == 0) {
512a8e1175bSopenharmony_ci                SET_OID(exts[0].buf, MBEDTLS_OID_CODE_SIGNING);
513a8e1175bSopenharmony_ci                exts[0].next = &exts[1];
514a8e1175bSopenharmony_ci                SET_OID(exts[1].buf, MBEDTLS_OID_TIME_STAMPING);
515a8e1175bSopenharmony_ci            }
516a8e1175bSopenharmony_ci            TEST_ASSERT(mbedtls_x509write_crt_set_ext_key_usage(&crt, exts) == 0);
517a8e1175bSopenharmony_ci        }
518a8e1175bSopenharmony_ci    }
519a8e1175bSopenharmony_ci
520a8e1175bSopenharmony_ci    if (set_subjectAltNames) {
521a8e1175bSopenharmony_ci        TEST_ASSERT(mbedtls_x509write_crt_set_subject_alternative_name(&crt, san_list) == 0);
522a8e1175bSopenharmony_ci    }
523a8e1175bSopenharmony_ci    ret = mbedtls_x509write_crt_pem(&crt, buf, sizeof(buf),
524a8e1175bSopenharmony_ci                                    mbedtls_test_rnd_pseudo_rand, &rnd_info);
525a8e1175bSopenharmony_ci    TEST_ASSERT(ret == 0);
526a8e1175bSopenharmony_ci
527a8e1175bSopenharmony_ci    pem_len = strlen((char *) buf);
528a8e1175bSopenharmony_ci
529a8e1175bSopenharmony_ci    // check that the rest of the buffer remains clear
530a8e1175bSopenharmony_ci    for (buf_index = pem_len; buf_index < sizeof(buf); ++buf_index) {
531a8e1175bSopenharmony_ci        TEST_ASSERT(buf[buf_index] == 0);
532a8e1175bSopenharmony_ci    }
533a8e1175bSopenharmony_ci
534a8e1175bSopenharmony_ci    if (issuer_key_type != MBEDTLS_PK_RSA) {
535a8e1175bSopenharmony_ci        mbedtls_x509_crt crt_parse, trusted;
536a8e1175bSopenharmony_ci        uint32_t flags;
537a8e1175bSopenharmony_ci
538a8e1175bSopenharmony_ci        mbedtls_x509_crt_init(&crt_parse);
539a8e1175bSopenharmony_ci        mbedtls_x509_crt_init(&trusted);
540a8e1175bSopenharmony_ci
541a8e1175bSopenharmony_ci        TEST_ASSERT(mbedtls_x509_crt_parse_file(&trusted,
542a8e1175bSopenharmony_ci                                                cert_verify_file) == 0);
543a8e1175bSopenharmony_ci        TEST_ASSERT(mbedtls_x509_crt_parse(&crt_parse,
544a8e1175bSopenharmony_ci                                           buf, sizeof(buf)) == 0);
545a8e1175bSopenharmony_ci
546a8e1175bSopenharmony_ci        ret = mbedtls_x509_crt_verify(&crt_parse, &trusted, NULL, NULL, &flags,
547a8e1175bSopenharmony_ci                                      NULL, NULL);
548a8e1175bSopenharmony_ci
549a8e1175bSopenharmony_ci        mbedtls_x509_crt_free(&crt_parse);
550a8e1175bSopenharmony_ci        mbedtls_x509_crt_free(&trusted);
551a8e1175bSopenharmony_ci
552a8e1175bSopenharmony_ci        TEST_EQUAL(flags, 0);
553a8e1175bSopenharmony_ci        TEST_EQUAL(ret, 0);
554a8e1175bSopenharmony_ci    } else if (*cert_check_file != '\0') {
555a8e1175bSopenharmony_ci        f = fopen(cert_check_file, "r");
556a8e1175bSopenharmony_ci        TEST_ASSERT(f != NULL);
557a8e1175bSopenharmony_ci        olen = fread(check_buf, 1, sizeof(check_buf), f);
558a8e1175bSopenharmony_ci        fclose(f);
559a8e1175bSopenharmony_ci        TEST_ASSERT(olen < sizeof(check_buf));
560a8e1175bSopenharmony_ci
561a8e1175bSopenharmony_ci        TEST_EQUAL(olen, pem_len);
562a8e1175bSopenharmony_ci        TEST_ASSERT(olen >= pem_len - 1);
563a8e1175bSopenharmony_ci        TEST_ASSERT(memcmp(buf, check_buf, pem_len - 1) == 0);
564a8e1175bSopenharmony_ci    }
565a8e1175bSopenharmony_ci
566a8e1175bSopenharmony_ci    der_len = mbedtls_x509write_crt_der(&crt, buf, sizeof(buf),
567a8e1175bSopenharmony_ci                                        mbedtls_test_rnd_pseudo_rand,
568a8e1175bSopenharmony_ci                                        &rnd_info);
569a8e1175bSopenharmony_ci    TEST_ASSERT(der_len >= 0);
570a8e1175bSopenharmony_ci
571a8e1175bSopenharmony_ci    if (der_len == 0) {
572a8e1175bSopenharmony_ci        goto exit;
573a8e1175bSopenharmony_ci    }
574a8e1175bSopenharmony_ci
575a8e1175bSopenharmony_ci    // Not testing against file, check date format
576a8e1175bSopenharmony_ci    if (*cert_check_file == '\0') {
577a8e1175bSopenharmony_ci        // UTC tag if before 2050, 2 digits less for year
578a8e1175bSopenharmony_ci        if (not_before[0] == '2' && (not_before[1] > '0' || not_before[2] > '4')) {
579a8e1175bSopenharmony_ci            before_tag = MBEDTLS_ASN1_GENERALIZED_TIME;
580a8e1175bSopenharmony_ci        } else {
581a8e1175bSopenharmony_ci            before_tag = MBEDTLS_ASN1_UTC_TIME;
582a8e1175bSopenharmony_ci            not_before += 2;
583a8e1175bSopenharmony_ci        }
584a8e1175bSopenharmony_ci        if (not_after[0] == '2' && (not_after[1] > '0' || not_after[2] > '4')) {
585a8e1175bSopenharmony_ci            after_tag = MBEDTLS_ASN1_GENERALIZED_TIME;
586a8e1175bSopenharmony_ci        } else {
587a8e1175bSopenharmony_ci            after_tag = MBEDTLS_ASN1_UTC_TIME;
588a8e1175bSopenharmony_ci            not_after += 2;
589a8e1175bSopenharmony_ci        }
590a8e1175bSopenharmony_ci        end = buf + sizeof(buf);
591a8e1175bSopenharmony_ci        for (p = end - der_len; p < end;) {
592a8e1175bSopenharmony_ci            tag = *p++;
593a8e1175bSopenharmony_ci            sz = *p++;
594a8e1175bSopenharmony_ci            if (tag == MBEDTLS_ASN1_UTC_TIME || tag == MBEDTLS_ASN1_GENERALIZED_TIME) {
595a8e1175bSopenharmony_ci                // Check correct tag and time written
596a8e1175bSopenharmony_ci                TEST_ASSERT(before_tag == tag);
597a8e1175bSopenharmony_ci                TEST_ASSERT(memcmp(p, not_before, sz - 1) == 0);
598a8e1175bSopenharmony_ci                p += sz;
599a8e1175bSopenharmony_ci                tag = *p++;
600a8e1175bSopenharmony_ci                sz = *p++;
601a8e1175bSopenharmony_ci                TEST_ASSERT(after_tag == tag);
602a8e1175bSopenharmony_ci                TEST_ASSERT(memcmp(p, not_after, sz - 1) == 0);
603a8e1175bSopenharmony_ci                break;
604a8e1175bSopenharmony_ci            }
605a8e1175bSopenharmony_ci            // Increment if long form ASN1 length
606a8e1175bSopenharmony_ci            if (sz & 0x80) {
607a8e1175bSopenharmony_ci                p += sz & 0x0F;
608a8e1175bSopenharmony_ci            }
609a8e1175bSopenharmony_ci            if (tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
610a8e1175bSopenharmony_ci                p += sz;
611a8e1175bSopenharmony_ci            }
612a8e1175bSopenharmony_ci        }
613a8e1175bSopenharmony_ci        TEST_ASSERT(p < end);
614a8e1175bSopenharmony_ci    }
615a8e1175bSopenharmony_ci
616a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
617a8e1175bSopenharmony_ci    // When using PSA crypto, RNG isn't controllable, result length isn't
618a8e1175bSopenharmony_ci    // deterministic over multiple runs, removing a single byte isn't enough to
619a8e1175bSopenharmony_ci    // go into the MBEDTLS_ERR_ASN1_BUF_TOO_SMALL error case
620a8e1175bSopenharmony_ci    if (issuer_key_type != MBEDTLS_PK_RSA) {
621a8e1175bSopenharmony_ci        der_len /= 2;
622a8e1175bSopenharmony_ci    } else
623a8e1175bSopenharmony_ci#endif
624a8e1175bSopenharmony_ci    der_len -= 1;
625a8e1175bSopenharmony_ci
626a8e1175bSopenharmony_ci    ret = mbedtls_x509write_crt_der(&crt, buf, (size_t) (der_len),
627a8e1175bSopenharmony_ci                                    mbedtls_test_rnd_pseudo_rand, &rnd_info);
628a8e1175bSopenharmony_ci    TEST_ASSERT(ret == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
629a8e1175bSopenharmony_ci
630a8e1175bSopenharmony_ciexit:
631a8e1175bSopenharmony_ci    mbedtls_asn1_free_named_data_list(&ext_san_dirname);
632a8e1175bSopenharmony_ci    mbedtls_x509write_crt_free(&crt);
633a8e1175bSopenharmony_ci    mbedtls_pk_free(&issuer_key_alt);
634a8e1175bSopenharmony_ci    mbedtls_pk_free(&subject_key);
635a8e1175bSopenharmony_ci    mbedtls_pk_free(&issuer_key);
636a8e1175bSopenharmony_ci#if defined(MBEDTLS_TEST_DEPRECATED) && defined(MBEDTLS_BIGNUM_C)
637a8e1175bSopenharmony_ci    mbedtls_mpi_free(&serial_mpi);
638a8e1175bSopenharmony_ci#endif
639a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
640a8e1175bSopenharmony_ci    psa_destroy_key(key_id);
641a8e1175bSopenharmony_ci#endif
642a8e1175bSopenharmony_ci    MD_OR_USE_PSA_DONE();
643a8e1175bSopenharmony_ci}
644a8e1175bSopenharmony_ci/* END_CASE */
645a8e1175bSopenharmony_ci
646a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_WRITE_C */
647a8e1175bSopenharmony_civoid x509_set_serial_check()
648a8e1175bSopenharmony_ci{
649a8e1175bSopenharmony_ci    mbedtls_x509write_cert ctx;
650a8e1175bSopenharmony_ci    uint8_t invalid_serial[MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN + 1];
651a8e1175bSopenharmony_ci
652a8e1175bSopenharmony_ci#if defined(MBEDTLS_TEST_DEPRECATED) && defined(MBEDTLS_BIGNUM_C)
653a8e1175bSopenharmony_ci    mbedtls_mpi serial_mpi;
654a8e1175bSopenharmony_ci    mbedtls_mpi_init(&serial_mpi);
655a8e1175bSopenharmony_ci#endif
656a8e1175bSopenharmony_ci
657a8e1175bSopenharmony_ci    USE_PSA_INIT();
658a8e1175bSopenharmony_ci    memset(invalid_serial, 0x01, sizeof(invalid_serial));
659a8e1175bSopenharmony_ci
660a8e1175bSopenharmony_ci#if defined(MBEDTLS_TEST_DEPRECATED) && defined(MBEDTLS_BIGNUM_C)
661a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_mpi_read_binary(&serial_mpi, invalid_serial,
662a8e1175bSopenharmony_ci                                       sizeof(invalid_serial)), 0);
663a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_x509write_crt_set_serial(&ctx, &serial_mpi),
664a8e1175bSopenharmony_ci               MBEDTLS_ERR_X509_BAD_INPUT_DATA);
665a8e1175bSopenharmony_ci#endif
666a8e1175bSopenharmony_ci
667a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_x509write_crt_set_serial_raw(&ctx, invalid_serial,
668a8e1175bSopenharmony_ci                                                    sizeof(invalid_serial)),
669a8e1175bSopenharmony_ci               MBEDTLS_ERR_X509_BAD_INPUT_DATA);
670a8e1175bSopenharmony_ci
671a8e1175bSopenharmony_ciexit:
672a8e1175bSopenharmony_ci#if defined(MBEDTLS_TEST_DEPRECATED) && defined(MBEDTLS_BIGNUM_C)
673a8e1175bSopenharmony_ci    mbedtls_mpi_free(&serial_mpi);
674a8e1175bSopenharmony_ci#else
675a8e1175bSopenharmony_ci    ;
676a8e1175bSopenharmony_ci#endif
677a8e1175bSopenharmony_ci    USE_PSA_DONE();
678a8e1175bSopenharmony_ci}
679a8e1175bSopenharmony_ci/* END_CASE */
680a8e1175bSopenharmony_ci
681a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_X509_CREATE_C:MBEDTLS_X509_USE_C */
682a8e1175bSopenharmony_civoid mbedtls_x509_string_to_names(char *name, char *parsed_name,
683a8e1175bSopenharmony_ci                                  int result, int may_fail)
684a8e1175bSopenharmony_ci{
685a8e1175bSopenharmony_ci    int ret;
686a8e1175bSopenharmony_ci    size_t len = 0;
687a8e1175bSopenharmony_ci    mbedtls_asn1_named_data *names = NULL;
688a8e1175bSopenharmony_ci    mbedtls_x509_name parsed;
689a8e1175bSopenharmony_ci    memset(&parsed, 0, sizeof(parsed));
690a8e1175bSopenharmony_ci    mbedtls_x509_name *parsed_cur = NULL;
691a8e1175bSopenharmony_ci    mbedtls_x509_name *parsed_prv = NULL;
692a8e1175bSopenharmony_ci    unsigned char buf[1024] = { 0 };
693a8e1175bSopenharmony_ci    unsigned char out[1024] = { 0 };
694a8e1175bSopenharmony_ci    unsigned char *c = buf + sizeof(buf);
695a8e1175bSopenharmony_ci
696a8e1175bSopenharmony_ci    USE_PSA_INIT();
697a8e1175bSopenharmony_ci
698a8e1175bSopenharmony_ci    ret = mbedtls_x509_string_to_names(&names, name);
699a8e1175bSopenharmony_ci    TEST_EQUAL(ret, result);
700a8e1175bSopenharmony_ci
701a8e1175bSopenharmony_ci    if (ret != 0) {
702a8e1175bSopenharmony_ci        goto exit;
703a8e1175bSopenharmony_ci    }
704a8e1175bSopenharmony_ci
705a8e1175bSopenharmony_ci    ret = mbedtls_x509_write_names(&c, buf, names);
706a8e1175bSopenharmony_ci    TEST_LE_S(1, ret);
707a8e1175bSopenharmony_ci
708a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_asn1_get_tag(&c, buf + sizeof(buf), &len,
709a8e1175bSopenharmony_ci                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE), 0);
710a8e1175bSopenharmony_ci    ret = mbedtls_x509_get_name(&c, buf + sizeof(buf), &parsed);
711a8e1175bSopenharmony_ci    if ((may_fail & MAY_FAIL_GET_NAME) && ret < 0) {
712a8e1175bSopenharmony_ci        /* Validation inconsistency between mbedtls_x509_string_to_names() and
713a8e1175bSopenharmony_ci         * mbedtls_x509_get_name(). Accept it for now. */
714a8e1175bSopenharmony_ci        goto exit;
715a8e1175bSopenharmony_ci    }
716a8e1175bSopenharmony_ci    TEST_EQUAL(ret, 0);
717a8e1175bSopenharmony_ci
718a8e1175bSopenharmony_ci    ret = mbedtls_x509_dn_gets((char *) out, sizeof(out), &parsed);
719a8e1175bSopenharmony_ci    if ((may_fail & MAY_FAIL_DN_GETS) && ret < 0) {
720a8e1175bSopenharmony_ci        /* Validation inconsistency between mbedtls_x509_string_to_names() and
721a8e1175bSopenharmony_ci         * mbedtls_x509_dn_gets(). Accept it for now. */
722a8e1175bSopenharmony_ci        goto exit;
723a8e1175bSopenharmony_ci    }
724a8e1175bSopenharmony_ci    TEST_LE_S(1, ret);
725a8e1175bSopenharmony_ci    TEST_ASSERT(strcmp((char *) out, parsed_name) == 0);
726a8e1175bSopenharmony_ci
727a8e1175bSopenharmony_ciexit:
728a8e1175bSopenharmony_ci    mbedtls_asn1_free_named_data_list(&names);
729a8e1175bSopenharmony_ci
730a8e1175bSopenharmony_ci    parsed_cur = parsed.next;
731a8e1175bSopenharmony_ci    while (parsed_cur != 0) {
732a8e1175bSopenharmony_ci        parsed_prv = parsed_cur;
733a8e1175bSopenharmony_ci        parsed_cur = parsed_cur->next;
734a8e1175bSopenharmony_ci        mbedtls_free(parsed_prv);
735a8e1175bSopenharmony_ci    }
736a8e1175bSopenharmony_ci    USE_PSA_DONE();
737a8e1175bSopenharmony_ci}
738a8e1175bSopenharmony_ci/* END_CASE */
739a8e1175bSopenharmony_ci
740a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_X509_CSR_WRITE_C */
741a8e1175bSopenharmony_civoid x509_set_extension_length_check()
742a8e1175bSopenharmony_ci{
743a8e1175bSopenharmony_ci    int ret = 0;
744a8e1175bSopenharmony_ci
745a8e1175bSopenharmony_ci    mbedtls_x509write_csr ctx;
746a8e1175bSopenharmony_ci    mbedtls_x509write_csr_init(&ctx);
747a8e1175bSopenharmony_ci
748a8e1175bSopenharmony_ci    unsigned char buf[EXT_KEY_USAGE_TMP_BUF_MAX_LENGTH] = { 0 };
749a8e1175bSopenharmony_ci    unsigned char *p = buf + sizeof(buf);
750a8e1175bSopenharmony_ci
751a8e1175bSopenharmony_ci    ret = mbedtls_x509_set_extension(&(ctx.MBEDTLS_PRIVATE(extensions)),
752a8e1175bSopenharmony_ci                                     MBEDTLS_OID_EXTENDED_KEY_USAGE,
753a8e1175bSopenharmony_ci                                     MBEDTLS_OID_SIZE(MBEDTLS_OID_EXTENDED_KEY_USAGE),
754a8e1175bSopenharmony_ci                                     0,
755a8e1175bSopenharmony_ci                                     p,
756a8e1175bSopenharmony_ci                                     SIZE_MAX);
757a8e1175bSopenharmony_ci    TEST_ASSERT(MBEDTLS_ERR_X509_BAD_INPUT_DATA == ret);
758a8e1175bSopenharmony_ci}
759a8e1175bSopenharmony_ci/* END_CASE */
760