diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.c | 382 |
1 files changed, 265 insertions, 117 deletions
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c index 7a6d272023..abd5c65e31 100644 --- a/src/lib/libcrypto/x509/x509_vfy.c +++ b/src/lib/libcrypto/x509/x509_vfy.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_vfy.c,v 1.51 2016/11/04 18:07:23 beck Exp $ */ | 1 | /* $OpenBSD: x509_vfy.c,v 1.52 2016/11/06 10:37:38 beck Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -74,6 +74,7 @@ | |||
| 74 | #include <openssl/x509.h> | 74 | #include <openssl/x509.h> |
| 75 | #include <openssl/x509v3.h> | 75 | #include <openssl/x509v3.h> |
| 76 | #include "x509_lcl.h" | 76 | #include "x509_lcl.h" |
| 77 | #include "vpm_int.h" | ||
| 77 | 78 | ||
| 78 | /* CRL score values */ | 79 | /* CRL score values */ |
| 79 | 80 | ||
| @@ -153,41 +154,115 @@ x509_subject_cmp(X509 **a, X509 **b) | |||
| 153 | } | 154 | } |
| 154 | #endif | 155 | #endif |
| 155 | 156 | ||
| 157 | /* Return 1 is a certificate is self signed */ | ||
| 158 | static int | ||
| 159 | cert_self_signed(X509 *x) | ||
| 160 | { | ||
| 161 | X509_check_purpose(x, -1, 0); | ||
| 162 | if (x->ex_flags & EXFLAG_SS) | ||
| 163 | return 1; | ||
| 164 | else | ||
| 165 | return 0; | ||
| 166 | } | ||
| 167 | |||
| 168 | static int | ||
| 169 | check_id_error(X509_STORE_CTX *ctx, int errcode) | ||
| 170 | { | ||
| 171 | ctx->error = errcode; | ||
| 172 | ctx->current_cert = ctx->cert; | ||
| 173 | ctx->error_depth = 0; | ||
| 174 | return ctx->verify_cb(0, ctx); | ||
| 175 | } | ||
| 176 | |||
| 177 | static int | ||
| 178 | check_hosts(X509 *x, X509_VERIFY_PARAM_ID *id) | ||
| 179 | { | ||
| 180 | size_t i; | ||
| 181 | size_t n = sk_OPENSSL_STRING_num(id->hosts); | ||
| 182 | char *name; | ||
| 183 | |||
| 184 | free(id->peername); | ||
| 185 | id->peername = NULL; | ||
| 186 | |||
| 187 | for (i = 0; i < n; ++i) { | ||
| 188 | name = sk_OPENSSL_STRING_value(id->hosts, i); | ||
| 189 | if (X509_check_host(x, name, strlen(name), id->hostflags, | ||
| 190 | &id->peername) > 0) | ||
| 191 | return 1; | ||
| 192 | } | ||
| 193 | return n == 0; | ||
| 194 | } | ||
| 195 | |||
| 196 | static int | ||
| 197 | check_id(X509_STORE_CTX *ctx) | ||
| 198 | { | ||
| 199 | X509_VERIFY_PARAM *vpm = ctx->param; | ||
| 200 | X509_VERIFY_PARAM_ID *id = vpm->id; | ||
| 201 | X509 *x = ctx->cert; | ||
| 202 | |||
| 203 | if (id->hosts && check_hosts(x, id) <= 0) { | ||
| 204 | if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH)) | ||
| 205 | return 0; | ||
| 206 | } | ||
| 207 | if (id->email != NULL && X509_check_email(x, id->email, id->emaillen, 0) | ||
| 208 | <= 0) { | ||
| 209 | if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH)) | ||
| 210 | return 0; | ||
| 211 | } | ||
| 212 | if (id->ip != NULL && X509_check_ip(x, id->ip, id->iplen, 0) <= 0) { | ||
| 213 | if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH)) | ||
| 214 | return 0; | ||
| 215 | } | ||
| 216 | return 1; | ||
| 217 | } | ||
| 218 | |||
| 156 | int | 219 | int |
| 157 | X509_verify_cert(X509_STORE_CTX *ctx) | 220 | X509_verify_cert(X509_STORE_CTX *ctx) |
| 158 | { | 221 | { |
| 159 | X509 *x, *xtmp, *chain_ss = NULL; | 222 | X509 *x, *xtmp, *xtmp2, *chain_ss = NULL; |
| 160 | int bad_chain = 0; | 223 | int bad_chain = 0; |
| 161 | X509_VERIFY_PARAM *param = ctx->param; | 224 | X509_VERIFY_PARAM *param = ctx->param; |
| 162 | int depth, i, ok = 0; | 225 | int depth, i, ok = 0; |
| 163 | int num; | 226 | int num, j, retry, trust; |
| 164 | int (*cb)(int xok, X509_STORE_CTX *xctx); | 227 | int (*cb) (int xok, X509_STORE_CTX *xctx); |
| 165 | STACK_OF(X509) *sktmp = NULL; | 228 | STACK_OF(X509) *sktmp = NULL; |
| 166 | |||
| 167 | if (ctx->cert == NULL) { | 229 | if (ctx->cert == NULL) { |
| 168 | X509err(X509_F_X509_VERIFY_CERT, | 230 | X509err(X509_F_X509_VERIFY_CERT, |
| 169 | X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); | 231 | X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); |
| 232 | ctx->error = X509_V_ERR_INVALID_CALL; | ||
| 233 | return -1; | ||
| 234 | } | ||
| 235 | if (ctx->chain != NULL) { | ||
| 236 | /* | ||
| 237 | * This X509_STORE_CTX has already been used to verify | ||
| 238 | * a cert. We cannot do another one. | ||
| 239 | */ | ||
| 240 | X509err(X509_F_X509_VERIFY_CERT, | ||
| 241 | ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | ||
| 242 | ctx->error = X509_V_ERR_INVALID_CALL; | ||
| 170 | return -1; | 243 | return -1; |
| 171 | } | 244 | } |
| 172 | 245 | ||
| 173 | cb = ctx->verify_cb; | 246 | cb = ctx->verify_cb; |
| 174 | 247 | ||
| 175 | /* first we make sure the chain we are going to build is | 248 | /* |
| 176 | * present and that the first entry is in place */ | 249 | * First we make sure the chain we are going to build is |
| 177 | if (ctx->chain == NULL) { | 250 | * present and that the first entry is in place. |
| 178 | if (((ctx->chain = sk_X509_new_null()) == NULL) || | 251 | */ |
| 179 | (!sk_X509_push(ctx->chain, ctx->cert))) { | 252 | ctx->chain = sk_X509_new_null(); |
| 180 | X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); | 253 | if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert)) { |
| 181 | goto end; | 254 | X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); |
| 182 | } | 255 | ctx->error = X509_V_ERR_OUT_OF_MEM; |
| 183 | CRYPTO_add(&ctx->cert->references, 1, CRYPTO_LOCK_X509); | 256 | goto end; |
| 184 | ctx->last_untrusted = 1; | ||
| 185 | } | 257 | } |
| 258 | X509_up_ref(ctx->cert); | ||
| 259 | ctx->last_untrusted = 1; | ||
| 186 | 260 | ||
| 187 | /* We use a temporary STACK so we can chop and hack at it */ | 261 | /* We use a temporary STACK so we can chop and hack at it */ |
| 188 | if (ctx->untrusted != NULL && | 262 | if (ctx->untrusted != NULL && |
| 189 | (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) { | 263 | (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) { |
| 190 | X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); | 264 | X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); |
| 265 | ctx->error = X509_V_ERR_OUT_OF_MEM; | ||
| 191 | goto end; | 266 | goto end; |
| 192 | } | 267 | } |
| 193 | 268 | ||
| @@ -197,17 +272,34 @@ X509_verify_cert(X509_STORE_CTX *ctx) | |||
| 197 | 272 | ||
| 198 | for (;;) { | 273 | for (;;) { |
| 199 | /* If we have enough, we break */ | 274 | /* If we have enough, we break */ |
| 275 | /* FIXME: If this happens, we should take | ||
| 276 | * note of it and, if appropriate, use the | ||
| 277 | * X509_V_ERR_CERT_CHAIN_TOO_LONG error code | ||
| 278 | * later. | ||
| 279 | */ | ||
| 200 | if (depth < num) | 280 | if (depth < num) |
| 201 | break; /* FIXME: If this happens, we should take | 281 | break; |
| 202 | * note of it and, if appropriate, use the | ||
| 203 | * X509_V_ERR_CERT_CHAIN_TOO_LONG error | ||
| 204 | * code later. | ||
| 205 | */ | ||
| 206 | |||
| 207 | /* If we are self signed, we break */ | 282 | /* If we are self signed, we break */ |
| 208 | if (ctx->check_issued(ctx, x, x)) | 283 | if (cert_self_signed(x)) |
| 209 | break; | 284 | break; |
| 210 | 285 | /* | |
| 286 | * If asked see if we can find issuer in trusted store first | ||
| 287 | */ | ||
| 288 | if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) { | ||
| 289 | ok = ctx->get_issuer(&xtmp, ctx, x); | ||
| 290 | if (ok < 0) { | ||
| 291 | ctx->error = X509_V_ERR_STORE_LOOKUP; | ||
| 292 | goto end; | ||
| 293 | } | ||
| 294 | /* | ||
| 295 | * If successful for now free up cert so it | ||
| 296 | * will be picked up again later. | ||
| 297 | */ | ||
| 298 | if (ok > 0) { | ||
| 299 | X509_free(xtmp); | ||
| 300 | break; | ||
| 301 | } | ||
| 302 | } | ||
| 211 | /* If we were passed a cert chain, use it first */ | 303 | /* If we were passed a cert chain, use it first */ |
| 212 | if (ctx->untrusted != NULL) { | 304 | if (ctx->untrusted != NULL) { |
| 213 | xtmp = find_issuer(ctx, sktmp, x); | 305 | xtmp = find_issuer(ctx, sktmp, x); |
| @@ -215,109 +307,174 @@ X509_verify_cert(X509_STORE_CTX *ctx) | |||
| 215 | if (!sk_X509_push(ctx->chain, xtmp)) { | 307 | if (!sk_X509_push(ctx->chain, xtmp)) { |
| 216 | X509err(X509_F_X509_VERIFY_CERT, | 308 | X509err(X509_F_X509_VERIFY_CERT, |
| 217 | ERR_R_MALLOC_FAILURE); | 309 | ERR_R_MALLOC_FAILURE); |
| 310 | ctx->error = X509_V_ERR_OUT_OF_MEM; | ||
| 311 | ok = 0; | ||
| 218 | goto end; | 312 | goto end; |
| 219 | } | 313 | } |
| 220 | CRYPTO_add(&xtmp->references, 1, | 314 | X509_up_ref(xtmp); |
| 221 | CRYPTO_LOCK_X509); | ||
| 222 | (void)sk_X509_delete_ptr(sktmp, xtmp); | 315 | (void)sk_X509_delete_ptr(sktmp, xtmp); |
| 223 | ctx->last_untrusted++; | 316 | ctx->last_untrusted++; |
| 224 | x = xtmp; | 317 | x = xtmp; |
| 225 | num++; | 318 | num++; |
| 226 | /* reparse the full chain for | 319 | /* |
| 227 | * the next one */ | 320 | * reparse the full chain for the next one |
| 321 | */ | ||
| 228 | continue; | 322 | continue; |
| 229 | } | 323 | } |
| 230 | } | 324 | } |
| 231 | break; | 325 | break; |
| 232 | } | 326 | } |
| 233 | sk_X509_free(sktmp); | 327 | /* Remember how many untrusted certs we have */ |
| 234 | sktmp = NULL; | 328 | j = num; |
| 235 | 329 | ||
| 236 | /* at this point, chain should contain a list of untrusted | 330 | /* |
| 331 | * At this point, chain should contain a list of untrusted | ||
| 237 | * certificates. We now need to add at least one trusted one, | 332 | * certificates. We now need to add at least one trusted one, |
| 238 | * if possible, otherwise we complain. */ | 333 | * if possible, otherwise we complain. |
| 239 | 334 | */ | |
| 240 | /* Examine last certificate in chain and see if it | 335 | |
| 241 | * is self signed. | 336 | do { |
| 242 | */ | 337 | /* |
| 243 | 338 | * Examine last certificate in chain and see if it is | |
| 244 | i = sk_X509_num(ctx->chain); | 339 | * self signed. |
| 245 | x = sk_X509_value(ctx->chain, i - 1); | 340 | */ |
| 246 | if (ctx->check_issued(ctx, x, x)) { | 341 | i = sk_X509_num(ctx->chain); |
| 247 | /* we have a self signed certificate */ | 342 | x = sk_X509_value(ctx->chain, i - 1); |
| 248 | if (sk_X509_num(ctx->chain) == 1) { | 343 | if (cert_self_signed(x)) { |
| 249 | /* We have a single self signed certificate: see if | 344 | /* we have a self signed certificate */ |
| 250 | * we can find it in the store. We must have an exact | 345 | if (i == 1) { |
| 251 | * match to avoid possible impersonation. | 346 | /* |
| 252 | */ | 347 | * We have a single self signed |
| 253 | ok = ctx->get_issuer(&xtmp, ctx, x); | 348 | * certificate: see if we can find it |
| 254 | if ((ok <= 0) || X509_cmp(x, xtmp)) { | 349 | * in the store. We must have an exact |
| 255 | ctx->error = | 350 | * match to avoid possible |
| 256 | X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; | 351 | * impersonation. |
| 257 | ctx->current_cert = x; | 352 | */ |
| 258 | ctx->error_depth = i - 1; | 353 | ok = ctx->get_issuer(&xtmp, ctx, x); |
| 259 | if (ok == 1) | 354 | if ((ok <= 0) || X509_cmp(x, xtmp)) { |
| 260 | X509_free(xtmp); | 355 | ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; |
| 261 | bad_chain = 1; | 356 | ctx->current_cert = x; |
| 262 | ok = cb(0, ctx); | 357 | ctx->error_depth = i - 1; |
| 263 | if (!ok) | 358 | if (ok == 1) |
| 264 | goto end; | 359 | X509_free(xtmp); |
| 360 | bad_chain = 1; | ||
| 361 | ok = cb(0, ctx); | ||
| 362 | if (!ok) | ||
| 363 | goto end; | ||
| 364 | } else { | ||
| 365 | /* | ||
| 366 | * We have a match: replace | ||
| 367 | * certificate with store | ||
| 368 | * version so we get any trust | ||
| 369 | * settings. | ||
| 370 | */ | ||
| 371 | X509_free(x); | ||
| 372 | x = xtmp; | ||
| 373 | (void)sk_X509_set(ctx->chain, i - 1, x); | ||
| 374 | ctx->last_untrusted = 0; | ||
| 375 | } | ||
| 265 | } else { | 376 | } else { |
| 266 | /* We have a match: replace certificate with store version | 377 | /* |
| 267 | * so we get any trust settings. | 378 | * extract and save self signed |
| 379 | * certificate for later use | ||
| 268 | */ | 380 | */ |
| 269 | X509_free(x); | 381 | chain_ss = sk_X509_pop(ctx->chain); |
| 270 | x = xtmp; | 382 | ctx->last_untrusted--; |
| 271 | (void)sk_X509_set(ctx->chain, i - 1, x); | 383 | num--; |
| 272 | ctx->last_untrusted = 0; | 384 | j--; |
| 385 | x = sk_X509_value(ctx->chain, num - 1); | ||
| 273 | } | 386 | } |
| 274 | } else { | ||
| 275 | /* extract and save self signed certificate for later use */ | ||
| 276 | chain_ss = sk_X509_pop(ctx->chain); | ||
| 277 | ctx->last_untrusted--; | ||
| 278 | num--; | ||
| 279 | x = sk_X509_value(ctx->chain, num - 1); | ||
| 280 | } | 387 | } |
| 281 | } | 388 | /* We now lookup certs from the certificate store */ |
| 282 | 389 | for (;;) { | |
| 283 | /* We now lookup certs from the certificate store */ | 390 | /* If we have enough, we break */ |
| 284 | for (;;) { | 391 | if (depth < num) |
| 285 | /* If we have enough, we break */ | 392 | break; |
| 286 | if (depth < num) | 393 | /* If we are self signed, we break */ |
| 287 | break; | 394 | if (cert_self_signed(x)) |
| 395 | break; | ||
| 396 | ok = ctx->get_issuer(&xtmp, ctx, x); | ||
| 288 | 397 | ||
| 289 | /* If we are self signed, we break */ | 398 | if (ok < 0) { |
| 290 | if (ctx->check_issued(ctx, x, x)) | 399 | ctx->error = X509_V_ERR_STORE_LOOKUP; |
| 291 | break; | 400 | goto end; |
| 401 | } | ||
| 402 | if (ok == 0) | ||
| 403 | break; | ||
| 404 | x = xtmp; | ||
| 405 | if (!sk_X509_push(ctx->chain, x)) { | ||
| 406 | X509_free(xtmp); | ||
| 407 | X509err(X509_F_X509_VERIFY_CERT, | ||
| 408 | ERR_R_MALLOC_FAILURE); | ||
| 409 | ctx->error = X509_V_ERR_OUT_OF_MEM; | ||
| 410 | ok = 0; | ||
| 411 | goto end; | ||
| 412 | } | ||
| 413 | num++; | ||
| 414 | } | ||
| 292 | 415 | ||
| 293 | ok = ctx->get_issuer(&xtmp, ctx, x); | 416 | /* we now have our chain, lets check it... */ |
| 294 | if (ok < 0) | 417 | trust = check_trust(ctx); |
| 295 | return ok; | ||
| 296 | if (ok == 0) | ||
| 297 | break; | ||
| 298 | 418 | ||
| 299 | x = xtmp; | 419 | /* If explicitly rejected error */ |
| 300 | if (!sk_X509_push(ctx->chain, x)) { | 420 | if (trust == X509_TRUST_REJECTED) { |
| 301 | X509_free(xtmp); | 421 | ok = 0; |
| 302 | X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); | 422 | goto end; |
| 303 | return 0; | ||
| 304 | } | 423 | } |
| 305 | num++; | 424 | /* |
| 306 | } | 425 | * If it's not explicitly trusted then check if there |
| 307 | 426 | * is an alternative chain that could be used. We only | |
| 308 | /* we now have our chain, lets check it... */ | 427 | * do this if we haven't already checked via |
| 428 | * TRUSTED_FIRST and the user hasn't switched off | ||
| 429 | * alternate chain checking | ||
| 430 | */ | ||
| 431 | retry = 0; | ||
| 432 | if (trust != X509_TRUST_TRUSTED && | ||
| 433 | !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) && | ||
| 434 | !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) { | ||
| 435 | while (j-- > 1) { | ||
| 436 | xtmp2 = sk_X509_value(ctx->chain, j - 1); | ||
| 437 | ok = ctx->get_issuer(&xtmp, ctx, xtmp2); | ||
| 438 | if (ok < 0) | ||
| 439 | goto end; | ||
| 440 | /* Check if we found an alternate chain */ | ||
| 441 | if (ok > 0) { | ||
| 442 | /* | ||
| 443 | * Free up the found cert | ||
| 444 | * we'll add it again later | ||
| 445 | */ | ||
| 446 | X509_free(xtmp); | ||
| 447 | /* | ||
| 448 | * Dump all the certs above | ||
| 449 | * this point - we've found an | ||
| 450 | * alternate chain | ||
| 451 | */ | ||
| 452 | while (num > j) { | ||
| 453 | xtmp = sk_X509_pop(ctx->chain); | ||
| 454 | X509_free(xtmp); | ||
| 455 | num--; | ||
| 456 | } | ||
| 457 | ctx->last_untrusted = sk_X509_num(ctx->chain); | ||
| 458 | retry = 1; | ||
| 459 | break; | ||
| 460 | } | ||
| 461 | } | ||
| 462 | } | ||
| 463 | } while (retry); | ||
| 309 | 464 | ||
| 310 | /* Is last certificate looked up self signed? */ | 465 | /* |
| 311 | if (!ctx->check_issued(ctx, x, x)) { | 466 | * If not explicitly trusted then indicate error unless it's a single |
| 312 | if ((chain_ss == NULL) || | 467 | * self signed certificate in which case we've indicated an error already |
| 313 | !ctx->check_issued(ctx, x, chain_ss)) { | 468 | * and set bad_chain == 1 |
| 469 | */ | ||
| 470 | if (trust != X509_TRUST_TRUSTED && !bad_chain) { | ||
| 471 | if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) { | ||
| 314 | if (ctx->last_untrusted >= num) | 472 | if (ctx->last_untrusted >= num) |
| 315 | ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; | 473 | ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; |
| 316 | else | 474 | else |
| 317 | ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; | 475 | ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; |
| 318 | ctx->current_cert = x; | 476 | ctx->current_cert = x; |
| 319 | } else { | 477 | } else { |
| 320 | |||
| 321 | if (!sk_X509_push(ctx->chain, chain_ss)) { | 478 | if (!sk_X509_push(ctx->chain, chain_ss)) { |
| 322 | X509_free(chain_ss); | 479 | X509_free(chain_ss); |
| 323 | X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); | 480 | X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); |
| @@ -350,19 +507,13 @@ X509_verify_cert(X509_STORE_CTX *ctx) | |||
| 350 | if (!ok) | 507 | if (!ok) |
| 351 | goto end; | 508 | goto end; |
| 352 | 509 | ||
| 353 | /* The chain extensions are OK: check trust */ | 510 | ok = check_id(ctx); |
| 354 | |||
| 355 | if (param->trust > 0) | ||
| 356 | ok = check_trust(ctx); | ||
| 357 | 511 | ||
| 358 | if (!ok) | 512 | if (!ok) |
| 359 | goto end; | 513 | goto end; |
| 360 | 514 | /* | |
| 361 | /* We may as well copy down any DSA parameters that are required */ | 515 | * Check revocation status: we do this after copying parameters because |
| 362 | X509_get_pubkey_parameters(NULL, ctx->chain); | 516 | * they may be needed for CRL signature verification. |
| 363 | |||
| 364 | /* Check revocation status: we do this after copying parameters | ||
| 365 | * because they may be needed for CRL signature verification. | ||
| 366 | */ | 517 | */ |
| 367 | 518 | ||
| 368 | ok = ctx->check_revocation(ctx); | 519 | ok = ctx->check_revocation(ctx); |
| @@ -376,23 +527,20 @@ X509_verify_cert(X509_STORE_CTX *ctx) | |||
| 376 | ok = internal_verify(ctx); | 527 | ok = internal_verify(ctx); |
| 377 | if (!ok) | 528 | if (!ok) |
| 378 | goto end; | 529 | goto end; |
| 379 | |||
| 380 | /* If we get this far evaluate policies */ | 530 | /* If we get this far evaluate policies */ |
| 381 | if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)) | 531 | if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)) |
| 382 | ok = ctx->check_policy(ctx); | 532 | ok = ctx->check_policy(ctx); |
| 383 | if (!ok) | 533 | end: |
| 384 | goto end; | ||
| 385 | if (0) { | ||
| 386 | end: | ||
| 387 | X509_get_pubkey_parameters(NULL, ctx->chain); | ||
| 388 | } | ||
| 389 | if (sktmp != NULL) | 534 | if (sktmp != NULL) |
| 390 | sk_X509_free(sktmp); | 535 | sk_X509_free(sktmp); |
| 391 | X509_free(chain_ss); | 536 | X509_free(chain_ss); |
| 537 | |||
| 538 | /* Safety net, error returns must set ctx->error */ | ||
| 539 | if (ok <= 0 && ctx->error == X509_V_OK) | ||
| 540 | ctx->error = X509_V_ERR_UNSPECIFIED; | ||
| 392 | return ok; | 541 | return ok; |
| 393 | } | 542 | } |
| 394 | 543 | ||
| 395 | |||
| 396 | /* Given a STACK_OF(X509) find the issuer of cert (if any) | 544 | /* Given a STACK_OF(X509) find the issuer of cert (if any) |
| 397 | */ | 545 | */ |
| 398 | 546 | ||
