7
7
* https://www.openssl.org/source/license.html
8
8
*/
9
9
10
+ #include <openssl/safestack.h>
10
11
#include <openssl/store.h>
11
12
#include "internal/cryptlib.h"
12
13
#include "crypto/x509.h"
13
14
#include "x509_local.h"
14
15
16
+ typedef struct cached_store_st {
17
+ char * uri ;
18
+ OSSL_LIB_CTX * libctx ;
19
+ char * propq ;
20
+ OSSL_STORE_CTX * ctx ;
21
+ } CACHED_STORE ;
22
+
23
+ DEFINE_STACK_OF (CACHED_STORE )
24
+
15
25
/* Generic object loader, given expected type and criterion */
16
- static int cache_objects (X509_LOOKUP * lctx , const char * uri ,
17
- const OSSL_STORE_SEARCH * criterion ,
18
- int depth , OSSL_LIB_CTX * libctx , const char * propq )
26
+ static int cache_objects (X509_LOOKUP * lctx , CACHED_STORE * store ,
27
+ const OSSL_STORE_SEARCH * criterion , int depth )
19
28
{
20
29
int ok = 0 ;
21
- OSSL_STORE_CTX * ctx = NULL ;
30
+ OSSL_STORE_CTX * ctx = store -> ctx ;
22
31
X509_STORE * xstore = X509_LOOKUP_get_store (lctx );
23
32
24
- if ((ctx = OSSL_STORE_open_ex (uri , libctx , propq , NULL , NULL , NULL ,
25
- NULL , NULL )) == NULL )
33
+ if (ctx == NULL
34
+ && (ctx = OSSL_STORE_open_ex (store -> uri , store -> libctx , store -> propq ,
35
+ NULL , NULL , NULL , NULL , NULL )) == NULL )
26
36
return 0 ;
37
+ store -> ctx = ctx ;
27
38
28
39
/*
29
40
* We try to set the criterion, but don't care if it was valid or not.
@@ -62,9 +73,15 @@ static int cache_objects(X509_LOOKUP *lctx, const char *uri,
62
73
* This is an entry in the "directory" represented by the current
63
74
* uri. if |depth| allows, dive into it.
64
75
*/
65
- if (depth > 0 )
66
- ok = cache_objects (lctx , OSSL_STORE_INFO_get0_NAME (info ),
67
- criterion , depth - 1 , libctx , propq );
76
+ if (depth > 0 ) {
77
+ CACHED_STORE substore ;
78
+
79
+ substore .uri = (char * )OSSL_STORE_INFO_get0_NAME (info );
80
+ substore .libctx = store -> libctx ;
81
+ substore .propq = store -> propq ;
82
+ substore .ctx = NULL ;
83
+ ok = cache_objects (lctx , & substore , criterion , depth - 1 );
84
+ }
68
85
} else {
69
86
/*
70
87
* We know that X509_STORE_add_{cert|crl} increments the object's
@@ -88,27 +105,38 @@ static int cache_objects(X509_LOOKUP *lctx, const char *uri,
88
105
break ;
89
106
}
90
107
OSSL_STORE_close (ctx );
108
+ store -> ctx = NULL ;
91
109
92
110
return ok ;
93
111
}
94
112
95
113
96
- /* Because OPENSSL_free is a macro and for C type match */
97
- static void free_uri (OPENSSL_STRING data )
114
+ static void free_store (CACHED_STORE * store )
98
115
{
99
- OPENSSL_free (data );
116
+ if (store != NULL ) {
117
+ OSSL_STORE_close (store -> ctx );
118
+ OPENSSL_free (store -> uri );
119
+ OPENSSL_free (store -> propq );
120
+ OPENSSL_free (store );
121
+ }
100
122
}
101
123
102
124
static void by_store_free (X509_LOOKUP * ctx )
103
125
{
104
- STACK_OF (OPENSSL_STRING ) * uris = X509_LOOKUP_get_method_data (ctx );
105
- sk_OPENSSL_STRING_pop_free ( uris , free_uri );
126
+ STACK_OF (CACHED_STORE ) * stores = X509_LOOKUP_get_method_data (ctx );
127
+ sk_CACHED_STORE_pop_free ( stores , free_store );
106
128
}
107
129
108
130
static int by_store_ctrl_ex (X509_LOOKUP * ctx , int cmd , const char * argp ,
109
131
long argl , char * * retp , OSSL_LIB_CTX * libctx ,
110
132
const char * propq )
111
133
{
134
+ /*
135
+ * In some cases below, failing to use the defaults shouldn't result in
136
+ * an error. |use_default| is used as the return code in those cases.
137
+ */
138
+ int use_default = argp == NULL ;
139
+
112
140
switch (cmd ) {
113
141
case X509_L_ADD_STORE :
114
142
/* If no URI is given, use the default cert dir as default URI */
@@ -119,21 +147,50 @@ static int by_store_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argp,
119
147
argp = X509_get_default_cert_dir ();
120
148
121
149
{
122
- STACK_OF (OPENSSL_STRING ) * uris = X509_LOOKUP_get_method_data (ctx );
123
- char * data = OPENSSL_strdup ( argp );
150
+ STACK_OF (CACHED_STORE ) * stores = X509_LOOKUP_get_method_data (ctx );
151
+ CACHED_STORE * store = OPENSSL_zalloc ( sizeof ( * store ) );
124
152
125
- if (data == NULL ) {
153
+ if (store == NULL ) {
126
154
return 0 ;
127
155
}
128
- if (uris == NULL ) {
129
- uris = sk_OPENSSL_STRING_new_null ();
130
- X509_LOOKUP_set_method_data (ctx , uris );
156
+
157
+ store -> uri = OPENSSL_strdup (argp );
158
+ store -> libctx = libctx ;
159
+ if (propq != NULL )
160
+ store -> propq = OPENSSL_strdup (propq );
161
+ store -> ctx = OSSL_STORE_open_ex (argp , libctx , propq , NULL , NULL ,
162
+ NULL , NULL , NULL );
163
+ if (store -> ctx == NULL
164
+ || (propq != NULL && store -> propq == NULL )
165
+ || store -> uri == NULL ) {
166
+ free_store (store );
167
+ return use_default ;
168
+ }
169
+
170
+ if (stores == NULL ) {
171
+ stores = sk_CACHED_STORE_new_null ();
172
+ if (stores != NULL )
173
+ X509_LOOKUP_set_method_data (ctx , stores );
174
+ }
175
+ if (stores == NULL || sk_CACHED_STORE_push (stores , store ) <= 0 ) {
176
+ free_store (store );
177
+ return 0 ;
131
178
}
132
- return sk_OPENSSL_STRING_push ( uris , data ) > 0 ;
179
+ return 1 ;
133
180
}
134
- case X509_L_LOAD_STORE :
181
+ case X509_L_LOAD_STORE : {
135
182
/* This is a shortcut for quick loading of specific containers */
136
- return cache_objects (ctx , argp , NULL , 0 , libctx , propq );
183
+ CACHED_STORE store ;
184
+
185
+ store .uri = (char * )argp ;
186
+ store .libctx = libctx ;
187
+ store .propq = (char * )propq ;
188
+ store .ctx = NULL ;
189
+ return cache_objects (ctx , & store , NULL , 0 );
190
+ }
191
+ default :
192
+ /* Unsupported command */
193
+ return 0 ;
137
194
}
138
195
139
196
return 0 ;
@@ -149,13 +206,13 @@ static int by_store(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
149
206
const OSSL_STORE_SEARCH * criterion , X509_OBJECT * ret ,
150
207
OSSL_LIB_CTX * libctx , const char * propq )
151
208
{
152
- STACK_OF (OPENSSL_STRING ) * uris = X509_LOOKUP_get_method_data (ctx );
209
+ STACK_OF (CACHED_STORE ) * stores = X509_LOOKUP_get_method_data (ctx );
153
210
int i ;
154
211
int ok = 0 ;
155
212
156
- for (i = 0 ; i < sk_OPENSSL_STRING_num ( uris ); i ++ ) {
157
- ok = cache_objects (ctx , sk_OPENSSL_STRING_value ( uris , i ), criterion ,
158
- 1 /* depth */ , libctx , propq );
213
+ for (i = 0 ; i < sk_CACHED_STORE_num ( stores ); i ++ ) {
214
+ ok = cache_objects (ctx , sk_CACHED_STORE_value ( stores , i ), criterion ,
215
+ 1 /* depth */ );
159
216
160
217
if (ok )
161
218
break ;
0 commit comments