x509_lu.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  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. ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
  173. ret->cache = 1;
  174. ret->get_cert_methods = sk_X509_LOOKUP_new_null();
  175. ret->verify = 0;
  176. ret->verify_cb = 0;
  177. if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
  178. return NULL;
  179. ret->get_issuer = 0;
  180. ret->check_issued = 0;
  181. ret->check_revocation = 0;
  182. ret->get_crl = 0;
  183. ret->check_crl = 0;
  184. ret->cert_crl = 0;
  185. ret->lookup_certs = 0;
  186. ret->lookup_crls = 0;
  187. ret->cleanup = 0;
  188. if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) {
  189. sk_X509_OBJECT_free(ret->objs);
  190. OPENSSL_free(ret);
  191. return NULL;
  192. }
  193. ret->references = 1;
  194. return ret;
  195. }
  196. static void cleanup(X509_OBJECT *a)
  197. {
  198. if (!a)
  199. return;
  200. if (a->type == X509_LU_X509) {
  201. X509_free(a->data.x509);
  202. } else if (a->type == X509_LU_CRL) {
  203. X509_CRL_free(a->data.crl);
  204. } else {
  205. /* abort(); */
  206. }
  207. OPENSSL_free(a);
  208. }
  209. void X509_STORE_free(X509_STORE *vfy)
  210. {
  211. int i;
  212. STACK_OF(X509_LOOKUP) *sk;
  213. X509_LOOKUP *lu;
  214. if (vfy == NULL)
  215. return;
  216. i = CRYPTO_add(&vfy->references, -1, CRYPTO_LOCK_X509_STORE);
  217. #ifdef REF_PRINT
  218. REF_PRINT("X509_STORE", vfy);
  219. #endif
  220. if (i > 0)
  221. return;
  222. #ifdef REF_CHECK
  223. if (i < 0) {
  224. fprintf(stderr, "X509_STORE_free, bad reference count\n");
  225. abort(); /* ok */
  226. }
  227. #endif
  228. sk = vfy->get_cert_methods;
  229. for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
  230. lu = sk_X509_LOOKUP_value(sk, i);
  231. X509_LOOKUP_shutdown(lu);
  232. X509_LOOKUP_free(lu);
  233. }
  234. sk_X509_LOOKUP_free(sk);
  235. sk_X509_OBJECT_pop_free(vfy->objs, cleanup);
  236. CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data);
  237. if (vfy->param)
  238. X509_VERIFY_PARAM_free(vfy->param);
  239. OPENSSL_free(vfy);
  240. }
  241. X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
  242. {
  243. int i;
  244. STACK_OF(X509_LOOKUP) *sk;
  245. X509_LOOKUP *lu;
  246. sk = v->get_cert_methods;
  247. for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
  248. lu = sk_X509_LOOKUP_value(sk, i);
  249. if (m == lu->method) {
  250. return lu;
  251. }
  252. }
  253. /* a new one */
  254. lu = X509_LOOKUP_new(m);
  255. if (lu == NULL)
  256. return NULL;
  257. else {
  258. lu->store_ctx = v;
  259. if (sk_X509_LOOKUP_push(v->get_cert_methods, lu))
  260. return lu;
  261. else {
  262. X509_LOOKUP_free(lu);
  263. return NULL;
  264. }
  265. }
  266. }
  267. int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
  268. X509_OBJECT *ret)
  269. {
  270. X509_STORE *ctx = vs->ctx;
  271. X509_LOOKUP *lu;
  272. X509_OBJECT stmp, *tmp;
  273. int i, j;
  274. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  275. tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
  276. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  277. if (tmp == NULL || type == X509_LU_CRL) {
  278. for (i = vs->current_method;
  279. i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
  280. lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
  281. j = X509_LOOKUP_by_subject(lu, type, name, &stmp);
  282. if (j < 0) {
  283. vs->current_method = j;
  284. return j;
  285. } else if (j) {
  286. tmp = &stmp;
  287. break;
  288. }
  289. }
  290. vs->current_method = 0;
  291. if (tmp == NULL)
  292. return 0;
  293. }
  294. /*- if (ret->data.ptr != NULL)
  295. X509_OBJECT_free_contents(ret); */
  296. ret->type = tmp->type;
  297. ret->data.ptr = tmp->data.ptr;
  298. X509_OBJECT_up_ref_count(ret);
  299. return 1;
  300. }
  301. int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
  302. {
  303. X509_OBJECT *obj;
  304. int ret = 1;
  305. if (x == NULL)
  306. return 0;
  307. obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
  308. if (obj == NULL) {
  309. X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE);
  310. return 0;
  311. }
  312. obj->type = X509_LU_X509;
  313. obj->data.x509 = x;
  314. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  315. X509_OBJECT_up_ref_count(obj);
  316. if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
  317. X509_OBJECT_free_contents(obj);
  318. OPENSSL_free(obj);
  319. X509err(X509_F_X509_STORE_ADD_CERT,
  320. X509_R_CERT_ALREADY_IN_HASH_TABLE);
  321. ret = 0;
  322. } else
  323. sk_X509_OBJECT_push(ctx->objs, obj);
  324. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  325. return ret;
  326. }
  327. int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
  328. {
  329. X509_OBJECT *obj;
  330. int ret = 1;
  331. if (x == NULL)
  332. return 0;
  333. obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
  334. if (obj == NULL) {
  335. X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE);
  336. return 0;
  337. }
  338. obj->type = X509_LU_CRL;
  339. obj->data.crl = x;
  340. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  341. X509_OBJECT_up_ref_count(obj);
  342. if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
  343. X509_OBJECT_free_contents(obj);
  344. OPENSSL_free(obj);
  345. X509err(X509_F_X509_STORE_ADD_CRL, X509_R_CERT_ALREADY_IN_HASH_TABLE);
  346. ret = 0;
  347. } else
  348. sk_X509_OBJECT_push(ctx->objs, obj);
  349. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  350. return ret;
  351. }
  352. void X509_OBJECT_up_ref_count(X509_OBJECT *a)
  353. {
  354. switch (a->type) {
  355. case X509_LU_X509:
  356. CRYPTO_add(&a->data.x509->references, 1, CRYPTO_LOCK_X509);
  357. break;
  358. case X509_LU_CRL:
  359. CRYPTO_add(&a->data.crl->references, 1, CRYPTO_LOCK_X509_CRL);
  360. break;
  361. }
  362. }
  363. void X509_OBJECT_free_contents(X509_OBJECT *a)
  364. {
  365. switch (a->type) {
  366. case X509_LU_X509:
  367. X509_free(a->data.x509);
  368. break;
  369. case X509_LU_CRL:
  370. X509_CRL_free(a->data.crl);
  371. break;
  372. }
  373. }
  374. static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
  375. X509_NAME *name, int *pnmatch)
  376. {
  377. X509_OBJECT stmp;
  378. X509 x509_s;
  379. X509_CINF cinf_s;
  380. X509_CRL crl_s;
  381. X509_CRL_INFO crl_info_s;
  382. int idx;
  383. stmp.type = type;
  384. switch (type) {
  385. case X509_LU_X509:
  386. stmp.data.x509 = &x509_s;
  387. x509_s.cert_info = &cinf_s;
  388. cinf_s.subject = name;
  389. break;
  390. case X509_LU_CRL:
  391. stmp.data.crl = &crl_s;
  392. crl_s.crl = &crl_info_s;
  393. crl_info_s.issuer = name;
  394. break;
  395. default:
  396. /* abort(); */
  397. return -1;
  398. }
  399. idx = sk_X509_OBJECT_find(h, &stmp);
  400. if (idx >= 0 && pnmatch) {
  401. int tidx;
  402. const X509_OBJECT *tobj, *pstmp;
  403. *pnmatch = 1;
  404. pstmp = &stmp;
  405. for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) {
  406. tobj = sk_X509_OBJECT_value(h, tidx);
  407. if (x509_object_cmp(&tobj, &pstmp))
  408. break;
  409. (*pnmatch)++;
  410. }
  411. }
  412. return idx;
  413. }
  414. int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
  415. X509_NAME *name)
  416. {
  417. return x509_object_idx_cnt(h, type, name, NULL);
  418. }
  419. X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
  420. int type, X509_NAME *name)
  421. {
  422. int idx;
  423. idx = X509_OBJECT_idx_by_subject(h, type, name);
  424. if (idx == -1)
  425. return NULL;
  426. return sk_X509_OBJECT_value(h, idx);
  427. }
  428. STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
  429. {
  430. int i, idx, cnt;
  431. STACK_OF(X509) *sk;
  432. X509 *x;
  433. X509_OBJECT *obj;
  434. sk = sk_X509_new_null();
  435. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  436. idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
  437. if (idx < 0) {
  438. /*
  439. * Nothing found in cache: do lookup to possibly add new objects to
  440. * cache
  441. */
  442. X509_OBJECT xobj;
  443. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  444. if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) {
  445. sk_X509_free(sk);
  446. return NULL;
  447. }
  448. X509_OBJECT_free_contents(&xobj);
  449. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  450. idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
  451. if (idx < 0) {
  452. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  453. sk_X509_free(sk);
  454. return NULL;
  455. }
  456. }
  457. for (i = 0; i < cnt; i++, idx++) {
  458. obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
  459. x = obj->data.x509;
  460. CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
  461. if (!sk_X509_push(sk, x)) {
  462. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  463. X509_free(x);
  464. sk_X509_pop_free(sk, X509_free);
  465. return NULL;
  466. }
  467. }
  468. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  469. return sk;
  470. }
  471. STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
  472. {
  473. int i, idx, cnt;
  474. STACK_OF(X509_CRL) *sk;
  475. X509_CRL *x;
  476. X509_OBJECT *obj, xobj;
  477. sk = sk_X509_CRL_new_null();
  478. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  479. /*
  480. * Always do lookup to possibly add new CRLs to cache
  481. */
  482. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  483. if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) {
  484. sk_X509_CRL_free(sk);
  485. return NULL;
  486. }
  487. X509_OBJECT_free_contents(&xobj);
  488. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  489. idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
  490. if (idx < 0) {
  491. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  492. sk_X509_CRL_free(sk);
  493. return NULL;
  494. }
  495. for (i = 0; i < cnt; i++, idx++) {
  496. obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
  497. x = obj->data.crl;
  498. CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL);
  499. if (!sk_X509_CRL_push(sk, x)) {
  500. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  501. X509_CRL_free(x);
  502. sk_X509_CRL_pop_free(sk, X509_CRL_free);
  503. return NULL;
  504. }
  505. }
  506. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  507. return sk;
  508. }
  509. X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
  510. X509_OBJECT *x)
  511. {
  512. int idx, i;
  513. X509_OBJECT *obj;
  514. idx = sk_X509_OBJECT_find(h, x);
  515. if (idx == -1)
  516. return NULL;
  517. if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
  518. return sk_X509_OBJECT_value(h, idx);
  519. for (i = idx; i < sk_X509_OBJECT_num(h); i++) {
  520. obj = sk_X509_OBJECT_value(h, i);
  521. if (x509_object_cmp
  522. ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
  523. return NULL;
  524. if (x->type == X509_LU_X509) {
  525. if (!X509_cmp(obj->data.x509, x->data.x509))
  526. return obj;
  527. } else if (x->type == X509_LU_CRL) {
  528. if (!X509_CRL_match(obj->data.crl, x->data.crl))
  529. return obj;
  530. } else
  531. return obj;
  532. }
  533. return NULL;
  534. }
  535. /*-
  536. * Try to get issuer certificate from store. Due to limitations
  537. * of the API this can only retrieve a single certificate matching
  538. * a given subject name. However it will fill the cache with all
  539. * matching certificates, so we can examine the cache for all
  540. * matches.
  541. *
  542. * Return values are:
  543. * 1 lookup successful.
  544. * 0 certificate not found.
  545. * -1 some other error.
  546. */
  547. int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
  548. {
  549. X509_NAME *xn;
  550. X509_OBJECT obj, *pobj;
  551. int i, ok, idx, ret;
  552. xn = X509_get_issuer_name(x);
  553. ok = X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj);
  554. if (ok != X509_LU_X509) {
  555. if (ok == X509_LU_RETRY) {
  556. X509_OBJECT_free_contents(&obj);
  557. X509err(X509_F_X509_STORE_CTX_GET1_ISSUER, X509_R_SHOULD_RETRY);
  558. return -1;
  559. } else if (ok != X509_LU_FAIL) {
  560. X509_OBJECT_free_contents(&obj);
  561. /* not good :-(, break anyway */
  562. return -1;
  563. }
  564. return 0;
  565. }
  566. /* If certificate matches all OK */
  567. if (ctx->check_issued(ctx, x, obj.data.x509)) {
  568. *issuer = obj.data.x509;
  569. return 1;
  570. }
  571. X509_OBJECT_free_contents(&obj);
  572. /* Else find index of first cert accepted by 'check_issued' */
  573. ret = 0;
  574. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  575. idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
  576. if (idx != -1) { /* should be true as we've had at least one
  577. * match */
  578. /* Look through all matching certs for suitable issuer */
  579. for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) {
  580. pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
  581. /* See if we've run past the matches */
  582. if (pobj->type != X509_LU_X509)
  583. break;
  584. if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
  585. break;
  586. if (ctx->check_issued(ctx, x, pobj->data.x509)) {
  587. *issuer = pobj->data.x509;
  588. X509_OBJECT_up_ref_count(pobj);
  589. ret = 1;
  590. break;
  591. }
  592. }
  593. }
  594. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  595. return ret;
  596. }
  597. int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
  598. {
  599. return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
  600. }
  601. int X509_STORE_set_depth(X509_STORE *ctx, int depth)
  602. {
  603. X509_VERIFY_PARAM_set_depth(ctx->param, depth);
  604. return 1;
  605. }
  606. int X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
  607. {
  608. return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
  609. }
  610. int X509_STORE_set_trust(X509_STORE *ctx, int trust)
  611. {
  612. return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
  613. }
  614. int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
  615. {
  616. return X509_VERIFY_PARAM_set1(ctx->param, param);
  617. }
  618. void X509_STORE_set_verify_cb(X509_STORE *ctx,
  619. int (*verify_cb) (int, X509_STORE_CTX *))
  620. {
  621. ctx->verify_cb = verify_cb;
  622. }
  623. void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx,
  624. STACK_OF(X509_CRL) *(*cb) (X509_STORE_CTX
  625. *ctx,
  626. X509_NAME *nm))
  627. {
  628. ctx->lookup_crls = cb;
  629. }
  630. X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx)
  631. {
  632. return ctx->ctx;
  633. }
  634. IMPLEMENT_STACK_OF(X509_LOOKUP)
  635. IMPLEMENT_STACK_OF(X509_OBJECT)