@@ -51,8 +51,8 @@ enum FunctionList {
5151 //V3_2(cryptoki_sys::CK_FUNCTION_LIST_3_2),
5252}
5353
54- // Implementation of Pkcs11 class that can be enclosed in a single Arc
55- pub ( crate ) struct Pkcs11Impl {
54+ /// Implementation of Pkcs11 class that can be enclosed in a single Arc
55+ pub struct Pkcs11Impl {
5656 // Even if this field is never read, it is needed for the pointers in function_list to remain
5757 // valid.
5858 _pkcs11_lib : cryptoki_sys:: Pkcs11 ,
@@ -68,6 +68,51 @@ impl fmt::Debug for Pkcs11Impl {
6868}
6969
7070impl Pkcs11Impl {
71+ /// Initializes Pkcs11 using raw Pkcs11 object.
72+ pub unsafe fn new_unchecked ( pkcs11_lib : cryptoki_sys:: Pkcs11 ) -> Result < Self > {
73+ /* First try the 3.0 API to get default interface. It might have some more functions than
74+ * the 2.4 API */
75+ let mut interface = mem:: MaybeUninit :: uninit ( ) ;
76+ if pkcs11_lib. C_GetInterface . is_ok ( ) {
77+ Rv :: from ( pkcs11_lib. C_GetInterface (
78+ ptr:: null_mut ( ) ,
79+ ptr:: null_mut ( ) ,
80+ interface. as_mut_ptr ( ) ,
81+ 0 ,
82+ ) )
83+ . into_result ( Function :: GetInterface ) ?;
84+ if !interface. as_ptr ( ) . is_null ( ) {
85+ let ifce_ptr: * mut cryptoki_sys:: CK_INTERFACE = * interface. as_ptr ( ) ;
86+ let ifce: cryptoki_sys:: CK_INTERFACE = * ifce_ptr;
87+
88+ let list_ptr: * mut cryptoki_sys:: CK_FUNCTION_LIST =
89+ ifce. pFunctionList as * mut cryptoki_sys:: CK_FUNCTION_LIST ;
90+ let list: cryptoki_sys:: CK_FUNCTION_LIST = * list_ptr;
91+ if list. version . major >= 3 {
92+ let list30_ptr: * mut cryptoki_sys:: CK_FUNCTION_LIST_3_0 =
93+ ifce. pFunctionList as * mut cryptoki_sys:: CK_FUNCTION_LIST_3_0 ;
94+ return Ok ( Pkcs11Impl {
95+ _pkcs11_lib : pkcs11_lib,
96+ function_list : FunctionList :: V3_0 ( * list30_ptr) ,
97+ } ) ;
98+ }
99+ /* fall back to the 2.* API */
100+ }
101+ }
102+
103+ let mut list = mem:: MaybeUninit :: uninit ( ) ;
104+
105+ Rv :: from ( pkcs11_lib. C_GetFunctionList ( list. as_mut_ptr ( ) ) )
106+ . into_result ( Function :: GetFunctionList ) ?;
107+
108+ let list_ptr = * list. as_ptr ( ) ;
109+
110+ Ok ( Pkcs11Impl {
111+ _pkcs11_lib : pkcs11_lib,
112+ function_list : FunctionList :: V2 ( v2tov3 ( * list_ptr) ) ,
113+ } )
114+ }
115+
71116 #[ inline( always) ]
72117 pub ( crate ) fn get_function_list ( & self ) -> cryptoki_sys:: CK_FUNCTION_LIST_3_0 {
73118 match self . function_list {
@@ -118,7 +163,10 @@ impl Pkcs11 {
118163 unsafe {
119164 let pkcs11_lib =
120165 cryptoki_sys:: Pkcs11 :: new ( filename. as_ref ( ) ) . map_err ( Error :: LibraryLoading ) ?;
121- Self :: _new ( pkcs11_lib)
166+ Ok ( Self {
167+ impl_ : Pkcs11Impl :: new_unchecked ( pkcs11_lib) ?,
168+ initialized : RwLock :: new ( false ) ,
169+ } )
122170 }
123171 }
124172
@@ -130,60 +178,13 @@ impl Pkcs11 {
130178 #[ cfg( windows) ]
131179 let this_lib = libloading:: os:: windows:: Library :: this ( ) ?;
132180 let pkcs11_lib = cryptoki_sys:: Pkcs11 :: from_library ( this_lib) ?;
133- Self :: _new ( pkcs11_lib)
181+ Ok ( Self {
182+ impl_ : Pkcs11Impl :: new_unchecked ( pkcs11_lib) ?,
183+ initialized : RwLock :: new ( false ) ,
184+ } )
134185 }
135186 }
136187
137- unsafe fn _new ( pkcs11_lib : cryptoki_sys:: Pkcs11 ) -> Result < Self > {
138- /* First try the 3.0 API to get default interface. It might have some more functions than
139- * the 2.4 API */
140- let mut interface = mem:: MaybeUninit :: uninit ( ) ;
141- if pkcs11_lib. C_GetInterface . is_ok ( ) {
142- Rv :: from ( pkcs11_lib. C_GetInterface (
143- ptr:: null_mut ( ) ,
144- ptr:: null_mut ( ) ,
145- interface. as_mut_ptr ( ) ,
146- 0 ,
147- ) )
148- . into_result ( Function :: GetInterface ) ?;
149- if !interface. as_ptr ( ) . is_null ( ) {
150- let ifce_ptr: * mut cryptoki_sys:: CK_INTERFACE = * interface. as_ptr ( ) ;
151- let ifce: cryptoki_sys:: CK_INTERFACE = * ifce_ptr;
152-
153- let list_ptr: * mut cryptoki_sys:: CK_FUNCTION_LIST =
154- ifce. pFunctionList as * mut cryptoki_sys:: CK_FUNCTION_LIST ;
155- let list: cryptoki_sys:: CK_FUNCTION_LIST = * list_ptr;
156- if list. version . major >= 3 {
157- let list30_ptr: * mut cryptoki_sys:: CK_FUNCTION_LIST_3_0 =
158- ifce. pFunctionList as * mut cryptoki_sys:: CK_FUNCTION_LIST_3_0 ;
159- return Ok ( Pkcs11 {
160- impl_ : Pkcs11Impl {
161- _pkcs11_lib : pkcs11_lib,
162- function_list : FunctionList :: V3_0 ( * list30_ptr) ,
163- } ,
164- initialized : RwLock :: new ( false ) ,
165- } ) ;
166- }
167- /* fall back to the 2.* API */
168- }
169- }
170-
171- let mut list = mem:: MaybeUninit :: uninit ( ) ;
172-
173- Rv :: from ( pkcs11_lib. C_GetFunctionList ( list. as_mut_ptr ( ) ) )
174- . into_result ( Function :: GetFunctionList ) ?;
175-
176- let list_ptr = * list. as_ptr ( ) ;
177-
178- Ok ( Pkcs11 {
179- impl_ : Pkcs11Impl {
180- _pkcs11_lib : pkcs11_lib,
181- function_list : FunctionList :: V2 ( v2tov3 ( * list_ptr) ) ,
182- } ,
183- initialized : RwLock :: new ( false ) ,
184- } )
185- }
186-
187188 /// Initialize the PKCS11 library
188189 pub fn initialize ( & self , init_args : CInitializeArgs ) -> Result < ( ) > {
189190 let mut init_lock = self . initialized . write ( ) . expect ( "lock not to be poisoned" ) ;
0 commit comments