summary refs log tree commit diff stats
diff options
context:
space:
mode:
authormetagn <metagngn@gmail.com>2022-09-14 21:14:58 +0300
committerGitHub <noreply@github.com>2022-09-14 14:14:58 -0400
commit79afee868d784eb90972deb3ea89c96702585968 (patch)
tree65724d3c2ceb13ee5e4cf53a40028b7741da7c4b
parenta73ae3e066caecb7a891de87cf7c004805f96ff0 (diff)
downloadNim-79afee868d784eb90972deb3ea89c96702585968.tar.gz
partial revert and redesign of #19814, changelog (#20341)
* conservative partial revert of #19814

* fix

* revert tssl

* revert azure CI change

* keep azure, revert version range

* fully revert CI, add changelog

* useOpenssl3 as separate define, .3 is a version
-rw-r--r--.github/workflows/ci_packages.yml4
-rw-r--r--azure-pipelines.yml7
-rw-r--r--changelog.md4
-rw-r--r--lib/pure/net.nim6
-rw-r--r--lib/wrappers/openssl.nim31
-rw-r--r--tests/stdlib/tssl.nim44
6 files changed, 60 insertions, 36 deletions
diff --git a/.github/workflows/ci_packages.yml b/.github/workflows/ci_packages.yml
index 1be06e696..1bb4438d8 100644
--- a/.github/workflows/ci_packages.yml
+++ b/.github/workflows/ci_packages.yml
@@ -43,9 +43,7 @@ jobs:
       - name: 'Install dependencies (macOS)'
         if: runner.os == 'macOS'
         run: |
-          brew install boehmgc make sfml gtk+3 openssl@1.1
-          ln -s $(brew --prefix)/opt/openssl/lib/libcrypto.1.1.dylib /usr/local/lib
-          ln -s $(brew --prefix)/opt/openssl/lib/libssl.1.1.dylib /usr/local/lib/
+          brew install boehmgc make sfml gtk+3
       - name: 'Install dependencies (Windows)'
         if: runner.os == 'Windows'
         shell: bash
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 734adbc7e..bfc58d072 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -131,13 +131,6 @@ jobs:
       condition: and(succeeded(), eq(variables['skipci'], 'false'), eq(variables['Agent.OS'], 'Darwin'))
 
     - bash: |
-        brew install openssl@1.1
-        ln -s $(brew --prefix)/opt/openssl/lib/libcrypto.1.1.dylib /usr/local/lib
-        ln -s $(brew --prefix)/opt/openssl/lib/libssl.1.1.dylib /usr/local/lib/
-      displayName: 'Install OpenSSL (OSX)'
-      condition: and(succeeded(), eq(variables['skipci'], 'false'), eq(variables['Agent.OS'], 'Darwin'))
-
-    - bash: |
         set -e
         . ci/funs.sh
         nimInternalInstallDepsWindows
