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