diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..d7a3ed5 --- /dev/null +++ b/.github/dependabot.yml @@ -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: + - "*" diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 1e6c841..2f69ee3 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -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: @@ -26,7 +26,7 @@ jobs: fail-fast: false matrix: version: - - '1.6' + - 'lts' - '1' - 'nightly' os: @@ -34,27 +34,18 @@ jobs: - 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 diff --git a/src/OpenSSL.jl b/src/OpenSSL.jl index abdfa0f..f5ee5c7 100644 --- a/src/OpenSSL.jl +++ b/src/OpenSSL.jl @@ -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), @@ -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) @@ -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) diff --git a/src/ssl.jl b/src/ssl.jl index f7a02f6..cd5f0a4 100644 --- a/src/ssl.jl +++ b/src/ssl.jl @@ -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 """ diff --git a/test/http_helpers.jl b/test/http_helpers.jl index e43d234..f499d3c 100644 --- a/test/http_helpers.jl +++ b/test/http_helpers.jl @@ -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()) @@ -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) @@ -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()) diff --git a/test/runtests.jl b/test/runtests.jl index 707a89f..93ca949 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -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" @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" @@ -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()) @@ -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)