diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pure/net.nim | 17 | ||||
-rw-r--r-- | lib/wrappers/openssl.nim | 128 |
2 files changed, 100 insertions, 45 deletions
diff --git a/lib/pure/net.nim b/lib/pure/net.nim index 8dd9e2c8b..3b3cdf27f 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -624,7 +624,8 @@ when defineSsl: caDir = "", caFile = ""): SslContext = ## Creates an SSL context. ## - ## protVersion is currently unsed. + ## Protocol version is currently ignored by default and TLS is used. + ## With `-d:openssl10`, only SSLv23 and TLSv1 may be used. ## ## There are three options for verify mode: ## `CVerifyNone`: certificates are not verified; @@ -651,7 +652,19 @@ when defineSsl: ## or using ECDSA: ## - `openssl ecparam -out mykey.pem -name secp256k1 -genkey` ## - `openssl req -new -key mykey.pem -x509 -nodes -days 365 -out mycert.pem` - let mtd = TLS_method() + var mtd: PSSL_METHOD + when defined(openssl10): + case protVersion + of protSSLv23: + mtd = SSLv23_method() + 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: + mtd = TLSv1_method() + else: + mtd = TLS_method() if mtd == nil: raiseSSLError("Failed to create TLS context") var newCTX = SSL_CTX_new(mtd) diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index e9c9c581f..dedea355c 100644 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -10,7 +10,11 @@ ## OpenSSL wrapper. Supports OpenSSL >= 1.1.0 dynamically (as default) or statically linked ## using `--dynlibOverride:ssl`. ## -## To use openSSL 3, either set `-d:sslVersion=3` or `-d:useOpenssl3`. +## `-d:sslVersion=1.2.3` can be used to force an SSL version. +## This version must be included in the library name. +## `-d:useOpenssl3` may be set for OpenSSL 3 instead. +## +## There is also limited support for OpenSSL 1.0.x which may require `-d:openssl10`. ## ## Build and test examples: ## @@ -59,7 +63,7 @@ when sslVersion != "": from posix import SocketHandle elif useWinVersion: - when defined(nimOldDlls): + when defined(openssl10) or defined(nimOldDlls): when defined(cpu64): const DLLSSLName* = "(ssleay32|ssleay64).dll" @@ -276,40 +280,60 @@ proc TLSv1_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.} # 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"): +when compileOption("dynlibOverride", "ssl") or defined(noOpenSSLHacks): # Static linking - when not useOpenssl3: + + 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() + + proc ERR_load_BIO_strings*() {.cdecl, dynlib: DLLUtilName, importc.} + 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 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 OpenSSL_version_num(): culong {.cdecl, dynlib: DLLUtilName, importc.} - proc getOpenSSLVersion*(): culong = - ## Return OpenSSL version as unsigned long - OpenSSL_version_num() + 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 + 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): + proc ERR_load_BIO_strings*() = + 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 + 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 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.1.*. Some + # Here we're trying to stay compatible between openssl versions. Some # symbols are loaded dynamically and we don't use them if not found. proc thisModule(): LibHandle {.inline.} = var thisMod {.global.}: LibHandle @@ -367,29 +391,47 @@ 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_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 ERR_load_BIO_strings*() = + let theProc = cast[proc() {.cdecl.}](utilModule().symNullable("ERR_load_BIO_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")) @@ -423,11 +465,6 @@ else: theProc = cast[typeof(theProc)](sslSymThrows("SSL_CTX_set_ciphersuites")) theProc(ctx, str) -proc ERR_load_BIO_strings*(){.cdecl, dynlib: DLLUtilName, importc.} - -proc TLS_client_method*(): PSSL_METHOD {.cdecl, dynlib: DLLSSLName, importc.} - - proc SSL_new*(context: SslCtx): SslPtr{.cdecl, dynlib: DLLSSLName, importc.} proc SSL_free*(ssl: SslPtr){.cdecl, dynlib: DLLSSLName, importc.} proc SSL_get_SSL_CTX*(ssl: SslPtr): SslCtx {.cdecl, dynlib: DLLSSLName, importc.} @@ -535,8 +572,9 @@ const useNimsAlloc = not defined(nimNoAllocForSSL) and not defined(gcDestructors) when not useWinVersion and not defined(macosx) and not defined(android) and useNimsAlloc: - proc CRYPTO_set_mem_functions(a,b,c: pointer){.cdecl, - dynlib: DLLUtilName, importc.} + proc CRYPTO_set_mem_functions(a,b,c: pointer) = + let theProc = cast[proc(a,b,c: pointer) {.cdecl.}](utilModule().symNullable("CRYPTO_set_mem_functions")) + if not theProc.isNil: theProc(a, b, c) proc allocWrapper(size: int): pointer {.cdecl.} = allocShared(size) proc reallocWrapper(p: pointer; newSize: int): pointer {.cdecl.} = @@ -547,9 +585,11 @@ when not useWinVersion and not defined(macosx) and not defined(android) and useN proc deallocWrapper(p: pointer) {.cdecl.} = if p != nil: deallocShared(p) -proc CRYPTO_malloc_init*() = - when not useWinVersion and not defined(macosx) and not defined(android) and useNimsAlloc: + proc CRYPTO_malloc_init*() = CRYPTO_set_mem_functions(allocWrapper, reallocWrapper, deallocWrapper) +else: + proc CRYPTO_malloc_init*() = + discard proc SSL_CTX_ctrl*(ctx: SslCtx, cmd: cint, larg: clong, parg: pointer): clong{. cdecl, dynlib: DLLSSLName, importc.} @@ -792,17 +832,19 @@ when defined(nimHasStyleChecks): # On old openSSL version some of these symbols are not available 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") - + # SSL_get_peer_certificate removed in 3.0 + # SSL_get1_peer_certificate added in 3.0 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) - else: - proc SSL_get_peer_certificate*(ssl: SslCtx): PX509 {.cdecl, dynlib: DLLSSLName, importc.} - + proc SSL_get_peer_certificate*(ssl: SslCtx): PX509 = + let methodSym = sslSymNullable("SSL_get_peer_certificate", "SSL_get1_peer_certificate") + if methodSym.isNil: + raise newException(LibraryError, "Could not load SSL_get_peer_certificate or SSL_get1_peer_certificate") + let method2Proc = cast[proc(ssl: SslCtx): PX509 {.cdecl, gcsafe, raises: [].}](methodSym) + return method2Proc(ssl) proc X509_get_subject_name*(a: PX509): PX509_NAME{.cdecl, dynlib: DLLSSLName, importc.} |