@@ -11,19 +11,26 @@ import (
11
11
// osslHandle is the handle to the OpenSSL shared library loaded in the [Init] function.
12
12
var osslHandle unsafe.Pointer
13
13
14
- // opensslInit loads and initialize OpenSSL.
15
- // If successful, it returns the major and minor OpenSSL version
16
- // as reported by the OpenSSL API.
14
+ // opensslInit loads and initializes OpenSSL.
17
15
//
18
- // See Init() for details about file.
16
+ // See [ Init] for details about file.
19
17
func opensslInit (file string ) error {
20
18
// Load the OpenSSL shared library using dlopen.
21
- handle , err := openLibrary (file )
19
+ handle , close , err := openLibrary (file )
22
20
if err != nil {
23
21
return err
24
22
}
25
23
26
- loadOpenSSLFuncs (handle )
24
+ mkcgoLoad_ (handle )
25
+ if vMajor == 1 {
26
+ mkcgoLoad_legacy_1 (handle )
27
+ if vPatch == 1 {
28
+ mkcgoLoad_111 (handle )
29
+ }
30
+ } else {
31
+ mkcgoLoad_111 (handle )
32
+ mkcgoLoad_3 (handle )
33
+ }
27
34
28
35
// Initialize OpenSSL.
29
36
go_openssl_OPENSSL_init ()
@@ -33,84 +40,87 @@ func opensslInit(file string) error {
33
40
_OPENSSL_INIT_LOAD_CONFIG |
34
41
_OPENSSL_INIT_LOAD_CRYPTO_STRINGS ,
35
42
nil ); err != nil {
36
- dlclose ( handle )
43
+ close ( )
37
44
return err
38
45
}
39
46
osslHandle = handle
40
47
return nil
41
48
}
42
49
43
- // loadFuncs loads and initialize the OpenSSL functions.
44
- // See shims.go for the complete list of supported functions.
45
- func loadOpenSSLFuncs (handle unsafe.Pointer ) {
46
- mkcgoLoad_ (handle )
47
- if vMajor == 1 {
48
- mkcgoLoad_legacy_1 (handle )
49
- if vPatch == 1 {
50
- mkcgoLoad_111 (handle )
51
- }
52
- } else {
53
- mkcgoLoad_111 (handle )
54
- mkcgoLoad_3 (handle )
55
- }
56
- }
57
-
58
50
// initForCheckVersion loads and initialize only the
59
51
// functions required in [CheckVersion].
60
- // It returns a function that must be called to release the resources.
61
- // The function leaves all the global variables in the same state as they were
62
- // before the call.
52
+ // It returns a close function that must be called to release the resources.
53
+ //
54
+ // This function modifies the vMajor, vMinor, and vPatch global variables as
55
+ // well as other internal global variables that facilitate OpenSSL calls.
56
+ //
57
+ // If the function succeeds, calling the close function restores the previous
58
+ // state of the global variables. If it fails, the global variables are restored
59
+ // before returning.
63
60
func initForCheckVersion (file string ) (func (), error ) {
64
- // This function can be called when the
65
61
prevMajor , prevMinor , prevPatch := vMajor , vMinor , vPatch
66
- // Load the OpenSSL shared library using dlopen.
67
- handle , err := openLibrary (file )
68
- if err != nil {
62
+ restoreVersion := func () {
69
63
vMajor , vMinor , vPatch = prevMajor , prevMinor , prevPatch
64
+ }
65
+ handle , close , err := openLibrary (file )
66
+ if err != nil {
67
+ restoreVersion ()
70
68
return nil , err
71
69
}
72
-
73
- switch vMajor {
74
- case 1 :
75
- mkcgoLoad_init_1 (handle )
76
- case 3 :
77
- mkcgoLoad_init_3 (handle )
78
- default :
79
- // We shouldn't get here: openLibrary should have already returned an error.
80
- panic (errUnsupportedVersion ())
70
+ initFuncs := func () (loadX func (unsafe.Pointer ), unloadX func ()) {
71
+ switch vMajor {
72
+ case 1 :
73
+ loadX = mkcgoLoad_init_1
74
+ unloadX = mkcgoUnload_init_1
75
+ case 3 :
76
+ loadX = mkcgoLoad_init_3
77
+ unloadX = mkcgoUnload_init_3
78
+ default :
79
+ // We shouldn't get here: openLibrary should have already returned an error.
80
+ panic (errUnsupportedVersion ())
81
+ }
82
+ return
81
83
}
84
+ loadX , unloadX := initFuncs ()
85
+ loadX (handle )
82
86
return func () {
83
- dlclose (handle )
84
- // Undo all the changes made in this function.
85
- mkcgoUnload_version ()
86
- mkcgoUnload_init_1 ()
87
- mkcgoUnload_init_3 ()
88
- vMajor , vMinor , vPatch = prevMajor , prevMinor , prevPatch
87
+ restoreVersion ()
88
+ close ()
89
+ unloadX ()
89
90
if osslHandle != nil {
90
- loadOpenSSLFuncs (osslHandle )
91
+ // If osslHandle is not nil, it means that the library was already loaded
92
+ // and initialized. In this case, we need to reload the functions from
93
+ // the original handle.
94
+ loadX , _ = initFuncs ()
95
+ loadX (osslHandle )
91
96
}
92
97
}, nil
93
98
}
94
99
95
100
// openLibrary loads and initialize the version of OpenSSL.
96
- func openLibrary (file string ) (unsafe.Pointer , error ) {
97
- handle , err := dlopen (file )
101
+ // It returns the handle to the OpenSSL shared library
102
+ // and a function that can be called to release the resources.
103
+ func openLibrary (file string ) (handle unsafe.Pointer , close func (), err error ) {
104
+ vMajor , vMinor , vPatch = 0 , 0 , 0
105
+ handle , err = dlopen (file )
98
106
if err != nil {
99
- return nil , err
107
+ return nil , nil , err
100
108
}
101
- if err := initVersion (handle ); err != nil {
102
- return nil , err
103
- }
104
- return handle , nil
105
- }
106
-
107
- func initVersion (handle unsafe.Pointer ) error {
108
- vMajor , vMinor , vPatch = 0 , 0 , 0
109
109
// Retrieve the loaded OpenSSL version and check if it is supported.
110
110
// Notice that major and minor could not match with the version parameter
111
111
// in case the name of the shared library file differs from the OpenSSL
112
112
// version it contains.
113
113
mkcgoLoad_version (handle )
114
+ close = func () {
115
+ dlclose (handle )
116
+ mkcgoUnload_version ()
117
+ }
118
+ defer func () {
119
+ if err != nil {
120
+ close ()
121
+ }
122
+ }()
123
+
114
124
if go_openssl_OPENSSL_version_major_Available () &&
115
125
go_openssl_OPENSSL_version_minor_Available () &&
116
126
go_openssl_OPENSSL_version_patch_Available () {
@@ -125,7 +135,7 @@ func initVersion(handle unsafe.Pointer) error {
125
135
vMinor = uint (ver >> 20 & 0xFF )
126
136
vPatch = uint (ver >> 12 & 0xFF )
127
137
} else {
128
- return errors .New ("openssl: version not available" )
138
+ return handle , nil , errors .New ("openssl: version not available" )
129
139
}
130
140
var supported bool
131
141
if vMajor == 1 {
@@ -135,7 +145,7 @@ func initVersion(handle unsafe.Pointer) error {
135
145
supported = true
136
146
}
137
147
if ! supported {
138
- return errUnsupportedVersion ()
148
+ return handle , nil , errUnsupportedVersion ()
139
149
}
140
- return nil
150
+ return handle , close , nil
141
151
}
0 commit comments