Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
groups:
all-actions:
patterns:
- "*"
19 changes: 5 additions & 14 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

name: CI

# Controls when the action will run.
# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
Expand All @@ -26,35 +26,26 @@ jobs:
fail-fast: false
matrix:
version:
- '1.6'
- 'lts'
- '1'
- 'nightly'
os:
- ubuntu-latest
- macOS-latest
- windows-latest
arch:
- x64
- 'default'
include:
- os: windows-latest
version: '1'
arch: x86
steps:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@v1
- uses: julia-actions/setup-julia@v2
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- uses: actions/cache@v1
env:
cache-name: cache-artifacts
with:
path: ~/.julia/artifacts
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
restore-keys: |
${{ runner.os }}-test-${{ env.cache-name }}-
${{ runner.os }}-test-
${{ runner.os }}-
- uses: julia-actions/cache@v2
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
- name: Test with OpenSSL v1.1
Expand Down
20 changes: 20 additions & 0 deletions src/OpenSSL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2668,6 +2668,22 @@ function set_public_key(x509_req::X509Request, evp_pkey::EvpPKey)
end
end

function set_version(x509_req::X509Request, version::Int)
if ccall(
(:X509_REQ_set_version, libcrypto),
Cint,
(X509Request, Cint),
x509_req,
version) != 1
throw(OpenSSLError())
end
end

function get_version(x509_req::X509Request)::Int
version = ccall((:X509_REQ_get_version, libcrypto), Clong, (X509Request,), x509_req)
return Int(version)
end

function get_extensions(x509_req::X509Request)
sk = ccall(
(:X509_REQ_get_extensions, libcrypto),
Expand All @@ -2688,6 +2704,8 @@ function Base.getproperty(x509_req::X509Request, name::Symbol)
return get_public_key(x509_req)
elseif name === :extensions
return get_extensions(x509_req)
elseif name === :version
return get_version(x509_req)
else
# fallback to getfield
return getfield(x509_req, name)
Expand All @@ -2699,6 +2717,8 @@ function Base.setproperty!(x509_req::X509Request, name::Symbol, value)
set_subject_name(x509_req, value)
elseif name === :public_key
set_public_key(x509_req, value)
elseif name === :version
set_version(x509_req, value)
else
# fallback to setfield
setfield!(x509_req, name, value)
Expand Down
24 changes: 11 additions & 13 deletions src/ssl.jl
Original file line number Diff line number Diff line change
Expand Up @@ -679,25 +679,23 @@ end
Close SSL stream.
"""
function Base.close(ssl::SSLStream, shutdown::Bool=true)
close_socket = false
Base.@lock ssl.lock begin
ssl.closed && return
ssl.closed = true
close_socket = true
# Ignore the disconnect result.
shutdown && ssl_disconnect(ssl.ssl)
if shutdown
try
ssl_disconnect(ssl.ssl)
catch err
@debug "SSL disconnect failed" err
end
end
free(ssl.ssl)
end
if close_socket
# close underlying io; because closing a TCPSocket may block
# we do it outside holding the ssl.lock
try
Base.close(ssl.io)
catch e
e isa Base.IOError || rethrow()
end
@async try
Base.close(ssl.io)
catch e
e isa Base.IOError || rethrow()
end
return
end

"""
Expand Down
6 changes: 4 additions & 2 deletions test/http_helpers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ using Dates
using OpenSSL
using Sockets

function test_server()
function test_server(handshake_ready::Threads.Condition)
x509_certificate = X509Certificate()

evp_pkey = EvpPKey(rsa_generate_key())
Expand All @@ -22,6 +22,7 @@ function test_server()
sign_certificate(x509_certificate, evp_pkey)

server_socket = listen(5000)
@lock handshake_ready notify(handshake_ready)
try
accepted_socket = accept(server_socket)

Expand Down Expand Up @@ -59,7 +60,8 @@ function test_server()
return nothing
end

function test_client()
function test_client(handshake_ready::Threads.Condition)
@lock handshake_ready wait(handshake_ready)
tcp_stream = connect(5000)

ssl_ctx = OpenSSL.SSLContext(OpenSSL.TLSClientMethod())
Expand Down
9 changes: 6 additions & 3 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ end

x509_server_cert = OpenSSL.get_peer_certificate(ssl)

@test String(x509_server_cert.issuer_name) == "/C=US/O=Let's Encrypt/CN=R3"
@test String(x509_server_cert.issuer_name) == "/C=US/O=Let's Encrypt/CN=R11"
Copy link
Member Author

@IanButterworth IanButterworth May 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@quinnj @staticfloat Does this fix look correct/reasonable?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@test String(x509_server_cert.subject_name) == "/CN=httpbingo.julialang.org"

request_str = "GET /status/200 HTTP/1.1\r\nHost: httpbingo.julialang.org\r\nUser-Agent: curl\r\nAccept: */*\r\n\r\n"
Expand Down Expand Up @@ -339,6 +339,8 @@ end

# Create a certificate sign request.
x509_request = X509Request()
x509_request.version = 0
@test x509_request.version == 0

evp_pkey = EvpPKey(rsa_generate_key())

Expand Down Expand Up @@ -570,8 +572,9 @@ end
end

@testset "SSLServer" begin
server_task = @async test_server()
client_task = @async test_client()
server_ready = Threads.Condition()
server_task = @async test_server(server_ready)
client_task = @async test_client(server_ready)
if isdefined(Base, :errormonitor)
errormonitor(server_task)
errormonitor(client_task)
Expand Down
Loading