@@ -1013,6 +1013,10 @@ int testFallback(struct sslCheckOptions *options, const SSL_METHOD *sslMethod)
1013
1013
1014
1014
// Connect SSL over socket
1015
1015
connStatus = SSL_connect (ssl );
1016
+
1017
+ // We can't check for "acceptable" errors for "client cert required" here, since SSL Alert 40 (Handshake failure)
1018
+ // can be reported for either client cert required, or downgrade failure. So it's not possible to distinguish
1019
+ // between them.
1016
1020
if (connStatus )
1017
1021
{
1018
1022
if (!downgraded )
@@ -1062,8 +1066,8 @@ int testFallback(struct sslCheckOptions *options, const SSL_METHOD *sslMethod)
1062
1066
}
1063
1067
else
1064
1068
{
1065
- printf ("%sConnection failed%s - unable to determine TLS Fallback SCSV support\n\n" ,
1066
- COL_YELLOW , RESET );
1069
+ printf ("%sConnection failed%s - unable to determine TLS Fallback SCSV support%s. \n\n" ,
1070
+ COL_YELLOW , RESET , acceptableError () ? " - Server requires a client cert" : "" );
1067
1071
status = false;
1068
1072
}
1069
1073
}
@@ -1198,7 +1202,7 @@ int testRenegotiation(struct sslCheckOptions *options, const SSL_METHOD *sslMeth
1198
1202
}
1199
1203
1200
1204
1201
- if (cipherStatus == 1 )
1205
+ if (cipherStatus == 1 || acceptableError ());
1202
1206
{
1203
1207
1204
1208
#if ( OPENSSL_VERSION_NUMBER > 0x009080cfL )
@@ -1564,13 +1568,16 @@ int testCipher(struct sslCheckOptions *options, const SSL_METHOD *sslMethod)
1564
1568
// Connect SSL over socket
1565
1569
cipherStatus = SSL_connect (ssl );
1566
1570
1567
- sslCipherPointer = SSL_get_current_cipher (ssl );
1568
- cipherbits = SSL_CIPHER_get_bits (sslCipherPointer , NULL );
1569
-
1570
1571
if (cipherStatus == 0 )
1571
1572
{
1572
- SSL_free (ssl );
1573
- return false;
1573
+ // An "acceptable" error is eg "client certificate required". We can still produce a list of supported ciphers.
1574
+ if (acceptableError ())
1575
+ cipherStatus = 1 ;
1576
+ else
1577
+ {
1578
+ SSL_free (ssl );
1579
+ return false;
1580
+ }
1574
1581
}
1575
1582
else if (cipherStatus != 1 )
1576
1583
{
@@ -1590,6 +1597,15 @@ int testCipher(struct sslCheckOptions *options, const SSL_METHOD *sslMethod)
1590
1597
return false;
1591
1598
}
1592
1599
1600
+ sslCipherPointer = SSL_get_current_cipher (ssl );
1601
+ // If sslCipherPointer is NULL, SSL_CIPHER_get_bits() will segfault
1602
+ if (sslCipherPointer == NULL )
1603
+ {
1604
+ SSL_free (ssl );
1605
+ return false;
1606
+ }
1607
+ cipherbits = SSL_CIPHER_get_bits (sslCipherPointer , NULL );
1608
+
1593
1609
cipherid = SSL_CIPHER_get_id (sslCipherPointer );
1594
1610
cipherid = cipherid & 0x00ffffff ; // remove first byte which is the version (0x03 for TLSv1/SSLv3)
1595
1611
@@ -1879,7 +1895,7 @@ int checkCertificate(struct sslCheckOptions *options, const SSL_METHOD *sslMetho
1879
1895
1880
1896
// Connect SSL over socket
1881
1897
cipherStatus = SSL_connect (ssl );
1882
- if (cipherStatus == 1 )
1898
+ if (cipherStatus == 1 || acceptableError () )
1883
1899
{
1884
1900
// Setup BIO's
1885
1901
if (!xml_to_stdout ) {
@@ -2299,7 +2315,7 @@ int ocspRequest(struct sslCheckOptions *options)
2299
2315
2300
2316
// Connect SSL over socket
2301
2317
cipherStatus = SSL_connect (ssl );
2302
- if (cipherStatus == 1 )
2318
+ if (cipherStatus == 1 || acceptableError () )
2303
2319
{
2304
2320
// Setup BIO's
2305
2321
if (!xml_to_stdout ) {
@@ -2568,7 +2584,7 @@ int showCertificate(struct sslCheckOptions *options)
2568
2584
2569
2585
// Connect SSL over socket
2570
2586
cipherStatus = SSL_connect (ssl );
2571
- if (cipherStatus == 1 )
2587
+ if (cipherStatus == 1 || acceptableError () )
2572
2588
{
2573
2589
// Setup BIO's
2574
2590
if (!xml_to_stdout ) {
@@ -3011,7 +3027,7 @@ int showTrustedCAs(struct sslCheckOptions *options)
3011
3027
3012
3028
// Connect SSL over socket
3013
3029
cipherStatus = SSL_connect (ssl );
3014
- if (cipherStatus >= 0 )
3030
+ if (cipherStatus >= 0 || acceptableError () )
3015
3031
{
3016
3032
// Setup BIO's
3017
3033
if (!xml_to_stdout ) {
@@ -3213,7 +3229,7 @@ int testHost(struct sslCheckOptions *options)
3213
3229
// Verbose warning about STARTTLS and SSLv3
3214
3230
if (options -> sslVersion == ssl_v3 || options -> sslVersion == ssl_all )
3215
3231
{
3216
- printf_verbose ("Some servers will fail to response to SSLv3 ciphers over STARTTLS\nIf your scan hangs, try using the --tlsall option\n\n" );
3232
+ printf_verbose ("Some servers will fail to respond to SSLv3 ciphers over STARTTLS\nIf your scan hangs, try using the --tlsall option\n\n" );
3217
3233
}
3218
3234
3219
3235
printf ("Testing SSL server %s%s%s on port %s%d%s using SNI name %s%s%s\n\n" , COL_GREEN , options -> host , RESET ,
@@ -3421,6 +3437,9 @@ int testHost(struct sslCheckOptions *options)
3421
3437
if (status != false)
3422
3438
status = checkCertificateProtocol (options , SSLv2_client_method ());
3423
3439
#endif
3440
+ // Reset status to true, otherwise show trusted CAs below can never run
3441
+ // with the default checkCertificate == true
3442
+ status = true;
3424
3443
}
3425
3444
3426
3445
// Print client auth trusted CAs
@@ -3466,6 +3485,20 @@ const char *SSL_ERR_to_string (int sslerr)
3466
3485
}
3467
3486
}
3468
3487
3488
+ // Define a list of "acceptable" SSL errors which might indicate a client certificate is required, and continue anyway.
3489
+ static inline int acceptableError (void )
3490
+ {
3491
+ // Error 0x14094410 = SSL Alert 40 = Handshake Failure, probably because Server requested client Cert, which we'll treat as a "success".
3492
+ // Error 0x14094416 = SSL Alert 46 = Certificate Unknown, treat as "success".
3493
+ // Error 0x14094412 = SSL Alert 42 = Bad Certificate - probably means Server requested client Cert. Will also send a list of Acceptable client certificate CA names.
3494
+ // SSL Alerts documented here: https://tools.ietf.org/html/rfc5246#section-7.2
3495
+
3496
+ if (ERR_peek_error () == 0x14094410L || ERR_peek_error () == 0x14094416L || ERR_peek_error () == 0x14094412L )
3497
+ return true;
3498
+
3499
+ return false;
3500
+ }
3501
+
3469
3502
int main (int argc , char * argv [])
3470
3503
{
3471
3504
// Variables...
0 commit comments