2
0

ts_rsp_verify.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. /* crypto/ts/ts_resp_verify.c */
  2. /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
  3. * project 2002.
  4. */
  5. /* ====================================================================
  6. * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. All advertising materials mentioning features or use of this
  21. * software must display the following acknowledgment:
  22. * "This product includes software developed by the OpenSSL Project
  23. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  24. *
  25. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  26. * endorse or promote products derived from this software without
  27. * prior written permission. For written permission, please contact
  28. * licensing@OpenSSL.org.
  29. *
  30. * 5. Products derived from this software may not be called "OpenSSL"
  31. * nor may "OpenSSL" appear in their names without prior written
  32. * permission of the OpenSSL Project.
  33. *
  34. * 6. Redistributions of any form whatsoever must retain the following
  35. * acknowledgment:
  36. * "This product includes software developed by the OpenSSL Project
  37. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  38. *
  39. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  40. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  41. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  42. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  43. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  44. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  45. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  48. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  49. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  50. * OF THE POSSIBILITY OF SUCH DAMAGE.
  51. * ====================================================================
  52. *
  53. * This product includes cryptographic software written by Eric Young
  54. * (eay@cryptsoft.com). This product includes software written by Tim
  55. * Hudson (tjh@cryptsoft.com).
  56. *
  57. */
  58. #include <stdio.h>
  59. #include "cryptlib.h"
  60. #include <openssl/objects.h>
  61. #include <openssl/ts.h>
  62. #include <openssl/pkcs7.h>
  63. /* Private function declarations. */
  64. static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
  65. X509 *signer, STACK_OF(X509) **chain);
  66. static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain);
  67. static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si);
  68. static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert);
  69. static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo);
  70. static int _TS_RESP_verify_token(TS_VERIFY_CTX *ctx,
  71. PKCS7 *token, TS_TST_INFO *tst_info);
  72. static int TS_check_status_info(TS_RESP *response);
  73. static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text);
  74. static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info);
  75. static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
  76. X509_ALGOR **md_alg,
  77. unsigned char **imprint, unsigned *imprint_len);
  78. static int TS_check_imprints(X509_ALGOR *algor_a,
  79. unsigned char *imprint_a, unsigned len_a,
  80. TS_TST_INFO *tst_info);
  81. static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info);
  82. static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer);
  83. static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name);
  84. /*
  85. * Local mapping between response codes and descriptions.
  86. * Don't forget to change TS_STATUS_BUF_SIZE when modifying
  87. * the elements of this array.
  88. */
  89. static const char *TS_status_text[] =
  90. { "granted",
  91. "grantedWithMods",
  92. "rejection",
  93. "waiting",
  94. "revocationWarning",
  95. "revocationNotification" };
  96. #define TS_STATUS_TEXT_SIZE (sizeof(TS_status_text)/sizeof(*TS_status_text))
  97. /*
  98. * This must be greater or equal to the sum of the strings in TS_status_text
  99. * plus the number of its elements.
  100. */
  101. #define TS_STATUS_BUF_SIZE 256
  102. static struct
  103. {
  104. int code;
  105. const char *text;
  106. } TS_failure_info[] =
  107. { { TS_INFO_BAD_ALG, "badAlg" },
  108. { TS_INFO_BAD_REQUEST, "badRequest" },
  109. { TS_INFO_BAD_DATA_FORMAT, "badDataFormat" },
  110. { TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable" },
  111. { TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy" },
  112. { TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension" },
  113. { TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable" },
  114. { TS_INFO_SYSTEM_FAILURE, "systemFailure" } };
  115. #define TS_FAILURE_INFO_SIZE (sizeof(TS_failure_info) / \
  116. sizeof(*TS_failure_info))
  117. /* Functions for verifying a signed TS_TST_INFO structure. */
  118. /*
  119. * This function carries out the following tasks:
  120. * - Checks if there is one and only one signer.
  121. * - Search for the signing certificate in 'certs' and in the response.
  122. * - Check the extended key usage and key usage fields of the signer
  123. * certificate (done by the path validation).
  124. * - Build and validate the certificate path.
  125. * - Check if the certificate path meets the requirements of the
  126. * SigningCertificate ESS signed attribute.
  127. * - Verify the signature value.
  128. * - Returns the signer certificate in 'signer', if 'signer' is not NULL.
  129. */
  130. int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
  131. X509_STORE *store, X509 **signer_out)
  132. {
  133. STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL;
  134. PKCS7_SIGNER_INFO *si;
  135. STACK_OF(X509) *signers = NULL;
  136. X509 *signer;
  137. STACK_OF(X509) *chain = NULL;
  138. char buf[4096];
  139. int i, j = 0, ret = 0;
  140. BIO *p7bio = NULL;
  141. /* Some sanity checks first. */
  142. if (!token)
  143. {
  144. TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_INVALID_NULL_POINTER);
  145. goto err;
  146. }
  147. /* Check for the correct content type */
  148. if(!PKCS7_type_is_signed(token))
  149. {
  150. TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_WRONG_CONTENT_TYPE);
  151. goto err;
  152. }
  153. /* Check if there is one and only one signer. */
  154. sinfos = PKCS7_get_signer_info(token);
  155. if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1)
  156. {
  157. TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE,
  158. TS_R_THERE_MUST_BE_ONE_SIGNER);
  159. goto err;
  160. }
  161. si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0);
  162. /* Check for no content: no data to verify signature. */
  163. if (PKCS7_get_detached(token))
  164. {
  165. TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_NO_CONTENT);
  166. goto err;
  167. }
  168. /* Get hold of the signer certificate, search only internal
  169. certificates if it was requested. */
  170. signers = PKCS7_get0_signers(token, certs, 0);
  171. if (!signers || sk_X509_num(signers) != 1) goto err;
  172. signer = sk_X509_value(signers, 0);
  173. /* Now verify the certificate. */
  174. if (!TS_verify_cert(store, certs, signer, &chain)) goto err;
  175. /* Check if the signer certificate is consistent with the
  176. ESS extension. */
  177. if (!TS_check_signing_certs(si, chain)) goto err;
  178. /* Creating the message digest. */
  179. p7bio = PKCS7_dataInit(token, NULL);
  180. /* We now have to 'read' from p7bio to calculate digests etc. */
  181. while ((i = BIO_read(p7bio,buf,sizeof(buf))) > 0);
  182. /* Verifying the signature. */
  183. j = PKCS7_signatureVerify(p7bio, token, si, signer);
  184. if (j <= 0)
  185. {
  186. TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_SIGNATURE_FAILURE);
  187. goto err;
  188. }
  189. /* Return the signer certificate if needed. */
  190. if (signer_out)
  191. {
  192. *signer_out = signer;
  193. CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
  194. }
  195. ret = 1;
  196. err:
  197. BIO_free_all(p7bio);
  198. sk_X509_pop_free(chain, X509_free);
  199. sk_X509_free(signers);
  200. return ret;
  201. }
  202. /*
  203. * The certificate chain is returned in chain. Caller is responsible for
  204. * freeing the vector.
  205. */
  206. static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
  207. X509 *signer, STACK_OF(X509) **chain)
  208. {
  209. X509_STORE_CTX cert_ctx;
  210. int i;
  211. int ret = 1;
  212. /* chain is an out argument. */
  213. *chain = NULL;
  214. X509_STORE_CTX_init(&cert_ctx, store, signer, untrusted);
  215. X509_STORE_CTX_set_purpose(&cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN);
  216. i = X509_verify_cert(&cert_ctx);
  217. if (i <= 0)
  218. {
  219. int j = X509_STORE_CTX_get_error(&cert_ctx);
  220. TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR);
  221. ERR_add_error_data(2, "Verify error:",
  222. X509_verify_cert_error_string(j));
  223. ret = 0;
  224. }
  225. else
  226. {
  227. /* Get a copy of the certificate chain. */
  228. *chain = X509_STORE_CTX_get1_chain(&cert_ctx);
  229. }
  230. X509_STORE_CTX_cleanup(&cert_ctx);
  231. return ret;
  232. }
  233. static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain)
  234. {
  235. ESS_SIGNING_CERT *ss = ESS_get_signing_cert(si);
  236. STACK_OF(ESS_CERT_ID) *cert_ids = NULL;
  237. X509 *cert;
  238. int i = 0;
  239. int ret = 0;
  240. if (!ss) goto err;
  241. cert_ids = ss->cert_ids;
  242. /* The signer certificate must be the first in cert_ids. */
  243. cert = sk_X509_value(chain, 0);
  244. if (TS_find_cert(cert_ids, cert) != 0) goto err;
  245. /* Check the other certificates of the chain if there are more
  246. than one certificate ids in cert_ids. */
  247. if (sk_ESS_CERT_ID_num(cert_ids) > 1)
  248. {
  249. /* All the certificates of the chain must be in cert_ids. */
  250. for (i = 1; i < sk_X509_num(chain); ++i)
  251. {
  252. cert = sk_X509_value(chain, i);
  253. if (TS_find_cert(cert_ids, cert) < 0) goto err;
  254. }
  255. }
  256. ret = 1;
  257. err:
  258. if (!ret)
  259. TSerr(TS_F_TS_CHECK_SIGNING_CERTS,
  260. TS_R_ESS_SIGNING_CERTIFICATE_ERROR);
  261. ESS_SIGNING_CERT_free(ss);
  262. return ret;
  263. }
  264. static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si)
  265. {
  266. ASN1_TYPE *attr;
  267. const unsigned char *p;
  268. attr = PKCS7_get_signed_attribute(si,
  269. NID_id_smime_aa_signingCertificate);
  270. if (!attr) return NULL;
  271. p = attr->value.sequence->data;
  272. return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length);
  273. }
  274. /* Returns < 0 if certificate is not found, certificate index otherwise. */
  275. static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert)
  276. {
  277. int i;
  278. if (!cert_ids || !cert) return -1;
  279. /* Recompute SHA1 hash of certificate if necessary (side effect). */
  280. X509_check_purpose(cert, -1, 0);
  281. /* Look for cert in the cert_ids vector. */
  282. for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i)
  283. {
  284. ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i);
  285. /* Check the SHA-1 hash first. */
  286. if (cid->hash->length == sizeof(cert->sha1_hash)
  287. && !memcmp(cid->hash->data, cert->sha1_hash,
  288. sizeof(cert->sha1_hash)))
  289. {
  290. /* Check the issuer/serial as well if specified. */
  291. ESS_ISSUER_SERIAL *is = cid->issuer_serial;
  292. if (!is || !TS_issuer_serial_cmp(is, cert->cert_info))
  293. return i;
  294. }
  295. }
  296. return -1;
  297. }
  298. static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo)
  299. {
  300. GENERAL_NAME *issuer;
  301. if (!is || !cinfo || sk_GENERAL_NAME_num(is->issuer) != 1) return -1;
  302. /* Check the issuer first. It must be a directory name. */
  303. issuer = sk_GENERAL_NAME_value(is->issuer, 0);
  304. if (issuer->type != GEN_DIRNAME
  305. || X509_NAME_cmp(issuer->d.dirn, cinfo->issuer))
  306. return -1;
  307. /* Check the serial number, too. */
  308. if (ASN1_INTEGER_cmp(is->serial, cinfo->serialNumber))
  309. return -1;
  310. return 0;
  311. }
  312. /*
  313. * Verifies whether 'response' contains a valid response with regards
  314. * to the settings of the context:
  315. * - Gives an error message if the TS_TST_INFO is not present.
  316. * - Calls _TS_RESP_verify_token to verify the token content.
  317. */
  318. int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response)
  319. {
  320. PKCS7 *token = TS_RESP_get_token(response);
  321. TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response);
  322. int ret = 0;
  323. /* Check if we have a successful TS_TST_INFO object in place. */
  324. if (!TS_check_status_info(response)) goto err;
  325. /* Check the contents of the time stamp token. */
  326. if (!_TS_RESP_verify_token(ctx, token, tst_info))
  327. goto err;
  328. ret = 1;
  329. err:
  330. return ret;
  331. }
  332. /*
  333. * Tries to extract a TS_TST_INFO structure from the PKCS7 token and
  334. * calls the internal _TS_RESP_verify_token function for verifying it.
  335. */
  336. int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token)
  337. {
  338. TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token);
  339. int ret = 0;
  340. if (tst_info)
  341. {
  342. ret = _TS_RESP_verify_token(ctx, token, tst_info);
  343. TS_TST_INFO_free(tst_info);
  344. }
  345. return ret;
  346. }
  347. /*
  348. * Verifies whether the 'token' contains a valid time stamp token
  349. * with regards to the settings of the context. Only those checks are
  350. * carried out that are specified in the context:
  351. * - Verifies the signature of the TS_TST_INFO.
  352. * - Checks the version number of the response.
  353. * - Check if the requested and returned policies math.
  354. * - Check if the message imprints are the same.
  355. * - Check if the nonces are the same.
  356. * - Check if the TSA name matches the signer.
  357. * - Check if the TSA name is the expected TSA.
  358. */
  359. static int _TS_RESP_verify_token(TS_VERIFY_CTX *ctx,
  360. PKCS7 *token, TS_TST_INFO *tst_info)
  361. {
  362. X509 *signer = NULL;
  363. GENERAL_NAME *tsa_name = TS_TST_INFO_get_tsa(tst_info);
  364. X509_ALGOR *md_alg = NULL;
  365. unsigned char *imprint = NULL;
  366. unsigned imprint_len = 0;
  367. int ret = 0;
  368. /* Verify the signature. */
  369. if ((ctx->flags & TS_VFY_SIGNATURE)
  370. && !TS_RESP_verify_signature(token, ctx->certs, ctx->store,
  371. &signer))
  372. goto err;
  373. /* Check version number of response. */
  374. if ((ctx->flags & TS_VFY_VERSION)
  375. && TS_TST_INFO_get_version(tst_info) != 1)
  376. {
  377. TSerr(TS_F_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION);
  378. goto err;
  379. }
  380. /* Check policies. */
  381. if ((ctx->flags & TS_VFY_POLICY)
  382. && !TS_check_policy(ctx->policy, tst_info))
  383. goto err;
  384. /* Check message imprints. */
  385. if ((ctx->flags & TS_VFY_IMPRINT)
  386. && !TS_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len,
  387. tst_info))
  388. goto err;
  389. /* Compute and check message imprints. */
  390. if ((ctx->flags & TS_VFY_DATA)
  391. && (!TS_compute_imprint(ctx->data, tst_info,
  392. &md_alg, &imprint, &imprint_len)
  393. || !TS_check_imprints(md_alg, imprint, imprint_len, tst_info)))
  394. goto err;
  395. /* Check nonces. */
  396. if ((ctx->flags & TS_VFY_NONCE)
  397. && !TS_check_nonces(ctx->nonce, tst_info))
  398. goto err;
  399. /* Check whether TSA name and signer certificate match. */
  400. if ((ctx->flags & TS_VFY_SIGNER)
  401. && tsa_name && !TS_check_signer_name(tsa_name, signer))
  402. {
  403. TSerr(TS_F_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH);
  404. goto err;
  405. }
  406. /* Check whether the TSA is the expected one. */
  407. if ((ctx->flags & TS_VFY_TSA_NAME)
  408. && !TS_check_signer_name(ctx->tsa_name, signer))
  409. {
  410. TSerr(TS_F_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED);
  411. goto err;
  412. }
  413. ret = 1;
  414. err:
  415. X509_free(signer);
  416. X509_ALGOR_free(md_alg);
  417. OPENSSL_free(imprint);
  418. return ret;
  419. }
  420. static int TS_check_status_info(TS_RESP *response)
  421. {
  422. TS_STATUS_INFO *info = TS_RESP_get_status_info(response);
  423. long status = ASN1_INTEGER_get(info->status);
  424. const char *status_text = NULL;
  425. char *embedded_status_text = NULL;
  426. char failure_text[TS_STATUS_BUF_SIZE] = "";
  427. /* Check if everything went fine. */
  428. if (status == 0 || status == 1) return 1;
  429. /* There was an error, get the description in status_text. */
  430. if (0 <= status && status < (long)TS_STATUS_TEXT_SIZE)
  431. status_text = TS_status_text[status];
  432. else
  433. status_text = "unknown code";
  434. /* Set the embedded_status_text to the returned description. */
  435. if (sk_ASN1_UTF8STRING_num(info->text) > 0
  436. && !(embedded_status_text = TS_get_status_text(info->text)))
  437. return 0;
  438. /* Filling in failure_text with the failure information. */
  439. if (info->failure_info)
  440. {
  441. int i;
  442. int first = 1;
  443. for (i = 0; i < (int)TS_FAILURE_INFO_SIZE; ++i)
  444. {
  445. if (ASN1_BIT_STRING_get_bit(info->failure_info,
  446. TS_failure_info[i].code))
  447. {
  448. if (!first)
  449. strcpy(failure_text, ",");
  450. else
  451. first = 0;
  452. strcat(failure_text, TS_failure_info[i].text);
  453. }
  454. }
  455. }
  456. if (failure_text[0] == '\0')
  457. strcpy(failure_text, "unspecified");
  458. /* Making up the error string. */
  459. TSerr(TS_F_TS_CHECK_STATUS_INFO, TS_R_NO_TIME_STAMP_TOKEN);
  460. ERR_add_error_data(6,
  461. "status code: ", status_text,
  462. ", status text: ", embedded_status_text ?
  463. embedded_status_text : "unspecified",
  464. ", failure codes: ", failure_text);
  465. OPENSSL_free(embedded_status_text);
  466. return 0;
  467. }
  468. static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text)
  469. {
  470. int i;
  471. unsigned int length = 0;
  472. char *result = NULL;
  473. char *p;
  474. /* Determine length first. */
  475. for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i)
  476. {
  477. ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
  478. length += ASN1_STRING_length(current);
  479. length += 1; /* separator character */
  480. }
  481. /* Allocate memory (closing '\0' included). */
  482. if (!(result = OPENSSL_malloc(length)))
  483. {
  484. TSerr(TS_F_TS_GET_STATUS_TEXT, ERR_R_MALLOC_FAILURE);
  485. return NULL;
  486. }
  487. /* Concatenate the descriptions. */
  488. for (i = 0, p = result; i < sk_ASN1_UTF8STRING_num(text); ++i)
  489. {
  490. ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
  491. length = ASN1_STRING_length(current);
  492. if (i > 0) *p++ = '/';
  493. strncpy(p, (const char *)ASN1_STRING_data(current), length);
  494. p += length;
  495. }
  496. /* We do have space for this, too. */
  497. *p = '\0';
  498. return result;
  499. }
  500. static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info)
  501. {
  502. ASN1_OBJECT *resp_oid = TS_TST_INFO_get_policy_id(tst_info);
  503. if (OBJ_cmp(req_oid, resp_oid) != 0)
  504. {
  505. TSerr(TS_F_TS_CHECK_POLICY, TS_R_POLICY_MISMATCH);
  506. return 0;
  507. }
  508. return 1;
  509. }
  510. static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
  511. X509_ALGOR **md_alg,
  512. unsigned char **imprint, unsigned *imprint_len)
  513. {
  514. TS_MSG_IMPRINT *msg_imprint = TS_TST_INFO_get_msg_imprint(tst_info);
  515. X509_ALGOR *md_alg_resp = TS_MSG_IMPRINT_get_algo(msg_imprint);
  516. const EVP_MD *md;
  517. EVP_MD_CTX md_ctx;
  518. unsigned char buffer[4096];
  519. int length;
  520. *md_alg = NULL;
  521. *imprint = NULL;
  522. /* Return the MD algorithm of the response. */
  523. if (!(*md_alg = X509_ALGOR_dup(md_alg_resp))) goto err;
  524. /* Getting the MD object. */
  525. if (!(md = EVP_get_digestbyobj((*md_alg)->algorithm)))
  526. {
  527. TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM);
  528. goto err;
  529. }
  530. /* Compute message digest. */
  531. *imprint_len = EVP_MD_size(md);
  532. if (!(*imprint = OPENSSL_malloc(*imprint_len)))
  533. {
  534. TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE);
  535. goto err;
  536. }
  537. EVP_DigestInit(&md_ctx, md);
  538. while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0)
  539. {
  540. EVP_DigestUpdate(&md_ctx, buffer, length);
  541. }
  542. EVP_DigestFinal(&md_ctx, *imprint, NULL);
  543. return 1;
  544. err:
  545. X509_ALGOR_free(*md_alg);
  546. OPENSSL_free(*imprint);
  547. *imprint_len = 0;
  548. return 0;
  549. }
  550. static int TS_check_imprints(X509_ALGOR *algor_a,
  551. unsigned char *imprint_a, unsigned len_a,
  552. TS_TST_INFO *tst_info)
  553. {
  554. TS_MSG_IMPRINT *b = TS_TST_INFO_get_msg_imprint(tst_info);
  555. X509_ALGOR *algor_b = TS_MSG_IMPRINT_get_algo(b);
  556. int ret = 0;
  557. /* algor_a is optional. */
  558. if (algor_a)
  559. {
  560. /* Compare algorithm OIDs. */
  561. if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm)) goto err;
  562. /* The parameter must be NULL in both. */
  563. if ((algor_a->parameter
  564. && ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL)
  565. || (algor_b->parameter
  566. && ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL))
  567. goto err;
  568. }
  569. /* Compare octet strings. */
  570. ret = len_a == (unsigned) ASN1_STRING_length(b->hashed_msg) &&
  571. memcmp(imprint_a, ASN1_STRING_data(b->hashed_msg), len_a) == 0;
  572. err:
  573. if (!ret)
  574. TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH);
  575. return ret;
  576. }
  577. static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info)
  578. {
  579. const ASN1_INTEGER *b = TS_TST_INFO_get_nonce(tst_info);
  580. /* Error if nonce is missing. */
  581. if (!b)
  582. {
  583. TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_NOT_RETURNED);
  584. return 0;
  585. }
  586. /* No error if a nonce is returned without being requested. */
  587. if (ASN1_INTEGER_cmp(a, b) != 0)
  588. {
  589. TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_MISMATCH);
  590. return 0;
  591. }
  592. return 1;
  593. }
  594. /* Check if the specified TSA name matches either the subject
  595. or one of the subject alternative names of the TSA certificate. */
  596. static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer)
  597. {
  598. STACK_OF(GENERAL_NAME) *gen_names = NULL;
  599. int idx = -1;
  600. int found = 0;
  601. /* Check the subject name first. */
  602. if (tsa_name->type == GEN_DIRNAME
  603. && X509_name_cmp(tsa_name->d.dirn, signer->cert_info->subject) == 0)
  604. return 1;
  605. /* Check all the alternative names. */
  606. gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name,
  607. NULL, &idx);
  608. while (gen_names != NULL
  609. && !(found = TS_find_name(gen_names, tsa_name) >= 0))
  610. {
  611. /* Get the next subject alternative name,
  612. although there should be no more than one. */
  613. GENERAL_NAMES_free(gen_names);
  614. gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name,
  615. NULL, &idx);
  616. }
  617. if (gen_names) GENERAL_NAMES_free(gen_names);
  618. return found;
  619. }
  620. /* Returns 1 if name is in gen_names, 0 otherwise. */
  621. static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name)
  622. {
  623. int i, found;
  624. for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names);
  625. ++i)
  626. {
  627. GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i);
  628. found = GENERAL_NAME_cmp(current, name) == 0;
  629. }
  630. return found ? i - 1 : -1;
  631. }