x509_lu.c 20 KB

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