You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

738 lines
18 KiB

  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. #include <string.h>
  58. #include <openssl/err.h>
  59. #include <openssl/lhash.h>
  60. #include <openssl/mem.h>
  61. #include <openssl/thread.h>
  62. #include <openssl/x509.h>
  63. #include <openssl/x509v3.h>
  64. X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
  65. {
  66. X509_LOOKUP *ret;
  67. ret=(X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP));
  68. if (ret == NULL) 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. {
  76. OPENSSL_free(ret);
  77. return NULL;
  78. }
  79. return ret;
  80. }
  81. void X509_LOOKUP_free(X509_LOOKUP *ctx)
  82. {
  83. if (ctx == NULL) return;
  84. if ( (ctx->method != NULL) &&
  85. (ctx->method->free != NULL))
  86. (*ctx->method->free)(ctx);
  87. OPENSSL_free(ctx);
  88. }
  89. int X509_LOOKUP_init(X509_LOOKUP *ctx)
  90. {
  91. if (ctx->method == NULL) 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) return 0;
  100. if (ctx->method->shutdown != NULL)
  101. return ctx->method->shutdown(ctx);
  102. else
  103. return 1;
  104. }
  105. int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
  106. char **ret)
  107. {
  108. if (ctx->method == NULL) return -1;
  109. if (ctx->method->ctrl != NULL)
  110. return ctx->method->ctrl(ctx,cmd,argc,argl,ret);
  111. else
  112. return 1;
  113. }
  114. int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
  115. X509_OBJECT *ret)
  116. {
  117. if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
  118. return X509_LU_FAIL;
  119. if (ctx->skip) return 0;
  120. return ctx->method->get_by_subject(ctx,type,name,ret);
  121. }
  122. int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
  123. ASN1_INTEGER *serial, X509_OBJECT *ret)
  124. {
  125. if ((ctx->method == NULL) ||
  126. (ctx->method->get_by_issuer_serial == NULL))
  127. return X509_LU_FAIL;
  128. return ctx->method->get_by_issuer_serial(ctx,type,name,serial,ret);
  129. }
  130. int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
  131. unsigned char *bytes, int len, X509_OBJECT *ret)
  132. {
  133. if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
  134. return X509_LU_FAIL;
  135. return ctx->method->get_by_fingerprint(ctx,type,bytes,len,ret);
  136. }
  137. int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len,
  138. X509_OBJECT *ret)
  139. {
  140. if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
  141. return X509_LU_FAIL;
  142. return ctx->method->get_by_alias(ctx,type,str,len,ret);
  143. }
  144. static int x509_object_cmp(const X509_OBJECT **a, const X509_OBJECT **b)
  145. {
  146. int ret;
  147. ret=((*a)->type - (*b)->type);
  148. if (ret) return ret;
  149. switch ((*a)->type)
  150. {
  151. case X509_LU_X509:
  152. ret=X509_subject_name_cmp((*a)->data.x509,(*b)->data.x509);
  153. break;
  154. case X509_LU_CRL:
  155. ret=X509_CRL_cmp((*a)->data.crl,(*b)->data.crl);
  156. break;
  157. default:
  158. /* abort(); */
  159. return 0;
  160. }
  161. return ret;
  162. }
  163. X509_STORE *X509_STORE_new(void)
  164. {
  165. X509_STORE *ret;
  166. if ((ret=(X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL)
  167. return NULL;
  168. memset(ret, 0, sizeof(*ret));
  169. ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
  170. ret->cache = 1;
  171. ret->get_cert_methods = sk_X509_LOOKUP_new_null();
  172. if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
  173. goto err;
  174. ret->references = 1;
  175. return ret;
  176. err:
  177. if (ret)
  178. {
  179. if (ret->param)
  180. X509_VERIFY_PARAM_free(ret->param);
  181. if (ret->get_cert_methods)
  182. sk_X509_LOOKUP_free(ret->get_cert_methods);
  183. if (ret->objs)
  184. sk_X509_OBJECT_free(ret->objs);
  185. OPENSSL_free(ret);
  186. }
  187. return NULL;
  188. }
  189. static void cleanup(X509_OBJECT *a)
  190. {
  191. if (a->type == X509_LU_X509)
  192. {
  193. X509_free(a->data.x509);
  194. }
  195. else if (a->type == X509_LU_CRL)
  196. {
  197. X509_CRL_free(a->data.crl);
  198. }
  199. else
  200. {
  201. /* abort(); */
  202. }
  203. OPENSSL_free(a);
  204. }
  205. void X509_STORE_free(X509_STORE *vfy)
  206. {
  207. int i;
  208. size_t j;
  209. STACK_OF(X509_LOOKUP) *sk;
  210. X509_LOOKUP *lu;
  211. if (vfy == NULL)
  212. return;
  213. i=CRYPTO_add(&vfy->references,-1,CRYPTO_LOCK_X509_STORE);
  214. #ifdef REF_PRINT
  215. REF_PRINT("X509_STORE",vfy);
  216. #endif
  217. if (i > 0) return;
  218. #ifdef REF_CHECK
  219. if (i < 0)
  220. {
  221. fprintf(stderr,"X509_STORE_free, bad reference count\n");
  222. abort(); /* ok */
  223. }
  224. #endif
  225. sk=vfy->get_cert_methods;
  226. for (j=0; j<sk_X509_LOOKUP_num(sk); j++)
  227. {
  228. lu=sk_X509_LOOKUP_value(sk,j);
  229. X509_LOOKUP_shutdown(lu);
  230. X509_LOOKUP_free(lu);
  231. }
  232. sk_X509_LOOKUP_free(sk);
  233. sk_X509_OBJECT_pop_free(vfy->objs, cleanup);
  234. if (vfy->param)
  235. X509_VERIFY_PARAM_free(vfy->param);
  236. OPENSSL_free(vfy);
  237. }
  238. X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
  239. {
  240. size_t i;
  241. STACK_OF(X509_LOOKUP) *sk;
  242. X509_LOOKUP *lu;
  243. sk=v->get_cert_methods;
  244. for (i=0; i<sk_X509_LOOKUP_num(sk); i++)
  245. {
  246. lu=sk_X509_LOOKUP_value(sk,i);
  247. if (m == lu->method)
  248. {
  249. return lu;
  250. }
  251. }
  252. /* a new one */
  253. lu=X509_LOOKUP_new(m);
  254. if (lu == NULL)
  255. return NULL;
  256. else
  257. {
  258. lu->store_ctx=v;
  259. if (sk_X509_LOOKUP_push(v->get_cert_methods,lu))
  260. return lu;
  261. else
  262. {
  263. X509_LOOKUP_free(lu);
  264. return NULL;
  265. }
  266. }
  267. }
  268. int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
  269. X509_OBJECT *ret)
  270. {
  271. X509_STORE *ctx=vs->ctx;
  272. X509_LOOKUP *lu;
  273. X509_OBJECT stmp,*tmp;
  274. int i,j;
  275. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  276. tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name);
  277. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  278. if (tmp == NULL || type == X509_LU_CRL)
  279. {
  280. for (i=vs->current_method; i<(int)sk_X509_LOOKUP_num(ctx->get_cert_methods); i++)
  281. {
  282. lu=sk_X509_LOOKUP_value(ctx->get_cert_methods,i);
  283. j=X509_LOOKUP_by_subject(lu,type,name,&stmp);
  284. if (j < 0)
  285. {
  286. vs->current_method=j;
  287. return j;
  288. }
  289. else if (j)
  290. {
  291. tmp= &stmp;
  292. break;
  293. }
  294. }
  295. vs->current_method=0;
  296. if (tmp == NULL)
  297. return 0;
  298. }
  299. /* if (ret->data.ptr != NULL)
  300. X509_OBJECT_free_contents(ret); */
  301. ret->type=tmp->type;
  302. ret->data.ptr=tmp->data.ptr;
  303. X509_OBJECT_up_ref_count(ret);
  304. return 1;
  305. }
  306. int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
  307. {
  308. X509_OBJECT *obj;
  309. int ret=1;
  310. if (x == NULL) return 0;
  311. obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
  312. if (obj == NULL)
  313. {
  314. OPENSSL_PUT_ERROR(X509, X509_STORE_add_cert, ERR_R_MALLOC_FAILURE);
  315. return 0;
  316. }
  317. obj->type=X509_LU_X509;
  318. obj->data.x509=x;
  319. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  320. X509_OBJECT_up_ref_count(obj);
  321. if (X509_OBJECT_retrieve_match(ctx->objs, obj))
  322. {
  323. X509_OBJECT_free_contents(obj);
  324. OPENSSL_free(obj);
  325. OPENSSL_PUT_ERROR(X509, X509_STORE_add_cert, X509_R_CERT_ALREADY_IN_HASH_TABLE);
  326. ret=0;
  327. }
  328. else sk_X509_OBJECT_push(ctx->objs, obj);
  329. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  330. return ret;
  331. }
  332. int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
  333. {
  334. X509_OBJECT *obj;
  335. int ret=1;
  336. if (x == NULL) return 0;
  337. obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
  338. if (obj == NULL)
  339. {
  340. OPENSSL_PUT_ERROR(X509, X509_STORE_add_crl, ERR_R_MALLOC_FAILURE);
  341. return 0;
  342. }
  343. obj->type=X509_LU_CRL;
  344. obj->data.crl=x;
  345. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  346. X509_OBJECT_up_ref_count(obj);
  347. if (X509_OBJECT_retrieve_match(ctx->objs, obj))
  348. {
  349. X509_OBJECT_free_contents(obj);
  350. OPENSSL_free(obj);
  351. OPENSSL_PUT_ERROR(X509, X509_STORE_add_crl, X509_R_CERT_ALREADY_IN_HASH_TABLE);
  352. ret=0;
  353. }
  354. else sk_X509_OBJECT_push(ctx->objs, obj);
  355. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  356. return ret;
  357. }
  358. void X509_OBJECT_up_ref_count(X509_OBJECT *a)
  359. {
  360. switch (a->type)
  361. {
  362. case X509_LU_X509:
  363. X509_up_ref(a->data.x509);
  364. break;
  365. case X509_LU_CRL:
  366. CRYPTO_add(&a->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
  367. break;
  368. }
  369. }
  370. void X509_OBJECT_free_contents(X509_OBJECT *a)
  371. {
  372. switch (a->type)
  373. {
  374. case X509_LU_X509:
  375. X509_free(a->data.x509);
  376. break;
  377. case X509_LU_CRL:
  378. X509_CRL_free(a->data.crl);
  379. break;
  380. }
  381. }
  382. static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type,
  383. X509_NAME *name, int *pnmatch)
  384. {
  385. X509_OBJECT stmp;
  386. X509 x509_s;
  387. X509_CINF cinf_s;
  388. X509_CRL crl_s;
  389. X509_CRL_INFO crl_info_s;
  390. size_t idx;
  391. stmp.type=type;
  392. switch (type)
  393. {
  394. case X509_LU_X509:
  395. stmp.data.x509= &x509_s;
  396. x509_s.cert_info= &cinf_s;
  397. cinf_s.subject=name;
  398. break;
  399. case X509_LU_CRL:
  400. stmp.data.crl= &crl_s;
  401. crl_s.crl= &crl_info_s;
  402. crl_info_s.issuer=name;
  403. break;
  404. default:
  405. /* abort(); */
  406. return -1;
  407. }
  408. idx = -1;
  409. if (sk_X509_OBJECT_find(h, &idx, &stmp) && pnmatch)
  410. {
  411. int tidx;
  412. const X509_OBJECT *tobj, *pstmp;
  413. *pnmatch = 1;
  414. pstmp = &stmp;
  415. for (tidx = idx + 1; tidx < (int)sk_X509_OBJECT_num(h); tidx++)
  416. {
  417. tobj = sk_X509_OBJECT_value(h, tidx);
  418. if (x509_object_cmp(&tobj, &pstmp))
  419. break;
  420. (*pnmatch)++;
  421. }
  422. }
  423. return idx;
  424. }
  425. int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
  426. X509_NAME *name)
  427. {
  428. return x509_object_idx_cnt(h, type, name, NULL);
  429. }
  430. X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type,
  431. X509_NAME *name)
  432. {
  433. int idx;
  434. idx = X509_OBJECT_idx_by_subject(h, type, name);
  435. if (idx==-1) return NULL;
  436. return sk_X509_OBJECT_value(h, idx);
  437. }
  438. STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
  439. {
  440. int i, idx, cnt;
  441. STACK_OF(X509) *sk;
  442. X509 *x;
  443. X509_OBJECT *obj;
  444. sk = sk_X509_new_null();
  445. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  446. idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
  447. if (idx < 0)
  448. {
  449. /* Nothing found in cache: do lookup to possibly add new
  450. * objects to cache
  451. */
  452. X509_OBJECT xobj;
  453. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  454. if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj))
  455. {
  456. sk_X509_free(sk);
  457. return NULL;
  458. }
  459. X509_OBJECT_free_contents(&xobj);
  460. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  461. idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_X509,nm, &cnt);
  462. if (idx < 0)
  463. {
  464. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  465. sk_X509_free(sk);
  466. return NULL;
  467. }
  468. }
  469. for (i = 0; i < cnt; i++, idx++)
  470. {
  471. obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
  472. x = obj->data.x509;
  473. if (!sk_X509_push(sk, X509_up_ref(x)))
  474. {
  475. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  476. X509_free(x);
  477. sk_X509_pop_free(sk, X509_free);
  478. return NULL;
  479. }
  480. }
  481. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  482. return sk;
  483. }
  484. STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
  485. {
  486. int i, idx, cnt;
  487. STACK_OF(X509_CRL) *sk;
  488. X509_CRL *x;
  489. X509_OBJECT *obj, xobj;
  490. sk = sk_X509_CRL_new_null();
  491. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  492. /* Check cache first */
  493. idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
  494. /* Always do lookup to possibly add new CRLs to cache
  495. */
  496. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  497. if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj))
  498. {
  499. sk_X509_CRL_free(sk);
  500. return NULL;
  501. }
  502. X509_OBJECT_free_contents(&xobj);
  503. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  504. idx = x509_object_idx_cnt(ctx->ctx->objs,X509_LU_CRL, nm, &cnt);
  505. if (idx < 0)
  506. {
  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. {
  513. obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
  514. x = obj->data.crl;
  515. CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL);
  516. if (!sk_X509_CRL_push(sk, x))
  517. {
  518. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  519. X509_CRL_free(x);
  520. sk_X509_CRL_pop_free(sk, X509_CRL_free);
  521. return NULL;
  522. }
  523. }
  524. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  525. return sk;
  526. }
  527. X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
  528. {
  529. size_t idx, i;
  530. X509_OBJECT *obj;
  531. if (!sk_X509_OBJECT_find(h, &idx, x)) {
  532. return NULL;
  533. }
  534. if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
  535. return sk_X509_OBJECT_value(h, idx);
  536. for (i = idx; i < sk_X509_OBJECT_num(h); i++)
  537. {
  538. obj = sk_X509_OBJECT_value(h, i);
  539. if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
  540. return NULL;
  541. if (x->type == X509_LU_X509)
  542. {
  543. if (!X509_cmp(obj->data.x509, x->data.x509))
  544. return obj;
  545. }
  546. else if (x->type == X509_LU_CRL)
  547. {
  548. if (!X509_CRL_match(obj->data.crl, x->data.crl))
  549. return obj;
  550. }
  551. else
  552. return obj;
  553. }
  554. return NULL;
  555. }
  556. /* Try to get issuer certificate from store. Due to limitations
  557. * of the API this can only retrieve a single certificate matching
  558. * a given subject name. However it will fill the cache with all
  559. * matching certificates, so we can examine the cache for all
  560. * matches.
  561. *
  562. * Return values are:
  563. * 1 lookup successful.
  564. * 0 certificate not found.
  565. * -1 some other error.
  566. */
  567. int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
  568. {
  569. X509_NAME *xn;
  570. X509_OBJECT obj, *pobj;
  571. int ok, idx, ret;
  572. size_t i;
  573. xn=X509_get_issuer_name(x);
  574. ok=X509_STORE_get_by_subject(ctx,X509_LU_X509,xn,&obj);
  575. if (ok != X509_LU_X509)
  576. {
  577. if (ok == X509_LU_RETRY)
  578. {
  579. X509_OBJECT_free_contents(&obj);
  580. OPENSSL_PUT_ERROR(X509, X509_STORE_CTX_get1_issuer, X509_R_SHOULD_RETRY);
  581. return -1;
  582. }
  583. else if (ok != X509_LU_FAIL)
  584. {
  585. X509_OBJECT_free_contents(&obj);
  586. /* not good :-(, break anyway */
  587. return -1;
  588. }
  589. return 0;
  590. }
  591. /* If certificate matches all OK */
  592. if (ctx->check_issued(ctx, x, obj.data.x509))
  593. {
  594. *issuer = obj.data.x509;
  595. return 1;
  596. }
  597. X509_OBJECT_free_contents(&obj);
  598. /* Else find index of first cert accepted by 'check_issued' */
  599. ret = 0;
  600. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  601. idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
  602. if (idx != -1) /* should be true as we've had at least one match */
  603. {
  604. /* Look through all matching certs for suitable issuer */
  605. for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++)
  606. {
  607. pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
  608. /* See if we've run past the matches */
  609. if (pobj->type != X509_LU_X509)
  610. break;
  611. if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
  612. break;
  613. if (ctx->check_issued(ctx, x, pobj->data.x509))
  614. {
  615. *issuer = pobj->data.x509;
  616. X509_OBJECT_up_ref_count(pobj);
  617. ret = 1;
  618. break;
  619. }
  620. }
  621. }
  622. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  623. return ret;
  624. }
  625. int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
  626. {
  627. return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
  628. }
  629. int X509_STORE_set_depth(X509_STORE *ctx, int depth)
  630. {
  631. X509_VERIFY_PARAM_set_depth(ctx->param, depth);
  632. return 1;
  633. }
  634. int X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
  635. {
  636. return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
  637. }
  638. int X509_STORE_set_trust(X509_STORE *ctx, int trust)
  639. {
  640. return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
  641. }
  642. int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
  643. {
  644. return X509_VERIFY_PARAM_set1(ctx->param, param);
  645. }
  646. void X509_STORE_set_verify_cb(X509_STORE *ctx,
  647. int (*verify_cb)(int, X509_STORE_CTX *))
  648. {
  649. ctx->verify_cb = verify_cb;
  650. }
  651. void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx,
  652. STACK_OF(X509_CRL)* (*cb)(X509_STORE_CTX *ctx, X509_NAME *nm))
  653. {
  654. ctx->lookup_crls = cb;
  655. }
  656. X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx)
  657. {
  658. return ctx->ctx;
  659. }