/* BEGIN_HEADER */ #include "mbedtls/bignum.h" #include "mbedtls/pkcs7.h" #include "mbedtls/x509.h" #include "mbedtls/x509_crt.h" #include "mbedtls/x509_crl.h" #include "x509_internal.h" #include "mbedtls/oid.h" #include "sys/types.h" #include "sys/stat.h" #include "mbedtls/rsa.h" #include "mbedtls/error.h" /* END_HEADER */ /* BEGIN_DEPENDENCIES * depends_on:MBEDTLS_PKCS7_C * END_DEPENDENCIES */ /* BEGIN_SUITE_HELPERS */ int pkcs7_parse_buffer(unsigned char *pkcs7_buf, int buflen) { int res; mbedtls_pkcs7 pkcs7; mbedtls_pkcs7_init(&pkcs7); res = mbedtls_pkcs7_parse_der(&pkcs7, pkcs7_buf, buflen); mbedtls_pkcs7_free(&pkcs7); return res; } /* END_SUITE_HELPERS */ /* BEGIN_CASE */ void pkcs7_asn1_fail(data_t *pkcs7_buf) { int res; res = pkcs7_parse_buffer(pkcs7_buf->x, pkcs7_buf->len); TEST_ASSERT(res != MBEDTLS_PKCS7_SIGNED_DATA); } /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_FS_IO */ void pkcs7_parse(char *pkcs7_file, int res_expect) { unsigned char *pkcs7_buf = NULL; size_t buflen; int res; res = mbedtls_pk_load_file(pkcs7_file, &pkcs7_buf, &buflen); TEST_EQUAL(res, 0); res = pkcs7_parse_buffer(pkcs7_buf, buflen); TEST_EQUAL(res, res_expect); exit: mbedtls_free(pkcs7_buf); } /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C:MBEDTLS_PKCS1_V15:MBEDTLS_RSA_C */ void pkcs7_verify(char *pkcs7_file, char *crt_files, char *filetobesigned, int do_hash_alg, int res_expect) { unsigned char *pkcs7_buf = NULL; size_t buflen, i, k, cnt = 0, n_crts = 1; unsigned char *data = NULL; char **crt_files_arr = NULL; unsigned char *hash = NULL; struct stat st; size_t datalen; int res; FILE *file; const mbedtls_md_info_t *md_info; mbedtls_pkcs7 pkcs7; mbedtls_x509_crt **crts = NULL; MD_OR_USE_PSA_INIT(); mbedtls_pkcs7_init(&pkcs7); /* crt_files are space seprated list */ for (i = 0; i < strlen(crt_files); i++) { if (crt_files[i] == ' ') { n_crts++; } } TEST_CALLOC(crts, n_crts); TEST_CALLOC(crt_files_arr, n_crts); for (i = 0; i < strlen(crt_files); i++) { for (k = i; k < strlen(crt_files); k++) { if (crt_files[k] == ' ') { break; } } TEST_CALLOC(crt_files_arr[cnt], (k-i)+1); crt_files_arr[cnt][k-i] = '\0'; memcpy(crt_files_arr[cnt++], crt_files + i, k-i); i = k; } for (i = 0; i < n_crts; i++) { TEST_CALLOC(crts[i], 1); mbedtls_x509_crt_init(crts[i]); } res = mbedtls_pk_load_file(pkcs7_file, &pkcs7_buf, &buflen); TEST_EQUAL(res, 0); res = mbedtls_pkcs7_parse_der(&pkcs7, pkcs7_buf, buflen); TEST_EQUAL(res, MBEDTLS_PKCS7_SIGNED_DATA); TEST_EQUAL(pkcs7.signed_data.no_of_signers, n_crts); for (i = 0; i < n_crts; i++) { res = mbedtls_x509_crt_parse_file(crts[i], crt_files_arr[i]); TEST_EQUAL(res, 0); } res = stat(filetobesigned, &st); TEST_EQUAL(res, 0); file = fopen(filetobesigned, "rb"); TEST_ASSERT(file != NULL); datalen = st.st_size; /* Special-case for zero-length input so that data will be non-NULL */ TEST_CALLOC(data, datalen == 0 ? 1 : datalen); buflen = fread((void *) data, sizeof(unsigned char), datalen, file); TEST_EQUAL(buflen, datalen); fclose(file); if (do_hash_alg) { md_info = mbedtls_md_info_from_type((mbedtls_md_type_t) do_hash_alg); TEST_CALLOC(hash, mbedtls_md_get_size(md_info)); res = mbedtls_md(md_info, data, datalen, hash); TEST_EQUAL(res, 0); for (i = 0; i < n_crts; i++) { res = mbedtls_pkcs7_signed_hash_verify(&pkcs7, crts[i], hash, mbedtls_md_get_size(md_info)); TEST_EQUAL(res, res_expect); } } else { for (i = 0; i < n_crts; i++) { res = mbedtls_pkcs7_signed_data_verify(&pkcs7, crts[i], data, datalen); TEST_EQUAL(res, res_expect); } } exit: for (i = 0; i < n_crts; i++) { mbedtls_x509_crt_free(crts[i]); mbedtls_free(crts[i]); mbedtls_free(crt_files_arr[i]); } mbedtls_free(hash); mbedtls_pkcs7_free(&pkcs7); mbedtls_free(crt_files_arr); mbedtls_free(crts); mbedtls_free(data); mbedtls_free(pkcs7_buf); MD_OR_USE_PSA_DONE(); } /* END_CASE */