diff --git a/changelog.md b/changelog.md
index 7945120ff..8d574f2b0 100644
--- a/changelog.md
+++ b/changelog.md
@@ -36,9 +36,13 @@
 - [Overloadable enums](https://nim-lang.github.io/Nim/manual_experimental.html#overloadable-enum-value-names)
   are no longer experimental.
 
+- Static linking against OpenSSL versions below 1.1, previously done by
+  setting `-d:openssl10`, is no longer supported.
+
 ## Standard library additions and changes
 
 [//]: # "Changes:"
+- OpenSSL version 3 is now supported by setting either `-d:sslVersion=3` or `-d:useOpenssl3`.
 - `macros.parseExpr` and `macros.parseStmt` now accept an optional
   filename argument for more informative errors.
 - Module `colors` expanded with missing colors from the CSS color standard.
diff --git a/lib/pure/net.nim b/lib/pure/net.nim
index 73a085220..9ed73e723 100644
--- a/lib/pure/net.nim
+++ b/lib/pure/net.nim
@@ -544,6 +544,12 @@ proc fromSockAddr*(sa: Sockaddr_storage | SockAddr | Sockaddr_in | Sockaddr_in6,
 
 when defineSsl:
   # OpenSSL >= 1.1.0 does not need explicit init.
+  when not useOpenssl3:
+    CRYPTO_malloc_init()
+    doAssert SslLibraryInit() == 1
+    SSL_load_error_strings()
+    ERR_load_BIO_strings()
+    OpenSSL_add_all_algorithms()
 
   proc sslHandle*(self: Socket): SslPtr =
     ## Retrieve the ssl pointer of `socket`.
diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim
index d86001c5e..e049ac9d2 100644
--- a/lib/wrappers/openssl.nim
+++ b/lib/wrappers/openssl.nim
@@ -10,7 +10,7 @@
 ## OpenSSL wrapper. Supports OpenSSL >= 1.1.0 dynamically (as default) or statically linked
 ## using `--dynlibOverride:ssl`.
 ##
-## To use openSSL 3 set the symbol: -d:sslVersion=3
+## To use openSSL 3, either set `-d:sslVersion=3` or `-d:useOpenssl3`.
 ##
 ## Build and test examples:
 ##
@@ -37,6 +37,7 @@ const useWinVersion = defined(windows) or defined(nimdoc)
 # Having two different openSSL loaded version causes a crash.
 # Use this compile time define to force the openSSL version that your other dynamic libraries want.
 const sslVersion {.strdefine.}: string = ""
+const useOpenssl3* {.booldefine.} = sslVersion.startsWith('3')
 when sslVersion != "":
   when defined(macosx):
     const
@@ -75,7 +76,11 @@ elif useWinVersion:
 
   from winlean import SocketHandle
 else:
-  const versions = "(.1.1|.48|.47|.46|.45|.44|.43|.41|.39|.38|.10|)"
+  # same list of versions but ordered differently?
+  when defined(osx):
+    const versions = "(.3|.1.1|.38|.39|.41|.43|.44|.45|.46|.47|.48|.10|.1.0.2|.1.0.1|.1.0.0|.0.9.9|.0.9.8|)"
+  else:
+    const versions = "(.3|.1.1|.1.0.2|.1.0.1|.1.0.0|.0.9.9|.0.9.8|.48|.47|.46|.45|.44|.43|.41|.39|.38|.10|)"
 
   when defined(macosx):
     const
@@ -270,6 +275,11 @@ proc TLSv1_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.}
 
 when compileOption("dynlibOverride", "ssl"):
   # Static linking
+  when not useOpenssl3:
+    proc OPENSSL_init_ssl*(opts: uint64, settings: uint8): cint {.cdecl, dynlib: DLLSSLName, importc, discardable.}
+    proc SSL_library_init*(): cint {.discardable.} =
+      ## Initialize SSL using OPENSSL_init_ssl for OpenSSL >= 1.1.0
+      return OPENSSL_init_ssl(0.uint64, 0.uint8)
 
   proc TLS_method*(): PSSL_METHOD {.cdecl, dynlib: DLLSSLName, importc.}
 
@@ -354,6 +364,18 @@ else:
     let method2Proc = cast[proc(): PSSL_METHOD {.cdecl, gcsafe, raises: [].}](methodSym)
     return method2Proc()
 
+  when not useOpenssl3:
+    proc SSL_library_init*(): cint {.discardable.} =
+      ## Initialize SSL using OPENSSL_init_ssl for OpenSSL >= 1.1.0 otherwise
+      ## SSL_library_init
+      let newInitSym = sslSymNullable("OPENSSL_init_ssl")
+      if not newInitSym.isNil:
+        let newInitProc =
+          cast[proc(opts: uint64, settings: uint8): cint {.cdecl.}](newInitSym)
+        return newInitProc(0, 0)
+      let olderProc = cast[proc(): cint {.cdecl.}](sslSymThrows("SSL_library_init"))
+      if not olderProc.isNil: result = olderProc()
+
   proc SSL_load_error_strings*() =
     # TODO: Are we ignoring this on purpose? SSL GitHub CI fails otherwise.
     let theProc = cast[proc() {.cdecl.}](sslSymNullable("SSL_load_error_strings"))
@@ -398,8 +420,7 @@ else:
       theProc = cast[typeof(theProc)](sslSymThrows("SSL_CTX_set_ciphersuites"))
     theProc(ctx, str)
 
-
-proc OPENSSL_init_ssl*(opts: uint64, settings: uint8): cint {.cdecl, dynlib: DLLSSLName, importc.}
+proc ERR_load_BIO_strings*(){.cdecl, dynlib: DLLUtilName, importc.}
 
 proc TLS_client_method*(): PSSL_METHOD {.cdecl, dynlib: DLLSSLName, importc.}
 
@@ -768,7 +789,7 @@ when not defined(nimDisableCertificateValidation) and not defined(windows):
   # proc SSL_get_peer_certificate*(ssl: SslCtx): PX509 =
   #  loadPSSLMethod("SSL_get_peer_certificate", "SSL_get1_peer_certificate")
 
-  when sslVersion.startsWith('3'):
+  when useOpenssl3:
     proc SSL_get1_peer_certificate*(ssl: SslCtx): PX509 {.cdecl, dynlib: DLLSSLName, importc.}
     proc SSL_get_peer_certificate*(ssl: SslCtx): PX509 =
       SSL_get1_peer_certificate(ssl)
diff --git a/tests/stdlib/tssl.nim b/tests/stdlib/tssl.nim
index fd85cb55b..379c1b1e5 100644
--- a/tests/stdlib/tssl.nim
+++ b/tests/stdlib/tssl.nim
@@ -16,22 +16,9 @@ when not defined(ssl):
 
 const DummyData = "dummy data\n"
 
-proc createSocket(): Socket =
-  result = newSocket(buffered = false)
-  result.setSockOpt(OptReuseAddr, true)
-  result.setSockOpt(OptReusePort, true)
-
-proc createServer(serverContext: SslContext): (Socket, Port) =
-  var server = createSocket()
-  serverContext.wrapSocket(server)
-  server.bindAddr(address = "localhost")
-  let (_, port) = server.getLocalAddr()
-  server.listen()
-  return (server, port)
-
 proc abruptShutdown(port: Port) {.thread.} =
   let clientContext = newContext(verifyMode = CVerifyNone)
-  var client = createSocket()
+  var client = newSocket(buffered = false)
   clientContext.wrapSocket(client)
   client.connect("localhost", port)
 
@@ -40,7 +27,7 @@ proc abruptShutdown(port: Port) {.thread.} =
 
 proc notifiedShutdown(port: Port) {.thread.} =
   let clientContext = newContext(verifyMode = CVerifyNone)
-  var client = createSocket()
+  var client = newSocket(buffered = false)
   clientContext.wrapSocket(client)
   client.connect("localhost", port)
 
@@ -62,7 +49,13 @@ proc main() =
                                  keyFile = "tests/testdata/mycert.pem")
 
   block peer_close_during_write_without_shutdown:
-    var (server, port) = createServer(serverContext)
+    var server = newSocket(buffered = false)
+    defer: server.close()
+    serverContext.wrapSocket(server)
+    server.bindAddr(address = "localhost")
+    let (_, port) = server.getLocalAddr()
+    server.listen()
+
     var clientThread: Thread[Port]
     createThread(clientThread, abruptShutdown, port)
 
@@ -80,14 +73,19 @@ proc main() =
       discard
     finally:
       peer.close()
-      server.close()
 
   when defined(posix):
     if sigaction(SIGPIPE, oldSigPipeHandler, nil) == -1:
       raiseOSError(osLastError(), "Couldn't restore SIGPIPE handler")
 
   block peer_close_before_received_shutdown:
-    var (server, port) = createServer(serverContext)
+    var server = newSocket(buffered = false)
+    defer: server.close()
+    serverContext.wrapSocket(server)
+    server.bindAddr(address = "localhost")
+    let (_, port) = server.getLocalAddr()
+    server.listen()
+
     var clientThread: Thread[Port]
     createThread(clientThread, abruptShutdown, port)
 
@@ -106,10 +104,15 @@ proc main() =
         discard peer.getFd.shutdown(SD_SEND)
     finally:
       peer.close()
-      server.close()
 
   block peer_close_after_received_shutdown:
-    var (server, port) = createServer(serverContext)
+    var server = newSocket(buffered = false)
+    defer: server.close()
+    serverContext.wrapSocket(server)
+    server.bindAddr(address = "localhost")
+    let (_, port) = server.getLocalAddr()
+    server.listen()
+
     var clientThread: Thread[Port]
     createThread(clientThread, notifiedShutdown, port)
 
@@ -129,6 +132,5 @@ proc main() =
         discard peer.getFd.shutdown(SD_SEND)
     finally:
       peer.close()
-      server.close()
 
 when isMainModule: main()