This fixes at least a couple of issues: * Procs loaded from the DLL being used even when the pointer is nil. * The actual issue (#13903) which appeared to cause stack corruption on Android 7.1.1 with OpenSSL 1.1.1f. The change that fixed this was the move to loading the procs in `sslSym`.
This commit is contained in:
parent
3dc8068075
commit
350ee0308a
1 changed files with 39 additions and 19 deletions
|
|
@ -244,7 +244,7 @@ proc TLSv1_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.}
|
||||||
# and support SSLv3, TLSv1, TLSv1.1 and TLSv1.2
|
# and support SSLv3, TLSv1, TLSv1.1 and TLSv1.2
|
||||||
# SSLv23_method(), SSLv23_server_method(), SSLv23_client_method() are removed in 1.1.0
|
# 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
|
# Static linking
|
||||||
|
|
||||||
when defined(openssl10):
|
when defined(openssl10):
|
||||||
|
|
@ -285,40 +285,59 @@ else:
|
||||||
proc thisModule(): LibHandle {.inline.} =
|
proc thisModule(): LibHandle {.inline.} =
|
||||||
var thisMod {.global.}: LibHandle
|
var thisMod {.global.}: LibHandle
|
||||||
if thisMod.isNil: thisMod = loadLib()
|
if thisMod.isNil: thisMod = loadLib()
|
||||||
|
|
||||||
result = thisMod
|
result = thisMod
|
||||||
|
|
||||||
proc sslModule(): LibHandle {.inline.} =
|
proc sslModule(): LibHandle {.inline.} =
|
||||||
var sslMod {.global.}: LibHandle
|
var sslMod {.global.}: LibHandle
|
||||||
if sslMod.isNil: sslMod = loadLibPattern(DLLSSLName)
|
if sslMod.isNil: sslMod = loadLibPattern(DLLSSLName)
|
||||||
|
|
||||||
result = sslMod
|
result = sslMod
|
||||||
|
|
||||||
proc sslSym(name: string): pointer =
|
proc sslSymNullable(name: string, alternativeName = ""): pointer =
|
||||||
var dl = thisModule()
|
# Load from DLL.
|
||||||
if not dl.isNil:
|
var sslDynlib = sslModule()
|
||||||
result = symAddr(dl, name)
|
if not sslDynlib.isNil:
|
||||||
|
result = symAddr(sslDynlib, name)
|
||||||
|
if result.isNil and alternativeName.len > 0:
|
||||||
|
result = symAddr(sslDynlib, alternativeName)
|
||||||
|
|
||||||
|
# Attempt to load from current exe.
|
||||||
if result.isNil:
|
if result.isNil:
|
||||||
dl = sslModule()
|
let thisDynlib = thisModule()
|
||||||
if not dl.isNil:
|
if thisDynlib.isNil: return nil
|
||||||
result = symAddr(dl, name)
|
result = symAddr(thisDynlib, name)
|
||||||
|
if result.isNil and alternativeName.len > 0:
|
||||||
|
result = symAddr(sslDynlib, alternativeName)
|
||||||
|
|
||||||
|
proc sslSymThrows(name: string, alternativeName = ""): pointer =
|
||||||
|
result = sslSymNullable(name, alternativeName)
|
||||||
|
if result.isNil: raiseInvalidLibrary(name)
|
||||||
|
|
||||||
proc loadPSSLMethod(method1, method2: string): PSSL_METHOD =
|
proc loadPSSLMethod(method1, method2: string): PSSL_METHOD =
|
||||||
## Load <method1> from OpenSSL if available, otherwise <method2>
|
## Load <method1> from OpenSSL if available, otherwise <method2>
|
||||||
let m1 = cast[proc(): PSSL_METHOD {.cdecl, gcsafe.}](sslSym(method1))
|
##
|
||||||
if not m1.isNil:
|
let methodSym = sslSymNullable(method1, method2)
|
||||||
return m1()
|
if methodSym.isNil:
|
||||||
cast[proc(): PSSL_METHOD {.cdecl, gcsafe.}](sslSym(method2))()
|
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.} =
|
proc SSL_library_init*(): cint {.discardable.} =
|
||||||
## Initialize SSL using OPENSSL_init_ssl for OpenSSL >= 1.1.0 otherwise
|
## Initialize SSL using OPENSSL_init_ssl for OpenSSL >= 1.1.0 otherwise
|
||||||
## SSL_library_init
|
## SSL_library_init
|
||||||
let theProc = cast[proc(opts: uint64, settings: uint8): cint {.cdecl.}](sslSym("OPENSSL_init_ssl"))
|
let newInitSym = sslSymNullable("OPENSSL_init_ssl")
|
||||||
if not theProc.isNil:
|
if not newInitSym.isNil:
|
||||||
return theProc(0, 0)
|
let newInitProc =
|
||||||
let olderProc = cast[proc(): cint {.cdecl.}](sslSym("SSL_library_init"))
|
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()
|
if not olderProc.isNil: result = olderProc()
|
||||||
|
|
||||||
proc SSL_load_error_strings*() =
|
proc SSL_load_error_strings*() =
|
||||||
let theProc = cast[proc() {.cdecl.}](sslSym("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()
|
if not theProc.isNil: theProc()
|
||||||
|
|
||||||
proc SSLv23_client_method*(): PSSL_METHOD =
|
proc SSLv23_client_method*(): PSSL_METHOD =
|
||||||
|
|
@ -343,12 +362,13 @@ else:
|
||||||
loadPSSLMethod("TLS_server_method", "SSLv23_server_method")
|
loadPSSLMethod("TLS_server_method", "SSLv23_server_method")
|
||||||
|
|
||||||
proc OpenSSL_add_all_algorithms*() =
|
proc OpenSSL_add_all_algorithms*() =
|
||||||
let theProc = cast[proc() {.cdecl.}](sslSym("OPENSSL_add_all_algorithms_conf"))
|
# 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()
|
if not theProc.isNil: theProc()
|
||||||
|
|
||||||
proc getOpenSSLVersion*(): culong =
|
proc getOpenSSLVersion*(): culong =
|
||||||
## Return OpenSSL version as unsigned long or 0 if not available
|
## Return OpenSSL version as unsigned long or 0 if not available
|
||||||
let theProc = cast[proc(): culong {.cdecl.}](sslSym("OpenSSL_version_num"))
|
let theProc = cast[proc(): culong {.cdecl.}](sslSymNullable("OpenSSL_version_num"))
|
||||||
result =
|
result =
|
||||||
if theProc.isNil: 0.culong
|
if theProc.isNil: 0.culong
|
||||||
else: theProc()
|
else: theProc()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue