pkcs7.c 23 KB

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