25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

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