-int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
- {
- X509_OBJECT *obj;
- int ret=1;
-
- if (x == NULL) return 0;
- obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
- if (obj == NULL)
- {
- X509err(X509_F_X509_STORE_ADD_CRL,ERR_R_MALLOC_FAILURE);
- return 0;
- }
- obj->type=X509_LU_CRL;
- obj->data.crl=x;
-
- CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
-
- X509_OBJECT_up_ref_count(obj);
-
- if (X509_OBJECT_retrieve_match(ctx->objs, obj))
- {
- X509_OBJECT_free_contents(obj);
- OPENSSL_free(obj);
- X509err(X509_F_X509_STORE_ADD_CRL,X509_R_CERT_ALREADY_IN_HASH_TABLE);
- ret=0;
- }
- else sk_X509_OBJECT_push(ctx->objs, obj);
-
- CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
-
- return ret;
- }
-
-void X509_OBJECT_up_ref_count(X509_OBJECT *a)
- {
- switch (a->type)
- {
- case X509_LU_X509:
- CRYPTO_add(&a->data.x509->references,1,CRYPTO_LOCK_X509);
- break;
- case X509_LU_CRL:
- CRYPTO_add(&a->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
- break;
- }
- }
-
-void X509_OBJECT_free_contents(X509_OBJECT *a)
- {
- switch (a->type)
- {
- case X509_LU_X509:
- X509_free(a->data.x509);
- break;
- case X509_LU_CRL:
- X509_CRL_free(a->data.crl);
- break;
- }
- }
-
-int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
- X509_NAME *name)
- {
- X509_OBJECT stmp;
- X509 x509_s;
- X509_CINF cinf_s;
- X509_CRL crl_s;
- X509_CRL_INFO crl_info_s;
-
- stmp.type=type;
- switch (type)
- {
- case X509_LU_X509:
- stmp.data.x509= &x509_s;
- x509_s.cert_info= &cinf_s;
- cinf_s.subject=name;
- break;
- case X509_LU_CRL:
- stmp.data.crl= &crl_s;
- crl_s.crl= &crl_info_s;
- crl_info_s.issuer=name;
- break;
- default:
- /* abort(); */
- return -1;
- }
-
- return sk_X509_OBJECT_find(h,&stmp);
- }
-
-X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type,
- X509_NAME *name)
-{
- int idx;
- idx = X509_OBJECT_idx_by_subject(h, type, name);
- if (idx==-1) return NULL;
- return sk_X509_OBJECT_value(h, idx);
-}
-
-X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
-{
- int idx, i;
- X509_OBJECT *obj;
- idx = sk_X509_OBJECT_find(h, x);
- if (idx == -1) return NULL;
- if (x->type != X509_LU_X509) return sk_X509_OBJECT_value(h, idx);
- for (i = idx; i < sk_X509_OBJECT_num(h); i++)
- {
- obj = sk_X509_OBJECT_value(h, i);
- if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
- return NULL;
- if ((x->type != X509_LU_X509) || !X509_cmp(obj->data.x509, x->data.x509))
- return obj;
- }
- return NULL;
-}
-
-
-/* Try to get issuer certificate from store. Due to limitations
+ x509_object_free_internal(a);
+ a->type = X509_LU_X509;
+ a->data.x509 = obj;
+ return 1;
+}
+
+int X509_OBJECT_set1_X509_CRL(X509_OBJECT *a, X509_CRL *obj)
+{
+ if (a == NULL || !X509_CRL_up_ref(obj))
+ return 0;
+
+ x509_object_free_internal(a);
+ a->type = X509_LU_CRL;
+ a->data.crl = obj;
+ return 1;
+}
+
+void X509_OBJECT_free(X509_OBJECT *a)
+{
+ x509_object_free_internal(a);
+ OPENSSL_free(a);
+}
+
+static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
+ const X509_NAME *name, int *pnmatch)
+{
+ X509_OBJECT stmp;
+ X509 x509_s;
+ X509_CRL crl_s;
+ int idx;
+
+ stmp.type = type;
+ switch (type) {
+ case X509_LU_X509:
+ stmp.data.x509 = &x509_s;
+ x509_s.cert_info.subject = (X509_NAME *)name; /* won't modify it */
+ break;
+ case X509_LU_CRL:
+ stmp.data.crl = &crl_s;
+ crl_s.crl.issuer = (X509_NAME *)name; /* won't modify it */
+ break;
+ case X509_LU_NONE:
+ /* abort(); */
+ return -1;
+ }
+
+ idx = sk_X509_OBJECT_find(h, &stmp);
+ if (idx >= 0 && pnmatch) {
+ int tidx;
+ const X509_OBJECT *tobj, *pstmp;
+ *pnmatch = 1;
+ pstmp = &stmp;
+ for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) {
+ tobj = sk_X509_OBJECT_value(h, tidx);
+ if (x509_object_cmp(&tobj, &pstmp))
+ break;
+ (*pnmatch)++;
+ }
+ }
+ return idx;
+}
+
+int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
+ const X509_NAME *name)
+{
+ return x509_object_idx_cnt(h, type, name, NULL);
+}
+
+X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
+ X509_LOOKUP_TYPE type,
+ const X509_NAME *name)
+{
+ int idx;
+ idx = X509_OBJECT_idx_by_subject(h, type, name);
+ if (idx == -1)
+ return NULL;
+ return sk_X509_OBJECT_value(h, idx);
+}
+
+STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(const X509_STORE *v)
+{
+ return v->objs;
+}
+
+/* TODO param type could be constified as change to lock is intermittent */
+STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *store)
+{
+ STACK_OF(X509) *sk;
+ STACK_OF(X509_OBJECT) *objs;
+ int i;
+
+ if (store == NULL) {
+ X509err(0, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ if ((sk = sk_X509_new_null()) == NULL)
+ return NULL;
+ X509_STORE_lock(store);
+ objs = X509_STORE_get0_objects(store);
+ for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
+ X509 *cert = X509_OBJECT_get0_X509(sk_X509_OBJECT_value(objs, i));
+
+ if (cert != NULL) {
+ if (!X509_up_ref(cert))
+ goto err;
+ if (!sk_X509_push(sk, cert)) {
+ X509_free(cert);
+ goto err;
+ }
+ }
+ }
+ X509_STORE_unlock(store);
+ return sk;
+
+ err:
+ X509_STORE_unlock(store);
+ sk_X509_pop_free(sk, X509_free);
+ return NULL;
+}
+
+STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx,
+ const X509_NAME *nm)
+{
+ int i, idx, cnt;
+ STACK_OF(X509) *sk = NULL;
+ X509 *x;
+ X509_OBJECT *obj;
+ X509_STORE *store = ctx->store;
+
+ if (store == NULL)
+ return NULL;
+
+ X509_STORE_lock(store);
+ idx = x509_object_idx_cnt(store->objs, X509_LU_X509, nm, &cnt);
+ if (idx < 0) {
+ /*
+ * Nothing found in cache: do lookup to possibly add new objects to
+ * cache
+ */
+ X509_OBJECT *xobj = X509_OBJECT_new();
+
+ X509_STORE_unlock(store);
+
+ if (xobj == NULL)
+ return NULL;
+ if (!X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, nm, xobj)) {
+ X509_OBJECT_free(xobj);
+ return NULL;
+ }
+ X509_OBJECT_free(xobj);
+ X509_STORE_lock(store);
+ idx = x509_object_idx_cnt(store->objs, X509_LU_X509, nm, &cnt);
+ if (idx < 0) {
+ X509_STORE_unlock(store);
+ return NULL;
+ }
+ }
+
+ sk = sk_X509_new_null();
+ for (i = 0; i < cnt; i++, idx++) {
+ obj = sk_X509_OBJECT_value(store->objs, idx);
+ x = obj->data.x509;
+ if (!X509_up_ref(x)) {
+ X509_STORE_unlock(store);
+ sk_X509_pop_free(sk, X509_free);
+ return NULL;
+ }
+ if (!sk_X509_push(sk, x)) {
+ X509_STORE_unlock(store);
+ X509_free(x);
+ sk_X509_pop_free(sk, X509_free);
+ return NULL;
+ }
+ }
+ X509_STORE_unlock(store);
+ return sk;
+}
+
+STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(const X509_STORE_CTX *ctx,
+ const X509_NAME *nm)
+{
+ int i, idx, cnt;
+ STACK_OF(X509_CRL) *sk = sk_X509_CRL_new_null();
+ X509_CRL *x;
+ X509_OBJECT *obj, *xobj = X509_OBJECT_new();
+ X509_STORE *store = ctx->store;
+
+ /* Always do lookup to possibly add new CRLs to cache */
+ if (sk == NULL
+ || xobj == NULL
+ || store == NULL
+ || !X509_STORE_CTX_get_by_subject(ctx, X509_LU_CRL, nm, xobj)) {
+ X509_OBJECT_free(xobj);
+ sk_X509_CRL_free(sk);
+ return NULL;
+ }
+ X509_OBJECT_free(xobj);
+ X509_STORE_lock(store);
+ idx = x509_object_idx_cnt(store->objs, X509_LU_CRL, nm, &cnt);
+ if (idx < 0) {
+ X509_STORE_unlock(store);
+ sk_X509_CRL_free(sk);
+ return NULL;
+ }
+
+ for (i = 0; i < cnt; i++, idx++) {
+ obj = sk_X509_OBJECT_value(store->objs, idx);
+ x = obj->data.crl;
+ if (!X509_CRL_up_ref(x)) {
+ X509_STORE_unlock(store);
+ sk_X509_CRL_pop_free(sk, X509_CRL_free);
+ return NULL;
+ }
+ if (!sk_X509_CRL_push(sk, x)) {
+ X509_STORE_unlock(store);
+ X509_CRL_free(x);
+ sk_X509_CRL_pop_free(sk, X509_CRL_free);
+ return NULL;
+ }
+ }
+ X509_STORE_unlock(store);
+ return sk;
+}
+
+X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
+ X509_OBJECT *x)
+{
+ int idx, i, num;
+ X509_OBJECT *obj;
+
+ idx = sk_X509_OBJECT_find(h, x);
+ if (idx < 0)
+ return NULL;
+ if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
+ return sk_X509_OBJECT_value(h, idx);
+ for (i = idx, num = sk_X509_OBJECT_num(h); i < num; i++) {
+ obj = sk_X509_OBJECT_value(h, i);
+ if (x509_object_cmp((const X509_OBJECT **)&obj,
+ (const X509_OBJECT **)&x))
+ return NULL;
+ if (x->type == X509_LU_X509) {
+ if (!X509_cmp(obj->data.x509, x->data.x509))
+ return obj;
+ } else if (x->type == X509_LU_CRL) {
+ if (!X509_CRL_match(obj->data.crl, x->data.crl))
+ return obj;
+ } else
+ return obj;
+ }
+ return NULL;
+}
+
+/*-
+ * Try to get issuer certificate from store. Due to limitations