2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 #include "internal/cryptlib.h"
12 #include <openssl/lhash.h>
13 #include <openssl/x509.h>
14 #include "internal/x509_int.h"
15 #include <openssl/x509v3.h>
18 X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
22 ret = OPENSSL_zalloc(sizeof(*ret));
27 if ((method->new_item != NULL) && !method->new_item(ret)) {
34 void X509_LOOKUP_free(X509_LOOKUP *ctx)
38 if ((ctx->method != NULL) && (ctx->method->free != NULL))
39 (*ctx->method->free) (ctx);
43 int X509_STORE_lock(X509_STORE *s)
45 return CRYPTO_THREAD_write_lock(s->lock);
48 int X509_STORE_unlock(X509_STORE *s)
50 return CRYPTO_THREAD_unlock(s->lock);
53 int X509_LOOKUP_init(X509_LOOKUP *ctx)
55 if (ctx->method == NULL)
57 if (ctx->method->init != NULL)
58 return ctx->method->init(ctx);
63 int X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
65 if (ctx->method == NULL)
67 if (ctx->method->shutdown != NULL)
68 return ctx->method->shutdown(ctx);
73 int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
76 if (ctx->method == NULL)
78 if (ctx->method->ctrl != NULL)
79 return ctx->method->ctrl(ctx, cmd, argc, argl, ret);
84 int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
85 X509_NAME *name, X509_OBJECT *ret)
87 if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
91 return ctx->method->get_by_subject(ctx, type, name, ret);
94 int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
95 X509_NAME *name, ASN1_INTEGER *serial,
98 if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL))
100 return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret);
103 int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
104 const unsigned char *bytes, int len,
107 if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
109 return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret);
112 int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
113 const char *str, int len, X509_OBJECT *ret)
115 if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
117 return ctx->method->get_by_alias(ctx, type, str, len, ret);
120 int X509_LOOKUP_set_method_data(X509_LOOKUP *ctx, void *data)
122 ctx->method_data = data;
126 void *X509_LOOKUP_get_method_data(const X509_LOOKUP *ctx)
128 return ctx->method_data;
131 X509_STORE *X509_LOOKUP_get_store(const X509_LOOKUP *ctx)
133 return ctx->store_ctx;
137 static int x509_object_cmp(const X509_OBJECT *const *a,
138 const X509_OBJECT *const *b)
142 ret = ((*a)->type - (*b)->type);
145 switch ((*a)->type) {
147 ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509);
150 ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl);
159 X509_STORE *X509_STORE_new(void)
163 if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
165 if ((ret->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL)
168 if ((ret->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL)
171 if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
174 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data))
177 ret->lock = CRYPTO_THREAD_lock_new();
178 if (ret->lock == NULL)
185 X509_VERIFY_PARAM_free(ret->param);
186 sk_X509_OBJECT_free(ret->objs);
187 sk_X509_LOOKUP_free(ret->get_cert_methods);
192 void X509_STORE_free(X509_STORE *vfy)
195 STACK_OF(X509_LOOKUP) *sk;
201 CRYPTO_atomic_add(&vfy->references, -1, &i, vfy->lock);
202 REF_PRINT_COUNT("X509_STORE", vfy);
205 REF_ASSERT_ISNT(i < 0);
207 sk = vfy->get_cert_methods;
208 for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
209 lu = sk_X509_LOOKUP_value(sk, i);
210 X509_LOOKUP_shutdown(lu);
211 X509_LOOKUP_free(lu);
213 sk_X509_LOOKUP_free(sk);
214 sk_X509_OBJECT_pop_free(vfy->objs, X509_OBJECT_free);
216 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data);
217 X509_VERIFY_PARAM_free(vfy->param);
218 CRYPTO_THREAD_lock_free(vfy->lock);
222 int X509_STORE_up_ref(X509_STORE *vfy)
226 if (CRYPTO_atomic_add(&vfy->references, 1, &i, vfy->lock) <= 0)
229 REF_PRINT_COUNT("X509_STORE", a);
230 REF_ASSERT_ISNT(i < 2);
231 return ((i > 1) ? 1 : 0);
234 X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
237 STACK_OF(X509_LOOKUP) *sk;
240 sk = v->get_cert_methods;
241 for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
242 lu = sk_X509_LOOKUP_value(sk, i);
243 if (m == lu->method) {
248 lu = X509_LOOKUP_new(m);
253 if (sk_X509_LOOKUP_push(v->get_cert_methods, lu))
256 X509_LOOKUP_free(lu);
262 X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs,
263 X509_LOOKUP_TYPE type,
266 X509_OBJECT *ret = X509_OBJECT_new();
270 if (!X509_STORE_CTX_get_by_subject(vs, type, name, ret)) {
271 X509_OBJECT_free(ret);
277 int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type,
278 X509_NAME *name, X509_OBJECT *ret)
280 X509_STORE *ctx = vs->ctx;
282 X509_OBJECT stmp, *tmp;
288 CRYPTO_THREAD_write_lock(ctx->lock);
289 tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
290 CRYPTO_THREAD_unlock(ctx->lock);
292 if (tmp == NULL || type == X509_LU_CRL) {
293 for (i = 0; i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
294 lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
295 j = X509_LOOKUP_by_subject(lu, type, name, &stmp);
305 ret->type = tmp->type;
306 ret->data.ptr = tmp->data.ptr;
308 X509_OBJECT_up_ref_count(ret);
313 int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
316 int ret = 1, added = 1;
320 obj = X509_OBJECT_new();
323 obj->type = X509_LU_X509;
325 X509_OBJECT_up_ref_count(obj);
327 CRYPTO_THREAD_write_lock(ctx->lock);
329 if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
330 X509err(X509_F_X509_STORE_ADD_CERT,
331 X509_R_CERT_ALREADY_IN_HASH_TABLE);
334 added = sk_X509_OBJECT_push(ctx->objs, obj);
338 CRYPTO_THREAD_unlock(ctx->lock);
340 if (!ret) /* obj not pushed */
341 X509_OBJECT_free(obj);
342 if (!added) /* on push failure */
343 X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE);
348 int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
351 int ret = 1, added = 1;
355 obj = X509_OBJECT_new();
358 obj->type = X509_LU_CRL;
360 X509_OBJECT_up_ref_count(obj);
362 CRYPTO_THREAD_write_lock(ctx->lock);
364 if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
365 X509err(X509_F_X509_STORE_ADD_CRL, X509_R_CERT_ALREADY_IN_HASH_TABLE);
368 added = sk_X509_OBJECT_push(ctx->objs, obj);
372 CRYPTO_THREAD_unlock(ctx->lock);
374 if (!ret) /* obj not pushed */
375 X509_OBJECT_free(obj);
376 if (!added) /* on push failure */
377 X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE);
382 int X509_OBJECT_up_ref_count(X509_OBJECT *a)
388 return X509_up_ref(a->data.x509);
390 return X509_CRL_up_ref(a->data.crl);
395 X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a)
397 if (a == NULL || a->type != X509_LU_X509)
402 X509_CRL *X509_OBJECT_get0_X509_CRL(X509_OBJECT *a)
404 if (a == NULL || a->type != X509_LU_CRL)
409 X509_LOOKUP_TYPE X509_OBJECT_get_type(const X509_OBJECT *a)
414 X509_OBJECT *X509_OBJECT_new()
416 X509_OBJECT *ret = OPENSSL_zalloc(sizeof(*ret));
419 X509err(X509_F_X509_OBJECT_NEW, ERR_R_MALLOC_FAILURE);
422 ret->type = X509_LU_NONE;
426 static void x509_object_free_internal(X509_OBJECT *a)
434 X509_free(a->data.x509);
437 X509_CRL_free(a->data.crl);
442 int X509_OBJECT_set1_X509(X509_OBJECT *a, X509 *obj)
444 if (a == NULL || !X509_up_ref(obj))
447 x509_object_free_internal(a);
448 a->type = X509_LU_X509;
453 int X509_OBJECT_set1_X509_CRL(X509_OBJECT *a, X509_CRL *obj)
455 if (a == NULL || !X509_CRL_up_ref(obj))
458 x509_object_free_internal(a);
459 a->type = X509_LU_CRL;
464 void X509_OBJECT_free(X509_OBJECT *a)
466 x509_object_free_internal(a);
470 static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
471 X509_NAME *name, int *pnmatch)
481 stmp.data.x509 = &x509_s;
482 x509_s.cert_info.subject = name;
485 stmp.data.crl = &crl_s;
486 crl_s.crl.issuer = name;
493 idx = sk_X509_OBJECT_find(h, &stmp);
494 if (idx >= 0 && pnmatch) {
496 const X509_OBJECT *tobj, *pstmp;
499 for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) {
500 tobj = sk_X509_OBJECT_value(h, tidx);
501 if (x509_object_cmp(&tobj, &pstmp))
509 int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
512 return x509_object_idx_cnt(h, type, name, NULL);
515 X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
516 X509_LOOKUP_TYPE type,
520 idx = X509_OBJECT_idx_by_subject(h, type, name);
523 return sk_X509_OBJECT_value(h, idx);
526 STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *v)
531 STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
534 STACK_OF(X509) *sk = NULL;
538 if (ctx->ctx == NULL)
541 CRYPTO_THREAD_write_lock(ctx->ctx->lock);
542 idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
545 * Nothing found in cache: do lookup to possibly add new objects to
548 X509_OBJECT *xobj = X509_OBJECT_new();
550 CRYPTO_THREAD_unlock(ctx->ctx->lock);
553 if (!X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, nm, xobj)) {
554 X509_OBJECT_free(xobj);
557 X509_OBJECT_free(xobj);
558 CRYPTO_THREAD_write_lock(ctx->ctx->lock);
559 idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
561 CRYPTO_THREAD_unlock(ctx->ctx->lock);
566 sk = sk_X509_new_null();
567 for (i = 0; i < cnt; i++, idx++) {
568 obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
571 if (!sk_X509_push(sk, x)) {
572 CRYPTO_THREAD_unlock(ctx->ctx->lock);
574 sk_X509_pop_free(sk, X509_free);
578 CRYPTO_THREAD_unlock(ctx->ctx->lock);
582 STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
585 STACK_OF(X509_CRL) *sk = sk_X509_CRL_new_null();
587 X509_OBJECT *obj, *xobj = X509_OBJECT_new();
589 /* Always do lookup to possibly add new CRLs to cache */
593 || !X509_STORE_CTX_get_by_subject(ctx, X509_LU_CRL, nm, xobj)) {
594 X509_OBJECT_free(xobj);
595 sk_X509_CRL_free(sk);
598 X509_OBJECT_free(xobj);
599 CRYPTO_THREAD_write_lock(ctx->ctx->lock);
600 idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
602 CRYPTO_THREAD_unlock(ctx->ctx->lock);
603 sk_X509_CRL_free(sk);
607 for (i = 0; i < cnt; i++, idx++) {
608 obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
611 if (!sk_X509_CRL_push(sk, x)) {
612 CRYPTO_THREAD_unlock(ctx->ctx->lock);
614 sk_X509_CRL_pop_free(sk, X509_CRL_free);
618 CRYPTO_THREAD_unlock(ctx->ctx->lock);
622 X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
627 idx = sk_X509_OBJECT_find(h, x);
630 if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
631 return sk_X509_OBJECT_value(h, idx);
632 for (i = idx; i < sk_X509_OBJECT_num(h); i++) {
633 obj = sk_X509_OBJECT_value(h, i);
635 ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
637 if (x->type == X509_LU_X509) {
638 if (!X509_cmp(obj->data.x509, x->data.x509))
640 } else if (x->type == X509_LU_CRL) {
641 if (!X509_CRL_match(obj->data.crl, x->data.crl))
650 * Try to get issuer certificate from store. Due to limitations
651 * of the API this can only retrieve a single certificate matching
652 * a given subject name. However it will fill the cache with all
653 * matching certificates, so we can examine the cache for all
657 * 1 lookup successful.
658 * 0 certificate not found.
659 * -1 some other error.
661 int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
664 X509_OBJECT *obj = X509_OBJECT_new(), *pobj = NULL;
670 xn = X509_get_issuer_name(x);
671 ok = X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, xn, obj);
673 X509_OBJECT_free(obj);
676 /* If certificate matches all OK */
677 if (ctx->check_issued(ctx, x, obj->data.x509)) {
678 if (x509_check_cert_time(ctx, obj->data.x509, -1)) {
679 *issuer = obj->data.x509;
680 X509_up_ref(*issuer);
681 X509_OBJECT_free(obj);
685 X509_OBJECT_free(obj);
687 if (ctx->ctx == NULL)
690 /* Else find index of first cert accepted by 'check_issued' */
692 CRYPTO_THREAD_write_lock(ctx->ctx->lock);
693 idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
694 if (idx != -1) { /* should be true as we've had at least one
696 /* Look through all matching certs for suitable issuer */
697 for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) {
698 pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
699 /* See if we've run past the matches */
700 if (pobj->type != X509_LU_X509)
702 if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
704 if (ctx->check_issued(ctx, x, pobj->data.x509)) {
705 *issuer = pobj->data.x509;
708 * If times check, exit with match,
709 * otherwise keep looking. Leave last
710 * match in issuer so we return nearest
711 * match if no certificate time is OK.
714 if (x509_check_cert_time(ctx, *issuer, -1))
719 CRYPTO_THREAD_unlock(ctx->ctx->lock);
721 X509_up_ref(*issuer);
725 int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
727 return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
730 int X509_STORE_set_depth(X509_STORE *ctx, int depth)
732 X509_VERIFY_PARAM_set_depth(ctx->param, depth);
736 int X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
738 return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
741 int X509_STORE_set_trust(X509_STORE *ctx, int trust)
743 return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
746 int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
748 return X509_VERIFY_PARAM_set1(ctx->param, param);
751 X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx)
756 void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify)
758 ctx->verify = verify;
761 X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx)
766 void X509_STORE_set_verify_cb(X509_STORE *ctx,
767 X509_STORE_CTX_verify_cb verify_cb)
769 ctx->verify_cb = verify_cb;
772 X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *ctx)
774 return ctx->verify_cb;
777 void X509_STORE_set_get_issuer(X509_STORE *ctx,
778 X509_STORE_CTX_get_issuer_fn get_issuer)
780 ctx->get_issuer = get_issuer;
783 X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(X509_STORE *ctx)
785 return ctx->get_issuer;
788 void X509_STORE_set_check_issued(X509_STORE *ctx,
789 X509_STORE_CTX_check_issued_fn check_issued)
791 ctx->check_issued = check_issued;
794 X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *ctx)
796 return ctx->check_issued;
799 void X509_STORE_set_check_revocation(X509_STORE *ctx,
800 X509_STORE_CTX_check_revocation_fn check_revocation)
802 ctx->check_revocation = check_revocation;
805 X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(X509_STORE *ctx)
807 return ctx->check_revocation;
810 void X509_STORE_set_get_crl(X509_STORE *ctx,
811 X509_STORE_CTX_get_crl_fn get_crl)
813 ctx->get_crl = get_crl;
816 X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(X509_STORE *ctx)
821 void X509_STORE_set_check_crl(X509_STORE *ctx,
822 X509_STORE_CTX_check_crl_fn check_crl)
824 ctx->check_crl = check_crl;
827 X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(X509_STORE *ctx)
829 return ctx->check_crl;
832 void X509_STORE_set_cert_crl(X509_STORE *ctx,
833 X509_STORE_CTX_cert_crl_fn cert_crl)
835 ctx->cert_crl = cert_crl;
838 X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(X509_STORE *ctx)
840 return ctx->cert_crl;
843 void X509_STORE_set_check_policy(X509_STORE *ctx,
844 X509_STORE_CTX_check_policy_fn check_policy)
846 ctx->check_policy = check_policy;
849 X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(X509_STORE *ctx)
851 return ctx->check_policy;
854 void X509_STORE_set_lookup_certs(X509_STORE *ctx,
855 X509_STORE_CTX_lookup_certs_fn lookup_certs)
857 ctx->lookup_certs = lookup_certs;
860 X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(X509_STORE *ctx)
862 return ctx->lookup_certs;
865 void X509_STORE_set_lookup_crls(X509_STORE *ctx,
866 X509_STORE_CTX_lookup_crls_fn lookup_crls)
868 ctx->lookup_crls = lookup_crls;
871 X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx)
873 return ctx->lookup_crls;
876 void X509_STORE_set_cleanup(X509_STORE *ctx,
877 X509_STORE_CTX_cleanup_fn ctx_cleanup)
879 ctx->cleanup = ctx_cleanup;
882 X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(X509_STORE *ctx)
887 int X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data)
889 return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
892 void *X509_STORE_get_ex_data(X509_STORE *ctx, int idx)
894 return CRYPTO_get_ex_data(&ctx->ex_data, idx);
897 X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx)