diff --git a/lib/pure/net.nim b/lib/pure/net.nim index c33c7bf4631..218e9ea6e2f 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -518,10 +518,6 @@ proc fromSockAddr*(sa: Sockaddr_storage | SockAddr | Sockaddr_in | Sockaddr_in6, when defineSsl: 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`. @@ -625,29 +621,18 @@ when defineSsl: var newCTX: SslCtx case protVersion of protSSLv23: - newCTX = SSL_CTX_new(SSLv23_method()) # SSlv2,3 and TLS1 support. + newCTX = SSL_CTX_new(TLS_method()) # SSLv3, TLS 1.0 and above of protSSLv2: raiseSSLError("SSLv2 is no longer secure and has been deprecated, use protSSLv23") of protSSLv3: raiseSSLError("SSLv3 is no longer secure and has been deprecated, use protSSLv23") of protTLSv1: - newCTX = SSL_CTX_new(TLSv1_method()) + raiseSSLError("TLSv1 is no longer secure and has been deprecated, use protSSLv23") if newCTX.SSL_CTX_set_cipher_list(cipherList) != 1: raiseSSLError() - when not defined(openssl10) and not defined(libressl): - let sslVersion = getOpenSSLVersion() - if sslVersion >= 0x010101000 and not sslVersion == 0x020000000: - # In OpenSSL >= 1.1.1, TLSv1.3 cipher suites can only be configured via - # this API. - if newCTX.SSL_CTX_set_ciphersuites(cipherList) != 1: - raiseSSLError() - # Automatically the best ECDH curve for client exchange. Without this, ECDH - # ciphers will be ignored by the server. - # - # From OpenSSL >= 1.1.0, this setting is set by default and can't be - # overriden. - if newCTX.SSL_CTX_set_ecdh_auto(1) != 1: + # TLSv1.3 cipher suites can only be configured via this API. + if newCTX.SSL_CTX_set_ciphersuites(cipherList) != 1: raiseSSLError() when defined(nimDisableCertificateValidation): diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index 38c5ac6f59e..a2d08f63282 100644 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -10,11 +10,9 @@ ## OpenSSL support ## ## When OpenSSL is dynamically linked, the wrapper provides partial forward and backward -## compatibility for OpenSSL versions above and below 1.1.0 +## compatibility for OpenSSL versions 1.1.1 and above. ## -## OpenSSL can also be statically linked using `--dynlibOverride:ssl` for OpenSSL >= 1.1.0. -## If you want to statically link against OpenSSL 1.0.x, you now have to -## define the `openssl10` symbol via `-d:openssl10`. +## OpenSSL can also be statically linked using `--dynlibOverride:ssl` for OpenSSL >= 1.1.1. ## ## Build and test examples: ## @@ -52,30 +50,18 @@ when sslVersion != "": from std/posix import SocketHandle elif useWinVersion: - when defined(openssl10) or defined(nimOldDlls): - when defined(cpu64): - const - DLLSSLName* = "(ssleay32|ssleay64).dll" - DLLUtilName* = "(libeay32|libeay64).dll" - else: - const - DLLSSLName* = "ssleay32.dll" - DLLUtilName* = "libeay32.dll" - elif defined(cpu64): + when defined(cpu64): const - DLLSSLName* = "(libssl-3-x64|libssl-1_1-x64|ssleay64|libssl64).dll" - DLLUtilName* = "(libcrypto-3-x64|libcrypto-1_1-x64|libeay64).dll" + DLLSSLName* = "(libssl-3-x64|libssl-1_1-x64).dll" + DLLUtilName* = "(libcrypto-3-x64|libcrypto-1_1-x64).dll" else: const - DLLSSLName* = "(libssl-3|libssl-1_1|ssleay32|libssl32).dll" - DLLUtilName* = "(libssl-3|libcrypto-1_1|libeay32).dll" + DLLSSLName* = "(libssl-3|libssl-1_1).dll" + DLLUtilName* = "(libssl-3|libcrypto-1_1).dll" from std/winlean import SocketHandle else: - 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|)" + const versions = "(.3|.1.1)" when defined(macosx): const @@ -87,8 +73,6 @@ else: DLLUtilName* = "libcrypto.so" & versions from std/posix import SocketHandle -import std/dynlib - type SslStruct {.final, pure.} = object SslPtr* = ptr SslStruct @@ -256,186 +240,15 @@ const BIO_C_DO_STATE_MACHINE = 101 BIO_C_GET_SSL = 110 -proc TLSv1_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.} - # TLS_method(), TLS_server_method(), TLS_client_method() are introduced in 1.1.0 # and support SSLv3, TLSv1, TLSv1.1 and TLSv1.2 # SSLv23_method(), SSLv23_server_method(), SSLv23_client_method() are removed in 1.1.0 -when compileOption("dynlibOverride", "ssl") or defined(noOpenSSLHacks): - # Static linking - - when defined(openssl10): - proc SSL_library_init*(): cint {.cdecl, dynlib: DLLSSLName, importc, discardable.} - proc SSL_load_error_strings*() {.cdecl, dynlib: DLLSSLName, importc.} - proc SSLv23_method*(): PSSL_METHOD {.cdecl, dynlib: DLLSSLName, importc.} - proc SSLeay(): culong {.cdecl, dynlib: DLLUtilName, importc.} - - proc getOpenSSLVersion*(): culong = - SSLeay() - else: - 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.} - proc SSLv23_method*(): PSSL_METHOD = - TLS_method() - - proc OpenSSL_version_num(): culong {.cdecl, dynlib: DLLUtilName, importc.} - - proc getOpenSSLVersion*(): culong = - ## Return OpenSSL version as unsigned long - OpenSSL_version_num() - - proc SSL_load_error_strings*() = - ## Removed from OpenSSL 1.1.0 - # This proc prevents breaking existing code calling SslLoadErrorStrings - # Static linking against OpenSSL < 1.1.0 is not supported - discard - - when defined(libressl) or defined(openssl10): - proc SSL_state(ssl: SslPtr): cint {.cdecl, dynlib: DLLSSLName, importc.} - proc SSL_in_init*(ssl: SslPtr): cint {.inline.} = - SSl_state(ssl) and SSL_ST_INIT - else: - proc SSL_in_init*(ssl: SslPtr): cint {.cdecl, dynlib: DLLSSLName, importc.} - proc SSL_CTX_set_ciphersuites*(ctx: SslCtx, str: cstring): cint {.cdecl, dynlib: DLLSSLName, importc.} - - template OpenSSL_add_all_algorithms*() = discard +proc TLS_method*(): PSSL_METHOD {.cdecl, dynlib: DLLSSLName, importc.} +proc OpenSSL_version_num*(): culong {.cdecl, dynlib: DLLUtilName, importc.} - proc SSLv23_client_method*(): PSSL_METHOD {.cdecl, dynlib: DLLSSLName, importc.} - proc SSLv2_method*(): PSSL_METHOD {.cdecl, dynlib: DLLSSLName, importc.} - proc SSLv3_method*(): PSSL_METHOD {.cdecl, dynlib: DLLSSLName, importc.} - -else: - # Here we're trying to stay compatible with openssl 1.0.* and 1.1.*. Some - # symbols are loaded dynamically and we don't use them if not found. - proc thisModule(): LibHandle {.inline.} = - var thisMod {.global.}: LibHandle - if thisMod.isNil: thisMod = loadLib() - - result = thisMod - - proc sslModule(): LibHandle {.inline.} = - var sslMod {.global.}: LibHandle - if sslMod.isNil: sslMod = loadLibPattern(DLLSSLName) - - result = sslMod - - proc utilModule(): LibHandle {.inline.} = - var utilMod {.global.}: LibHandle - if utilMod.isNil: utilMod = loadLibPattern(DLLUtilName) - - result = utilMod - - proc symNullable(dll: LibHandle, name: string, alternativeName = ""): pointer = - # Load from DLL. - if not dll.isNil: - result = symAddr(dll, name) - if result.isNil and alternativeName.len > 0: - result = symAddr(dll, alternativeName) - - # Attempt to load from current exe. - if result.isNil: - let thisDynlib = thisModule() - if thisDynlib.isNil: return nil - result = symAddr(thisDynlib, name) - if result.isNil and alternativeName.len > 0: - result = symAddr(thisDynlib, alternativeName) - - proc sslSymNullable(name: string, alternativeName = ""): pointer = - sslModule().symNullable(name, alternativeName) - - proc sslSymThrows(name: string, alternativeName = ""): pointer = - result = sslSymNullable(name, alternativeName) - if result.isNil: raiseInvalidLibrary(name) - - proc utilSymNullable(name: string, alternativeName = ""): pointer = - utilModule().symNullable(name, alternativeName) - - proc loadPSSLMethod(method1, method2: string): PSSL_METHOD = - ## Load from OpenSSL if available, otherwise - ## - let methodSym = sslSymNullable(method1, method2) - if methodSym.isNil: - raise newException(LibraryError, "Could not load " & method1 & " nor " & method2) - - let method2Proc = cast[proc(): PSSL_METHOD {.cdecl, gcsafe.}](methodSym) - return method2Proc() - - 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")) - if not theProc.isNil: theProc() - - proc SSLv23_client_method*(): PSSL_METHOD = - loadPSSLMethod("SSLv23_client_method", "TLS_client_method") - - proc SSLv23_method*(): PSSL_METHOD = - loadPSSLMethod("SSLv23_method", "TLS_method") - - proc SSLv2_method*(): PSSL_METHOD = - loadPSSLMethod("SSLv2_method", "TLS_method") - - proc SSLv3_method*(): PSSL_METHOD = - loadPSSLMethod("SSLv3_method", "TLS_method") - - proc TLS_method*(): PSSL_METHOD = - loadPSSLMethod("TLS_method", "SSLv23_method") - - proc TLS_client_method*(): PSSL_METHOD = - loadPSSLMethod("TLS_client_method", "SSLv23_client_method") - - proc TLS_server_method*(): PSSL_METHOD = - loadPSSLMethod("TLS_server_method", "SSLv23_server_method") - - proc OpenSSL_add_all_algorithms*() = - # TODO: Are we ignoring this on purpose? SSL GitHub CI fails otherwise. - let theProc = cast[proc() {.cdecl.}](sslSymNullable("OPENSSL_add_all_algorithms_conf")) - if not theProc.isNil: theProc() - - proc getOpenSSLVersion*(): culong = - ## Return OpenSSL version as unsigned long or 0 if not available - let theProc = cast[proc(): culong {.cdecl, gcsafe.}](utilSymNullable("OpenSSL_version_num", "SSLeay")) - result = - if theProc.isNil: 0.culong - else: theProc() - - proc SSL_in_init*(ssl: SslPtr): cint = - # A compatibility wrapper for `SSL_in_init()` for OpenSSL 1.0, 1.1 and LibreSSL - const MainProc = "SSL_in_init" - let - theProc {.global.} = cast[proc(ssl: SslPtr): cint {.cdecl, gcsafe.}](sslSymNullable(MainProc)) - # Fallback - sslState {.global.} = cast[proc(ssl: SslPtr): cint {.cdecl, gcsafe.}](sslSymNullable("SSL_state")) - - if not theProc.isNil: - result = theProc(ssl) - elif not sslState.isNil: - result = sslState(ssl) and SSL_ST_INIT - else: - raiseInvalidLibrary MainProc - - proc SSL_CTX_set_ciphersuites*(ctx: SslCtx, str: cstring): cint = - var theProc {.global.}: proc(ctx: SslCtx, str: cstring) {.cdecl, gcsafe.} - if theProc.isNil: - theProc = cast[typeof(theProc)](sslSymThrows("SSL_CTX_set_ciphersuites")) - theProc(ctx, str) - -proc ERR_load_BIO_strings*(){.cdecl, dynlib: DLLUtilName, importc.} +proc SSL_in_init*(ssl: SslPtr): cint {.cdecl, dynlib: DLLSSLName, importc.} +proc SSL_CTX_set_ciphersuites*(ctx: SslCtx, str: cstring): cint {.cdecl, dynlib: DLLSSLName, importc.} proc SSL_new*(context: SslCtx): SslPtr{.cdecl, dynlib: DLLSSLName, importc.} proc SSL_free*(ssl: SslPtr){.cdecl, dynlib: DLLSSLName, importc.}