10
10
# # OpenSSL wrapper. Supports OpenSSL >= 1.1.0 dynamically (as default) or statically linked
11
11
# # using `--dynlibOverride:ssl`.
12
12
# #
13
- # # To use openSSL 3, either set `-d:sslVersion=3` or `-d:useOpenssl3`.
13
+ # # `-d:sslVersion=1.2.3` can be used to force an SSL version.
14
+ # # This version must be included in the library name.
15
+ # # `-d:useOpenssl3` may be set for OpenSSL 3 instead.
16
+ # #
17
+ # # There is also limited support for OpenSSL 1.0.x which may require `-d:openssl10`.
14
18
# #
15
19
# # Build and test examples:
16
20
# #
@@ -59,7 +63,7 @@ when sslVersion != "":
59
63
from posix import SocketHandle
60
64
61
65
elif useWinVersion:
62
- when defined (nimOldDlls):
66
+ when defined (openssl10) or defined ( nimOldDlls):
63
67
when defined (cpu64):
64
68
const
65
69
DLLSSLName * = " (ssleay32|ssleay64).dll"
@@ -276,40 +280,60 @@ proc TLSv1_method*(): PSSL_METHOD{.cdecl, dynlib: DLLSSLName, importc.}
276
280
# and support SSLv3, TLSv1, TLSv1.1 and TLSv1.2
277
281
# SSLv23_method(), SSLv23_server_method(), SSLv23_client_method() are removed in 1.1.0
278
282
279
- when compileOption (" dynlibOverride" , " ssl" ):
283
+ when compileOption (" dynlibOverride" , " ssl" ) or defined (noOpenSSLHacks) :
280
284
# Static linking
281
- when not useOpenssl3:
285
+
286
+ when defined (openssl10):
287
+ proc SSL_library_init * (): cint {.cdecl , dynlib : DLLSSLName , importc , discardable .}
288
+ proc SSL_load_error_strings * () {.cdecl , dynlib : DLLSSLName , importc .}
289
+ proc SSLv23_method * (): PSSL_METHOD {.cdecl , dynlib : DLLSSLName , importc .}
290
+ proc SSLeay (): culong {.cdecl , dynlib : DLLUtilName , importc .}
291
+
292
+ proc getOpenSSLVersion * (): culong =
293
+ SSLeay ()
294
+
295
+ proc ERR_load_BIO_strings * () {.cdecl , dynlib : DLLUtilName , importc .}
296
+ else :
282
297
proc OPENSSL_init_ssl * (opts: uint64 , settings: uint8 ): cint {.cdecl , dynlib : DLLSSLName , importc , discardable .}
283
298
proc SSL_library_init * (): cint {.discardable .} =
284
299
# # Initialize SSL using OPENSSL_init_ssl for OpenSSL >= 1.1.0
285
300
return OPENSSL_init_ssl (0 .uint64 , 0 .uint8 )
286
301
287
- proc TLS_method * (): PSSL_METHOD {.cdecl , dynlib : DLLSSLName , importc .}
302
+ proc TLS_method * (): PSSL_METHOD {.cdecl , dynlib : DLLSSLName , importc .}
303
+ proc SSLv23_method * (): PSSL_METHOD =
304
+ TLS_method ()
288
305
289
- proc OpenSSL_version_num (): culong {.cdecl , dynlib : DLLUtilName , importc .}
306
+ proc OpenSSL_version_num (): culong {.cdecl , dynlib : DLLUtilName , importc .}
290
307
291
- proc getOpenSSLVersion * (): culong =
292
- # # Return OpenSSL version as unsigned long
293
- OpenSSL_version_num ()
308
+ proc getOpenSSLVersion * (): culong =
309
+ # # Return OpenSSL version as unsigned long
310
+ OpenSSL_version_num ()
294
311
295
- proc SSL_load_error_strings * () =
296
- # # Removed from OpenSSL 1.1.0
297
- # This proc prevents breaking existing code calling SslLoadErrorStrings
298
- # Static linking against OpenSSL < 1.1.0 is not supported
299
- discard
312
+ proc SSL_load_error_strings * () =
313
+ # # Removed from OpenSSL 1.1.0
314
+ # This proc prevents breaking existing code calling SslLoadErrorStrings
315
+ # Static linking against OpenSSL < 1.1.0 is not supported
316
+ discard
300
317
301
- when defined (libressl):
318
+ proc ERR_load_BIO_strings * () =
319
+ discard
320
+
321
+ when defined (libressl) or defined (openssl10):
302
322
proc SSL_state (ssl: SslPtr ): cint {.cdecl , dynlib : DLLSSLName , importc .}
303
323
proc SSL_in_init * (ssl: SslPtr ): cint {.inline .} =
304
- SSl_state (ssl) and SSL_ST_INIT
324
+ SSL_state (ssl) and SSL_ST_INIT
305
325
else :
306
326
proc SSL_in_init * (ssl: SslPtr ): cint {.cdecl , dynlib : DLLSSLName , importc .}
307
327
proc SSL_CTX_set_ciphersuites * (ctx: SslCtx , str: cstring ): cint {.cdecl , dynlib : DLLSSLName , importc .}
308
328
309
329
template OpenSSL_add_all_algorithms * () = discard
310
330
331
+ proc SSLv23_client_method * (): PSSL_METHOD {.cdecl , dynlib : DLLSSLName , importc .}
332
+ proc SSLv2_method * (): PSSL_METHOD {.cdecl , dynlib : DLLSSLName , importc .}
333
+ proc SSLv3_method * (): PSSL_METHOD {.cdecl , dynlib : DLLSSLName , importc .}
334
+
311
335
else :
312
- # Here we're trying to stay compatible with openssl 1.1.* . Some
336
+ # Here we're trying to stay compatible between openssl versions . Some
313
337
# symbols are loaded dynamically and we don't use them if not found.
314
338
proc thisModule (): LibHandle {.inline .} =
315
339
var thisMod {.global .}: LibHandle
@@ -367,29 +391,47 @@ else:
367
391
let method2Proc = cast [proc (): PSSL_METHOD {.cdecl , gcsafe , raises : [].}](methodSym)
368
392
return method2Proc ()
369
393
370
- when not useOpenssl3:
371
- proc SSL_library_init * (): cint {.discardable .} =
372
- # # Initialize SSL using OPENSSL_init_ssl for OpenSSL >= 1.1.0 otherwise
373
- # # SSL_library_init
374
- let newInitSym = sslSymNullable (" OPENSSL_init_ssl" )
375
- if not newInitSym.isNil:
376
- let newInitProc =
377
- cast [proc (opts: uint64 , settings: uint8 ): cint {.cdecl .}](newInitSym)
378
- return newInitProc (0 , 0 )
379
- let olderProc = cast [proc (): cint {.cdecl .}](sslSymThrows (" SSL_library_init" ))
380
- if not olderProc.isNil: result = olderProc ()
394
+ proc SSL_library_init * (): cint {.discardable .} =
395
+ # # Initialize SSL using OPENSSL_init_ssl for OpenSSL >= 1.1.0 otherwise
396
+ # # SSL_library_init
397
+ let newInitSym = sslSymNullable (" OPENSSL_init_ssl" )
398
+ if not newInitSym.isNil:
399
+ let newInitProc =
400
+ cast [proc (opts: uint64 , settings: uint8 ): cint {.cdecl .}](newInitSym)
401
+ return newInitProc (0 , 0 )
402
+ let olderProc = cast [proc (): cint {.cdecl .}](sslSymThrows (" SSL_library_init" ))
403
+ if not olderProc.isNil: result = olderProc ()
381
404
382
405
proc SSL_load_error_strings * () =
383
406
# TODO : Are we ignoring this on purpose? SSL GitHub CI fails otherwise.
384
407
let theProc = cast [proc () {.cdecl .}](sslSymNullable (" SSL_load_error_strings" ))
385
408
if not theProc.isNil: theProc ()
386
409
410
+ proc ERR_load_BIO_strings * () =
411
+ let theProc = cast [proc () {.cdecl .}](utilModule ().symNullable (" ERR_load_BIO_strings" ))
412
+ if not theProc.isNil: theProc ()
413
+
414
+ proc SSLv23_client_method * (): PSSL_METHOD =
415
+ loadPSSLMethod (" SSLv23_client_method" , " TLS_client_method" )
416
+
417
+ proc SSLv23_method * (): PSSL_METHOD =
418
+ loadPSSLMethod (" SSLv23_method" , " TLS_method" )
419
+
420
+ proc SSLv2_method * (): PSSL_METHOD =
421
+ loadPSSLMethod (" SSLv2_method" , " TLS_method" )
422
+
387
423
proc SSLv3_method * (): PSSL_METHOD =
388
424
loadPSSLMethod (" SSLv3_method" , " TLS_method" )
389
425
390
426
proc TLS_method * (): PSSL_METHOD =
391
427
loadPSSLMethod (" TLS_method" , " SSLv23_method" )
392
428
429
+ proc TLS_client_method * (): PSSL_METHOD =
430
+ loadPSSLMethod (" TLS_client_method" , " SSLv23_client_method" )
431
+
432
+ proc TLS_server_method * (): PSSL_METHOD =
433
+ loadPSSLMethod (" TLS_server_method" , " SSLv23_server_method" )
434
+
393
435
proc OpenSSL_add_all_algorithms * () =
394
436
# TODO : Are we ignoring this on purpose? SSL GitHub CI fails otherwise.
395
437
let theProc = cast [proc () {.cdecl .}](sslSymNullable (" OPENSSL_add_all_algorithms_conf" ))
@@ -423,11 +465,6 @@ else:
423
465
theProc = cast [typeof (theProc)](sslSymThrows (" SSL_CTX_set_ciphersuites" ))
424
466
theProc (ctx, str)
425
467
426
- proc ERR_load_BIO_strings * (){.cdecl , dynlib : DLLUtilName , importc .}
427
-
428
- proc TLS_client_method * (): PSSL_METHOD {.cdecl , dynlib : DLLSSLName , importc .}
429
-
430
-
431
468
proc SSL_new * (context: SslCtx ): SslPtr {.cdecl , dynlib : DLLSSLName , importc .}
432
469
proc SSL_free * (ssl: SslPtr ){.cdecl , dynlib : DLLSSLName , importc .}
433
470
proc SSL_get_SSL_CTX * (ssl: SslPtr ): SslCtx {.cdecl , dynlib : DLLSSLName , importc .}
@@ -535,8 +572,9 @@ const
535
572
useNimsAlloc = not defined (nimNoAllocForSSL) and not defined (gcDestructors)
536
573
537
574
when not useWinVersion and not defined (macosx) and not defined (android) and useNimsAlloc:
538
- proc CRYPTO_set_mem_functions (a,b,c: pointer ){.cdecl ,
539
- dynlib : DLLUtilName , importc .}
575
+ proc CRYPTO_set_mem_functions (a,b,c: pointer ) =
576
+ let theProc = cast [proc (a,b,c: pointer ) {.cdecl .}](utilModule ().symNullable (" CRYPTO_set_mem_functions" ))
577
+ if not theProc.isNil: theProc (a, b, c)
540
578
541
579
proc allocWrapper (size: int ): pointer {.cdecl .} = allocShared (size)
542
580
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
547
585
proc deallocWrapper (p: pointer ) {.cdecl .} =
548
586
if p != nil : deallocShared (p)
549
587
550
- proc CRYPTO_malloc_init * () =
551
- when not useWinVersion and not defined (macosx) and not defined (android) and useNimsAlloc:
588
+ proc CRYPTO_malloc_init * () =
552
589
CRYPTO_set_mem_functions (allocWrapper, reallocWrapper, deallocWrapper)
590
+ else :
591
+ proc CRYPTO_malloc_init * () =
592
+ discard
553
593
554
594
proc SSL_CTX_ctrl * (ctx: SslCtx , cmd: cint , larg: clong , parg: pointer ): clong {.
555
595
cdecl , dynlib : DLLSSLName , importc .}
@@ -792,17 +832,19 @@ when defined(nimHasStyleChecks):
792
832
# On old openSSL version some of these symbols are not available
793
833
when not defined (nimDisableCertificateValidation) and not defined (windows):
794
834
795
- # proc SSL_get_peer_certificate*(ssl: SslCtx): PX509 =
796
- # loadPSSLMethod("SSL_get_peer_certificate", "SSL_get1_peer_certificate")
797
-
835
+ # SSL_get_peer_certificate removed in 3.0
836
+ # SSL_get1_peer_certificate added in 3.0
798
837
when useOpenssl3:
799
838
proc SSL_get1_peer_certificate * (ssl: SslCtx ): PX509 {.cdecl , dynlib : DLLSSLName , importc .}
800
839
proc SSL_get_peer_certificate * (ssl: SslCtx ): PX509 =
801
840
SSL_get1_peer_certificate (ssl)
802
-
803
841
else :
804
- proc SSL_get_peer_certificate * (ssl: SslCtx ): PX509 {.cdecl , dynlib : DLLSSLName , importc .}
805
-
842
+ proc SSL_get_peer_certificate * (ssl: SslCtx ): PX509 =
843
+ let methodSym = sslSymNullable (" SSL_get_peer_certificate" , " SSL_get1_peer_certificate" )
844
+ if methodSym.isNil:
845
+ raise newException (LibraryError , " Could not load SSL_get_peer_certificate or SSL_get1_peer_certificate" )
846
+ let method2Proc = cast [proc (ssl: SslCtx ): PX509 {.cdecl , gcsafe , raises : [].}](methodSym)
847
+ return method2Proc (ssl)
806
848
807
849
proc X509_get_subject_name * (a: PX509 ): PX509_NAME {.cdecl , dynlib : DLLSSLName , importc .}
808
850
0 commit comments