@@ -466,6 +466,141 @@ struct OpenSSLError <: Exception
466466 OpenSSLError (x:: SSLErrorCode ) = new (string (x))
467467end
468468
469+ """
470+ version(; [version_type::OpenSSLVersion])
471+
472+ Obtain the version as a `String`. See [`OpenSSLVersion`](@ref) to select
473+ the version type.
474+
475+ See also [`version_number`](@ref) to obtain a `VersionNumber`.
476+ """
477+ function version (; version_type:: OpenSSLVersion = OPENSSL_VERSION):: String
478+ version = ccall (
479+ (:OpenSSL_version , libcrypto),
480+ Cstring,
481+ (Cint,),
482+ version_type)
483+
484+ return unsafe_string (version)
485+ end
486+
487+ """
488+ version_number()::VersionNumber
489+
490+ Return the version number of the OpenSSL C library.
491+ This uses `OpenSSL_version_num()`.
492+ """
493+ function version_number ()
494+ # This works on OpenSSL v1.1
495+ vn = ccall ((:OpenSSL_version_num , libcrypto), Culong, ())
496+
497+ # 0xMNN00PP0L
498+ # M: major
499+ # NN: minor
500+ # PP: patch
501+ major = vn >> 28
502+ minor = vn >> 20 & 0xff
503+ patch = vn >> 4 & 0xff
504+
505+ return VersionNumber (major, minor, patch)
506+ end
507+
508+ @static if version_number () ≥ v " 3"
509+ # In OpenSSL v3, macros redirect these symbols
510+ const SSL_get_peer_certificate = :SSL_get1_peer_certificate
511+ const EVP_PKEY_base_id = :EVP_PKEY_get_base_id
512+ const EVP_CIPHER_key_length = :EVP_CIPHER_get_key_length
513+ const EVP_CIPHER_iv_length = :EVP_CIPHER_get_iv_length
514+ const EVP_CIPHER_block_size = :EVP_CIPHER_get_block_size
515+ const EVP_CIPHER_CTX_block_size = :EVP_CIPHER_CTX_get_block_size
516+ const EVP_CIPHER_CTX_key_length = :EVP_CIPHER_CTX_get_key_length
517+ const EVP_CIPHER_CTX_iv_length = :EVP_CIPHER_CTX_get_iv_length
518+ else
519+ const SSL_get_peer_certificate = :SSL_get_peer_certificate
520+ const EVP_PKEY_base_id = :EVP_PKEY_base_id
521+ const EVP_CIPHER_key_length = :EVP_CIPHER_key_length
522+ const EVP_CIPHER_iv_length = :EVP_CIPHER_iv_length
523+ const EVP_CIPHER_block_size = :EVP_CIPHER_block_size
524+ const EVP_CIPHER_CTX_block_size = :EVP_CIPHER_CTX_block_size
525+ const EVP_CIPHER_CTX_key_length = :EVP_CIPHER_CTX_key_length
526+ const EVP_CIPHER_CTX_iv_length = :EVP_CIPHER_CTX_iv_length
527+ end
528+
529+ # Locate oss-modules, which contains legacy shared library
530+ function _ossl_modules_path ()
531+ @static if Sys. iswindows ()
532+ bin_dir = dirname (OpenSSL_jll. libssl_path)
533+ lib_dir = joinpath (dirname (bin_dir), " lib" )
534+ if Sys. WORD_SIZE == 64
535+ return joinpath (lib_dir * " 64" , " ossl-modules" )
536+ else
537+ return joinpath (lib_dir, " ossl-modules" )
538+ end
539+ else
540+ return joinpath (dirname (OpenSSL_jll. libssl), " ossl-modules" )
541+ end
542+ end
543+
544+ """
545+ ossl_provider_set_default_search_path([libctx], [path])
546+
547+ Set the default search path for providers. If no arguments are given,
548+ the global context will be configured for the ossl-modules directory
549+ in the OpenSSL_jll artifact.
550+
551+ This is called with no arguments in OpenSSL.jl `__init__` when
552+ OpenSSL v3 is used.
553+
554+ !!! compat "OpenSSL v3" `ossl_provider_set_default_search_path` is only available with version 3 of the OpenSSL_jll
555+ """
556+ function ossl_provider_set_default_search_path (libctx = C_NULL , path = _ossl_modules_path ())
557+ result = ccall (
558+ (:OSSL_PROVIDER_set_default_search_path , libcrypto),
559+ Cint,
560+ (Ptr{Nothing}, Cstring),
561+ libctx,
562+ path
563+ )
564+ if result == 0
565+ throw (OpenSSLError ())
566+ end
567+ return result
568+ end
569+
570+ """
571+ load_provider([libctx], provider_name)
572+
573+ Load a provider. If libctx is omitted, the provider will be loaded into the
574+ global context.
575+
576+ !!! compat "OpenSSL v3" `load_provider` is only available with version 3 of the OpenSSL_jll
577+ """
578+ function load_provider (libctx, provider_name)
579+ result = ccall (
580+ (:OSSL_PROVIDER_load , libcrypto),
581+ Ptr{Nothing},
582+ (Ptr{Nothing}, Cstring),
583+ libctx,
584+ provider_name
585+ )
586+ if result == C_NULL
587+ throw (OpenSSLError ())
588+ end
589+ return nothing
590+ end
591+ load_provider (provider_name) = load_provider (C_NULL , provider_name)
592+
593+ """
594+ load_legacy_provider()
595+
596+ Load the legacy provider. This loads legacy ciphers such as Blowfish.
597+
598+ See https://www.openssl.org/docs/man3.0/man7/OSSL_PROVIDER-legacy.html
599+
600+ !!! compat "OpenSSL v3" `load_legacy_provider` is only available with version 3 of the OpenSSL_jll
601+ """
602+ load_legacy_provider () = load_provider (C_NULL , " legacy" )
603+
469604"""
470605 Random bytes.
471606"""
@@ -718,19 +853,19 @@ mutable struct EvpCipher
718853end
719854
720855get_block_size (evp_cipher:: EvpCipher ):: Int32 = ccall (
721- (: EVP_CIPHER_block_size , libcrypto),
856+ (EVP_CIPHER_block_size, libcrypto),
722857 Int32,
723858 (EvpCipher,),
724859 evp_cipher)
725860
726861get_key_length (evp_cipher:: EvpCipher ):: Int32 = ccall (
727- (: EVP_CIPHER_key_length , libcrypto),
862+ (EVP_CIPHER_key_length, libcrypto),
728863 Int32,
729864 (EvpCipher,),
730865 evp_cipher)
731866
732867get_init_vector_length (evp_cipher:: EvpCipher ):: Int32 = ccall (
733- (: EVP_CIPHER_iv_length , libcrypto),
868+ (EVP_CIPHER_iv_length, libcrypto),
734869 Int32,
735870 (EvpCipher,),
736871 evp_cipher)
@@ -997,19 +1132,19 @@ function cipher(evp_cipher_ctx::EvpCipherContext, in_io::IO, out_io::IO)
9971132end
9981133
9991134get_block_size (evp_cipher_ctx:: EvpCipherContext ):: Int32 = ccall (
1000- (: EVP_CIPHER_CTX_block_size , libcrypto),
1135+ (EVP_CIPHER_CTX_block_size, libcrypto),
10011136 Int32,
10021137 (EvpCipherContext,),
10031138 evp_cipher_ctx)
10041139
10051140get_key_length (evp_cipher_ctx:: EvpCipherContext ):: Int32 = ccall (
1006- (: EVP_CIPHER_CTX_key_length , libcrypto),
1141+ (EVP_CIPHER_CTX_key_length, libcrypto),
10071142 Int32,
10081143 (EvpCipherContext,),
10091144 evp_cipher_ctx)
10101145
10111146get_init_vector_length (evp_cipher_ctx:: EvpCipherContext ):: Int32 = ccall (
1012- (: EVP_CIPHER_CTX_iv_length , libcrypto),
1147+ (EVP_CIPHER_CTX_iv_length, libcrypto),
10131148 Int32,
10141149 (EvpCipherContext,),
10151150 evp_cipher_ctx)
@@ -1748,7 +1883,7 @@ end
17481883
17491884function get_key_type (evp_pkey:: EvpPKey ):: EvpPKeyType
17501885 pkey_type = ccall (
1751- (: EVP_PKEY_base_id , libcrypto),
1886+ (EVP_PKEY_base_id, libcrypto),
17521887 EvpPKeyType,
17531888 (EvpPKey,),
17541889 evp_pkey)
@@ -2971,16 +3106,6 @@ function update_tls_error_state()
29713106 end
29723107end
29733108
2974- function version (; version_type:: OpenSSLVersion = OPENSSL_VERSION):: String
2975- version = ccall (
2976- (:OpenSSL_version , libcrypto),
2977- Cstring,
2978- (Cint,),
2979- version_type)
2980-
2981- return unsafe_string (version)
2982- end
2983-
29843109include (" ssl.jl" )
29853110
29863111const OPEN_SSL_INIT = Ref {OpenSSLInit} ()
@@ -2994,6 +3119,12 @@ function __init__()
29943119 OPEN_SSL_INIT. x = OpenSSLInit ()
29953120 BIO_STREAM_CALLBACKS. x = BIOStreamCallbacks ()
29963121 BIO_STREAM_METHOD. x = BIOMethod (" BIO_STREAM_METHOD" )
3122+
3123+ # Set the openssl provider search path
3124+ if version_number () ≥ v " 3"
3125+ ossl_provider_set_default_search_path ()
3126+ end
3127+
29973128 return
29983129end
29993130
0 commit comments