34
34
#ifdef OPENSSL_EXTRA
35
35
static int X509StoreGetIssuerEx (WOLFSSL_X509 * * issuer ,
36
36
WOLFSSL_STACK * certs , WOLFSSL_X509 * x );
37
+ static int X509StorePopCert (WOLFSSL_STACK * certs_stack , WOLFSSL_STACK * dest_stack ,
38
+ WOLFSSL_X509 * cert );
37
39
static int X509StoreAddCa (WOLFSSL_X509_STORE * store ,
38
40
WOLFSSL_X509 * x509 , int type );
39
41
#endif
@@ -415,10 +417,12 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
415
417
int i = 0 ;
416
418
int numInterAdd = 0 ;
417
419
int depth = 0 ;
420
+ int origDepth = 0 ;
418
421
WOLFSSL_X509 * issuer = NULL ;
419
422
WOLFSSL_X509 * orig = NULL ;
420
423
WOLF_STACK_OF (WOLFSSL_X509 )* certs = NULL ;
421
424
WOLF_STACK_OF (WOLFSSL_X509 )* certsToUse = NULL ;
425
+ WOLF_STACK_OF (WOLFSSL_X509 )* failedCerts = NULL ;
422
426
WOLFSSL_ENTER ("wolfSSL_X509_verify_cert" );
423
427
424
428
if (ctx == NULL || ctx -> store == NULL || ctx -> store -> cm == NULL
@@ -427,6 +431,10 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
427
431
}
428
432
429
433
certs = ctx -> store -> certs ;
434
+ if (certs == NULL ) {
435
+ return WOLFSSL_FATAL_ERROR ;
436
+ }
437
+
430
438
if (ctx -> setTrustedSk != NULL ) {
431
439
certs = ctx -> setTrustedSk ;
432
440
}
@@ -450,6 +458,10 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
450
458
}
451
459
ctx -> chain = wolfSSL_sk_X509_new_null ();
452
460
461
+ failedCerts = wolfSSL_sk_X509_new_null ();
462
+ if (!failedCerts )
463
+ return WOLFSSL_FATAL_ERROR ;
464
+
453
465
if (ctx -> depth > 0 ) {
454
466
depth = ctx -> depth + 1 ;
455
467
}
@@ -458,6 +470,7 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
458
470
}
459
471
460
472
orig = ctx -> current_cert ;
473
+ origDepth = depth ;
461
474
while (done == 0 && depth > 0 ) {
462
475
issuer = NULL ;
463
476
@@ -491,12 +504,14 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
491
504
ret = X509StoreAddCa (ctx -> store , issuer ,
492
505
WOLFSSL_TEMP_CA );
493
506
if (ret != WOLFSSL_SUCCESS ) {
494
- goto exit ;
507
+ goto retry ;
495
508
}
496
509
added = 1 ;
497
510
ret = X509StoreVerifyCert (ctx );
498
511
if (ret != WOLFSSL_SUCCESS ) {
499
- goto exit ;
512
+ if ((origDepth - depth ) <= 1 )
513
+ added = 0 ;
514
+ goto retry ;
500
515
}
501
516
/* Add it to the current chain and look at the issuer cert next */
502
517
wolfSSL_sk_X509_push (ctx -> chain , ctx -> current_cert );
@@ -515,8 +530,9 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
515
530
(added == 1 )) {
516
531
wolfSSL_sk_X509_push (ctx -> chain , ctx -> current_cert );
517
532
ret = WOLFSSL_SUCCESS ;
533
+ } else {
534
+ goto retry ;
518
535
}
519
- goto exit ;
520
536
}
521
537
522
538
/* Cert verified, finish building the chain */
@@ -548,6 +564,19 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
548
564
}
549
565
550
566
depth -- ;
567
+ continue ;
568
+
569
+ retry :
570
+ /* Current certificate failed, but it is possible there is an alternative
571
+ * cert with the same subject key which will work. Retry until all
572
+ * possible candidate certs are exhausted. */
573
+ WOLFSSL_MSG ("X509_verify_cert current cert failed, retrying with other certs." );
574
+ RemoveCA (ctx -> store -> cm , ctx -> current_cert -> subjKeyId );
575
+ X509StorePopCert (certs , failedCerts , ctx -> current_cert );
576
+ if (numInterAdd > 0 )
577
+ numInterAdd -- ;
578
+ ctx -> current_cert = wolfSSL_sk_X509_pop (ctx -> chain );
579
+ depth ++ ;
551
580
}
552
581
553
582
exit :
@@ -572,6 +601,17 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
572
601
wolfSSL_sk_X509_free (certsToUse );
573
602
}
574
603
604
+ /* Copy back failed certs if verification failed. */
605
+ if (ret != WOLFSSL_SUCCESS ) {
606
+ while (wolfSSL_sk_X509_num (failedCerts ) > 0 )
607
+ {
608
+ wolfSSL_sk_X509_push (certs , wolfSSL_sk_X509_pop (failedCerts ));
609
+ }
610
+ }
611
+ if (failedCerts ) {
612
+ wolfSSL_sk_X509_free (failedCerts );
613
+ }
614
+
575
615
return ret == WOLFSSL_SUCCESS ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE ;
576
616
}
577
617
@@ -1055,6 +1095,22 @@ static int X509StoreGetIssuerEx(WOLFSSL_X509 **issuer,
1055
1095
return WOLFSSL_FAILURE ;
1056
1096
}
1057
1097
1098
+ static int X509StorePopCert (WOLFSSL_STACK * certs_stack , WOLFSSL_STACK * dest_stack , WOLFSSL_X509 * cert ) {
1099
+ int i ;
1100
+
1101
+ if (certs_stack == NULL || dest_stack == NULL || cert == NULL )
1102
+ return WOLFSSL_FATAL_ERROR ;
1103
+
1104
+ for (i = 0 ; i < wolfSSL_sk_X509_num (certs_stack ); i ++ ) {
1105
+ if (wolfSSL_sk_X509_value (certs_stack , i ) == cert ) {
1106
+ wolfSSL_sk_X509_push (dest_stack , wolfSSL_sk_pop_node (certs_stack , i ));
1107
+ return WOLFSSL_SUCCESS ;
1108
+ }
1109
+ }
1110
+
1111
+ return WOLFSSL_FAILURE ;
1112
+ }
1113
+
1058
1114
#endif
1059
1115
1060
1116
/******************************************************************************
0 commit comments