Skip to content

Commit bff0606

Browse files
authored
Merge pull request #640 from rhenium/ky/ssl-connect-verify-error-ssl-error-syscall
ssl: adjust "certificate verify failed" error on SSL_ERROR_SYSCALL
2 parents 6588fad + c309745 commit bff0606

File tree

2 files changed

+43
-41
lines changed

2 files changed

+43
-41
lines changed

ext/openssl/ossl_ssl.c

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1756,71 +1756,71 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
17561756
int ret, ret2;
17571757
VALUE cb_state;
17581758
int nonblock = opts != Qfalse;
1759-
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1760-
unsigned long err;
1761-
#endif
17621759

17631760
rb_ivar_set(self, ID_callback_state, Qnil);
17641761

17651762
GetSSL(self, ssl);
17661763

17671764
VALUE io = rb_attr_get(self, id_i_io);
1768-
for(;;){
1769-
ret = func(ssl);
1765+
for (;;) {
1766+
ret = func(ssl);
17701767

1771-
cb_state = rb_attr_get(self, ID_callback_state);
1768+
cb_state = rb_attr_get(self, ID_callback_state);
17721769
if (!NIL_P(cb_state)) {
1773-
/* must cleanup OpenSSL error stack before re-raising */
1774-
ossl_clear_error();
1775-
rb_jump_tag(NUM2INT(cb_state));
1776-
}
1770+
/* must cleanup OpenSSL error stack before re-raising */
1771+
ossl_clear_error();
1772+
rb_jump_tag(NUM2INT(cb_state));
1773+
}
17771774

1778-
if (ret > 0)
1779-
break;
1775+
if (ret > 0)
1776+
break;
17801777

1781-
switch((ret2 = ssl_get_error(ssl, ret))){
1782-
case SSL_ERROR_WANT_WRITE:
1778+
switch ((ret2 = ssl_get_error(ssl, ret))) {
1779+
case SSL_ERROR_WANT_WRITE:
17831780
if (no_exception_p(opts)) { return sym_wait_writable; }
17841781
write_would_block(nonblock);
17851782
io_wait_writable(io);
17861783
continue;
1787-
case SSL_ERROR_WANT_READ:
1784+
case SSL_ERROR_WANT_READ:
17881785
if (no_exception_p(opts)) { return sym_wait_readable; }
17891786
read_would_block(nonblock);
17901787
io_wait_readable(io);
17911788
continue;
1792-
case SSL_ERROR_SYSCALL:
1789+
case SSL_ERROR_SYSCALL:
17931790
#ifdef __APPLE__
17941791
/* See ossl_ssl_write_internal() */
17951792
if (errno == EPROTOTYPE)
17961793
continue;
17971794
#endif
1798-
if (errno) rb_sys_fail(funcname);
1799-
ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s",
1800-
funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl));
1801-
1795+
if (errno) rb_sys_fail(funcname);
1796+
/* fallthrough */
1797+
default: {
1798+
VALUE error_append = Qnil;
18021799
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
1803-
case SSL_ERROR_SSL:
1804-
err = ERR_peek_last_error();
1805-
if (ERR_GET_LIB(err) == ERR_LIB_SSL &&
1806-
ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
1807-
const char *err_msg = ERR_reason_error_string(err),
1808-
*verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
1809-
if (!err_msg)
1810-
err_msg = "(null)";
1811-
if (!verify_msg)
1812-
verify_msg = "(null)";
1813-
ossl_clear_error(); /* let ossl_raise() not append message */
1814-
ossl_raise(eSSLError, "%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s: %s (%s)",
1815-
funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl),
1816-
err_msg, verify_msg);
1817-
}
1800+
unsigned long err = ERR_peek_last_error();
1801+
if (ERR_GET_LIB(err) == ERR_LIB_SSL &&
1802+
ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) {
1803+
const char *err_msg = ERR_reason_error_string(err),
1804+
*verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl));
1805+
if (!err_msg)
1806+
err_msg = "(null)";
1807+
if (!verify_msg)
1808+
verify_msg = "(null)";
1809+
ossl_clear_error(); /* let ossl_raise() not append message */
1810+
error_append = rb_sprintf(": %s (%s)", err_msg, verify_msg);
1811+
}
18181812
#endif
1819-
/* fallthrough */
1820-
default:
1821-
ossl_raise(eSSLError, "%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s",
1822-
funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl));
1823-
}
1813+
ossl_raise(eSSLError,
1814+
"%s%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s%"PRIsVALUE,
1815+
funcname,
1816+
ret2 == SSL_ERROR_SYSCALL ? " SYSCALL" : "",
1817+
ret2,
1818+
errno,
1819+
peeraddr_ip_str(self),
1820+
SSL_state_string_long(ssl),
1821+
error_append);
1822+
}
1823+
}
18241824
}
18251825

18261826
return self;

test/openssl/test_ssl.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,9 @@ def test_connect_certificate_verify_failed_exception_message
10801080
start_server(ignore_listener_error: true) { |port|
10811081
ctx = OpenSSL::SSL::SSLContext.new
10821082
ctx.set_params
1083-
assert_raise_with_message(OpenSSL::SSL::SSLError, /certificate/) {
1083+
# OpenSSL <= 1.1.0: "self signed certificate in certificate chain"
1084+
# OpenSSL >= 3.0.0: "self-signed certificate in certificate chain"
1085+
assert_raise_with_message(OpenSSL::SSL::SSLError, /self.signed/) {
10841086
server_connect(port, ctx)
10851087
}
10861088
}

0 commit comments

Comments
 (0)