Skip to content

Commit

Permalink
on_bio_stream_read returns -1 if read fails, calls eof before calling…
Browse files Browse the repository at this point in the history
… bytesavailable

on_bio_stream_write return -1 if write fails (bss_sock.c)

This enables server side mode, however the logic in the bio still does not match what OpenSSL is doing.
  • Loading branch information
grlap committed May 14, 2023
1 parent 57f035d commit bfd3373
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 36 deletions.
6 changes: 4 additions & 2 deletions src/ssl.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ function bio_set_flags(bio::BIO, flags)
(BIO, Cint),
bio, flags)
end

bio_set_read_retry(bio::BIO) = bio_set_flags(bio, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY)
bio_clear_flags(bio::BIO) = bio_set_flags(bio, 0x00)

function on_bio_stream_read(bio::BIO, out::Ptr{Cchar}, outlen::Cint)
try
bio_clear_flags(bio)
io = bio_get_data(bio)::IO
eof(io)
n = bytesavailable(io)
if n == 0
bio_set_read_retry(bio)
Expand All @@ -45,7 +47,7 @@ function on_bio_stream_read(bio::BIO, out::Ptr{Cchar}, outlen::Cint)
return Cint(min(n, outlen))
catch e
# we don't want to throw a Julia exception from a C callback
return Cint(0)
return Cint(-1)
end
end

Expand All @@ -56,7 +58,7 @@ function on_bio_stream_write(bio::BIO, in::Ptr{Cchar}, inlen::Cint)::Cint
return Cint(written)
catch e
# we don't want to throw a Julia exception from a C callback
return Cint(0)
return Cint(-1)
end
end

Expand Down
58 changes: 24 additions & 34 deletions test/http_helpers.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Dates
using OpenSSL
using Sockets
using Test

function test_server()
x509_certificate = X509Certificate()
Expand All @@ -22,54 +23,47 @@ function test_server()
sign_certificate(x509_certificate, evp_pkey)

server_socket = listen(5000)
try
accepted_socket = accept(server_socket)
accepted_socket = accept(server_socket)

# Create and configure server SSLContext.
ssl_ctx = OpenSSL.SSLContext(OpenSSL.TLSServerMethod())
_ = OpenSSL.ssl_set_options(ssl_ctx, OpenSSL.SSL_OP_NO_COMPRESSION)
# Create and configure server SSLContext.
ssl_ctx = OpenSSL.SSLContext(OpenSSL.TLSServerMethod())
_ = OpenSSL.ssl_set_options(ssl_ctx, OpenSSL.SSL_OP_NO_COMPRESSION)

OpenSSL.ssl_set_ciphersuites(ssl_ctx, "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256")
OpenSSL.ssl_use_certificate(ssl_ctx, x509_certificate)
OpenSSL.ssl_use_private_key(ssl_ctx, evp_pkey)
OpenSSL.ssl_set_ciphersuites(ssl_ctx, "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256")
OpenSSL.ssl_use_certificate(ssl_ctx, x509_certificate)
OpenSSL.ssl_use_private_key(ssl_ctx, evp_pkey)

ssl = SSLStream(ssl_ctx, accepted_socket)
ssl = SSLStream(ssl_ctx, accepted_socket)

OpenSSL.accept(ssl)
OpenSSL.accept(ssl)

@test !eof(ssl)
request = readavailable(ssl)
reply = "reply: $(String(request))"
@test !eof(ssl)
request = readavailable(ssl)
reply = "reply: $(String(request))"

# eof(ssl) will block

# eof(ssl) will block
# Verify the are no more bytes available in the stream.
@test bytesavailable(ssl) == 0

# Verify the are no more bytes available in the stream.
@test bytesavailable(ssl) == 0
unsafe_write(ssl, pointer(reply), length(reply))

write(ssl, reply)
close(ssl)
finalize(ssl_ctx)

try
close(ssl)
catch
end
finalize(ssl_ctx)
finally
close(server_socket)
end
return nothing
end

function test_client()
tcp_stream = connect(5000)

ssl_ctx = OpenSSL.SSLContext(OpenSSL.TLSClientMethod())
ssl_options = OpenSSL.ssl_set_options(ssl_ctx, OpenSSL.SSL_OP_NO_COMPRESSION)
_ = OpenSSL.ssl_set_options(ssl_ctx, OpenSSL.SSL_OP_NO_COMPRESSION)

# Create SSL stream.
ssl = SSLStream(ssl_ctx, tcp_stream)

#TODO expose connect
OpenSSL.connect(ssl)
connect(ssl; require_ssl_verification = false)

# Verify the server certificate.
x509_server_cert = OpenSSL.get_peer_certificate(ssl)
Expand All @@ -87,12 +81,8 @@ function test_client()

response_str = String(readavailable(ssl))

@test response_str == "reply: $request_str"
@test response_str == "reply: $(request_str)"

try
close(ssl)
catch
end
close(ssl)
finalize(ssl_ctx)
return nothing
end

0 comments on commit bfd3373

Please sign in to comment.