Skip to content

Commit

Permalink
[ruby/openssl] ssl: adjust "certificate verify failed" error on SSL_E…
Browse files Browse the repository at this point in the history
…RROR_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.

ruby/openssl@5113777e82
  • Loading branch information
rhenium committed Aug 16, 2023
1 parent 66a7058 commit cb344e4
Showing 1 changed file with 25 additions and 25 deletions.
50 changes: 25 additions & 25 deletions ext/openssl/ossl_ssl.c
Expand Up @@ -1756,9 +1756,6 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
int ret, ret2;
VALUE cb_state;
int nonblock = opts != Qfalse;
#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED)
unsigned long err;
#endif

rb_ivar_set(self, ID_callback_state, Qnil);

Expand Down Expand Up @@ -1796,30 +1793,33 @@ ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts)
continue;
#endif
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));

/* fallthrough */
default: {
VALUE error_append = Qnil;
#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);
}
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
/* fallthrough */
default:
ossl_raise(eSSLError, "%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s",
funcname, ret2, errno, peeraddr_ip_str(self), SSL_state_string_long(ssl));
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);
}
}
}

Expand Down

0 comments on commit cb344e4

Please sign in to comment.