x509_lu.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  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->cleanup = 0;
  186. if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) {
  187. sk_X509_OBJECT_free(ret->objs);
  188. OPENSSL_free(ret);
  189. return NULL;
  190. }
  191. ret->references = 1;
  192. return ret;
  193. }
  194. static void cleanup(X509_OBJECT *a)
  195. {
  196. if (a->type == X509_LU_X509) {
  197. X509_free(a->data.x509);
  198. } else if (a->type == X509_LU_CRL) {
  199. X509_CRL_free(a->data.crl);
  200. } else {
  201. /* abort(); */
  202. }
  203. OPENSSL_free(a);
  204. }
  205. void X509_STORE_free(X509_STORE *vfy)
  206. {
  207. int i;
  208. STACK_OF(X509_LOOKUP) *sk;
  209. X509_LOOKUP *lu;
  210. if (vfy == NULL)
  211. return;
  212. sk = vfy->get_cert_methods;
  213. for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
  214. lu = sk_X509_LOOKUP_value(sk, i);
  215. X509_LOOKUP_shutdown(lu);
  216. X509_LOOKUP_free(lu);
  217. }
  218. sk_X509_LOOKUP_free(sk);
  219. sk_X509_OBJECT_pop_free(vfy->objs, cleanup);
  220. CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data);
  221. if (vfy->param)
  222. X509_VERIFY_PARAM_free(vfy->param);
  223. OPENSSL_free(vfy);
  224. }
  225. X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
  226. {
  227. int i;
  228. STACK_OF(X509_LOOKUP) *sk;
  229. X509_LOOKUP *lu;
  230. sk = v->get_cert_methods;
  231. for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
  232. lu = sk_X509_LOOKUP_value(sk, i);
  233. if (m == lu->method) {
  234. return lu;
  235. }
  236. }
  237. /* a new one */
  238. lu = X509_LOOKUP_new(m);
  239. if (lu == NULL)
  240. return NULL;
  241. else {
  242. lu->store_ctx = v;
  243. if (sk_X509_LOOKUP_push(v->get_cert_methods, lu))
  244. return lu;
  245. else {
  246. X509_LOOKUP_free(lu);
  247. return NULL;
  248. }
  249. }
  250. }
  251. int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
  252. X509_OBJECT *ret)
  253. {
  254. X509_STORE *ctx = vs->ctx;
  255. X509_LOOKUP *lu;
  256. X509_OBJECT stmp, *tmp;
  257. int i, j;
  258. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  259. tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
  260. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  261. if (tmp == NULL) {
  262. for (i = vs->current_method;
  263. i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
  264. lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
  265. j = X509_LOOKUP_by_subject(lu, type, name, &stmp);
  266. if (j < 0) {
  267. vs->current_method = j;
  268. return j;
  269. } else if (j) {
  270. tmp = &stmp;
  271. break;
  272. }
  273. }
  274. vs->current_method = 0;
  275. if (tmp == NULL)
  276. return 0;
  277. }
  278. /*- if (ret->data.ptr != NULL)
  279. X509_OBJECT_free_contents(ret); */
  280. ret->type = tmp->type;
  281. ret->data.ptr = tmp->data.ptr;
  282. X509_OBJECT_up_ref_count(ret);
  283. return 1;
  284. }
  285. int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
  286. {
  287. X509_OBJECT *obj;
  288. int ret = 1;
  289. if (x == NULL)
  290. return 0;
  291. obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
  292. if (obj == NULL) {
  293. X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE);
  294. return 0;
  295. }
  296. obj->type = X509_LU_X509;
  297. obj->data.x509 = x;
  298. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  299. X509_OBJECT_up_ref_count(obj);
  300. if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
  301. X509_OBJECT_free_contents(obj);
  302. OPENSSL_free(obj);
  303. X509err(X509_F_X509_STORE_ADD_CERT,
  304. X509_R_CERT_ALREADY_IN_HASH_TABLE);
  305. ret = 0;
  306. } else
  307. sk_X509_OBJECT_push(ctx->objs, obj);
  308. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  309. return ret;
  310. }
  311. int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
  312. {
  313. X509_OBJECT *obj;
  314. int ret = 1;
  315. if (x == NULL)
  316. return 0;
  317. obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
  318. if (obj == NULL) {
  319. X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE);
  320. return 0;
  321. }
  322. obj->type = X509_LU_CRL;
  323. obj->data.crl = x;
  324. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  325. X509_OBJECT_up_ref_count(obj);
  326. if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
  327. X509_OBJECT_free_contents(obj);
  328. OPENSSL_free(obj);
  329. X509err(X509_F_X509_STORE_ADD_CRL, X509_R_CERT_ALREADY_IN_HASH_TABLE);
  330. ret = 0;
  331. } else
  332. sk_X509_OBJECT_push(ctx->objs, obj);
  333. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  334. return ret;
  335. }
  336. void X509_OBJECT_up_ref_count(X509_OBJECT *a)
  337. {
  338. switch (a->type) {
  339. case X509_LU_X509:
  340. CRYPTO_add(&a->data.x509->references, 1, CRYPTO_LOCK_X509);
  341. break;
  342. case X509_LU_CRL:
  343. CRYPTO_add(&a->data.crl->references, 1, CRYPTO_LOCK_X509_CRL);
  344. break;
  345. }
  346. }
  347. void X509_OBJECT_free_contents(X509_OBJECT *a)
  348. {
  349. switch (a->type) {
  350. case X509_LU_X509:
  351. X509_free(a->data.x509);
  352. break;
  353. case X509_LU_CRL:
  354. X509_CRL_free(a->data.crl);
  355. break;
  356. }
  357. }
  358. int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
  359. X509_NAME *name)
  360. {
  361. X509_OBJECT stmp;
  362. X509 x509_s;
  363. X509_CINF cinf_s;
  364. X509_CRL crl_s;
  365. X509_CRL_INFO crl_info_s;
  366. stmp.type = type;
  367. switch (type) {
  368. case X509_LU_X509:
  369. stmp.data.x509 = &x509_s;
  370. x509_s.cert_info = &cinf_s;
  371. cinf_s.subject = name;
  372. break;
  373. case X509_LU_CRL:
  374. stmp.data.crl = &crl_s;
  375. crl_s.crl = &crl_info_s;
  376. crl_info_s.issuer = name;
  377. break;
  378. default:
  379. /* abort(); */
  380. return -1;
  381. }
  382. return sk_X509_OBJECT_find(h, &stmp);
  383. }
  384. X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
  385. int type, X509_NAME *name)
  386. {
  387. int idx;
  388. idx = X509_OBJECT_idx_by_subject(h, type, name);
  389. if (idx == -1)
  390. return NULL;
  391. return sk_X509_OBJECT_value(h, idx);
  392. }
  393. X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
  394. X509_OBJECT *x)
  395. {
  396. int idx, i;
  397. X509_OBJECT *obj;
  398. idx = sk_X509_OBJECT_find(h, x);
  399. if (idx == -1)
  400. return NULL;
  401. if (x->type != X509_LU_X509)
  402. return sk_X509_OBJECT_value(h, idx);
  403. for (i = idx; i < sk_X509_OBJECT_num(h); i++) {
  404. obj = sk_X509_OBJECT_value(h, i);
  405. if (x509_object_cmp
  406. ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
  407. return NULL;
  408. if ((x->type != X509_LU_X509)
  409. || !X509_cmp(obj->data.x509, x->data.x509))
  410. return obj;
  411. }
  412. return NULL;
  413. }
  414. /*-
  415. * Try to get issuer certificate from store. Due to limitations
  416. * of the API this can only retrieve a single certificate matching
  417. * a given subject name. However it will fill the cache with all
  418. * matching certificates, so we can examine the cache for all
  419. * matches.
  420. *
  421. * Return values are:
  422. * 1 lookup successful.
  423. * 0 certificate not found.
  424. * -1 some other error.
  425. */
  426. int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
  427. {
  428. X509_NAME *xn;
  429. X509_OBJECT obj, *pobj;
  430. int i, ok, idx, ret;
  431. xn = X509_get_issuer_name(x);
  432. ok = X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj);
  433. if (ok != X509_LU_X509) {
  434. if (ok == X509_LU_RETRY) {
  435. X509_OBJECT_free_contents(&obj);
  436. X509err(X509_F_X509_STORE_CTX_GET1_ISSUER, X509_R_SHOULD_RETRY);
  437. return -1;
  438. } else if (ok != X509_LU_FAIL) {
  439. X509_OBJECT_free_contents(&obj);
  440. /* not good :-(, break anyway */
  441. return -1;
  442. }
  443. return 0;
  444. }
  445. /* If certificate matches all OK */
  446. if (ctx->check_issued(ctx, x, obj.data.x509)) {
  447. *issuer = obj.data.x509;
  448. return 1;
  449. }
  450. X509_OBJECT_free_contents(&obj);
  451. /* Else find index of first cert accepted by 'check_issued' */
  452. ret = 0;
  453. CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
  454. idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
  455. if (idx != -1) { /* should be true as we've had at least one
  456. * match */
  457. /* Look through all matching certs for suitable issuer */
  458. for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) {
  459. pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
  460. /* See if we've run past the matches */
  461. if (pobj->type != X509_LU_X509)
  462. break;
  463. if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
  464. break;
  465. if (ctx->check_issued(ctx, x, pobj->data.x509)) {
  466. *issuer = pobj->data.x509;
  467. X509_OBJECT_up_ref_count(pobj);
  468. ret = 1;
  469. break;
  470. }
  471. }
  472. }
  473. CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
  474. return ret;
  475. }
  476. int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
  477. {
  478. return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
  479. }
  480. int X509_STORE_set_depth(X509_STORE *ctx, int depth)
  481. {
  482. X509_VERIFY_PARAM_set_depth(ctx->param, depth);
  483. return 1;
  484. }
  485. int X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
  486. {
  487. return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
  488. }
  489. int X509_STORE_set_trust(X509_STORE *ctx, int trust)
  490. {
  491. return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
  492. }
  493. int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
  494. {
  495. return X509_VERIFY_PARAM_set1(ctx->param, param);
  496. }
  497. IMPLEMENT_STACK_OF(X509_LOOKUP)
  498. IMPLEMENT_STACK_OF(X509_OBJECT)