Fix client verify mode to check SSL_VERIFY_PEER
authorViktor Dukhovni <openssl-users@dukhovni.org>
Sat, 2 Apr 2016 20:47:48 +0000 (16:47 -0400)
committerViktor Dukhovni <openssl-users@dukhovni.org>
Thu, 7 Apr 2016 18:41:34 +0000 (14:41 -0400)
The original check for != SSL_VERIFY_NONE can give surprising results
when flags SSL_VERIFY_PEER is not set, but other flags are.  Note
that SSL_VERIFY_NONE (0) is not a flag bit, it is rather the absense
of all other flag bits.

Signed-off-by: Rob Percival <robpercival@google.com>
Reviewed-by: Emilia Käsper <emilia@openssl.org>
doc/ssl/SSL_CTX_set_verify.pod
ssl/statem/statem_clnt.c

index 5da4166..d60bb6a 100644 (file)
@@ -89,8 +89,7 @@ B<Client mode:> ignored
 
 =back
 
-Exactly one of the B<mode> flags SSL_VERIFY_NONE and SSL_VERIFY_PEER must be
-set at any time.
+If the B<mode> is SSL_VERIFY_NONE none of the other flags may be set.
 
 The actual verification procedure is performed either using the built-in
 verification procedure or using another application provided verification
@@ -146,18 +145,6 @@ Its return value is identical to B<preverify_ok>, so that any verification
 failure will lead to a termination of the TLS/SSL handshake with an
 alert message, if SSL_VERIFY_PEER is set.
 
-=head1 BUGS
-
-In client mode, it is not checked whether the SSL_VERIFY_PEER flag
-is set, but whether SSL_VERIFY_NONE is not set. This can lead to
-unexpected behaviour, if the SSL_VERIFY_PEER and SSL_VERIFY_NONE are not
-used as required (exactly one must be set at any time).
-
-The certificate verification depth set with SSL[_CTX]_verify_depth()
-stops the verification at a certain depth. The error message produced
-will be that of an incomplete certificate chain and not
-X509_V_ERR_CERT_CHAIN_TOO_LONG as may be expected.
-
 =head1 RETURN VALUES
 
 The SSL*_set_verify*() functions do not provide diagnostic information.
index 4806e67..19ea227 100644 (file)
@@ -1334,7 +1334,7 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt)
     }
 
     i = ssl_verify_cert_chain(s, sk);
-    if (s->verify_mode != SSL_VERIFY_NONE && i <= 0) {
+    if ((s->verify_mode & SSL_VERIFY_PEER) && i <= 0) {
         al = ssl_verify_alarm_type(s->verify_result);
         SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE,
                SSL_R_CERTIFICATE_VERIFY_FAILED);