Skip to content

Commit

Permalink
Fix: OpenSSL 3.x reports unexpected EOF as SSL error (#14219)
Browse files Browse the repository at this point in the history
  • Loading branch information
ysbaddaden authored Mar 15, 2024
1 parent 2b0b506 commit eb743de
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 4 deletions.
23 changes: 19 additions & 4 deletions src/openssl.cr
Original file line number Diff line number Diff line change
Expand Up @@ -88,20 +88,35 @@ module OpenSSL
message = "Raised erroneously"
when .syscall?
@code, message = fetch_error_details
if @code == 0
{% if LibSSL.has_constant?(:SSL_R_UNEXPECTED_EOF_WHILE_READING) %}
if @code == 0
# FIXME: this isn't a per the OpenSSL documentation for how to
# detect EOF, but this fixes the EOF detection spec...
message = "Unexpected EOF while reading"
@underlying_eof = true
else
cause = RuntimeError.from_errno(func || "OpenSSL")
end
{% else %}
case return_code
when 0
message = "Unexpected EOF"
message = "Unexpected EOF while reading"
@underlying_eof = true
when -1
cause = RuntimeError.from_errno(func || "OpenSSL")
message = "I/O error"
else
message = "Unknown error"
end
end
{% end %}
when .ssl?
@code, message = fetch_error_details
code, message = fetch_error_details
@code = code
{% if LibSSL.has_constant?(:SSL_R_UNEXPECTED_EOF_WHILE_READING) %}
if get_reason(code) == LibSSL::SSL_R_UNEXPECTED_EOF_WHILE_READING
@underlying_eof = true
end
{% end %}
else
message = @error.to_s
end
Expand Down
12 changes: 12 additions & 0 deletions src/openssl/error.cr
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,17 @@ module OpenSSL
message = String.new(LibCrypto.err_error_string(code, nil)) unless code == 0
{code, message || "Unknown or no error"}
end

protected def get_reason(code)
{% if LibCrypto.has_constant?(:ERR_REASON_MASK) %}
if (code & LibCrypto::ERR_SYSTEM_FLAG) != 0
(code & LibCrypto::ERR_SYSTEM_MASK).to_i
else
(code & LibCrypto::ERR_REASON_MASK).to_i
end
{% else %}
(code & 0xFFF).to_i
{% end %}
end
end
end
6 changes: 6 additions & 0 deletions src/openssl/lib_crypto.cr
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,12 @@ lib LibCrypto
fun err_get_error = ERR_get_error : ULong
fun err_error_string = ERR_error_string(e : ULong, buf : Char*) : Char*

{% if compare_versions(OPENSSL_VERSION, "3.0.0") >= 0 %}
ERR_SYSTEM_FLAG = Int32::MAX.to_u32 + 1
ERR_SYSTEM_MASK = Int32::MAX.to_u32
ERR_REASON_MASK = 0x7FFFFF
{% end %}

struct MD5Context
a : UInt
b : UInt
Expand Down
5 changes: 5 additions & 0 deletions src/openssl/lib_ssl.cr
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@ lib LibSSL
fun ssl_ctx_set_security_level = SSL_CTX_set_security_level(ctx : SSLContext, level : Int) : Void
fun ssl_ctx_get_security_level = SSL_CTX_get_security_level(ctx : SSLContext) : Int
{% end %}

# SSL reason codes
{% if compare_versions(OPENSSL_VERSION, "3.0.0") >= 0 %}
SSL_R_UNEXPECTED_EOF_WHILE_READING = 294
{% end %}
end

{% unless compare_versions(LibSSL::OPENSSL_VERSION, "1.1.0") >= 0 %}
Expand Down

0 comments on commit eb743de

Please sign in to comment.