1a8e1175bSopenharmony_ci/* BEGIN_HEADER */
2a8e1175bSopenharmony_ci#include "mbedtls/bignum.h"
3a8e1175bSopenharmony_ci#include "mbedtls/pkcs7.h"
4a8e1175bSopenharmony_ci#include "mbedtls/x509.h"
5a8e1175bSopenharmony_ci#include "mbedtls/x509_crt.h"
6a8e1175bSopenharmony_ci#include "mbedtls/x509_crl.h"
7a8e1175bSopenharmony_ci#include "x509_internal.h"
8a8e1175bSopenharmony_ci#include "mbedtls/oid.h"
9a8e1175bSopenharmony_ci#include "sys/types.h"
10a8e1175bSopenharmony_ci#include "sys/stat.h"
11a8e1175bSopenharmony_ci#include "mbedtls/rsa.h"
12a8e1175bSopenharmony_ci#include "mbedtls/error.h"
13a8e1175bSopenharmony_ci/* END_HEADER */
14a8e1175bSopenharmony_ci
15a8e1175bSopenharmony_ci/* BEGIN_DEPENDENCIES
16a8e1175bSopenharmony_ci * depends_on:MBEDTLS_PKCS7_C
17a8e1175bSopenharmony_ci * END_DEPENDENCIES
18a8e1175bSopenharmony_ci */
19a8e1175bSopenharmony_ci/* BEGIN_SUITE_HELPERS */
20a8e1175bSopenharmony_ciint pkcs7_parse_buffer(unsigned char *pkcs7_buf, int buflen)
21a8e1175bSopenharmony_ci{
22a8e1175bSopenharmony_ci    int res;
23a8e1175bSopenharmony_ci    mbedtls_pkcs7 pkcs7;
24a8e1175bSopenharmony_ci
25a8e1175bSopenharmony_ci    mbedtls_pkcs7_init(&pkcs7);
26a8e1175bSopenharmony_ci    res = mbedtls_pkcs7_parse_der(&pkcs7, pkcs7_buf, buflen);
27a8e1175bSopenharmony_ci    mbedtls_pkcs7_free(&pkcs7);
28a8e1175bSopenharmony_ci    return res;
29a8e1175bSopenharmony_ci}
30a8e1175bSopenharmony_ci/* END_SUITE_HELPERS */
31a8e1175bSopenharmony_ci
32a8e1175bSopenharmony_ci/* BEGIN_CASE */
33a8e1175bSopenharmony_civoid pkcs7_asn1_fail(data_t *pkcs7_buf)
34a8e1175bSopenharmony_ci{
35a8e1175bSopenharmony_ci    int res;
36a8e1175bSopenharmony_ci    res = pkcs7_parse_buffer(pkcs7_buf->x, pkcs7_buf->len);
37a8e1175bSopenharmony_ci    TEST_ASSERT(res != MBEDTLS_PKCS7_SIGNED_DATA);
38a8e1175bSopenharmony_ci
39a8e1175bSopenharmony_ci}
40a8e1175bSopenharmony_ci/* END_CASE */
41a8e1175bSopenharmony_ci
42a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
43a8e1175bSopenharmony_civoid pkcs7_parse(char *pkcs7_file, int res_expect)
44a8e1175bSopenharmony_ci{
45a8e1175bSopenharmony_ci    unsigned char *pkcs7_buf = NULL;
46a8e1175bSopenharmony_ci    size_t buflen;
47a8e1175bSopenharmony_ci    int res;
48a8e1175bSopenharmony_ci
49a8e1175bSopenharmony_ci    res = mbedtls_pk_load_file(pkcs7_file, &pkcs7_buf, &buflen);
50a8e1175bSopenharmony_ci    TEST_EQUAL(res, 0);
51a8e1175bSopenharmony_ci
52a8e1175bSopenharmony_ci    res = pkcs7_parse_buffer(pkcs7_buf, buflen);
53a8e1175bSopenharmony_ci    TEST_EQUAL(res, res_expect);
54a8e1175bSopenharmony_ci
55a8e1175bSopenharmony_ciexit:
56a8e1175bSopenharmony_ci    mbedtls_free(pkcs7_buf);
57a8e1175bSopenharmony_ci}
58a8e1175bSopenharmony_ci/* END_CASE */
59a8e1175bSopenharmony_ci
60a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C */
61a8e1175bSopenharmony_civoid pkcs7_verify(char *pkcs7_file,
62a8e1175bSopenharmony_ci                  char *crt_files,
63a8e1175bSopenharmony_ci                  char *filetobesigned,
64a8e1175bSopenharmony_ci                  int do_hash_alg,
65a8e1175bSopenharmony_ci                  int res_expect)
66a8e1175bSopenharmony_ci{
67a8e1175bSopenharmony_ci    unsigned char *pkcs7_buf = NULL;
68a8e1175bSopenharmony_ci    size_t buflen, i, k, cnt = 0, n_crts = 1;
69a8e1175bSopenharmony_ci    unsigned char *data = NULL;
70a8e1175bSopenharmony_ci    char **crt_files_arr = NULL;
71a8e1175bSopenharmony_ci    unsigned char *hash = NULL;
72a8e1175bSopenharmony_ci    struct stat st;
73a8e1175bSopenharmony_ci    size_t datalen;
74a8e1175bSopenharmony_ci    int res;
75a8e1175bSopenharmony_ci    FILE *file;
76a8e1175bSopenharmony_ci    const mbedtls_md_info_t *md_info;
77a8e1175bSopenharmony_ci    mbedtls_pkcs7 pkcs7;
78a8e1175bSopenharmony_ci    mbedtls_x509_crt **crts = NULL;
79a8e1175bSopenharmony_ci
80a8e1175bSopenharmony_ci    MD_OR_USE_PSA_INIT();
81a8e1175bSopenharmony_ci
82a8e1175bSopenharmony_ci    mbedtls_pkcs7_init(&pkcs7);
83a8e1175bSopenharmony_ci
84a8e1175bSopenharmony_ci    /* crt_files are space seprated list */
85a8e1175bSopenharmony_ci    for (i = 0; i < strlen(crt_files); i++) {
86a8e1175bSopenharmony_ci        if (crt_files[i] == ' ') {
87a8e1175bSopenharmony_ci            n_crts++;
88a8e1175bSopenharmony_ci        }
89a8e1175bSopenharmony_ci    }
90a8e1175bSopenharmony_ci
91a8e1175bSopenharmony_ci    TEST_CALLOC(crts, n_crts);
92a8e1175bSopenharmony_ci    TEST_CALLOC(crt_files_arr, n_crts);
93a8e1175bSopenharmony_ci
94a8e1175bSopenharmony_ci    for (i = 0; i < strlen(crt_files); i++) {
95a8e1175bSopenharmony_ci        for (k = i; k < strlen(crt_files); k++) {
96a8e1175bSopenharmony_ci            if (crt_files[k] == ' ') {
97a8e1175bSopenharmony_ci                break;
98a8e1175bSopenharmony_ci            }
99a8e1175bSopenharmony_ci        }
100a8e1175bSopenharmony_ci        TEST_CALLOC(crt_files_arr[cnt], (k-i)+1);
101a8e1175bSopenharmony_ci        crt_files_arr[cnt][k-i] = '\0';
102a8e1175bSopenharmony_ci        memcpy(crt_files_arr[cnt++], crt_files + i, k-i);
103a8e1175bSopenharmony_ci        i = k;
104a8e1175bSopenharmony_ci    }
105a8e1175bSopenharmony_ci
106a8e1175bSopenharmony_ci    for (i = 0; i < n_crts; i++) {
107a8e1175bSopenharmony_ci        TEST_CALLOC(crts[i], 1);
108a8e1175bSopenharmony_ci        mbedtls_x509_crt_init(crts[i]);
109a8e1175bSopenharmony_ci    }
110a8e1175bSopenharmony_ci
111a8e1175bSopenharmony_ci    res = mbedtls_pk_load_file(pkcs7_file, &pkcs7_buf, &buflen);
112a8e1175bSopenharmony_ci    TEST_EQUAL(res, 0);
113a8e1175bSopenharmony_ci
114a8e1175bSopenharmony_ci    res = mbedtls_pkcs7_parse_der(&pkcs7, pkcs7_buf, buflen);
115a8e1175bSopenharmony_ci    TEST_EQUAL(res, MBEDTLS_PKCS7_SIGNED_DATA);
116a8e1175bSopenharmony_ci
117a8e1175bSopenharmony_ci    TEST_EQUAL(pkcs7.signed_data.no_of_signers, n_crts);
118a8e1175bSopenharmony_ci
119a8e1175bSopenharmony_ci    for (i = 0; i < n_crts; i++) {
120a8e1175bSopenharmony_ci        res = mbedtls_x509_crt_parse_file(crts[i], crt_files_arr[i]);
121a8e1175bSopenharmony_ci        TEST_EQUAL(res, 0);
122a8e1175bSopenharmony_ci    }
123a8e1175bSopenharmony_ci
124a8e1175bSopenharmony_ci    res = stat(filetobesigned, &st);
125a8e1175bSopenharmony_ci    TEST_EQUAL(res, 0);
126a8e1175bSopenharmony_ci
127a8e1175bSopenharmony_ci    file = fopen(filetobesigned, "rb");
128a8e1175bSopenharmony_ci    TEST_ASSERT(file != NULL);
129a8e1175bSopenharmony_ci
130a8e1175bSopenharmony_ci    datalen = st.st_size;
131a8e1175bSopenharmony_ci    /* Special-case for zero-length input so that data will be non-NULL */
132a8e1175bSopenharmony_ci    TEST_CALLOC(data, datalen == 0 ? 1 : datalen);
133a8e1175bSopenharmony_ci    buflen = fread((void *) data, sizeof(unsigned char), datalen, file);
134a8e1175bSopenharmony_ci    TEST_EQUAL(buflen, datalen);
135a8e1175bSopenharmony_ci
136a8e1175bSopenharmony_ci    fclose(file);
137a8e1175bSopenharmony_ci
138a8e1175bSopenharmony_ci    if (do_hash_alg) {
139a8e1175bSopenharmony_ci        md_info = mbedtls_md_info_from_type((mbedtls_md_type_t) do_hash_alg);
140a8e1175bSopenharmony_ci        TEST_CALLOC(hash, mbedtls_md_get_size(md_info));
141a8e1175bSopenharmony_ci        res = mbedtls_md(md_info, data, datalen, hash);
142a8e1175bSopenharmony_ci        TEST_EQUAL(res, 0);
143a8e1175bSopenharmony_ci
144a8e1175bSopenharmony_ci        for (i = 0; i < n_crts; i++) {
145a8e1175bSopenharmony_ci            res =
146a8e1175bSopenharmony_ci                mbedtls_pkcs7_signed_hash_verify(&pkcs7, crts[i], hash,
147a8e1175bSopenharmony_ci                                                 mbedtls_md_get_size(md_info));
148a8e1175bSopenharmony_ci            TEST_EQUAL(res, res_expect);
149a8e1175bSopenharmony_ci        }
150a8e1175bSopenharmony_ci    } else {
151a8e1175bSopenharmony_ci        for (i = 0; i < n_crts; i++) {
152a8e1175bSopenharmony_ci            res = mbedtls_pkcs7_signed_data_verify(&pkcs7, crts[i], data, datalen);
153a8e1175bSopenharmony_ci            TEST_EQUAL(res, res_expect);
154a8e1175bSopenharmony_ci        }
155a8e1175bSopenharmony_ci    }
156a8e1175bSopenharmony_ci
157a8e1175bSopenharmony_ciexit:
158a8e1175bSopenharmony_ci    for (i = 0; i < n_crts; i++) {
159a8e1175bSopenharmony_ci        mbedtls_x509_crt_free(crts[i]);
160a8e1175bSopenharmony_ci        mbedtls_free(crts[i]);
161a8e1175bSopenharmony_ci        mbedtls_free(crt_files_arr[i]);
162a8e1175bSopenharmony_ci    }
163a8e1175bSopenharmony_ci    mbedtls_free(hash);
164a8e1175bSopenharmony_ci    mbedtls_pkcs7_free(&pkcs7);
165a8e1175bSopenharmony_ci    mbedtls_free(crt_files_arr);
166a8e1175bSopenharmony_ci    mbedtls_free(crts);
167a8e1175bSopenharmony_ci    mbedtls_free(data);
168a8e1175bSopenharmony_ci    mbedtls_free(pkcs7_buf);
169a8e1175bSopenharmony_ci    MD_OR_USE_PSA_DONE();
170a8e1175bSopenharmony_ci}
171a8e1175bSopenharmony_ci/* END_CASE */
172