x509_lu.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. /* crypto/x509/x509_lu.c */
  2. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  3. * All rights reserved.
  4. *
  5. * This package is an SSL implementation written
  6. * by Eric Young (eay@cryptsoft.com).
  7. * The implementation was written so as to conform with Netscapes SSL.
  8. *
  9. * This library is free for commercial and non-commercial use as long as
  10. * the following conditions are aheared to. The following conditions
  11. * apply to all code found in this distribution, be it the RC4, RSA,
  12. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  13. * included with this distribution is covered by the same copyright terms
  14. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  15. *
  16. * Copyright remains Eric Young's, and as such any Copyright notices in
  17. * the code are not to be removed.
  18. * If this package is used in a product, Eric Young should be given attribution
  19. * as the author of the parts of the library used.
  20. * This can be in the form of a textual message at program startup or
  21. * in documentation (online or textual) provided with the package.
  22. *
  23. * Redistribution and use in source and binary forms, with or without
  24. * modification, are permitted provided that the following conditions
  25. * are met:
  26. * 1. Redistributions of source code must retain the copyright
  27. * notice, this list of conditions and the following disclaimer.
  28. * 2. Redistributions in binary form must reproduce the above copyright
  29. * notice, this list of conditions and the following disclaimer in the
  30. * documentation and/or other materials provided with the distribution.
  31. * 3. All advertising materials mentioning features or use of this software
  32. * must display the following acknowledgement:
  33. * "This product includes cryptographic software written by
  34. * Eric Young (eay@cryptsoft.com)"
  35. * The word 'cryptographic' can be left out if the rouines from the library
  36. * being used are not cryptographic related :-).
  37. * 4. If you include any Windows specific code (or a derivative thereof) from
  38. * the apps directory (application code) you must include an acknowledgement:
  39. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  40. *
  41. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  42. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  45. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51. * SUCH DAMAGE.
  52. *
  53. * The licence and distribution terms for any publically available version or
  54. * derivative of this code cannot be changed. i.e. this code cannot simply be
  55. * copied and put under another distribution licence
  56. * [including the GNU Public Licence.]
  57. */
  58. #include <stdio.h>
  59. #include "cryptlib.h"
  60. #include <openssl/lhash.h>
  61. #include <openssl/x509.h>
  62. #include <openssl/x509v3.h>
  63. X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
  64. {
  65. X509_LOOKUP *ret;
  66. ret = (X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP));
  67. if (ret == NULL)
  68. return NULL;
  69. ret->init = 0;
  70. ret->skip = 0;
  71. ret->method = method;
  72. ret->method_data = NULL;
  73. ret->store_ctx = NULL;
  74. if ((method->new_item != NULL) && !method->new_item(ret)) {
  75. OPENSSL_free(ret);
  76. return NULL;
  77. }
  78. return ret;
  79. }
  80. void X509_LOOKUP_free(X509_LOOKUP *ctx)
  81. {
  82. if (ctx == NULL)
  83. return;
  84. if ((ctx->method != NULL) && (ctx->method->free != NULL))
  85. (*ctx->method->free) (ctx);
  86. OPENSSL_free(ctx);
  87. }
  88. int X509_LOOKUP_init(X509_LOOKUP *ctx)
  89. {
  90. if (ctx->method == NULL)
  91. return 0;
  92. if (ctx->method->init != NULL)
  93. return ctx->method->init(ctx);
  94. else
  95. return 1;
  96. }
  97. int X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
  98. {
  99. if (ctx->method == NULL)
  100. return 0;
  101. if (ctx->method->shutdown != NULL)
  102. return ctx->method->shutdown(ctx);
  103. else
  104. return 1;
  105. }
  106. int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
  107. char **ret)
  108. {
  109. if (ctx->method == NULL)
  110. return -1;
  111. if (ctx->method->ctrl != NULL)
  112. return ctx->method->ctrl(ctx, cmd, argc, argl, ret);
  113. else
  114. return 1;
  115. }
  116. int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
  117. X509_OBJECT *ret)
  118. {
  119. if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
  120. return X509_LU_FAIL;
  121. if (ctx->skip)
  122. return 0;
  123. return ctx->method->get_by_subject(ctx, type, name, ret);
  124. }
  125. int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
  126. ASN1_INTEGER *serial, X509_OBJECT *ret)
  127. {
  128. if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL))
  129. return X509_LU_FAIL;
  130. return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret);
  131. }
  132. int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
  133. unsigned char *bytes, int len,
  134. X509_OBJECT *ret)
  135. {
  136. if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
  137. return X509_LU_FAIL;
  138. return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret);
  139. }
  140. int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len,
  141. X509_OBJECT *ret)
  142. {
  143. if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
  144. return X509_LU_FAIL;
  145. return ctx->method->get_by_alias(ctx, type, str, len, ret);
  146. }
  147. static int x509_object_cmp(const X509_OBJECT *const *a,
  148. const X509_OBJECT *const *b)
  149. {
  150. int ret;
  151. ret = ((*a)->type - (*b)->type);
  152. if (ret)
  153. return ret;
  154. switch ((*a)->type) {
  155. case X509_LU_X509:
  156. ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509);
  157. break;
  158. case X509_LU_CRL:
  159. ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl);
  160. break;
  161. default:
  162. /* abort(); */
  163. return 0;
  164. }
  165. return ret;
  166. }
  167. X509_STORE *X509_STORE_new(void)
  168. {
  169. X509_STORE *ret;
  170. if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL)
  171. return NULL;
  172. if ((ret->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL)
  173. goto err0;
  174. ret->cache = 1;
  175. if ((ret->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL)
  176. goto err1;
  177. ret->verify = 0;
  178. ret->verify_cb = 0;
  179. if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
  180. goto err2;
  181. ret->get_issuer = 0;
  182. ret->check_issued = 0;
  183. ret->check_revocation = 0;
  184. ret->get_crl = 0;
  185. ret->check_crl = 0;
  186. ret->cert_crl = 0;
  187. ret->lookup_certs = 0;
  188. ret->lookup_crls = 0;
  189. ret->cleanup = 0;
  190. if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data))
  191. goto err3;
  192. ret->references = 1;
  193. return ret;
  194. err3:
  195. X509_VERIFY_PARAM_free(ret->param);
  196. err2:
  197. sk_X509_LOOKUP_free(ret->get_cert_methods);
  198. err1:
  199. sk_X509_OBJECT_free(ret->objs);
  200. err0:
  201. OPENSSL_free(ret);
  202. return NULL;
  203. }
  204. static void cleanup(X509_OBJECT *a)
  205. {
  206. if (!a)
  207. return;
  208. if (a->type == X509_LU_X509) {
  209. X509_free(a->data.x509);
  210. } else if (a->type == X509_LU_CRL) {
  211. X509_CRL_free(a->data.crl);
  212. } else {
  213. /* abort(); */
  214. }
  215. OPENSSL_free(a);
  216. }
  217. void X509_STORE_free(X509_STORE *vfy)
  218. {
  219. int i;
  220. STACK_OF(X509_LOOKUP) *sk;
  221. X509_LOOKUP *lu;
  222. if (vfy == NULL)
  223. return;
  224. i = CRYPTO_add(&vfy->references, -1, CRYPTO_LOCK_X509_STORE);
  225. #ifdef REF_PRINT
  226. REF_PRINT("X509_STORE", vfy);
  227. #endif
  228. if (i > 0)
  229. return;
  230. #ifdef REF_CHECK
  231. if (i < 0) {
  232. fprintf(stderr, "X509_STORE_free, bad reference count\n");
  233. abort(); /* ok */
  234. }
  235. #endif
  236. sk = vfy->get_cert_methods;
  237. for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
  238. lu = sk_X509_LOOKUP_value(sk, i);
  239. X509_LOOKUP_shutdown(lu);
  240. X509_LOOKUP_free(lu);
  241. }
  242. sk_X509_LOOKUP_free(sk);
  243. sk_X509_OBJECT_pop_free(vfy->objs, cleanup);
  244. CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data);
  245. if (vfy->param)
  246. X509_VERIFY_PARAM_free(vfy->param);
  247. OPENSSL_free(vfy);
  248. }
  249. X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
  250. {
  251. int i;
  252. STACK_OF(X509_LOOKUP) *sk;
  253. X509_LOOKUP *lu;
  254. sk = v->get_cert_methods;
  255. for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
  256. lu = sk_X509_LOOKUP_value(sk, i);
  257. if (m == lu->method) {
  258. return lu;
  259. }
  260. }
  261. /* a new one */
  262. lu = X509_LOOKUP_new(m);
  263. if (lu == NULL)
  264. return NULL;
  265. else {
  266. lu->store_ctx = v;
  267. if (sk_X509_LOOKUP_push(v->get_cert_methods, lu))
  268. return lu;
  269. else {
  270. X509_LOOKUP_free(lu);
  271. return NULL;
  272. }
  273. }
  274. }
  275. int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
  276. X509_OBJECT *ret)
  277. {
  278. X509_STORE *ctx = vs->ctx;
  279. X509_LOOKUP *lu;
  280. X509_OBJECT stmp, *tmp;
  281. int i, j;
  282. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  283. tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
  284. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  285. if (tmp == NULL || type == X509_LU_CRL) {
  286. for (i = vs->current_method;
  287. i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
  288. lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
  289. j = X509_LOOKUP_by_subject(lu, type, name, &stmp);
  290. if (j < 0) {
  291. vs->current_method = j;
  292. return j;
  293. } else if (j) {
  294. tmp = &stmp;
  295. break;
  296. }
  297. }
  298. vs->current_method = 0;
  299. if (tmp == NULL)
  300. return 0;
  301. }
  302. /*- if (ret->data.ptr != NULL)
  303. X509_OBJECT_free_contents(ret); */
  304. ret->type = tmp->type;
  305. ret->data.ptr = tmp->data.ptr;
  306. X509_OBJECT_up_ref_count(ret);
  307. return 1;
  308. }
  309. int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
  310. {
  311. X509_OBJECT *obj;
  312. int ret = 1;
  313. if (x == NULL)
  314. return 0;
  315. obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
  316. if (obj == NULL) {
  317. X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE);
  318. return 0;
  319. }
  320. obj->type = X509_LU_X509;
  321. obj->data.x509 = x;
  322. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  323. X509_OBJECT_up_ref_count(obj);
  324. if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
  325. X509_OBJECT_free_contents(obj);
  326. OPENSSL_free(obj);
  327. X509err(X509_F_X509_STORE_ADD_CERT,
  328. X509_R_CERT_ALREADY_IN_HASH_TABLE);
  329. ret = 0;
  330. } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) {
  331. X509_OBJECT_free_contents(obj);
  332. OPENSSL_free(obj);
  333. X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE);
  334. ret = 0;
  335. }
  336. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  337. return ret;
  338. }
  339. int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
  340. {
  341. X509_OBJECT *obj;
  342. int ret = 1;
  343. if (x == NULL)
  344. return 0;
  345. obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
  346. if (obj == NULL) {
  347. X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE);
  348. return 0;
  349. }
  350. obj->type = X509_LU_CRL;
  351. obj->data.crl = x;
  352. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  353. X509_OBJECT_up_ref_count(obj);
  354. if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
  355. X509_OBJECT_free_contents(obj);
  356. OPENSSL_free(obj);
  357. X509err(X509_F_X509_STORE_ADD_CRL, X509_R_CERT_ALREADY_IN_HASH_TABLE);
  358. ret = 0;
  359. } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) {
  360. X509_OBJECT_free_contents(obj);
  361. OPENSSL_free(obj);
  362. X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE);
  363. ret = 0;
  364. }
  365. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  366. return ret;
  367. }
  368. void X509_OBJECT_up_ref_count(X509_OBJECT *a)
  369. {
  370. switch (a->type) {
  371. case X509_LU_X509:
  372. CRYPTO_add(&a->data.x509->references, 1, CRYPTO_LOCK_X509);
  373. break;
  374. case X509_LU_CRL:
  375. CRYPTO_add(&a->data.crl->references, 1, CRYPTO_LOCK_X509_CRL);
  376. break;
  377. }
  378. }
  379. void X509_OBJECT_free_contents(X509_OBJECT *a)
  380. {
  381. switch (a->type) {
  382. case X509_LU_X509:
  383. X509_free(a->data.x509);
  384. break;
  385. case X509_LU_CRL:
  386. X509_CRL_free(a->data.crl);
  387. break;
  388. }
  389. }
  390. static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
  391. X509_NAME *name, int *pnmatch)
  392. {
  393. X509_OBJECT stmp;
  394. X509 x509_s;
  395. X509_CINF cinf_s;
  396. X509_CRL crl_s;
  397. X509_CRL_INFO crl_info_s;
  398. int idx;
  399. stmp.type = type;
  400. switch (type) {
  401. case X509_LU_X509:
  402. stmp.data.x509 = &x509_s;
  403. x509_s.cert_info = &cinf_s;
  404. cinf_s.subject = name;
  405. break;
  406. case X509_LU_CRL:
  407. stmp.data.crl = &crl_s;
  408. crl_s.crl = &crl_info_s;
  409. crl_info_s.issuer = name;
  410. break;
  411. default:
  412. /* abort(); */
  413. return -1;
  414. }
  415. idx = sk_X509_OBJECT_find(h, &stmp);
  416. if (idx >= 0 && pnmatch) {
  417. int tidx;
  418. const X509_OBJECT *tobj, *pstmp;
  419. *pnmatch = 1;
  420. pstmp = &stmp;
  421. for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) {
  422. tobj = sk_X509_OBJECT_value(h, tidx);
  423. if (x509_object_cmp(&tobj, &pstmp))
  424. break;
  425. (*pnmatch)++;
  426. }
  427. }
  428. return idx;
  429. }
  430. int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
  431. X509_NAME *name)
  432. {
  433. return x509_object_idx_cnt(h, type, name, NULL);
  434. }
  435. X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
  436. int type, X509_NAME *name)
  437. {
  438. int idx;
  439. idx = X509_OBJECT_idx_by_subject(h, type, name);
  440. if (idx == -1)
  441. return NULL;
  442. return sk_X509_OBJECT_value(h, idx);
  443. }
  444. STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
  445. {
  446. int i, idx, cnt;
  447. STACK_OF(X509) *sk;
  448. X509 *x;
  449. X509_OBJECT *obj;
  450. sk = sk_X509_new_null();
  451. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  452. idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
  453. if (idx < 0) {
  454. /*
  455. * Nothing found in cache: do lookup to possibly add new objects to
  456. * cache
  457. */
  458. X509_OBJECT xobj;
  459. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  460. if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) {
  461. sk_X509_free(sk);
  462. return NULL;
  463. }
  464. X509_OBJECT_free_contents(&xobj);
  465. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  466. idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
  467. if (idx < 0) {
  468. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  469. sk_X509_free(sk);
  470. return NULL;
  471. }
  472. }
  473. for (i = 0; i < cnt; i++, idx++) {
  474. obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
  475. x = obj->data.x509;
  476. CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
  477. if (!sk_X509_push(sk, x)) {
  478. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  479. X509_free(x);
  480. sk_X509_pop_free(sk, X509_free);
  481. return NULL;
  482. }
  483. }
  484. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  485. return sk;
  486. }
  487. STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
  488. {
  489. int i, idx, cnt;
  490. STACK_OF(X509_CRL) *sk;
  491. X509_CRL *x;
  492. X509_OBJECT *obj, xobj;
  493. sk = sk_X509_CRL_new_null();
  494. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  495. /*
  496. * Always do lookup to possibly add new CRLs to cache
  497. */
  498. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  499. if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) {
  500. sk_X509_CRL_free(sk);
  501. return NULL;
  502. }
  503. X509_OBJECT_free_contents(&xobj);
  504. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  505. idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
  506. if (idx < 0) {
  507. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  508. sk_X509_CRL_free(sk);
  509. return NULL;
  510. }
  511. for (i = 0; i < cnt; i++, idx++) {
  512. obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
  513. x = obj->data.crl;
  514. CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL);
  515. if (!sk_X509_CRL_push(sk, x)) {
  516. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  517. X509_CRL_free(x);
  518. sk_X509_CRL_pop_free(sk, X509_CRL_free);
  519. return NULL;
  520. }
  521. }
  522. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  523. return sk;
  524. }
  525. X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
  526. X509_OBJECT *x)
  527. {
  528. int idx, i;
  529. X509_OBJECT *obj;
  530. idx = sk_X509_OBJECT_find(h, x);
  531. if (idx == -1)
  532. return NULL;
  533. if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
  534. return sk_X509_OBJECT_value(h, idx);
  535. for (i = idx; i < sk_X509_OBJECT_num(h); i++) {
  536. obj = sk_X509_OBJECT_value(h, i);
  537. if (x509_object_cmp
  538. ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
  539. return NULL;
  540. if (x->type == X509_LU_X509) {
  541. if (!X509_cmp(obj->data.x509, x->data.x509))
  542. return obj;
  543. } else if (x->type == X509_LU_CRL) {
  544. if (!X509_CRL_match(obj->data.crl, x->data.crl))
  545. return obj;
  546. } else
  547. return obj;
  548. }
  549. return NULL;
  550. }
  551. /*-
  552. * Try to get issuer certificate from store. Due to limitations
  553. * of the API this can only retrieve a single certificate matching
  554. * a given subject name. However it will fill the cache with all
  555. * matching certificates, so we can examine the cache for all
  556. * matches.
  557. *
  558. * Return values are:
  559. * 1 lookup successful.
  560. * 0 certificate not found.
  561. * -1 some other error.
  562. */
  563. int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
  564. {
  565. X509_NAME *xn;
  566. X509_OBJECT obj, *pobj;
  567. int i, ok, idx, ret;
  568. xn = X509_get_issuer_name(x);
  569. ok = X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj);
  570. if (ok != X509_LU_X509) {
  571. if (ok == X509_LU_RETRY) {
  572. X509_OBJECT_free_contents(&obj);
  573. X509err(X509_F_X509_STORE_CTX_GET1_ISSUER, X509_R_SHOULD_RETRY);
  574. return -1;
  575. } else if (ok != X509_LU_FAIL) {
  576. X509_OBJECT_free_contents(&obj);
  577. /* not good :-(, break anyway */
  578. return -1;
  579. }
  580. return 0;
  581. }
  582. /* If certificate matches all OK */
  583. if (ctx->check_issued(ctx, x, obj.data.x509)) {
  584. *issuer = obj.data.x509;
  585. return 1;
  586. }
  587. X509_OBJECT_free_contents(&obj);
  588. /* Else find index of first cert accepted by 'check_issued' */
  589. ret = 0;
  590. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  591. idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
  592. if (idx != -1) { /* should be true as we've had at least one
  593. * match */
  594. /* Look through all matching certs for suitable issuer */
  595. for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) {
  596. pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
  597. /* See if we've run past the matches */
  598. if (pobj->type != X509_LU_X509)
  599. break;
  600. if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
  601. break;
  602. if (ctx->check_issued(ctx, x, pobj->data.x509)) {
  603. *issuer = pobj->data.x509;
  604. X509_OBJECT_up_ref_count(pobj);
  605. ret = 1;
  606. break;
  607. }
  608. }
  609. }
  610. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  611. return ret;
  612. }
  613. int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
  614. {
  615. return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
  616. }
  617. int X509_STORE_set_depth(X509_STORE *ctx, int depth)
  618. {
  619. X509_VERIFY_PARAM_set_depth(ctx->param, depth);
  620. return 1;
  621. }
  622. int X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
  623. {
  624. return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
  625. }
  626. int X509_STORE_set_trust(X509_STORE *ctx, int trust)
  627. {
  628. return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
  629. }
  630. int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
  631. {
  632. return X509_VERIFY_PARAM_set1(ctx->param, param);
  633. }
  634. void X509_STORE_set_verify_cb(X509_STORE *ctx,
  635. int (*verify_cb) (int, X509_STORE_CTX *))
  636. {
  637. ctx->verify_cb = verify_cb;
  638. }
  639. void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx,
  640. STACK_OF(X509_CRL) *(*cb) (X509_STORE_CTX
  641. *ctx,
  642. X509_NAME *nm))
  643. {
  644. ctx->lookup_crls = cb;
  645. }
  646. X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx)
  647. {
  648. return ctx->ctx;
  649. }
  650. IMPLEMENT_STACK_OF(X509_LOOKUP)
  651. IMPLEMENT_STACK_OF(X509_OBJECT)