• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* BEGIN_HEADER */
2#include "mbedtls/bignum.h"
3#include "mbedtls/x509_crt.h"
4#include "mbedtls/x509_csr.h"
5#include "mbedtls/pem.h"
6#include "mbedtls/oid.h"
7#include "mbedtls/rsa.h"
8#include "mbedtls/asn1write.h"
9
10#if defined(MBEDTLS_RSA_C)
11int mbedtls_rsa_decrypt_func(void *ctx, int mode, size_t *olen,
12                             const unsigned char *input, unsigned char *output,
13                             size_t output_max_len)
14{
15    return mbedtls_rsa_pkcs1_decrypt((mbedtls_rsa_context *) ctx, NULL, NULL, mode, olen,
16                                     input, output, output_max_len);
17}
18int mbedtls_rsa_sign_func(void *ctx,
19                          int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
20                          int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,
21                          const unsigned char *hash, unsigned char *sig)
22{
23    return mbedtls_rsa_pkcs1_sign((mbedtls_rsa_context *) ctx, f_rng, p_rng, mode,
24                                  md_alg, hashlen, hash, sig);
25}
26size_t mbedtls_rsa_key_len_func(void *ctx)
27{
28    return ((const mbedtls_rsa_context *) ctx)->len;
29}
30#endif /* MBEDTLS_RSA_C */
31
32#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
33    defined(MBEDTLS_PEM_WRITE_C) && defined(MBEDTLS_X509_CSR_WRITE_C)
34static int x509_crt_verifycsr(const unsigned char *buf, size_t buflen)
35{
36    unsigned char hash[MBEDTLS_MD_MAX_SIZE];
37    const mbedtls_md_info_t *md_info;
38    mbedtls_x509_csr csr;
39    int ret = 0;
40
41    mbedtls_x509_csr_init(&csr);
42
43    if (mbedtls_x509_csr_parse(&csr, buf, buflen) != 0) {
44        ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
45        goto cleanup;
46    }
47
48    md_info = mbedtls_md_info_from_type(csr.sig_md);
49    if (mbedtls_md(md_info, csr.cri.p, csr.cri.len, hash) != 0) {
50        /* Note: this can't happen except after an internal error */
51        ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
52        goto cleanup;
53    }
54
55    if (mbedtls_pk_verify_ext(csr.sig_pk, csr.sig_opts, &csr.pk,
56                              csr.sig_md, hash, mbedtls_md_get_size(md_info),
57                              csr.sig.p, csr.sig.len) != 0) {
58        ret = MBEDTLS_ERR_X509_CERT_VERIFY_FAILED;
59        goto cleanup;
60    }
61
62cleanup:
63
64    mbedtls_x509_csr_free(&csr);
65    return ret;
66}
67#endif /* MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_PEM_WRITE_C && MBEDTLS_X509_CSR_WRITE_C */
68
69#if defined(MBEDTLS_X509_CSR_WRITE_C)
70
71/*
72 * The size of this temporary buffer is given by the sequence of functions
73 * called hereinafter:
74 * - mbedtls_asn1_write_oid()
75 *     - 8 bytes for MBEDTLS_OID_EXTENDED_KEY_USAGE raw value
76 *     - 1 byte for MBEDTLS_OID_EXTENDED_KEY_USAGE length
77 *     - 1 byte for MBEDTLS_ASN1_OID tag
78 * - mbedtls_asn1_write_len()
79 *     - 1 byte since we're dealing with sizes which are less than 0x80
80 * - mbedtls_asn1_write_tag()
81 *     - 1 byte
82 *
83 * This length is fine as long as this function is called using the
84 * MBEDTLS_OID_SERVER_AUTH OID. If this is changed in the future, then this
85 * buffer's length should be adjusted accordingly.
86 * Unfortunately there's no predefined max size for OIDs which can be used
87 * to set an overall upper boundary which is always guaranteed.
88 */
89#define EXT_KEY_USAGE_TMP_BUF_MAX_LENGTH    12
90
91static int csr_set_extended_key_usage(mbedtls_x509write_csr *ctx,
92                                      const char *oid, size_t oid_len)
93{
94    unsigned char buf[EXT_KEY_USAGE_TMP_BUF_MAX_LENGTH] = { 0 };
95    unsigned char *p = buf + sizeof(buf);
96    int ret;
97    size_t len = 0;
98
99    /*
100     * Following functions fail anyway if the temporary buffer is not large,
101     * but we set an extra check here to emphasize a possible source of errors
102     */
103    if (oid_len > EXT_KEY_USAGE_TMP_BUF_MAX_LENGTH) {
104        return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
105    }
106
107    MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_oid(&p, buf, oid, oid_len));
108    MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, buf, ret));
109    MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, buf,
110                                                     MBEDTLS_ASN1_CONSTRUCTED |
111                                                     MBEDTLS_ASN1_SEQUENCE));
112
113    ret = mbedtls_x509write_csr_set_extension(ctx,
114                                              MBEDTLS_OID_EXTENDED_KEY_USAGE,
115                                              MBEDTLS_OID_SIZE(MBEDTLS_OID_EXTENDED_KEY_USAGE),
116                                              p,
117                                              len);
118
119    return ret;
120}
121#endif  /* MBEDTLS_X509_CSR_WRITE_C */
122/* END_HEADER */
123
124/* BEGIN_DEPENDENCIES
125 * depends_on:MBEDTLS_BIGNUM_C:MBEDTLS_FS_IO:MBEDTLS_PK_PARSE_C
126 * END_DEPENDENCIES
127 */
128
129/* BEGIN_CASE depends_on:MBEDTLS_PEM_WRITE_C:MBEDTLS_X509_CSR_WRITE_C */
130void x509_csr_check(char *key_file, char *cert_req_check_file, int md_type,
131                    int key_usage, int set_key_usage, int cert_type,
132                    int set_cert_type, int set_extension)
133{
134    mbedtls_pk_context key;
135    mbedtls_x509write_csr req;
136    unsigned char buf[4096];
137    unsigned char check_buf[4000];
138    int ret;
139    size_t olen = 0, pem_len = 0, buf_index;
140    int der_len = -1;
141    FILE *f;
142    const char *subject_name = "C=NL,O=PolarSSL,CN=PolarSSL Server 1";
143    mbedtls_test_rnd_pseudo_info rnd_info;
144
145    memset(&rnd_info, 0x2a, sizeof(mbedtls_test_rnd_pseudo_info));
146
147    mbedtls_x509write_csr_init(&req);
148    mbedtls_pk_init(&key);
149    USE_PSA_INIT();
150
151    TEST_ASSERT(mbedtls_pk_parse_keyfile(&key, key_file, NULL) == 0);
152
153    mbedtls_x509write_csr_set_md_alg(&req, md_type);
154    mbedtls_x509write_csr_set_key(&req, &key);
155    TEST_ASSERT(mbedtls_x509write_csr_set_subject_name(&req, subject_name) == 0);
156    if (set_key_usage != 0) {
157        TEST_ASSERT(mbedtls_x509write_csr_set_key_usage(&req, key_usage) == 0);
158    }
159    if (set_cert_type != 0) {
160        TEST_ASSERT(mbedtls_x509write_csr_set_ns_cert_type(&req, cert_type) == 0);
161    }
162    if (set_extension != 0) {
163        TEST_ASSERT(csr_set_extended_key_usage(&req, MBEDTLS_OID_SERVER_AUTH,
164                                               MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH)) == 0);
165    }
166
167    ret = mbedtls_x509write_csr_pem(&req, buf, sizeof(buf),
168                                    mbedtls_test_rnd_pseudo_rand, &rnd_info);
169    TEST_ASSERT(ret == 0);
170
171    pem_len = strlen((char *) buf);
172
173    for (buf_index = pem_len; buf_index < sizeof(buf); ++buf_index) {
174        TEST_ASSERT(buf[buf_index] == 0);
175    }
176
177    f = fopen(cert_req_check_file, "r");
178    TEST_ASSERT(f != NULL);
179    olen = fread(check_buf, 1, sizeof(check_buf), f);
180    fclose(f);
181
182    TEST_ASSERT(olen >= pem_len - 1);
183    TEST_ASSERT(memcmp(buf, check_buf, pem_len - 1) == 0);
184
185    der_len = mbedtls_x509write_csr_der(&req, buf, sizeof(buf),
186                                        mbedtls_test_rnd_pseudo_rand,
187                                        &rnd_info);
188    TEST_ASSERT(der_len >= 0);
189
190    if (der_len == 0) {
191        goto exit;
192    }
193
194    ret = mbedtls_x509write_csr_der(&req, buf, (size_t) (der_len - 1),
195                                    mbedtls_test_rnd_pseudo_rand, &rnd_info);
196    TEST_ASSERT(ret == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
197
198exit:
199    mbedtls_x509write_csr_free(&req);
200    mbedtls_pk_free(&key);
201    USE_PSA_DONE();
202}
203/* END_CASE */
204
205/* BEGIN_CASE depends_on:MBEDTLS_PEM_WRITE_C:MBEDTLS_X509_CSR_WRITE_C:MBEDTLS_USE_PSA_CRYPTO */
206void x509_csr_check_opaque(char *key_file, int md_type, int key_usage,
207                           int cert_type)
208{
209    mbedtls_pk_context key;
210    mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
211    psa_algorithm_t md_alg_psa;
212    mbedtls_x509write_csr req;
213    unsigned char buf[4096];
214    int ret;
215    size_t pem_len = 0;
216    const char *subject_name = "C=NL,O=PolarSSL,CN=PolarSSL Server 1";
217    mbedtls_test_rnd_pseudo_info rnd_info;
218
219    memset(&rnd_info, 0x2a, sizeof(mbedtls_test_rnd_pseudo_info));
220
221    mbedtls_x509write_csr_init(&req);
222
223    USE_PSA_INIT();
224
225    md_alg_psa = mbedtls_psa_translate_md((mbedtls_md_type_t) md_type);
226    TEST_ASSERT(md_alg_psa != MBEDTLS_MD_NONE);
227
228    mbedtls_pk_init(&key);
229    TEST_ASSERT(mbedtls_pk_parse_keyfile(&key, key_file, NULL) == 0);
230    TEST_ASSERT(mbedtls_pk_wrap_as_opaque(&key, &key_id, md_alg_psa) == 0);
231
232    mbedtls_x509write_csr_set_md_alg(&req, md_type);
233    mbedtls_x509write_csr_set_key(&req, &key);
234    TEST_ASSERT(mbedtls_x509write_csr_set_subject_name(&req, subject_name) == 0);
235    if (key_usage != 0) {
236        TEST_ASSERT(mbedtls_x509write_csr_set_key_usage(&req, key_usage) == 0);
237    }
238    if (cert_type != 0) {
239        TEST_ASSERT(mbedtls_x509write_csr_set_ns_cert_type(&req, cert_type) == 0);
240    }
241
242    ret = mbedtls_x509write_csr_pem(&req, buf, sizeof(buf) - 1,
243                                    mbedtls_test_rnd_pseudo_rand, &rnd_info);
244
245    TEST_ASSERT(ret == 0);
246
247    pem_len = strlen((char *) buf);
248    buf[pem_len] = '\0';
249    TEST_ASSERT(x509_crt_verifycsr(buf, pem_len + 1) == 0);
250
251exit:
252    mbedtls_x509write_csr_free(&req);
253    mbedtls_pk_free(&key);
254    psa_destroy_key(key_id);
255    USE_PSA_DONE();
256}
257/* END_CASE */
258
259/* BEGIN_CASE depends_on:MBEDTLS_PEM_WRITE_C:MBEDTLS_X509_CRT_WRITE_C:MBEDTLS_SHA1_C */
260void x509_crt_check(char *subject_key_file, char *subject_pwd,
261                    char *subject_name, char *issuer_key_file,
262                    char *issuer_pwd, char *issuer_name,
263                    char *serial_str, char *not_before, char *not_after,
264                    int md_type, int key_usage, int set_key_usage,
265                    int cert_type, int set_cert_type, int auth_ident,
266                    int ver, char *cert_check_file, int rsa_alt, int is_ca)
267{
268    mbedtls_pk_context subject_key, issuer_key, issuer_key_alt;
269    mbedtls_pk_context *key = &issuer_key;
270
271    mbedtls_x509write_cert crt;
272    unsigned char buf[4096];
273    unsigned char check_buf[5000];
274    unsigned char *p, *end;
275    unsigned char tag, sz;
276    mbedtls_mpi serial;
277    int ret, before_tag, after_tag;
278    size_t olen = 0, pem_len = 0, buf_index = 0;
279    int der_len = -1;
280    FILE *f;
281    mbedtls_test_rnd_pseudo_info rnd_info;
282
283    memset(&rnd_info, 0x2a, sizeof(mbedtls_test_rnd_pseudo_info));
284    mbedtls_mpi_init(&serial);
285
286    mbedtls_pk_init(&subject_key);
287    mbedtls_pk_init(&issuer_key);
288    mbedtls_pk_init(&issuer_key_alt);
289
290    mbedtls_x509write_crt_init(&crt);
291    USE_PSA_INIT();
292
293    TEST_ASSERT(mbedtls_pk_parse_keyfile(&subject_key, subject_key_file,
294                                         subject_pwd) == 0);
295
296    TEST_ASSERT(mbedtls_pk_parse_keyfile(&issuer_key, issuer_key_file,
297                                         issuer_pwd) == 0);
298
299#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
300    /* For RSA PK contexts, create a copy as an alternative RSA context. */
301    if (rsa_alt == 1 && mbedtls_pk_get_type(&issuer_key) == MBEDTLS_PK_RSA) {
302        TEST_ASSERT(mbedtls_pk_setup_rsa_alt(&issuer_key_alt,
303                                             mbedtls_pk_rsa(issuer_key),
304                                             mbedtls_rsa_decrypt_func,
305                                             mbedtls_rsa_sign_func,
306                                             mbedtls_rsa_key_len_func) == 0);
307
308        key = &issuer_key_alt;
309    }
310#else
311    (void) rsa_alt;
312#endif
313
314    TEST_ASSERT(mbedtls_test_read_mpi(&serial, serial_str) == 0);
315
316    if (ver != -1) {
317        mbedtls_x509write_crt_set_version(&crt, ver);
318    }
319
320    TEST_ASSERT(mbedtls_x509write_crt_set_serial(&crt, &serial) == 0);
321    TEST_ASSERT(mbedtls_x509write_crt_set_validity(&crt, not_before,
322                                                   not_after) == 0);
323    mbedtls_x509write_crt_set_md_alg(&crt, md_type);
324    TEST_ASSERT(mbedtls_x509write_crt_set_issuer_name(&crt, issuer_name) == 0);
325    TEST_ASSERT(mbedtls_x509write_crt_set_subject_name(&crt, subject_name) == 0);
326    mbedtls_x509write_crt_set_subject_key(&crt, &subject_key);
327
328    mbedtls_x509write_crt_set_issuer_key(&crt, key);
329
330    if (crt.version >= MBEDTLS_X509_CRT_VERSION_3) {
331        /* For the CA case, a path length of -1 means unlimited. */
332        TEST_ASSERT(mbedtls_x509write_crt_set_basic_constraints(&crt, is_ca,
333                                                                (is_ca ? -1 : 0)) == 0);
334        TEST_ASSERT(mbedtls_x509write_crt_set_subject_key_identifier(&crt) == 0);
335        if (auth_ident) {
336            TEST_ASSERT(mbedtls_x509write_crt_set_authority_key_identifier(&crt) == 0);
337        }
338        if (set_key_usage != 0) {
339            TEST_ASSERT(mbedtls_x509write_crt_set_key_usage(&crt, key_usage) == 0);
340        }
341        if (set_cert_type != 0) {
342            TEST_ASSERT(mbedtls_x509write_crt_set_ns_cert_type(&crt, cert_type) == 0);
343        }
344    }
345
346    ret = mbedtls_x509write_crt_pem(&crt, buf, sizeof(buf),
347                                    mbedtls_test_rnd_pseudo_rand, &rnd_info);
348    TEST_ASSERT(ret == 0);
349
350    pem_len = strlen((char *) buf);
351
352    // check that the rest of the buffer remains clear
353    for (buf_index = pem_len; buf_index < sizeof(buf); ++buf_index) {
354        TEST_ASSERT(buf[buf_index] == 0);
355    }
356
357    if (*cert_check_file != '\0') {
358        f = fopen(cert_check_file, "r");
359        TEST_ASSERT(f != NULL);
360        olen = fread(check_buf, 1, sizeof(check_buf), f);
361        fclose(f);
362        TEST_ASSERT(olen < sizeof(check_buf));
363        TEST_ASSERT(olen >= pem_len - 1);
364        TEST_ASSERT(memcmp(buf, check_buf, pem_len - 1) == 0);
365    }
366
367    der_len = mbedtls_x509write_crt_der(&crt, buf, sizeof(buf),
368                                        mbedtls_test_rnd_pseudo_rand,
369                                        &rnd_info);
370    TEST_ASSERT(der_len >= 0);
371
372    if (der_len == 0) {
373        goto exit;
374    }
375
376    // Not testing against file, check date format
377    if (*cert_check_file == '\0') {
378        // UTC tag if before 2050, 2 digits less for year
379        if (not_before[0] == '2' && (not_before[1] > '0' || not_before[2] > '4')) {
380            before_tag = MBEDTLS_ASN1_GENERALIZED_TIME;
381        } else {
382            before_tag = MBEDTLS_ASN1_UTC_TIME;
383            not_before += 2;
384        }
385        if (not_after[0] == '2' && (not_after[1] > '0' || not_after[2] > '4')) {
386            after_tag = MBEDTLS_ASN1_GENERALIZED_TIME;
387        } else {
388            after_tag = MBEDTLS_ASN1_UTC_TIME;
389            not_after += 2;
390        }
391        end = buf + sizeof(buf);
392        for (p = end - der_len; p < end;) {
393            tag = *p++;
394            sz = *p++;
395            if (tag == MBEDTLS_ASN1_UTC_TIME || tag == MBEDTLS_ASN1_GENERALIZED_TIME) {
396                // Check correct tag and time written
397                TEST_ASSERT(before_tag == tag);
398                TEST_ASSERT(memcmp(p, not_before, sz - 1) == 0);
399                p += sz;
400                tag = *p++;
401                sz = *p++;
402                TEST_ASSERT(after_tag == tag);
403                TEST_ASSERT(memcmp(p, not_after, sz - 1) == 0);
404                break;
405            }
406            // Increment if long form ASN1 length
407            if (sz & 0x80) {
408                p += sz & 0x0F;
409            }
410            if (tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
411                p += sz;
412            }
413        }
414        TEST_ASSERT(p < end);
415    }
416
417    ret = mbedtls_x509write_crt_der(&crt, buf, (size_t) (der_len - 1),
418                                    mbedtls_test_rnd_pseudo_rand, &rnd_info);
419    TEST_ASSERT(ret == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
420
421exit:
422    mbedtls_x509write_crt_free(&crt);
423    mbedtls_pk_free(&issuer_key_alt);
424    mbedtls_pk_free(&subject_key);
425    mbedtls_pk_free(&issuer_key);
426    mbedtls_mpi_free(&serial);
427    USE_PSA_DONE();
428}
429/* END_CASE */
430
431/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_WRITE_C */
432void x509_set_serial_check()
433{
434    mbedtls_x509write_cert ctx;
435    mbedtls_mpi serial_mpi;
436    uint8_t invalid_serial[MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN + 1];
437
438    USE_PSA_INIT();
439    memset(invalid_serial, 0x01, sizeof(invalid_serial));
440
441    mbedtls_mpi_init(&serial_mpi);
442    TEST_EQUAL(mbedtls_mpi_read_binary(&serial_mpi, invalid_serial,
443                                       sizeof(invalid_serial)), 0);
444    TEST_EQUAL(mbedtls_x509write_crt_set_serial(&ctx, &serial_mpi),
445               MBEDTLS_ERR_X509_BAD_INPUT_DATA);
446
447exit:
448    mbedtls_mpi_free(&serial_mpi);
449    USE_PSA_DONE();
450}
451/* END_CASE */
452
453/* BEGIN_CASE depends_on:MBEDTLS_X509_CREATE_C:MBEDTLS_X509_USE_C */
454void mbedtls_x509_string_to_names(char *name, char *parsed_name, int result
455                                  )
456{
457    int ret;
458    size_t len = 0;
459    mbedtls_asn1_named_data *names = NULL;
460    mbedtls_x509_name parsed, *parsed_cur, *parsed_prv;
461    unsigned char buf[1024], out[1024], *c;
462
463    USE_PSA_INIT();
464
465    memset(&parsed, 0, sizeof(parsed));
466    memset(out, 0, sizeof(out));
467    memset(buf, 0, sizeof(buf));
468    c = buf + sizeof(buf);
469
470    ret = mbedtls_x509_string_to_names(&names, name);
471    TEST_ASSERT(ret == result);
472
473    if (ret != 0) {
474        goto exit;
475    }
476
477    ret = mbedtls_x509_write_names(&c, buf, names);
478    TEST_ASSERT(ret > 0);
479
480    TEST_ASSERT(mbedtls_asn1_get_tag(&c, buf + sizeof(buf), &len,
481                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) == 0);
482    TEST_ASSERT(mbedtls_x509_get_name(&c, buf + sizeof(buf), &parsed) == 0);
483
484    ret = mbedtls_x509_dn_gets((char *) out, sizeof(out), &parsed);
485    TEST_ASSERT(ret > 0);
486
487    TEST_ASSERT(strcmp((char *) out, parsed_name) == 0);
488
489exit:
490    mbedtls_asn1_free_named_data_list(&names);
491
492    parsed_cur = parsed.next;
493    while (parsed_cur != 0) {
494        parsed_prv = parsed_cur;
495        parsed_cur = parsed_cur->next;
496        mbedtls_free(parsed_prv);
497    }
498    USE_PSA_DONE();
499}
500/* END_CASE */
501
502/* BEGIN_CASE depends_on:MBEDTLS_X509_CSR_WRITE_C */
503void x509_set_extension_length_check()
504{
505    int ret = 0;
506
507    mbedtls_x509write_csr ctx;
508    mbedtls_x509write_csr_init(&ctx);
509
510    unsigned char buf[EXT_KEY_USAGE_TMP_BUF_MAX_LENGTH] = { 0 };
511    unsigned char *p = buf + sizeof(buf);
512
513    ret = mbedtls_x509_set_extension(&(ctx.extensions),
514                                     MBEDTLS_OID_EXTENDED_KEY_USAGE,
515                                     MBEDTLS_OID_SIZE(MBEDTLS_OID_EXTENDED_KEY_USAGE),
516                                     0,
517                                     p,
518                                     SIZE_MAX);
519    TEST_ASSERT(MBEDTLS_ERR_X509_BAD_INPUT_DATA == ret);
520}
521/* END_CASE */
522