[ruby/openssl] ssl: adjust "certificate verify failed" error on SSL_ERROR_SYSCALL
Enrich SSLError's message with the low-level certificate verification result, even if SSL_get_error() returns SSL_ERROR_SYSCALL. This is currently done on SSL_ERROR_SSL only. According to the man page of SSL_get_error(), SSL_ERROR_SYSCALL may be returned for "other errors, check the error queue for details". This apparently means we have to treat SSL_ERROR_SYSCALL, if errno is not set, as equivalent to SSL_ERROR_SSL. https://github.com/ruby/openssl/commit/5113777e82
This commit is contained in:
parent
66a70582f4
commit
cb344e4e25
@ -1756,9 +1756,6 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
|
|||||||
int ret, ret2;
|
int ret, ret2;
|
||||||
VALUE cb_state;
|
VALUE cb_state;
|
||||||
int nonblock = opts != Qfalse;
|
int nonblock = opts != Qfalse;
|
||||||
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
|
|
||||||
unsigned long err;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
rb_ivar_set(self, ID_callback_state, Qnil);
|
rb_ivar_set(self, ID_callback_state, Qnil);
|
||||||
|
|
||||||
@ -1796,30 +1793,33 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
|
|||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
if (errno) rb_sys_fail(funcname);
|
if (errno) rb_sys_fail(funcname);
|
||||||
ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s",
|
|
||||||
funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl));
|
|
||||||
|
|
||||||
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
|
|
||||||
case SSL_ERROR_SSL:
|
|
||||||
err = ERR_peek_last_error();
|
|
||||||
if (ERR_GET_LIB(err) == ERR_LIB_SSL &&
|
|
||||||
ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
|
|
||||||
const char *err_msg = ERR_reason_error_string(err),
|
|
||||||
*verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
|
|
||||||
if (!err_msg)
|
|
||||||
err_msg = "(null)";
|
|
||||||
if (!verify_msg)
|
|
||||||
verify_msg = "(null)";
|
|
||||||
ossl_clear_error(); /* let ossl_raise() not append message */
|
|
||||||
ossl_raise(eSSLError, "%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s: %s (%s)",
|
|
||||||
funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl),
|
|
||||||
err_msg, verify_msg);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
default:
|
default: {
|
||||||
ossl_raise(eSSLError, "%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s",
|
VALUE error_append = Qnil;
|
||||||
funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl));
|
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
|
||||||
|
unsigned long err = ERR_peek_last_error();
|
||||||
|
if (ERR_GET_LIB(err) == ERR_LIB_SSL &&
|
||||||
|
ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
|
||||||
|
const char *err_msg = ERR_reason_error_string(err),
|
||||||
|
*verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
|
||||||
|
if (!err_msg)
|
||||||
|
err_msg = "(null)";
|
||||||
|
if (!verify_msg)
|
||||||
|
verify_msg = "(null)";
|
||||||
|
ossl_clear_error(); /* let ossl_raise() not append message */
|
||||||
|
error_append = rb_sprintf(": %s (%s)", err_msg, verify_msg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
ossl_raise(eSSLError,
|
||||||
|
"%s%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s%"PRIsVALUE,
|
||||||
|
funcname,
|
||||||
|
ret2 == SSL_ERROR_SYSCALL ? " SYSCALL" : "",
|
||||||
|
ret2,
|
||||||
|
errno,
|
||||||
|
peeraddr_ip_str(self),
|
||||||
|
SSL_state_string_long(ssl),
|
||||||
|
error_append);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user