pkcs7.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. /*
  2. * Copyright The Mbed TLS Contributors
  3. * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
  4. */
  5. #include "common.h"
  6. #include "mbedtls/build_info.h"
  7. #if defined(MBEDTLS_PKCS7_C)
  8. #include "mbedtls/pkcs7.h"
  9. #include "x509_internal.h"
  10. #include "mbedtls/asn1.h"
  11. #include "mbedtls/x509_crt.h"
  12. #include "mbedtls/x509_crl.h"
  13. #include "mbedtls/oid.h"
  14. #include "mbedtls/error.h"
  15. #if defined(MBEDTLS_FS_IO)
  16. #include <sys/types.h>
  17. #include <sys/stat.h>
  18. #endif
  19. #include "mbedtls/platform.h"
  20. #include "mbedtls/platform_util.h"
  21. #if defined(MBEDTLS_HAVE_TIME)
  22. #include "mbedtls/platform_time.h"
  23. #endif
  24. #if defined(MBEDTLS_HAVE_TIME_DATE)
  25. #include <time.h>
  26. #endif
  27. /**
  28. * Initializes the mbedtls_pkcs7 structure.
  29. */
  30. void mbedtls_pkcs7_init(mbedtls_pkcs7 *pkcs7)
  31. {
  32. memset(pkcs7, 0, sizeof(*pkcs7));
  33. }
  34. static int pkcs7_get_next_content_len(unsigned char **p, unsigned char *end,
  35. size_t *len)
  36. {
  37. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  38. ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_CONSTRUCTED
  39. | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
  40. if (ret != 0) {
  41. ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
  42. } else if ((size_t) (end - *p) != *len) {
  43. ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO,
  44. MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
  45. }
  46. return ret;
  47. }
  48. /**
  49. * version Version
  50. * Version ::= INTEGER
  51. **/
  52. static int pkcs7_get_version(unsigned char **p, unsigned char *end, int *ver)
  53. {
  54. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  55. ret = mbedtls_asn1_get_int(p, end, ver);
  56. if (ret != 0) {
  57. ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_VERSION, ret);
  58. }
  59. /* If version != 1, return invalid version */
  60. if (*ver != MBEDTLS_PKCS7_SUPPORTED_VERSION) {
  61. ret = MBEDTLS_ERR_PKCS7_INVALID_VERSION;
  62. }
  63. return ret;
  64. }
  65. /**
  66. * ContentInfo ::= SEQUENCE {
  67. * contentType ContentType,
  68. * content
  69. * [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
  70. **/
  71. static int pkcs7_get_content_info_type(unsigned char **p, unsigned char *end,
  72. unsigned char **seq_end,
  73. mbedtls_pkcs7_buf *pkcs7)
  74. {
  75. size_t len = 0;
  76. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  77. unsigned char *start = *p;
  78. ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
  79. | MBEDTLS_ASN1_SEQUENCE);
  80. if (ret != 0) {
  81. *p = start;
  82. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
  83. }
  84. *seq_end = *p + len;
  85. ret = mbedtls_asn1_get_tag(p, *seq_end, &len, MBEDTLS_ASN1_OID);
  86. if (ret != 0) {
  87. *p = start;
  88. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
  89. }
  90. pkcs7->tag = MBEDTLS_ASN1_OID;
  91. pkcs7->len = len;
  92. pkcs7->p = *p;
  93. *p += len;
  94. return ret;
  95. }
  96. /**
  97. * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
  98. *
  99. * This is from x509.h
  100. **/
  101. static int pkcs7_get_digest_algorithm(unsigned char **p, unsigned char *end,
  102. mbedtls_x509_buf *alg)
  103. {
  104. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  105. if ((ret = mbedtls_asn1_get_alg_null(p, end, alg)) != 0) {
  106. ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
  107. }
  108. return ret;
  109. }
  110. /**
  111. * DigestAlgorithmIdentifiers :: SET of DigestAlgorithmIdentifier
  112. **/
  113. static int pkcs7_get_digest_algorithm_set(unsigned char **p,
  114. unsigned char *end,
  115. mbedtls_x509_buf *alg)
  116. {
  117. size_t len = 0;
  118. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  119. ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
  120. | MBEDTLS_ASN1_SET);
  121. if (ret != 0) {
  122. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
  123. }
  124. end = *p + len;
  125. ret = mbedtls_asn1_get_alg_null(p, end, alg);
  126. if (ret != 0) {
  127. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_ALG, ret);
  128. }
  129. /** For now, it assumes there is only one digest algorithm specified **/
  130. if (*p != end) {
  131. return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
  132. }
  133. return 0;
  134. }
  135. /**
  136. * certificates :: SET OF ExtendedCertificateOrCertificate,
  137. * ExtendedCertificateOrCertificate ::= CHOICE {
  138. * certificate Certificate -- x509,
  139. * extendedCertificate[0] IMPLICIT ExtendedCertificate }
  140. * Return number of certificates added to the signed data,
  141. * 0 or higher is valid.
  142. * Return negative error code for failure.
  143. **/
  144. static int pkcs7_get_certificates(unsigned char **p, unsigned char *end,
  145. mbedtls_x509_crt *certs)
  146. {
  147. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  148. size_t len1 = 0;
  149. size_t len2 = 0;
  150. unsigned char *end_set, *end_cert, *start;
  151. ret = mbedtls_asn1_get_tag(p, end, &len1, MBEDTLS_ASN1_CONSTRUCTED
  152. | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
  153. if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
  154. return 0;
  155. }
  156. if (ret != 0) {
  157. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
  158. }
  159. start = *p;
  160. end_set = *p + len1;
  161. ret = mbedtls_asn1_get_tag(p, end_set, &len2, MBEDTLS_ASN1_CONSTRUCTED
  162. | MBEDTLS_ASN1_SEQUENCE);
  163. if (ret != 0) {
  164. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CERT, ret);
  165. }
  166. end_cert = *p + len2;
  167. /*
  168. * This is to verify that there is only one signer certificate. It seems it is
  169. * not easy to differentiate between the chain vs different signer's certificate.
  170. * So, we support only the root certificate and the single signer.
  171. * The behaviour would be improved with addition of multiple signer support.
  172. */
  173. if (end_cert != end_set) {
  174. return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
  175. }
  176. if ((ret = mbedtls_x509_crt_parse_der(certs, start, len1)) < 0) {
  177. return MBEDTLS_ERR_PKCS7_INVALID_CERT;
  178. }
  179. *p = end_cert;
  180. /*
  181. * Since in this version we strictly support single certificate, and reaching
  182. * here implies we have parsed successfully, we return 1.
  183. */
  184. return 1;
  185. }
  186. /**
  187. * EncryptedDigest ::= OCTET STRING
  188. **/
  189. static int pkcs7_get_signature(unsigned char **p, unsigned char *end,
  190. mbedtls_pkcs7_buf *signature)
  191. {
  192. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  193. size_t len = 0;
  194. ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
  195. if (ret != 0) {
  196. return ret;
  197. }
  198. signature->tag = MBEDTLS_ASN1_OCTET_STRING;
  199. signature->len = len;
  200. signature->p = *p;
  201. *p = *p + len;
  202. return 0;
  203. }
  204. static void pkcs7_free_signer_info(mbedtls_pkcs7_signer_info *signer)
  205. {
  206. mbedtls_x509_name *name_cur;
  207. mbedtls_x509_name *name_prv;
  208. if (signer == NULL) {
  209. return;
  210. }
  211. name_cur = signer->issuer.next;
  212. while (name_cur != NULL) {
  213. name_prv = name_cur;
  214. name_cur = name_cur->next;
  215. mbedtls_free(name_prv);
  216. }
  217. signer->issuer.next = NULL;
  218. }
  219. /**
  220. * SignerInfo ::= SEQUENCE {
  221. * version Version;
  222. * issuerAndSerialNumber IssuerAndSerialNumber,
  223. * digestAlgorithm DigestAlgorithmIdentifier,
  224. * authenticatedAttributes
  225. * [0] IMPLICIT Attributes OPTIONAL,
  226. * digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
  227. * encryptedDigest EncryptedDigest,
  228. * unauthenticatedAttributes
  229. * [1] IMPLICIT Attributes OPTIONAL,
  230. * Returns 0 if the signerInfo is valid.
  231. * Return negative error code for failure.
  232. * Structure must not contain vales for authenticatedAttributes
  233. * and unauthenticatedAttributes.
  234. **/
  235. static int pkcs7_get_signer_info(unsigned char **p, unsigned char *end,
  236. mbedtls_pkcs7_signer_info *signer,
  237. mbedtls_x509_buf *alg)
  238. {
  239. unsigned char *end_signer, *end_issuer_and_sn;
  240. int asn1_ret = 0, ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  241. size_t len = 0;
  242. asn1_ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
  243. | MBEDTLS_ASN1_SEQUENCE);
  244. if (asn1_ret != 0) {
  245. goto out;
  246. }
  247. end_signer = *p + len;
  248. ret = pkcs7_get_version(p, end_signer, &signer->version);
  249. if (ret != 0) {
  250. goto out;
  251. }
  252. asn1_ret = mbedtls_asn1_get_tag(p, end_signer, &len,
  253. MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
  254. if (asn1_ret != 0) {
  255. goto out;
  256. }
  257. end_issuer_and_sn = *p + len;
  258. /* Parsing IssuerAndSerialNumber */
  259. signer->issuer_raw.p = *p;
  260. asn1_ret = mbedtls_asn1_get_tag(p, end_issuer_and_sn, &len,
  261. MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
  262. if (asn1_ret != 0) {
  263. goto out;
  264. }
  265. ret = mbedtls_x509_get_name(p, *p + len, &signer->issuer);
  266. if (ret != 0) {
  267. goto out;
  268. }
  269. signer->issuer_raw.len = (size_t) (*p - signer->issuer_raw.p);
  270. ret = mbedtls_x509_get_serial(p, end_issuer_and_sn, &signer->serial);
  271. if (ret != 0) {
  272. goto out;
  273. }
  274. /* ensure no extra or missing bytes */
  275. if (*p != end_issuer_and_sn) {
  276. ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
  277. goto out;
  278. }
  279. ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->alg_identifier);
  280. if (ret != 0) {
  281. goto out;
  282. }
  283. /* Check that the digest algorithm used matches the one provided earlier */
  284. if (signer->alg_identifier.tag != alg->tag ||
  285. signer->alg_identifier.len != alg->len ||
  286. memcmp(signer->alg_identifier.p, alg->p, alg->len) != 0) {
  287. ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
  288. goto out;
  289. }
  290. /* Assume authenticatedAttributes is nonexistent */
  291. ret = pkcs7_get_digest_algorithm(p, end_signer, &signer->sig_alg_identifier);
  292. if (ret != 0) {
  293. goto out;
  294. }
  295. ret = pkcs7_get_signature(p, end_signer, &signer->sig);
  296. if (ret != 0) {
  297. goto out;
  298. }
  299. /* Do not permit any unauthenticated attributes */
  300. if (*p != end_signer) {
  301. ret = MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO;
  302. }
  303. out:
  304. if (asn1_ret != 0 || ret != 0) {
  305. pkcs7_free_signer_info(signer);
  306. ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO,
  307. asn1_ret);
  308. }
  309. return ret;
  310. }
  311. /**
  312. * SignerInfos ::= SET of SignerInfo
  313. * Return number of signers added to the signed data,
  314. * 0 or higher is valid.
  315. * Return negative error code for failure.
  316. **/
  317. static int pkcs7_get_signers_info_set(unsigned char **p, unsigned char *end,
  318. mbedtls_pkcs7_signer_info *signers_set,
  319. mbedtls_x509_buf *digest_alg)
  320. {
  321. unsigned char *end_set;
  322. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  323. int count = 0;
  324. size_t len = 0;
  325. ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
  326. | MBEDTLS_ASN1_SET);
  327. if (ret != 0) {
  328. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO, ret);
  329. }
  330. /* Detect zero signers */
  331. if (len == 0) {
  332. return 0;
  333. }
  334. end_set = *p + len;
  335. ret = pkcs7_get_signer_info(p, end_set, signers_set, digest_alg);
  336. if (ret != 0) {
  337. return ret;
  338. }
  339. count++;
  340. mbedtls_pkcs7_signer_info *prev = signers_set;
  341. while (*p != end_set) {
  342. mbedtls_pkcs7_signer_info *signer =
  343. mbedtls_calloc(1, sizeof(mbedtls_pkcs7_signer_info));
  344. if (!signer) {
  345. ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
  346. goto cleanup;
  347. }
  348. ret = pkcs7_get_signer_info(p, end_set, signer, digest_alg);
  349. if (ret != 0) {
  350. mbedtls_free(signer);
  351. goto cleanup;
  352. }
  353. prev->next = signer;
  354. prev = signer;
  355. count++;
  356. }
  357. return count;
  358. cleanup:
  359. pkcs7_free_signer_info(signers_set);
  360. mbedtls_pkcs7_signer_info *signer = signers_set->next;
  361. while (signer != NULL) {
  362. prev = signer;
  363. signer = signer->next;
  364. pkcs7_free_signer_info(prev);
  365. mbedtls_free(prev);
  366. }
  367. signers_set->next = NULL;
  368. return ret;
  369. }
  370. /**
  371. * SignedData ::= SEQUENCE {
  372. * version Version,
  373. * digestAlgorithms DigestAlgorithmIdentifiers,
  374. * contentInfo ContentInfo,
  375. * certificates
  376. * [0] IMPLICIT ExtendedCertificatesAndCertificates
  377. * OPTIONAL,
  378. * crls
  379. * [0] IMPLICIT CertificateRevocationLists OPTIONAL,
  380. * signerInfos SignerInfos }
  381. */
  382. static int pkcs7_get_signed_data(unsigned char *buf, size_t buflen,
  383. mbedtls_pkcs7_signed_data *signed_data)
  384. {
  385. unsigned char *p = buf;
  386. unsigned char *end = buf + buflen;
  387. unsigned char *end_content_info = NULL;
  388. size_t len = 0;
  389. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  390. mbedtls_md_type_t md_alg;
  391. ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
  392. | MBEDTLS_ASN1_SEQUENCE);
  393. if (ret != 0) {
  394. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
  395. }
  396. if (p + len != end) {
  397. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT,
  398. MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
  399. }
  400. /* Get version of signed data */
  401. ret = pkcs7_get_version(&p, end, &signed_data->version);
  402. if (ret != 0) {
  403. return ret;
  404. }
  405. /* Get digest algorithm */
  406. ret = pkcs7_get_digest_algorithm_set(&p, end,
  407. &signed_data->digest_alg_identifiers);
  408. if (ret != 0) {
  409. return ret;
  410. }
  411. ret = mbedtls_oid_get_md_alg(&signed_data->digest_alg_identifiers, &md_alg);
  412. if (ret != 0) {
  413. return MBEDTLS_ERR_PKCS7_INVALID_ALG;
  414. }
  415. mbedtls_pkcs7_buf content_type;
  416. memset(&content_type, 0, sizeof(content_type));
  417. ret = pkcs7_get_content_info_type(&p, end, &end_content_info, &content_type);
  418. if (ret != 0) {
  419. return ret;
  420. }
  421. if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS7_DATA, &content_type)) {
  422. return MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO;
  423. }
  424. if (p != end_content_info) {
  425. /* Determine if valid content is present */
  426. ret = mbedtls_asn1_get_tag(&p,
  427. end_content_info,
  428. &len,
  429. MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC);
  430. if (ret != 0) {
  431. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
  432. }
  433. p += len;
  434. if (p != end_content_info) {
  435. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO, ret);
  436. }
  437. /* Valid content is present - this is not supported */
  438. return MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
  439. }
  440. /* Look for certificates, there may or may not be any */
  441. mbedtls_x509_crt_init(&signed_data->certs);
  442. ret = pkcs7_get_certificates(&p, end, &signed_data->certs);
  443. if (ret < 0) {
  444. return ret;
  445. }
  446. signed_data->no_of_certs = ret;
  447. /*
  448. * Currently CRLs are not supported. If CRL exist, the parsing will fail
  449. * at next step of getting signers info and return error as invalid
  450. * signer info.
  451. */
  452. signed_data->no_of_crls = 0;
  453. /* Get signers info */
  454. ret = pkcs7_get_signers_info_set(&p,
  455. end,
  456. &signed_data->signers,
  457. &signed_data->digest_alg_identifiers);
  458. if (ret < 0) {
  459. return ret;
  460. }
  461. signed_data->no_of_signers = ret;
  462. /* Don't permit trailing data */
  463. if (p != end) {
  464. return MBEDTLS_ERR_PKCS7_INVALID_FORMAT;
  465. }
  466. return 0;
  467. }
  468. int mbedtls_pkcs7_parse_der(mbedtls_pkcs7 *pkcs7, const unsigned char *buf,
  469. const size_t buflen)
  470. {
  471. unsigned char *p;
  472. unsigned char *end;
  473. size_t len = 0;
  474. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  475. if (pkcs7 == NULL) {
  476. return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
  477. }
  478. /* make an internal copy of the buffer for parsing */
  479. pkcs7->raw.p = p = mbedtls_calloc(1, buflen);
  480. if (pkcs7->raw.p == NULL) {
  481. ret = MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
  482. goto out;
  483. }
  484. memcpy(p, buf, buflen);
  485. pkcs7->raw.len = buflen;
  486. end = p + buflen;
  487. ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED
  488. | MBEDTLS_ASN1_SEQUENCE);
  489. if (ret != 0) {
  490. ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT, ret);
  491. goto out;
  492. }
  493. if ((size_t) (end - p) != len) {
  494. ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_PKCS7_INVALID_FORMAT,
  495. MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
  496. goto out;
  497. }
  498. if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) {
  499. if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
  500. goto out;
  501. }
  502. p = pkcs7->raw.p;
  503. len = buflen;
  504. goto try_data;
  505. }
  506. if (MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_DATA, p, len)) {
  507. /* OID is not MBEDTLS_OID_PKCS7_SIGNED_DATA, which is the only supported feature */
  508. if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DATA, p, len)
  509. || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENCRYPTED_DATA, p, len)
  510. || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_ENVELOPED_DATA, p, len)
  511. || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA, p, len)
  512. || !MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DIGESTED_DATA, p, len)) {
  513. /* OID is valid according to the spec, but unsupported */
  514. ret = MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE;
  515. } else {
  516. /* OID is invalid according to the spec */
  517. ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
  518. }
  519. goto out;
  520. }
  521. p += len;
  522. ret = pkcs7_get_next_content_len(&p, end, &len);
  523. if (ret != 0) {
  524. goto out;
  525. }
  526. /* ensure no extra/missing data */
  527. if (p + len != end) {
  528. ret = MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
  529. goto out;
  530. }
  531. try_data:
  532. ret = pkcs7_get_signed_data(p, len, &pkcs7->signed_data);
  533. if (ret != 0) {
  534. goto out;
  535. }
  536. ret = MBEDTLS_PKCS7_SIGNED_DATA;
  537. out:
  538. if (ret < 0) {
  539. mbedtls_pkcs7_free(pkcs7);
  540. }
  541. return ret;
  542. }
  543. static int mbedtls_pkcs7_data_or_hash_verify(mbedtls_pkcs7 *pkcs7,
  544. const mbedtls_x509_crt *cert,
  545. const unsigned char *data,
  546. size_t datalen,
  547. const int is_data_hash)
  548. {
  549. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  550. unsigned char *hash;
  551. mbedtls_pk_context pk_cxt = cert->pk;
  552. const mbedtls_md_info_t *md_info;
  553. mbedtls_md_type_t md_alg;
  554. mbedtls_pkcs7_signer_info *signer;
  555. if (pkcs7->signed_data.no_of_signers == 0) {
  556. return MBEDTLS_ERR_PKCS7_INVALID_CERT;
  557. }
  558. if (mbedtls_x509_time_is_past(&cert->valid_to) ||
  559. mbedtls_x509_time_is_future(&cert->valid_from)) {
  560. return MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID;
  561. }
  562. ret = mbedtls_oid_get_md_alg(&pkcs7->signed_data.digest_alg_identifiers, &md_alg);
  563. if (ret != 0) {
  564. return ret;
  565. }
  566. md_info = mbedtls_md_info_from_type(md_alg);
  567. if (md_info == NULL) {
  568. return MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
  569. }
  570. hash = mbedtls_calloc(mbedtls_md_get_size(md_info), 1);
  571. if (hash == NULL) {
  572. return MBEDTLS_ERR_PKCS7_ALLOC_FAILED;
  573. }
  574. /* BEGIN must free hash before jumping out */
  575. if (is_data_hash) {
  576. if (datalen != mbedtls_md_get_size(md_info)) {
  577. ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
  578. } else {
  579. memcpy(hash, data, datalen);
  580. }
  581. } else {
  582. ret = mbedtls_md(md_info, data, datalen, hash);
  583. }
  584. if (ret != 0) {
  585. mbedtls_free(hash);
  586. return MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
  587. }
  588. /* assume failure */
  589. ret = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
  590. /*
  591. * Potential TODOs
  592. * Currently we iterate over all signers and return success if any of them
  593. * verify.
  594. *
  595. * However, we could make this better by checking against the certificate's
  596. * identification and SignerIdentifier fields first. That would also allow
  597. * us to distinguish between 'no signature for key' and 'signature for key
  598. * failed to validate'.
  599. */
  600. for (signer = &pkcs7->signed_data.signers; signer; signer = signer->next) {
  601. ret = mbedtls_pk_verify(&pk_cxt, md_alg, hash,
  602. mbedtls_md_get_size(md_info),
  603. signer->sig.p, signer->sig.len);
  604. if (ret == 0) {
  605. break;
  606. }
  607. }
  608. mbedtls_free(hash);
  609. /* END must free hash before jumping out */
  610. return ret;
  611. }
  612. int mbedtls_pkcs7_signed_data_verify(mbedtls_pkcs7 *pkcs7,
  613. const mbedtls_x509_crt *cert,
  614. const unsigned char *data,
  615. size_t datalen)
  616. {
  617. if (data == NULL) {
  618. return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
  619. }
  620. return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, data, datalen, 0);
  621. }
  622. int mbedtls_pkcs7_signed_hash_verify(mbedtls_pkcs7 *pkcs7,
  623. const mbedtls_x509_crt *cert,
  624. const unsigned char *hash,
  625. size_t hashlen)
  626. {
  627. if (hash == NULL) {
  628. return MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA;
  629. }
  630. return mbedtls_pkcs7_data_or_hash_verify(pkcs7, cert, hash, hashlen, 1);
  631. }
  632. /*
  633. * Unallocate all pkcs7 data
  634. */
  635. void mbedtls_pkcs7_free(mbedtls_pkcs7 *pkcs7)
  636. {
  637. mbedtls_pkcs7_signer_info *signer_cur;
  638. mbedtls_pkcs7_signer_info *signer_prev;
  639. if (pkcs7 == NULL || pkcs7->raw.p == NULL) {
  640. return;
  641. }
  642. mbedtls_free(pkcs7->raw.p);
  643. mbedtls_x509_crt_free(&pkcs7->signed_data.certs);
  644. mbedtls_x509_crl_free(&pkcs7->signed_data.crl);
  645. signer_cur = pkcs7->signed_data.signers.next;
  646. pkcs7_free_signer_info(&pkcs7->signed_data.signers);
  647. while (signer_cur != NULL) {
  648. signer_prev = signer_cur;
  649. signer_cur = signer_prev->next;
  650. pkcs7_free_signer_info(signer_prev);
  651. mbedtls_free(signer_prev);
  652. }
  653. pkcs7->raw.p = NULL;
  654. }
  655. #endif