@@ -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,55 @@ impl fmt::Debug for Pkcs11Impl {
6868}
6969
7070impl Pkcs11Impl {
71+ /// Initializes Pkcs11 using raw Pkcs11 object.
72+ ///
73+ /// # Safety
74+ ///
75+ /// `pkcs11_lib` must point to a valid Pkcs11 object.
76+ pub unsafe fn new_unchecked ( pkcs11_lib : cryptoki_sys:: Pkcs11 ) -> Result < Self > {
77+ /* First try the 3.0 API to get default interface. It might have some more functions than
78+ * the 2.4 API */
79+ let mut interface = mem:: MaybeUninit :: uninit ( ) ;
80+ if pkcs11_lib. C_GetInterface . is_ok ( ) {
81+ Rv :: from ( pkcs11_lib. C_GetInterface (
82+ ptr:: null_mut ( ) ,
83+ ptr:: null_mut ( ) ,
84+ interface. as_mut_ptr ( ) ,
85+ 0 ,
86+ ) )
87+ . into_result ( Function :: GetInterface ) ?;
88+ if !interface. as_ptr ( ) . is_null ( ) {
89+ let ifce_ptr: * mut cryptoki_sys:: CK_INTERFACE = * interface. as_ptr ( ) ;
90+ let ifce: cryptoki_sys:: CK_INTERFACE = * ifce_ptr;
91+
92+ let list_ptr: * mut cryptoki_sys:: CK_FUNCTION_LIST =
93+ ifce. pFunctionList as * mut cryptoki_sys:: CK_FUNCTION_LIST ;
94+ let list: cryptoki_sys:: CK_FUNCTION_LIST = * list_ptr;
95+ if list. version . major >= 3 {
96+ let list30_ptr: * mut cryptoki_sys:: CK_FUNCTION_LIST_3_0 =
97+ ifce. pFunctionList as * mut cryptoki_sys:: CK_FUNCTION_LIST_3_0 ;
98+ return Ok ( Pkcs11Impl {
99+ _pkcs11_lib : pkcs11_lib,
100+ function_list : FunctionList :: V3_0 ( * list30_ptr) ,
101+ } ) ;
102+ }
103+ /* fall back to the 2.* API */
104+ }
105+ }
106+
107+ let mut list = mem:: MaybeUninit :: uninit ( ) ;
108+
109+ Rv :: from ( pkcs11_lib. C_GetFunctionList ( list. as_mut_ptr ( ) ) )
110+ . into_result ( Function :: GetFunctionList ) ?;
111+
112+ let list_ptr = * list. as_ptr ( ) ;
113+
114+ Ok ( Pkcs11Impl {
115+ _pkcs11_lib : pkcs11_lib,
116+ function_list : FunctionList :: V2 ( v2tov3 ( * list_ptr) ) ,
117+ } )
118+ }
119+
71120 #[ inline( always) ]
72121 pub ( crate ) fn get_function_list ( & self ) -> cryptoki_sys:: CK_FUNCTION_LIST_3_0 {
73122 match self . function_list {
@@ -118,7 +167,10 @@ impl Pkcs11 {
118167 unsafe {
119168 let pkcs11_lib =
120169 cryptoki_sys:: Pkcs11 :: new ( filename. as_ref ( ) ) . map_err ( Error :: LibraryLoading ) ?;
121- Self :: _new ( pkcs11_lib)
170+ Ok ( Self {
171+ impl_ : Pkcs11Impl :: new_unchecked ( pkcs11_lib) ?,
172+ initialized : RwLock :: new ( false ) ,
173+ } )
122174 }
123175 }
124176
@@ -130,60 +182,13 @@ impl Pkcs11 {
130182 #[ cfg( windows) ]
131183 let this_lib = libloading:: os:: windows:: Library :: this ( ) ?;
132184 let pkcs11_lib = cryptoki_sys:: Pkcs11 :: from_library ( this_lib) ?;
133- Self :: _new ( pkcs11_lib)
185+ Ok ( Self {
186+ impl_ : Pkcs11Impl :: new_unchecked ( pkcs11_lib) ?,
187+ initialized : RwLock :: new ( false ) ,
188+ } )
134189 }
135190 }
136191
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-
187192 /// Initialize the PKCS11 library
188193 pub fn initialize ( & self , init_args : CInitializeArgs ) -> Result < ( ) > {
189194 let mut init_lock = self . initialized . write ( ) . expect ( "lock not to be poisoned" ) ;
0 commit comments