diff options
Diffstat (limited to 'src/lib/libcrypto/x509/x509_lu.c')
| -rw-r--r-- | src/lib/libcrypto/x509/x509_lu.c | 332 |
1 files changed, 217 insertions, 115 deletions
diff --git a/src/lib/libcrypto/x509/x509_lu.c b/src/lib/libcrypto/x509/x509_lu.c index a20006d67e..863c738cad 100644 --- a/src/lib/libcrypto/x509/x509_lu.c +++ b/src/lib/libcrypto/x509/x509_lu.c | |||
| @@ -62,14 +62,13 @@ | |||
| 62 | #include <openssl/x509.h> | 62 | #include <openssl/x509.h> |
| 63 | 63 | ||
| 64 | static STACK_OF(CRYPTO_EX_DATA_FUNCS) *x509_store_meth=NULL; | 64 | static STACK_OF(CRYPTO_EX_DATA_FUNCS) *x509_store_meth=NULL; |
| 65 | static STACK_OF(CRYPTO_EX_DATA_FUNCS) *x509_store_ctx_meth=NULL; | ||
| 66 | 65 | ||
| 67 | X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) | 66 | X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) |
| 68 | { | 67 | { |
| 69 | X509_LOOKUP *ret; | 68 | X509_LOOKUP *ret; |
| 70 | 69 | ||
| 71 | ret=(X509_LOOKUP *)Malloc(sizeof(X509_LOOKUP)); | 70 | ret=(X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP)); |
| 72 | if (ret == NULL) return(NULL); | 71 | if (ret == NULL) return NULL; |
| 73 | 72 | ||
| 74 | ret->init=0; | 73 | ret->init=0; |
| 75 | ret->skip=0; | 74 | ret->skip=0; |
| @@ -78,10 +77,10 @@ X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) | |||
| 78 | ret->store_ctx=NULL; | 77 | ret->store_ctx=NULL; |
| 79 | if ((method->new_item != NULL) && !method->new_item(ret)) | 78 | if ((method->new_item != NULL) && !method->new_item(ret)) |
| 80 | { | 79 | { |
| 81 | Free(ret); | 80 | OPENSSL_free(ret); |
| 82 | return(NULL); | 81 | return NULL; |
| 83 | } | 82 | } |
| 84 | return(ret); | 83 | return ret; |
| 85 | } | 84 | } |
| 86 | 85 | ||
| 87 | void X509_LOOKUP_free(X509_LOOKUP *ctx) | 86 | void X509_LOOKUP_free(X509_LOOKUP *ctx) |
| @@ -90,44 +89,44 @@ void X509_LOOKUP_free(X509_LOOKUP *ctx) | |||
| 90 | if ( (ctx->method != NULL) && | 89 | if ( (ctx->method != NULL) && |
| 91 | (ctx->method->free != NULL)) | 90 | (ctx->method->free != NULL)) |
| 92 | ctx->method->free(ctx); | 91 | ctx->method->free(ctx); |
| 93 | Free(ctx); | 92 | OPENSSL_free(ctx); |
| 94 | } | 93 | } |
| 95 | 94 | ||
| 96 | int X509_LOOKUP_init(X509_LOOKUP *ctx) | 95 | int X509_LOOKUP_init(X509_LOOKUP *ctx) |
| 97 | { | 96 | { |
| 98 | if (ctx->method == NULL) return(0); | 97 | if (ctx->method == NULL) return 0; |
| 99 | if (ctx->method->init != NULL) | 98 | if (ctx->method->init != NULL) |
| 100 | return(ctx->method->init(ctx)); | 99 | return ctx->method->init(ctx); |
| 101 | else | 100 | else |
| 102 | return(1); | 101 | return 1; |
| 103 | } | 102 | } |
| 104 | 103 | ||
| 105 | int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) | 104 | int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) |
| 106 | { | 105 | { |
| 107 | if (ctx->method == NULL) return(0); | 106 | if (ctx->method == NULL) return 0; |
| 108 | if (ctx->method->shutdown != NULL) | 107 | if (ctx->method->shutdown != NULL) |
| 109 | return(ctx->method->shutdown(ctx)); | 108 | return ctx->method->shutdown(ctx); |
| 110 | else | 109 | else |
| 111 | return(1); | 110 | return 1; |
| 112 | } | 111 | } |
| 113 | 112 | ||
| 114 | int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, | 113 | int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, |
| 115 | char **ret) | 114 | char **ret) |
| 116 | { | 115 | { |
| 117 | if (ctx->method == NULL) return(-1); | 116 | if (ctx->method == NULL) return -1; |
| 118 | if (ctx->method->ctrl != NULL) | 117 | if (ctx->method->ctrl != NULL) |
| 119 | return(ctx->method->ctrl(ctx,cmd,argc,argl,ret)); | 118 | return ctx->method->ctrl(ctx,cmd,argc,argl,ret); |
| 120 | else | 119 | else |
| 121 | return(1); | 120 | return 1; |
| 122 | } | 121 | } |
| 123 | 122 | ||
| 124 | int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, | 123 | int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, |
| 125 | X509_OBJECT *ret) | 124 | X509_OBJECT *ret) |
| 126 | { | 125 | { |
| 127 | if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) | 126 | if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) |
| 128 | return(X509_LU_FAIL); | 127 | return X509_LU_FAIL; |
| 129 | if (ctx->skip) return(0); | 128 | if (ctx->skip) return 0; |
| 130 | return(ctx->method->get_by_subject(ctx,type,name,ret)); | 129 | return ctx->method->get_by_subject(ctx,type,name,ret); |
| 131 | } | 130 | } |
| 132 | 131 | ||
| 133 | int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, | 132 | int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, |
| @@ -135,71 +134,55 @@ int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, | |||
| 135 | { | 134 | { |
| 136 | if ((ctx->method == NULL) || | 135 | if ((ctx->method == NULL) || |
| 137 | (ctx->method->get_by_issuer_serial == NULL)) | 136 | (ctx->method->get_by_issuer_serial == NULL)) |
| 138 | return(X509_LU_FAIL); | 137 | return X509_LU_FAIL; |
| 139 | return(ctx->method->get_by_issuer_serial(ctx,type,name,serial,ret)); | 138 | return ctx->method->get_by_issuer_serial(ctx,type,name,serial,ret); |
| 140 | } | 139 | } |
| 141 | 140 | ||
| 142 | int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, | 141 | int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, |
| 143 | unsigned char *bytes, int len, X509_OBJECT *ret) | 142 | unsigned char *bytes, int len, X509_OBJECT *ret) |
| 144 | { | 143 | { |
| 145 | if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL)) | 144 | if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL)) |
| 146 | return(X509_LU_FAIL); | 145 | return X509_LU_FAIL; |
| 147 | return(ctx->method->get_by_fingerprint(ctx,type,bytes,len,ret)); | 146 | return ctx->method->get_by_fingerprint(ctx,type,bytes,len,ret); |
| 148 | } | 147 | } |
| 149 | 148 | ||
| 150 | int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len, | 149 | int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len, |
| 151 | X509_OBJECT *ret) | 150 | X509_OBJECT *ret) |
| 152 | { | 151 | { |
| 153 | if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL)) | 152 | if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL)) |
| 154 | return(X509_LU_FAIL); | 153 | return X509_LU_FAIL; |
| 155 | return(ctx->method->get_by_alias(ctx,type,str,len,ret)); | 154 | return ctx->method->get_by_alias(ctx,type,str,len,ret); |
| 156 | } | 155 | } |
| 157 | 156 | ||
| 158 | static unsigned long x509_object_hash(X509_OBJECT *a) | 157 | |
| 159 | { | 158 | static int x509_object_cmp(const X509_OBJECT * const *a, const X509_OBJECT * const *b) |
| 160 | unsigned long h; | 159 | { |
| 161 | 160 | int ret; | |
| 162 | switch (a->type) | 161 | |
| 163 | { | 162 | ret=((*a)->type - (*b)->type); |
| 164 | case X509_LU_X509: | 163 | if (ret) return ret; |
| 165 | h=X509_NAME_hash(a->data.x509->cert_info->subject); | 164 | switch ((*a)->type) |
| 166 | break; | 165 | { |
| 167 | case X509_LU_CRL: | 166 | case X509_LU_X509: |
| 168 | h=X509_NAME_hash(a->data.crl->crl->issuer); | 167 | ret=X509_subject_name_cmp((*a)->data.x509,(*b)->data.x509); |
| 169 | break; | 168 | break; |
| 170 | default: | 169 | case X509_LU_CRL: |
| 171 | abort(); | 170 | ret=X509_CRL_cmp((*a)->data.crl,(*b)->data.crl); |
| 172 | } | 171 | break; |
| 173 | return(h); | ||
| 174 | } | ||
| 175 | |||
| 176 | static int x509_object_cmp(X509_OBJECT *a, X509_OBJECT *b) | ||
| 177 | { | ||
| 178 | int ret; | ||
| 179 | |||
| 180 | ret=(a->type - b->type); | ||
| 181 | if (ret) return(ret); | ||
| 182 | switch (a->type) | ||
| 183 | { | ||
| 184 | case X509_LU_X509: | ||
| 185 | ret=X509_subject_name_cmp(a->data.x509,b->data.x509); | ||
| 186 | break; | ||
| 187 | case X509_LU_CRL: | ||
| 188 | ret=X509_CRL_cmp(a->data.crl,b->data.crl); | ||
| 189 | break; | ||
| 190 | default: | 172 | default: |
| 191 | abort(); | 173 | /* abort(); */ |
| 174 | return 0; | ||
| 192 | } | 175 | } |
| 193 | return(ret); | 176 | return ret; |
| 194 | } | 177 | } |
| 195 | 178 | ||
| 196 | X509_STORE *X509_STORE_new(void) | 179 | X509_STORE *X509_STORE_new(void) |
| 197 | { | 180 | { |
| 198 | X509_STORE *ret; | 181 | X509_STORE *ret; |
| 199 | 182 | ||
| 200 | if ((ret=(X509_STORE *)Malloc(sizeof(X509_STORE))) == NULL) | 183 | if ((ret=(X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL) |
| 201 | return(NULL); | 184 | return NULL; |
| 202 | ret->certs=lh_new(x509_object_hash,x509_object_cmp); | 185 | ret->objs = sk_X509_OBJECT_new(x509_object_cmp); |
| 203 | ret->cache=1; | 186 | ret->cache=1; |
| 204 | ret->get_cert_methods=sk_X509_LOOKUP_new_null(); | 187 | ret->get_cert_methods=sk_X509_LOOKUP_new_null(); |
| 205 | ret->verify=NULL; | 188 | ret->verify=NULL; |
| @@ -207,7 +190,7 @@ X509_STORE *X509_STORE_new(void) | |||
| 207 | memset(&ret->ex_data,0,sizeof(CRYPTO_EX_DATA)); | 190 | memset(&ret->ex_data,0,sizeof(CRYPTO_EX_DATA)); |
| 208 | ret->references=1; | 191 | ret->references=1; |
| 209 | ret->depth=0; | 192 | ret->depth=0; |
| 210 | return(ret); | 193 | return ret; |
| 211 | } | 194 | } |
| 212 | 195 | ||
| 213 | static void cleanup(X509_OBJECT *a) | 196 | static void cleanup(X509_OBJECT *a) |
| @@ -221,9 +204,11 @@ static void cleanup(X509_OBJECT *a) | |||
| 221 | X509_CRL_free(a->data.crl); | 204 | X509_CRL_free(a->data.crl); |
| 222 | } | 205 | } |
| 223 | else | 206 | else |
| 224 | abort(); | 207 | { |
| 208 | /* abort(); */ | ||
| 209 | } | ||
| 225 | 210 | ||
| 226 | Free(a); | 211 | OPENSSL_free(a); |
| 227 | } | 212 | } |
| 228 | 213 | ||
| 229 | void X509_STORE_free(X509_STORE *vfy) | 214 | void X509_STORE_free(X509_STORE *vfy) |
| @@ -232,7 +217,7 @@ void X509_STORE_free(X509_STORE *vfy) | |||
| 232 | STACK_OF(X509_LOOKUP) *sk; | 217 | STACK_OF(X509_LOOKUP) *sk; |
| 233 | X509_LOOKUP *lu; | 218 | X509_LOOKUP *lu; |
| 234 | 219 | ||
| 235 | if(vfy == NULL) | 220 | if (vfy == NULL) |
| 236 | return; | 221 | return; |
| 237 | 222 | ||
| 238 | sk=vfy->get_cert_methods; | 223 | sk=vfy->get_cert_methods; |
| @@ -243,11 +228,10 @@ void X509_STORE_free(X509_STORE *vfy) | |||
| 243 | X509_LOOKUP_free(lu); | 228 | X509_LOOKUP_free(lu); |
| 244 | } | 229 | } |
| 245 | sk_X509_LOOKUP_free(sk); | 230 | sk_X509_LOOKUP_free(sk); |
| 231 | sk_X509_OBJECT_pop_free(vfy->objs, cleanup); | ||
| 246 | 232 | ||
| 247 | CRYPTO_free_ex_data(x509_store_meth,vfy,&vfy->ex_data); | 233 | CRYPTO_free_ex_data(x509_store_meth,vfy,&vfy->ex_data); |
| 248 | lh_doall(vfy->certs,cleanup); | 234 | OPENSSL_free(vfy); |
| 249 | lh_free(vfy->certs); | ||
| 250 | Free(vfy); | ||
| 251 | } | 235 | } |
| 252 | 236 | ||
| 253 | X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) | 237 | X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) |
| @@ -262,22 +246,22 @@ X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) | |||
| 262 | lu=sk_X509_LOOKUP_value(sk,i); | 246 | lu=sk_X509_LOOKUP_value(sk,i); |
| 263 | if (m == lu->method) | 247 | if (m == lu->method) |
| 264 | { | 248 | { |
| 265 | return(lu); | 249 | return lu; |
| 266 | } | 250 | } |
| 267 | } | 251 | } |
| 268 | /* a new one */ | 252 | /* a new one */ |
| 269 | lu=X509_LOOKUP_new(m); | 253 | lu=X509_LOOKUP_new(m); |
| 270 | if (lu == NULL) | 254 | if (lu == NULL) |
| 271 | return(NULL); | 255 | return NULL; |
| 272 | else | 256 | else |
| 273 | { | 257 | { |
| 274 | lu->store_ctx=v; | 258 | lu->store_ctx=v; |
| 275 | if (sk_X509_LOOKUP_push(v->get_cert_methods,lu)) | 259 | if (sk_X509_LOOKUP_push(v->get_cert_methods,lu)) |
| 276 | return(lu); | 260 | return lu; |
| 277 | else | 261 | else |
| 278 | { | 262 | { |
| 279 | X509_LOOKUP_free(lu); | 263 | X509_LOOKUP_free(lu); |
| 280 | return(NULL); | 264 | return NULL; |
| 281 | } | 265 | } |
| 282 | } | 266 | } |
| 283 | } | 267 | } |
| @@ -290,7 +274,7 @@ int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, | |||
| 290 | X509_OBJECT stmp,*tmp; | 274 | X509_OBJECT stmp,*tmp; |
| 291 | int i,j; | 275 | int i,j; |
| 292 | 276 | ||
| 293 | tmp=X509_OBJECT_retrieve_by_subject(ctx->certs,type,name); | 277 | tmp=X509_OBJECT_retrieve_by_subject(ctx->objs,type,name); |
| 294 | 278 | ||
| 295 | if (tmp == NULL) | 279 | if (tmp == NULL) |
| 296 | { | 280 | { |
| @@ -301,7 +285,7 @@ int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, | |||
| 301 | if (j < 0) | 285 | if (j < 0) |
| 302 | { | 286 | { |
| 303 | vs->current_method=j; | 287 | vs->current_method=j; |
| 304 | return(j); | 288 | return j; |
| 305 | } | 289 | } |
| 306 | else if (j) | 290 | else if (j) |
| 307 | { | 291 | { |
| @@ -311,7 +295,7 @@ int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, | |||
| 311 | } | 295 | } |
| 312 | vs->current_method=0; | 296 | vs->current_method=0; |
| 313 | if (tmp == NULL) | 297 | if (tmp == NULL) |
| 314 | return(0); | 298 | return 0; |
| 315 | } | 299 | } |
| 316 | 300 | ||
| 317 | /* if (ret->data.ptr != NULL) | 301 | /* if (ret->data.ptr != NULL) |
| @@ -322,7 +306,74 @@ int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, | |||
| 322 | 306 | ||
| 323 | X509_OBJECT_up_ref_count(ret); | 307 | X509_OBJECT_up_ref_count(ret); |
| 324 | 308 | ||
| 325 | return(1); | 309 | return 1; |
| 310 | } | ||
| 311 | |||
| 312 | int X509_STORE_add_cert(X509_STORE *ctx, X509 *x) | ||
| 313 | { | ||
| 314 | X509_OBJECT *obj; | ||
| 315 | int ret=1; | ||
| 316 | |||
| 317 | if (x == NULL) return 0; | ||
| 318 | obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); | ||
| 319 | if (obj == NULL) | ||
| 320 | { | ||
| 321 | X509err(X509_F_X509_STORE_ADD_CERT,ERR_R_MALLOC_FAILURE); | ||
| 322 | return 0; | ||
| 323 | } | ||
| 324 | obj->type=X509_LU_X509; | ||
| 325 | obj->data.x509=x; | ||
| 326 | |||
| 327 | CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); | ||
| 328 | |||
| 329 | X509_OBJECT_up_ref_count(obj); | ||
| 330 | |||
| 331 | |||
| 332 | if (X509_OBJECT_retrieve_match(ctx->objs, obj)) | ||
| 333 | { | ||
| 334 | X509_OBJECT_free_contents(obj); | ||
| 335 | OPENSSL_free(obj); | ||
| 336 | X509err(X509_F_X509_STORE_ADD_CERT,X509_R_CERT_ALREADY_IN_HASH_TABLE); | ||
| 337 | ret=0; | ||
| 338 | } | ||
| 339 | else sk_X509_OBJECT_push(ctx->objs, obj); | ||
| 340 | |||
| 341 | CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); | ||
| 342 | |||
| 343 | return ret; | ||
| 344 | } | ||
| 345 | |||
| 346 | int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) | ||
| 347 | { | ||
| 348 | X509_OBJECT *obj; | ||
| 349 | int ret=1; | ||
| 350 | |||
| 351 | if (x == NULL) return 0; | ||
| 352 | obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); | ||
| 353 | if (obj == NULL) | ||
| 354 | { | ||
| 355 | X509err(X509_F_X509_STORE_ADD_CRL,ERR_R_MALLOC_FAILURE); | ||
| 356 | return 0; | ||
| 357 | } | ||
| 358 | obj->type=X509_LU_CRL; | ||
| 359 | obj->data.crl=x; | ||
| 360 | |||
| 361 | CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); | ||
| 362 | |||
| 363 | X509_OBJECT_up_ref_count(obj); | ||
| 364 | |||
| 365 | if (X509_OBJECT_retrieve_match(ctx->objs, obj)) | ||
| 366 | { | ||
| 367 | X509_OBJECT_free_contents(obj); | ||
| 368 | OPENSSL_free(obj); | ||
| 369 | X509err(X509_F_X509_STORE_ADD_CRL,X509_R_CERT_ALREADY_IN_HASH_TABLE); | ||
| 370 | ret=0; | ||
| 371 | } | ||
| 372 | else sk_X509_OBJECT_push(ctx->objs, obj); | ||
| 373 | |||
| 374 | CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); | ||
| 375 | |||
| 376 | return ret; | ||
| 326 | } | 377 | } |
| 327 | 378 | ||
| 328 | void X509_OBJECT_up_ref_count(X509_OBJECT *a) | 379 | void X509_OBJECT_up_ref_count(X509_OBJECT *a) |
| @@ -351,10 +402,10 @@ void X509_OBJECT_free_contents(X509_OBJECT *a) | |||
| 351 | } | 402 | } |
| 352 | } | 403 | } |
| 353 | 404 | ||
| 354 | X509_OBJECT *X509_OBJECT_retrieve_by_subject(LHASH *h, int type, | 405 | int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, |
| 355 | X509_NAME *name) | 406 | X509_NAME *name) |
| 356 | { | 407 | { |
| 357 | X509_OBJECT stmp,*tmp; | 408 | X509_OBJECT stmp; |
| 358 | X509 x509_s; | 409 | X509 x509_s; |
| 359 | X509_CINF cinf_s; | 410 | X509_CINF cinf_s; |
| 360 | X509_CRL crl_s; | 411 | X509_CRL crl_s; |
| @@ -374,54 +425,105 @@ X509_OBJECT *X509_OBJECT_retrieve_by_subject(LHASH *h, int type, | |||
| 374 | crl_info_s.issuer=name; | 425 | crl_info_s.issuer=name; |
| 375 | break; | 426 | break; |
| 376 | default: | 427 | default: |
| 377 | abort(); | 428 | /* abort(); */ |
| 429 | return -1; | ||
| 378 | } | 430 | } |
| 379 | 431 | ||
| 380 | tmp=(X509_OBJECT *)lh_retrieve(h,&stmp); | 432 | return sk_X509_OBJECT_find(h,&stmp); |
| 381 | return(tmp); | ||
| 382 | } | 433 | } |
| 383 | 434 | ||
| 384 | X509_STORE_CTX *X509_STORE_CTX_new(void) | 435 | X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type, |
| 436 | X509_NAME *name) | ||
| 385 | { | 437 | { |
| 386 | X509_STORE_CTX *ctx; | 438 | int idx; |
| 387 | ctx = (X509_STORE_CTX *)Malloc(sizeof(X509_STORE_CTX)); | 439 | idx = X509_OBJECT_idx_by_subject(h, type, name); |
| 388 | if(ctx) memset(ctx, 0, sizeof(X509_STORE_CTX)); | 440 | if (idx==-1) return NULL; |
| 389 | return ctx; | 441 | return sk_X509_OBJECT_value(h, idx); |
| 390 | } | 442 | } |
| 391 | 443 | ||
| 392 | void X509_STORE_CTX_free(X509_STORE_CTX *ctx) | 444 | X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x) |
| 393 | { | 445 | { |
| 394 | X509_STORE_CTX_cleanup(ctx); | 446 | int idx, i; |
| 395 | Free(ctx); | 447 | X509_OBJECT *obj; |
| 448 | idx = sk_X509_OBJECT_find(h, x); | ||
| 449 | if (idx == -1) return NULL; | ||
| 450 | if (x->type != X509_LU_X509) return sk_X509_OBJECT_value(h, idx); | ||
| 451 | for (i = idx; i < sk_X509_OBJECT_num(h); i++) | ||
| 452 | { | ||
| 453 | obj = sk_X509_OBJECT_value(h, i); | ||
| 454 | if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x)) | ||
| 455 | return NULL; | ||
| 456 | if ((x->type != X509_LU_X509) || !X509_cmp(obj->data.x509, x->data.x509)) | ||
| 457 | return obj; | ||
| 458 | } | ||
| 459 | return NULL; | ||
| 396 | } | 460 | } |
| 397 | 461 | ||
| 398 | void X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, | ||
| 399 | STACK_OF(X509) *chain) | ||
| 400 | { | ||
| 401 | ctx->ctx=store; | ||
| 402 | ctx->current_method=0; | ||
| 403 | ctx->cert=x509; | ||
| 404 | ctx->untrusted=chain; | ||
| 405 | ctx->last_untrusted=0; | ||
| 406 | ctx->purpose=0; | ||
| 407 | ctx->trust=0; | ||
| 408 | ctx->valid=0; | ||
| 409 | ctx->chain=NULL; | ||
| 410 | ctx->depth=9; | ||
| 411 | ctx->error=0; | ||
| 412 | ctx->current_cert=NULL; | ||
| 413 | memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); | ||
| 414 | } | ||
| 415 | 462 | ||
| 416 | void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) | 463 | /* Try to get issuer certificate from store. Due to limitations |
| 417 | { | 464 | * of the API this can only retrieve a single certificate matching |
| 418 | if (ctx->chain != NULL) | 465 | * a given subject name. However it will fill the cache with all |
| 466 | * matching certificates, so we can examine the cache for all | ||
| 467 | * matches. | ||
| 468 | * | ||
| 469 | * Return values are: | ||
| 470 | * 1 lookup successful. | ||
| 471 | * 0 certificate not found. | ||
| 472 | * -1 some other error. | ||
| 473 | */ | ||
| 474 | |||
| 475 | |||
| 476 | int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) | ||
| 477 | { | ||
| 478 | X509_NAME *xn; | ||
| 479 | X509_OBJECT obj, *pobj; | ||
| 480 | int i, ok, idx; | ||
| 481 | xn=X509_get_issuer_name(x); | ||
| 482 | ok=X509_STORE_get_by_subject(ctx,X509_LU_X509,xn,&obj); | ||
| 483 | if (ok != X509_LU_X509) | ||
| 484 | { | ||
| 485 | if (ok == X509_LU_RETRY) | ||
| 486 | { | ||
| 487 | X509_OBJECT_free_contents(&obj); | ||
| 488 | X509err(X509_F_X509_VERIFY_CERT,X509_R_SHOULD_RETRY); | ||
| 489 | return -1; | ||
| 490 | } | ||
| 491 | else if (ok != X509_LU_FAIL) | ||
| 492 | { | ||
| 493 | X509_OBJECT_free_contents(&obj); | ||
| 494 | /* not good :-(, break anyway */ | ||
| 495 | return -1; | ||
| 496 | } | ||
| 497 | return 0; | ||
| 498 | } | ||
| 499 | /* If certificate matches all OK */ | ||
| 500 | if (ctx->check_issued(ctx, x, obj.data.x509)) | ||
| 419 | { | 501 | { |
| 420 | sk_X509_pop_free(ctx->chain,X509_free); | 502 | *issuer = obj.data.x509; |
| 421 | ctx->chain=NULL; | 503 | return 1; |
| 422 | } | 504 | } |
| 423 | CRYPTO_free_ex_data(x509_store_ctx_meth,ctx,&(ctx->ex_data)); | 505 | X509_OBJECT_free_contents(&obj); |
| 424 | memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA)); | 506 | /* Else find index of first matching cert */ |
| 425 | } | 507 | idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); |
| 508 | /* This shouldn't normally happen since we already have one match */ | ||
| 509 | if (idx == -1) return 0; | ||
| 510 | |||
| 511 | /* Look through all matching certificates for a suitable issuer */ | ||
| 512 | for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) | ||
| 513 | { | ||
| 514 | pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); | ||
| 515 | /* See if we've ran out of matches */ | ||
| 516 | if (pobj->type != X509_LU_X509) return 0; | ||
| 517 | if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) return 0; | ||
| 518 | if (ctx->check_issued(ctx, x, pobj->data.x509)) | ||
| 519 | { | ||
| 520 | *issuer = pobj->data.x509; | ||
| 521 | X509_OBJECT_up_ref_count(pobj); | ||
| 522 | return 1; | ||
| 523 | } | ||
| 524 | } | ||
| 525 | return 0; | ||
| 526 | } | ||
| 426 | 527 | ||
| 427 | IMPLEMENT_STACK_OF(X509_LOOKUP) | 528 | IMPLEMENT_STACK_OF(X509_LOOKUP) |
| 529 | IMPLEMENT_STACK_OF(X509_OBJECT) | ||
