@@ -102,6 +102,142 @@ fn test_nssdb_token() {
102102 testtokn. finalize ( ) ;
103103}
104104
105+ #[ test]
106+ #[ parallel]
107+ #[ cfg( feature = "mldsa" ) ]
108+ fn test_nssdb_token_mldsa ( ) {
109+ let name = String :: from ( "test_nssdb_token_mldsa" ) ;
110+ let datadir = "testdata/nssdbdir2" ;
111+ let destdir = format ! ( "{}/{}" , TESTDIR , name) ;
112+
113+ let dbargs = format ! ( "configDir={}" , destdir) ;
114+ let dbtype = "nssdb" ;
115+
116+ /* allocates a unique slotid to use in the tests */
117+ let mut testtokn =
118+ TestToken :: new_type ( String :: from ( dbtype) , String :: from ( "" ) , name) ;
119+
120+ /* Do this after TestToken::new() otherwise the data
121+ * is wiped away by the initialization code */
122+ std:: fs:: create_dir_all ( destdir. clone ( ) ) . unwrap ( ) ;
123+ assert ! ( std:: fs:: copy(
124+ format!( "{}/cert9.db" , datadir) ,
125+ format!( "{}/cert9.db" , destdir) ,
126+ )
127+ . is_ok( ) ) ;
128+ assert ! ( std:: fs:: copy(
129+ format!( "{}/key4.db" , datadir) ,
130+ format!( "{}/key4.db" , destdir) ,
131+ )
132+ . is_ok( ) ) ;
133+ assert ! ( std:: fs:: copy(
134+ format!( "{}/pkcs11.txt" , datadir) ,
135+ format!( "{}/pkcs11.txt" , destdir) ,
136+ )
137+ . is_ok( ) ) ;
138+
139+ /* pre-populate conf so we get the correct slot number assigned */
140+ let mut slot = config:: Slot :: with_db ( dbtype, Some ( dbargs. clone ( ) ) ) ;
141+ slot. slot = u32:: try_from ( testtokn. get_slot ( ) ) . unwrap ( ) ;
142+ let ret = add_slot ( slot) ;
143+ assert_eq ! ( ret, CKR_OK ) ;
144+
145+ let mut args = TestToken :: make_init_args ( Some ( dbargs. clone ( ) ) ) ;
146+ let args_ptr = & mut args as * mut CK_C_INITIALIZE_ARGS ;
147+ let ret = fn_initialize ( args_ptr as * mut std:: ffi:: c_void ) ;
148+ assert_eq ! ( ret, CKR_OK ) ;
149+
150+ /* check slots and token */
151+ let mut info = CK_SLOT_INFO :: default ( ) ;
152+ let ret =
153+ fn_get_slot_info ( testtokn. get_slot ( ) , & mut info as CK_SLOT_INFO_PTR ) ;
154+ assert_eq ! ( ret, CKR_OK ) ;
155+ let desc = std:: str:: from_utf8 ( & info. slotDescription ) . unwrap ( ) ;
156+ assert_eq ! ( desc. starts_with( "Kryoptic Slot" ) , true ) ;
157+
158+ let user_pin = "1234" ;
159+ let session = testtokn. get_session ( true ) ;
160+
161+ /* try to login as user */
162+ let ret = fn_login (
163+ session,
164+ CKU_USER ,
165+ CString :: new ( user_pin) . unwrap ( ) . into_raw ( ) as * mut u8 ,
166+ user_pin. len ( ) as CK_ULONG ,
167+ ) ;
168+ assert_eq ! ( ret, CKR_OK ) ;
169+
170+ /* find the private key object */
171+ let mut privkey: CK_ULONG = CK_INVALID_HANDLE ;
172+ let mut template = make_attr_template (
173+ & [ ( CKA_CLASS , CKO_PRIVATE_KEY ) , ( CKA_KEY_TYPE , CKK_ML_DSA ) ] ,
174+ & [ ] ,
175+ & [ ] ,
176+ ) ;
177+ let ret = fn_find_objects_init (
178+ session,
179+ template. as_mut_ptr ( ) ,
180+ template. len ( ) as CK_ULONG ,
181+ ) ;
182+ assert_eq ! ( ret, CKR_OK ) ;
183+ let mut count: CK_ULONG = 0 ;
184+ let ret = fn_find_objects ( session, & mut privkey, 1 , & mut count) ;
185+ assert_eq ! ( ret, CKR_OK ) ;
186+ assert_eq ! ( count, 1 ) ;
187+ assert_ne ! ( privkey, CK_INVALID_HANDLE ) ;
188+ let ret = fn_find_objects_final ( session) ;
189+ assert_eq ! ( ret, CKR_OK ) ;
190+
191+ /* test that the key works */
192+ let mechanism: CK_MECHANISM = CK_MECHANISM {
193+ mechanism : CKM_ML_DSA ,
194+ pParameter : std:: ptr:: null_mut ( ) ,
195+ ulParameterLen : 0 ,
196+ } ;
197+
198+ let msg = hex:: decode (
199+ "1E5A78AD64DF229AA22FD794EC0E82D0F69953118C09D134DFA20F1CC64A3671" ,
200+ )
201+ . expect ( "failed to decode test input" ) ;
202+ let signature =
203+ ret_or_panic ! ( sig_gen( session, privkey, msg. as_slice( ) , & mechanism) ) ;
204+
205+ /* find the public key object */
206+ let mut pubkey: CK_ULONG = CK_INVALID_HANDLE ;
207+ let mut template = make_attr_template (
208+ & [ ( CKA_CLASS , CKO_PUBLIC_KEY ) , ( CKA_KEY_TYPE , CKK_ML_DSA ) ] ,
209+ & [ ] ,
210+ & [ ] ,
211+ ) ;
212+ let ret = fn_find_objects_init (
213+ session,
214+ template. as_mut_ptr ( ) ,
215+ template. len ( ) as CK_ULONG ,
216+ ) ;
217+ assert_eq ! ( ret, CKR_OK ) ;
218+ let mut count: CK_ULONG = 0 ;
219+ let ret = fn_find_objects ( session, & mut pubkey, 1 , & mut count) ;
220+ assert_eq ! ( ret, CKR_OK ) ;
221+ assert_eq ! ( count, 1 ) ;
222+ assert_ne ! ( pubkey, CK_INVALID_HANDLE ) ;
223+ let ret = fn_find_objects_final ( session) ;
224+ assert_eq ! ( ret, CKR_OK ) ;
225+
226+ /* test that the key works */
227+ let ret = sig_verify (
228+ session,
229+ pubkey,
230+ msg. as_slice ( ) ,
231+ signature. as_slice ( ) ,
232+ & mechanism,
233+ ) ;
234+ assert_eq ! ( ret, CKR_OK ) ;
235+
236+ testtokn. logout ( ) ;
237+
238+ testtokn. finalize ( ) ;
239+ }
240+
105241// This test must be run serially as it changes global configuration
106242#[ test]
107243#[ serial]
0 commit comments