The flag SSL_VERIFY_POST_HANDSHAKE for SSL_CTX_set_verify is documented as Client mode: ignored. I was under the impression that I can set the flag safely for client connections and OpenSSL would just ignore the flag.
However tls_process_server_certificate does not ignore the flag. SSL_VERIFY_POST_HANDSHAKE implicitly enables cert validation. The code comes with a long and good reasoning why it performs s->verify_mode != SSL_VERIFY_NONE.
|
/* |
|
* The documented interface is that SSL_VERIFY_PEER should be set in order |
|
* for client side verification of the server certificate to take place. |
|
* However, historically the code has only checked that *any* flag is set |
|
* to cause server verification to take place. Use of the other flags makes |
|
* no sense in client mode. An attempt to clean up the semantics was |
|
* reverted because at least one application *only* set |
|
* SSL_VERIFY_FAIL_IF_NO_PEER_CERT. Prior to the clean up this still caused |
|
* server verification to take place, after the clean up it silently did |
|
* nothing. SSL_CTX_set_verify()/SSL_set_verify() cannot validate the flags |
|
* sent to them because they are void functions. Therefore, we now use the |
|
* (less clean) historic behaviour of performing validation if any flag is |
|
* set. The *documented* interface remains the same. |
|
*/ |
|
if (s->verify_mode != SSL_VERIFY_NONE && i <= 0) { |
|
SSLfatal(s, ssl_x509err2alert(s->verify_result), |
|
SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, |
|
SSL_R_CERTIFICATE_VERIFY_FAILED); |
|
goto err; |
|
} |
I have two proposals to address the issue:
- Modify the check to ignore PHA and client once flags:
(s->verify_mode & ~(SSL_VERIFY_CLIENT_ONCE|SSL_VERIFY_POST_HANDSHAKE)) != SSL_VERIFY_NONE
- Update the documentation and explain that the flags implicitly enable cert chain validation.
The flag
SSL_VERIFY_POST_HANDSHAKEforSSL_CTX_set_verifyis documented asClient mode: ignored. I was under the impression that I can set the flag safely for client connections and OpenSSL would just ignore the flag.However
tls_process_server_certificatedoes not ignore the flag.SSL_VERIFY_POST_HANDSHAKEimplicitly enables cert validation. The code comes with a long and good reasoning why it performss->verify_mode != SSL_VERIFY_NONE.openssl/ssl/statem/statem_clnt.c
Lines 1899 to 1918 in 743694a
I have two proposals to address the issue:
(s->verify_mode & ~(SSL_VERIFY_CLIENT_ONCE|SSL_VERIFY_POST_HANDSHAKE)) != SSL_VERIFY_NONE