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