lib.rs (41604B)
1 /* -*- Mode: rust; rust-indent-offset: 4 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 extern crate byteorder; 7 extern crate pkcs11_bindings; 8 9 pub mod cryptoki; 10 pub mod manager; 11 12 // Helper macro to prefix log messages with the current thread ID. 13 #[macro_export] 14 macro_rules! log_with_thread_id { 15 ($log_level:ident, $($message:expr),*) => { 16 $log_level!("{:?} {}", std::thread::current().id(), format_args!($($message),*)); 17 }; 18 } 19 20 // This module defines a few helper macros that can be used to declare the repetitive, boilerplate 21 // code required to implement a PKCS#11 module. They require the macros `try_to_get_manager_guard` 22 // and `manager_guard_to_manager` to be defined. Generally speaking, these manager macros are used 23 // to get a mutable handle on a `Mutex<Option<Manager<...>>>` that represents the state of the 24 // module. 25 26 /// NB: Requires MANUFACTURER_ID_BYTES and LIBRARY_DESCRIPTION_BYTES to be defined. 27 #[macro_export] 28 macro_rules! declare_pkcs11_informational_functions { 29 () => { 30 /// This gets called to gather some information about the module. In particular, this 31 /// implementation supports (portions of) cryptoki (PKCS #11) version 2.2. 32 extern "C" fn C_GetInfo(pInfo: CK_INFO_PTR) -> CK_RV { 33 if pInfo.is_null() { 34 log_with_thread_id!(error, "C_GetInfo: CKR_ARGUMENTS_BAD"); 35 return CKR_ARGUMENTS_BAD; 36 } 37 let info = CK_INFO { 38 cryptokiVersion: CK_VERSION { major: 2, minor: 2 }, 39 manufacturerID: *MANUFACTURER_ID_BYTES, 40 flags: 0, 41 libraryDescription: *LIBRARY_DESCRIPTION_BYTES, 42 libraryVersion: CK_VERSION { major: 0, minor: 0 }, 43 }; 44 unsafe { 45 *pInfo = info; 46 } 47 log_with_thread_id!(debug, "C_GetInfo: CKR_OK"); 48 CKR_OK 49 } 50 51 /// This gets called twice: once with a null `pSlotList` to get the number of slots 52 /// (returned via `pulCount`) and a second time to get the ID for each slot. 53 extern "C" fn C_GetSlotList( 54 tokenPresent: CK_BBOOL, 55 pSlotList: CK_SLOT_ID_PTR, 56 pulCount: CK_ULONG_PTR, 57 ) -> CK_RV { 58 if pulCount.is_null() { 59 log_with_thread_id!(error, "C_GetSlotList: CKR_ARGUMENTS_BAD"); 60 return CKR_ARGUMENTS_BAD; 61 } 62 let mut manager_guard = try_to_get_manager_guard!(); 63 let manager = manager_guard_to_manager!(manager_guard); 64 let slot_ids = manager.get_slot_ids(if tokenPresent == CK_TRUE { true } else { false }); 65 let slot_count: CK_ULONG = slot_ids.len().try_into().unwrap(); 66 if !pSlotList.is_null() { 67 if unsafe { *pulCount } < slot_count { 68 log_with_thread_id!(error, "C_GetSlotList: CKR_BUFFER_TOO_SMALL"); 69 return CKR_BUFFER_TOO_SMALL; 70 } 71 unsafe { 72 std::ptr::copy_nonoverlapping(slot_ids.as_ptr(), pSlotList, slot_ids.len()); 73 } 74 }; 75 unsafe { 76 *pulCount = slot_count; 77 } 78 log_with_thread_id!(debug, "C_GetSlotList: CKR_OK"); 79 CKR_OK 80 } 81 82 extern "C" fn C_GetSlotInfo(slotID: CK_SLOT_ID, pInfo: CK_SLOT_INFO_PTR) -> CK_RV { 83 if pInfo.is_null() { 84 log_with_thread_id!(error, "C_GetSlotInfo: CKR_ARGUMENTS_BAD"); 85 return CKR_ARGUMENTS_BAD; 86 } 87 let mut manager_guard = try_to_get_manager_guard!(); 88 let manager = manager_guard_to_manager!(manager_guard); 89 let Ok(slot_info) = manager.get_slot_info(slotID) else { 90 log_with_thread_id!(error, "C_GetSlotInfo: CKR_ARGUMENTS_BAD"); 91 return CKR_ARGUMENTS_BAD; 92 }; 93 unsafe { 94 *pInfo = slot_info; 95 } 96 log_with_thread_id!(debug, "C_GetSlotInfo: CKR_OK"); 97 CKR_OK 98 } 99 100 extern "C" fn C_GetTokenInfo(slotID: CK_SLOT_ID, pInfo: CK_TOKEN_INFO_PTR) -> CK_RV { 101 if pInfo.is_null() { 102 log_with_thread_id!(error, "C_GetTokenInfo: CKR_ARGUMENTS_BAD"); 103 return CKR_ARGUMENTS_BAD; 104 } 105 let mut manager_guard = try_to_get_manager_guard!(); 106 let manager = manager_guard_to_manager!(manager_guard); 107 let Ok(token_info) = manager.get_token_info(slotID) else { 108 log_with_thread_id!(error, "C_GetTokenInfo: CKR_ARGUMENTS_BAD"); 109 return CKR_ARGUMENTS_BAD; 110 }; 111 unsafe { 112 *pInfo = token_info; 113 } 114 log_with_thread_id!(debug, "C_GetTokenInfo: CKR_OK"); 115 CKR_OK 116 } 117 118 extern "C" fn C_GetMechanismList( 119 slotID: CK_SLOT_ID, 120 pMechanismList: CK_MECHANISM_TYPE_PTR, 121 pulCount: CK_ULONG_PTR, 122 ) -> CK_RV { 123 if pulCount.is_null() { 124 log_with_thread_id!(error, "C_GetMechanismList: CKR_ARGUMENTS_BAD"); 125 return CKR_ARGUMENTS_BAD; 126 } 127 let mut manager_guard = try_to_get_manager_guard!(); 128 let manager = manager_guard_to_manager!(manager_guard); 129 let Ok(mechanisms) = manager.get_mechanism_list(slotID) else { 130 log_with_thread_id!(error, "C_GetMechanismList: CKR_ARGUMENTS_BAD"); 131 return CKR_ARGUMENTS_BAD; 132 }; 133 let mechanisms_len: CK_ULONG = mechanisms.len().try_into().unwrap(); 134 if !pMechanismList.is_null() { 135 if unsafe { *pulCount } < mechanisms_len { 136 log_with_thread_id!(error, "C_GetMechanismList: CKR_ARGUMENTS_BAD"); 137 return CKR_ARGUMENTS_BAD; 138 } 139 unsafe { 140 std::ptr::copy_nonoverlapping( 141 mechanisms.as_ptr(), 142 pMechanismList, 143 mechanisms.len(), 144 ); 145 } 146 } 147 unsafe { 148 *pulCount = mechanisms_len; 149 } 150 log_with_thread_id!(debug, "C_GetMechanismList: CKR_OK"); 151 CKR_OK 152 } 153 }; 154 } 155 156 #[macro_export] 157 macro_rules! declare_pkcs11_session_functions { 158 () => { 159 extern "C" fn C_OpenSession( 160 slotID: CK_SLOT_ID, 161 _flags: CK_FLAGS, 162 _pApplication: CK_VOID_PTR, 163 _Notify: CK_NOTIFY, 164 phSession: CK_SESSION_HANDLE_PTR, 165 ) -> CK_RV { 166 if phSession.is_null() { 167 log_with_thread_id!(error, "C_OpenSession: CKR_ARGUMENTS_BAD"); 168 return CKR_ARGUMENTS_BAD; 169 } 170 let mut manager_guard = try_to_get_manager_guard!(); 171 let manager = manager_guard_to_manager!(manager_guard); 172 let session_handle = match manager.open_session(slotID) { 173 Ok(session_handle) => session_handle, 174 Err(e) => { 175 log_with_thread_id!(error, "C_OpenSession: open_session failed: {}", e); 176 return CKR_DEVICE_ERROR; 177 } 178 }; 179 unsafe { 180 *phSession = session_handle; 181 } 182 log_with_thread_id!(debug, "C_OpenSession: CKR_OK"); 183 CKR_OK 184 } 185 186 extern "C" fn C_CloseSession(hSession: CK_SESSION_HANDLE) -> CK_RV { 187 let mut manager_guard = try_to_get_manager_guard!(); 188 let manager = manager_guard_to_manager!(manager_guard); 189 if manager.close_session(hSession).is_err() { 190 log_with_thread_id!(error, "C_CloseSession: CKR_SESSION_HANDLE_INVALID"); 191 return CKR_SESSION_HANDLE_INVALID; 192 } 193 log_with_thread_id!(debug, "C_CloseSession: CKR_OK"); 194 CKR_OK 195 } 196 197 extern "C" fn C_CloseAllSessions(slotID: CK_SLOT_ID) -> CK_RV { 198 let mut manager_guard = try_to_get_manager_guard!(); 199 let manager = manager_guard_to_manager!(manager_guard); 200 match manager.close_all_sessions(slotID) { 201 Ok(()) => { 202 log_with_thread_id!(debug, "C_CloseAllSessions: CKR_OK"); 203 CKR_OK 204 } 205 Err(e) => { 206 log_with_thread_id!( 207 error, 208 "C_CloseAllSessions: close_all_sessions failed: {}", 209 e 210 ); 211 CKR_DEVICE_ERROR 212 } 213 } 214 } 215 216 extern "C" fn C_GetSessionInfo( 217 hSession: CK_SESSION_HANDLE, 218 pInfo: CK_SESSION_INFO_PTR, 219 ) -> CK_RV { 220 if pInfo.is_null() { 221 log_with_thread_id!(error, "C_GetSessionInfo: CKR_ARGUMENTS_BAD"); 222 return CKR_ARGUMENTS_BAD; 223 } 224 let mut manager_guard = try_to_get_manager_guard!(); 225 let manager = manager_guard_to_manager!(manager_guard); 226 let Ok(session_info) = manager.get_session_info(hSession) else { 227 log_with_thread_id!(error, "C_GetSessionInfo: CKR_ARGUMENTS_BAD"); 228 return CKR_ARGUMENTS_BAD; 229 }; 230 unsafe { 231 *pInfo = session_info; 232 } 233 log_with_thread_id!(debug, "C_GetSessionInfo: CKR_OK"); 234 CKR_OK 235 } 236 237 extern "C" fn C_Login( 238 hSession: CK_SESSION_HANDLE, 239 _userType: CK_USER_TYPE, 240 _pPin: CK_UTF8CHAR_PTR, 241 _ulPinLen: CK_ULONG, 242 ) -> CK_RV { 243 let mut manager_guard = try_to_get_manager_guard!(); 244 let manager = manager_guard_to_manager!(manager_guard); 245 match manager.login(hSession) { 246 Ok(()) => { 247 log_with_thread_id!(debug, "C_Login: CKR_OK"); 248 CKR_OK 249 } 250 Err(e) => { 251 log_with_thread_id!(error, "C_Login failed: {}", e); 252 CKR_GENERAL_ERROR 253 } 254 } 255 } 256 257 extern "C" fn C_Logout(hSession: CK_SESSION_HANDLE) -> CK_RV { 258 let mut manager_guard = try_to_get_manager_guard!(); 259 let manager = manager_guard_to_manager!(manager_guard); 260 match manager.logout(hSession) { 261 Ok(()) => { 262 log_with_thread_id!(debug, "C_Logout: CKR_OK"); 263 CKR_OK 264 } 265 Err(e) => { 266 log_with_thread_id!(error, "C_Logout failed: {}", e); 267 CKR_GENERAL_ERROR 268 } 269 } 270 } 271 }; 272 } 273 274 #[macro_export] 275 macro_rules! declare_pkcs11_find_functions { 276 () => { 277 fn trace_attr(prefix: &str, attr: &CK_ATTRIBUTE) { 278 // Copying out the fields of `attr` avoids making a reference to an unaligned field. 279 let typ = attr.type_; 280 let typ = match typ { 281 CKA_CLASS => "CKA_CLASS".to_string(), 282 CKA_TOKEN => "CKA_TOKEN".to_string(), 283 CKA_LABEL => "CKA_LABEL".to_string(), 284 CKA_ID => "CKA_ID".to_string(), 285 CKA_VALUE => "CKA_VALUE".to_string(), 286 CKA_ISSUER => "CKA_ISSUER".to_string(), 287 CKA_SERIAL_NUMBER => "CKA_SERIAL_NUMBER".to_string(), 288 CKA_SUBJECT => "CKA_SUBJECT".to_string(), 289 CKA_PRIVATE => "CKA_PRIVATE".to_string(), 290 CKA_KEY_TYPE => "CKA_KEY_TYPE".to_string(), 291 CKA_MODULUS => "CKA_MODULUS".to_string(), 292 CKA_EC_PARAMS => "CKA_EC_PARAMS".to_string(), 293 _ => format!("0x{:x}", typ), 294 }; 295 let value = 296 unsafe { std::slice::from_raw_parts(attr.pValue as *const u8, attr.ulValueLen as usize) }; 297 let len = attr.ulValueLen; 298 log_with_thread_id!( 299 trace, 300 "{}CK_ATTRIBUTE {{ type: {}, pValue: {:?}, ulValueLen: {} }}", 301 prefix, 302 typ, 303 value, 304 len 305 ); 306 } 307 308 const RELEVANT_ATTRIBUTES: &[CK_ATTRIBUTE_TYPE] = &[ 309 CKA_CLASS, 310 CKA_EC_PARAMS, 311 CKA_ID, 312 CKA_ISSUER, 313 CKA_KEY_TYPE, 314 CKA_LABEL, 315 CKA_MODULUS, 316 CKA_PRIVATE, 317 CKA_SERIAL_NUMBER, 318 CKA_SUBJECT, 319 CKA_TOKEN, 320 CKA_VALUE, 321 ]; 322 323 /// This gets called to initialize a search for objects matching a given list of attributes. 324 extern "C" fn C_FindObjectsInit( 325 hSession: CK_SESSION_HANDLE, 326 pTemplate: CK_ATTRIBUTE_PTR, 327 ulCount: CK_ULONG, 328 ) -> CK_RV { 329 if pTemplate.is_null() { 330 log_with_thread_id!(error, "C_FindObjectsInit: CKR_ARGUMENTS_BAD"); 331 return CKR_ARGUMENTS_BAD; 332 } 333 let mut attrs = Vec::new(); 334 log_with_thread_id!(trace, "C_FindObjectsInit:"); 335 for i in 0..ulCount as usize { 336 let attr = unsafe { &*pTemplate.add(i) }; 337 trace_attr(" ", attr); 338 // Copy out the attribute type to avoid making a reference to an unaligned field. 339 let attr_type = attr.type_; 340 if !RELEVANT_ATTRIBUTES.contains(&attr_type) { 341 log_with_thread_id!( 342 debug, 343 "C_FindObjectsInit: irrelevant attribute, returning CKR_ATTRIBUTE_TYPE_INVALID" 344 ); 345 return CKR_ATTRIBUTE_TYPE_INVALID; 346 } 347 let slice = unsafe { 348 std::slice::from_raw_parts(attr.pValue as *const u8, attr.ulValueLen as usize) 349 }; 350 attrs.push((attr_type, slice.to_owned())); 351 } 352 let mut manager_guard = try_to_get_manager_guard!(); 353 let manager = manager_guard_to_manager!(manager_guard); 354 match manager.start_search(hSession, attrs) { 355 Ok(()) => {} 356 Err(e) => { 357 log_with_thread_id!(error, "C_FindObjectsInit: CKR_ARGUMENTS_BAD: {}", e); 358 return CKR_ARGUMENTS_BAD; 359 } 360 } 361 log_with_thread_id!(debug, "C_FindObjectsInit: CKR_OK"); 362 CKR_OK 363 } 364 365 /// This gets called after `C_FindObjectsInit` to get the results of a search. 366 extern "C" fn C_FindObjects( 367 hSession: CK_SESSION_HANDLE, 368 phObject: CK_OBJECT_HANDLE_PTR, 369 ulMaxObjectCount: CK_ULONG, 370 pulObjectCount: CK_ULONG_PTR, 371 ) -> CK_RV { 372 if phObject.is_null() || pulObjectCount.is_null() || ulMaxObjectCount == 0 { 373 log_with_thread_id!(error, "C_FindObjects: CKR_ARGUMENTS_BAD"); 374 return CKR_ARGUMENTS_BAD; 375 } 376 let mut manager_guard = try_to_get_manager_guard!(); 377 let manager = manager_guard_to_manager!(manager_guard); 378 let handles = match manager.search(hSession, ulMaxObjectCount as usize) { 379 Ok(handles) => handles, 380 Err(e) => { 381 log_with_thread_id!(error, "C_FindObjects: CKR_ARGUMENTS_BAD: {}", e); 382 return CKR_ARGUMENTS_BAD; 383 } 384 }; 385 log_with_thread_id!(debug, "C_FindObjects: found handles {:?}", handles); 386 if handles.len() > ulMaxObjectCount as usize { 387 log_with_thread_id!(error, "C_FindObjects: manager returned too many handles"); 388 return CKR_DEVICE_ERROR; 389 } 390 unsafe { 391 *pulObjectCount = handles.len() as CK_ULONG; 392 } 393 for (index, handle) in handles.iter().enumerate() { 394 if index < ulMaxObjectCount as usize { 395 unsafe { 396 *(phObject.add(index)) = *handle; 397 } 398 } 399 } 400 log_with_thread_id!(debug, "C_FindObjects: CKR_OK"); 401 CKR_OK 402 } 403 404 /// This gets called after `C_FindObjectsInit` and `C_FindObjects` to finish a search. 405 extern "C" fn C_FindObjectsFinal(hSession: CK_SESSION_HANDLE) -> CK_RV { 406 let mut manager_guard = try_to_get_manager_guard!(); 407 let manager = manager_guard_to_manager!(manager_guard); 408 // It would be an error if there were no search for this session, but we can be permissive here. 409 match manager.clear_search(hSession) { 410 Ok(()) => { 411 log_with_thread_id!(debug, "C_FindObjectsFinal: CKR_OK"); 412 CKR_OK 413 } 414 Err(e) => { 415 log_with_thread_id!(error, "C_FindObjectsFinal: clear_search failed: {}", e); 416 CKR_DEVICE_ERROR 417 } 418 } 419 } 420 421 /// This gets called to obtain the values of a number of attributes of an object identified 422 /// by the given handle. If a specified attribute is not defined on the object, the length 423 /// of that attribute is set to CK_UNAVAILABLE_INFORMATION to indicate that it is not 424 /// available. This gets called twice: once to obtain the lengths of the attributes and 425 /// again to get the values. 426 extern "C" fn C_GetAttributeValue( 427 hSession: CK_SESSION_HANDLE, 428 hObject: CK_OBJECT_HANDLE, 429 pTemplate: CK_ATTRIBUTE_PTR, 430 ulCount: CK_ULONG, 431 ) -> CK_RV { 432 if pTemplate.is_null() { 433 log_with_thread_id!(error, "C_GetAttributeValue: CKR_ARGUMENTS_BAD"); 434 return CKR_ARGUMENTS_BAD; 435 } 436 let mut attr_types = Vec::with_capacity(ulCount as usize); 437 for i in 0..ulCount as usize { 438 let attr = unsafe { &*pTemplate.add(i) }; 439 attr_types.push(attr.type_); 440 } 441 let mut manager_guard = try_to_get_manager_guard!(); 442 let manager = manager_guard_to_manager!(manager_guard); 443 let values = match manager.get_attributes(hSession, hObject, attr_types) { 444 Ok(values) => values, 445 Err(e) => { 446 log_with_thread_id!(error, "C_GetAttributeValue: CKR_ARGUMENTS_BAD ({})", e); 447 return CKR_ARGUMENTS_BAD; 448 } 449 }; 450 if values.len() != ulCount as usize { 451 log_with_thread_id!( 452 error, 453 "C_GetAttributeValue: manager.get_attributes didn't return the right number of values" 454 ); 455 return CKR_DEVICE_ERROR; 456 } 457 for (i, value) in values.iter().enumerate().take(ulCount as usize) { 458 let attr = unsafe { &mut *pTemplate.add(i) }; 459 if let Some(attr_value) = value { 460 if attr.pValue.is_null() { 461 attr.ulValueLen = attr_value.len() as CK_ULONG; 462 } else { 463 let ptr: *mut u8 = attr.pValue as *mut u8; 464 if attr_value.len() != attr.ulValueLen as usize { 465 log_with_thread_id!(error, "C_GetAttributeValue: incorrect attr size"); 466 return CKR_ARGUMENTS_BAD; 467 } 468 unsafe { 469 std::ptr::copy_nonoverlapping(attr_value.as_ptr(), ptr, attr_value.len()); 470 } 471 } 472 } else { 473 attr.ulValueLen = CK_UNAVAILABLE_INFORMATION; 474 } 475 } 476 log_with_thread_id!(debug, "C_GetAttributeValue: CKR_OK"); 477 CKR_OK 478 } 479 480 }; 481 } 482 483 #[macro_export] 484 macro_rules! declare_pkcs11_sign_functions { 485 () => { 486 /// This gets called to set up a sign operation. 487 extern "C" fn C_SignInit( 488 hSession: CK_SESSION_HANDLE, 489 pMechanism: CK_MECHANISM_PTR, 490 hKey: CK_OBJECT_HANDLE, 491 ) -> CK_RV { 492 if pMechanism.is_null() { 493 log_with_thread_id!(error, "C_SignInit: CKR_ARGUMENTS_BAD"); 494 return CKR_ARGUMENTS_BAD; 495 } 496 // Presumably we should validate the mechanism against hKey, but the specification 497 // doesn't actually seem to require this. 498 let mechanism = unsafe { *pMechanism }; 499 log_with_thread_id!(debug, "C_SignInit: mechanism is {:?}", mechanism); 500 let mechanism_params = if mechanism.mechanism == CKM_RSA_PKCS_PSS { 501 if mechanism.ulParameterLen as usize 502 != std::mem::size_of::<CK_RSA_PKCS_PSS_PARAMS>() 503 { 504 let len = mechanism.ulParameterLen; 505 log_with_thread_id!( 506 error, 507 "C_SignInit: bad ulParameterLen for CKM_RSA_PKCS_PSS: {}", 508 len 509 ); 510 return CKR_ARGUMENTS_BAD; 511 } 512 Some(unsafe { *(mechanism.pParameter as *const CK_RSA_PKCS_PSS_PARAMS) }) 513 } else { 514 None 515 }; 516 let mut manager_guard = try_to_get_manager_guard!(); 517 let manager = manager_guard_to_manager!(manager_guard); 518 match manager.start_sign(hSession, hKey, mechanism_params) { 519 Ok(()) => {} 520 Err(e) => { 521 log_with_thread_id!(error, "C_SignInit: CKR_GENERAL_ERROR: {}", e); 522 return CKR_GENERAL_ERROR; 523 } 524 }; 525 log_with_thread_id!(debug, "C_SignInit: CKR_OK"); 526 CKR_OK 527 } 528 529 /// NSS calls this after `C_SignInit` (there are more ways in the PKCS #11 specification to 530 /// sign data, but this is the only way supported by these modules). 531 extern "C" fn C_Sign( 532 hSession: CK_SESSION_HANDLE, 533 pData: CK_BYTE_PTR, 534 ulDataLen: CK_ULONG, 535 pSignature: CK_BYTE_PTR, 536 pulSignatureLen: CK_ULONG_PTR, 537 ) -> CK_RV { 538 if pData.is_null() || pulSignatureLen.is_null() { 539 log_with_thread_id!(error, "C_Sign: CKR_ARGUMENTS_BAD"); 540 return CKR_ARGUMENTS_BAD; 541 } 542 let data = unsafe { std::slice::from_raw_parts(pData, ulDataLen as usize) }; 543 if pSignature.is_null() { 544 let mut manager_guard = try_to_get_manager_guard!(); 545 let manager = manager_guard_to_manager!(manager_guard); 546 match manager.get_signature_length(hSession, data.to_vec()) { 547 Ok(signature_length) => unsafe { 548 *pulSignatureLen = signature_length as CK_ULONG; 549 }, 550 Err(e) => { 551 log_with_thread_id!(error, "C_Sign: get_signature_length failed: {}", e); 552 return CKR_GENERAL_ERROR; 553 } 554 } 555 } else { 556 let mut manager_guard = try_to_get_manager_guard!(); 557 let manager = manager_guard_to_manager!(manager_guard); 558 match manager.sign(hSession, data.to_vec()) { 559 Ok(signature) => { 560 let signature_capacity = unsafe { *pulSignatureLen } as usize; 561 if signature_capacity < signature.len() { 562 log_with_thread_id!(error, "C_Sign: CKR_ARGUMENTS_BAD"); 563 return CKR_ARGUMENTS_BAD; 564 } 565 let ptr: *mut u8 = pSignature as *mut u8; 566 unsafe { 567 std::ptr::copy_nonoverlapping(signature.as_ptr(), ptr, signature.len()); 568 *pulSignatureLen = signature.len() as CK_ULONG; 569 } 570 } 571 Err(e) => { 572 log_with_thread_id!(error, "C_Sign: sign failed: {}", e); 573 return CKR_GENERAL_ERROR; 574 } 575 } 576 } 577 log_with_thread_id!(debug, "C_Sign: CKR_OK"); 578 CKR_OK 579 } 580 }; 581 } 582 583 #[macro_export] 584 macro_rules! declare_unsupported_pkcs11_functions { 585 () => { 586 extern "C" fn C_GetMechanismInfo( 587 _slotID: CK_SLOT_ID, 588 _type: CK_MECHANISM_TYPE, 589 _pInfo: CK_MECHANISM_INFO_PTR, 590 ) -> CK_RV { 591 log_with_thread_id!(error, "C_GetMechanismInfo: CKR_FUNCTION_NOT_SUPPORTED"); 592 CKR_FUNCTION_NOT_SUPPORTED 593 } 594 595 extern "C" fn C_InitToken( 596 _slotID: CK_SLOT_ID, 597 _pPin: CK_UTF8CHAR_PTR, 598 _ulPinLen: CK_ULONG, 599 _pLabel: CK_UTF8CHAR_PTR, 600 ) -> CK_RV { 601 log_with_thread_id!(error, "C_InitToken: CKR_FUNCTION_NOT_SUPPORTED"); 602 CKR_FUNCTION_NOT_SUPPORTED 603 } 604 605 extern "C" fn C_InitPIN( 606 _hSession: CK_SESSION_HANDLE, 607 _pPin: CK_UTF8CHAR_PTR, 608 _ulPinLen: CK_ULONG, 609 ) -> CK_RV { 610 log_with_thread_id!(error, "C_InitPIN: CKR_FUNCTION_NOT_SUPPORTED"); 611 CKR_FUNCTION_NOT_SUPPORTED 612 } 613 614 extern "C" fn C_SetPIN( 615 _hSession: CK_SESSION_HANDLE, 616 _pOldPin: CK_UTF8CHAR_PTR, 617 _ulOldLen: CK_ULONG, 618 _pNewPin: CK_UTF8CHAR_PTR, 619 _ulNewLen: CK_ULONG, 620 ) -> CK_RV { 621 log_with_thread_id!(error, "C_SetPIN: CKR_FUNCTION_NOT_SUPPORTED"); 622 CKR_FUNCTION_NOT_SUPPORTED 623 } 624 625 extern "C" fn C_GetOperationState( 626 _hSession: CK_SESSION_HANDLE, 627 _pOperationState: CK_BYTE_PTR, 628 _pulOperationStateLen: CK_ULONG_PTR, 629 ) -> CK_RV { 630 log_with_thread_id!(error, "C_GetOperationState: CKR_FUNCTION_NOT_SUPPORTED"); 631 CKR_FUNCTION_NOT_SUPPORTED 632 } 633 634 extern "C" fn C_SetOperationState( 635 _hSession: CK_SESSION_HANDLE, 636 _pOperationState: CK_BYTE_PTR, 637 _ulOperationStateLen: CK_ULONG, 638 _hEncryptionKey: CK_OBJECT_HANDLE, 639 _hAuthenticationKey: CK_OBJECT_HANDLE, 640 ) -> CK_RV { 641 log_with_thread_id!(error, "C_SetOperationState: CKR_FUNCTION_NOT_SUPPORTED"); 642 CKR_FUNCTION_NOT_SUPPORTED 643 } 644 645 extern "C" fn C_CreateObject( 646 _hSession: CK_SESSION_HANDLE, 647 _pTemplate: CK_ATTRIBUTE_PTR, 648 _ulCount: CK_ULONG, 649 _phObject: CK_OBJECT_HANDLE_PTR, 650 ) -> CK_RV { 651 log_with_thread_id!(error, "C_InitPIN: CKR_FUNCTION_NOT_SUPPORTED"); 652 CKR_FUNCTION_NOT_SUPPORTED 653 } 654 655 extern "C" fn C_CopyObject( 656 _hSession: CK_SESSION_HANDLE, 657 _hObject: CK_OBJECT_HANDLE, 658 _pTemplate: CK_ATTRIBUTE_PTR, 659 _ulCount: CK_ULONG, 660 _phNewObject: CK_OBJECT_HANDLE_PTR, 661 ) -> CK_RV { 662 log_with_thread_id!(error, "C_CopyObject: CKR_FUNCTION_NOT_SUPPORTED"); 663 CKR_FUNCTION_NOT_SUPPORTED 664 } 665 666 extern "C" fn C_DestroyObject( 667 _hSession: CK_SESSION_HANDLE, 668 _hObject: CK_OBJECT_HANDLE, 669 ) -> CK_RV { 670 log_with_thread_id!(error, "C_DestroyObject: CKR_FUNCTION_NOT_SUPPORTED"); 671 CKR_FUNCTION_NOT_SUPPORTED 672 } 673 674 extern "C" fn C_GetObjectSize( 675 _hSession: CK_SESSION_HANDLE, 676 _hObject: CK_OBJECT_HANDLE, 677 _pulSize: CK_ULONG_PTR, 678 ) -> CK_RV { 679 log_with_thread_id!(error, "C_GetObjectSize: CKR_FUNCTION_NOT_SUPPORTED"); 680 CKR_FUNCTION_NOT_SUPPORTED 681 } 682 683 extern "C" fn C_SetAttributeValue( 684 _hSession: CK_SESSION_HANDLE, 685 _hObject: CK_OBJECT_HANDLE, 686 _pTemplate: CK_ATTRIBUTE_PTR, 687 _ulCount: CK_ULONG, 688 ) -> CK_RV { 689 log_with_thread_id!(error, "C_SetAttributeValue: CKR_FUNCTION_NOT_SUPPORTED"); 690 CKR_FUNCTION_NOT_SUPPORTED 691 } 692 693 extern "C" fn C_EncryptInit( 694 _hSession: CK_SESSION_HANDLE, 695 _pMechanism: CK_MECHANISM_PTR, 696 _hKey: CK_OBJECT_HANDLE, 697 ) -> CK_RV { 698 log_with_thread_id!(error, "C_EncryptInit: CKR_FUNCTION_NOT_SUPPORTED"); 699 CKR_FUNCTION_NOT_SUPPORTED 700 } 701 702 extern "C" fn C_Encrypt( 703 _hSession: CK_SESSION_HANDLE, 704 _pData: CK_BYTE_PTR, 705 _ulDataLen: CK_ULONG, 706 _pEncryptedData: CK_BYTE_PTR, 707 _pulEncryptedDataLen: CK_ULONG_PTR, 708 ) -> CK_RV { 709 log_with_thread_id!(error, "C_Encrypt: CKR_FUNCTION_NOT_SUPPORTED"); 710 CKR_FUNCTION_NOT_SUPPORTED 711 } 712 713 extern "C" fn C_EncryptUpdate( 714 _hSession: CK_SESSION_HANDLE, 715 _pPart: CK_BYTE_PTR, 716 _ulPartLen: CK_ULONG, 717 _pEncryptedPart: CK_BYTE_PTR, 718 _pulEncryptedPartLen: CK_ULONG_PTR, 719 ) -> CK_RV { 720 log_with_thread_id!(error, "C_EncryptUpdate: CKR_FUNCTION_NOT_SUPPORTED"); 721 CKR_FUNCTION_NOT_SUPPORTED 722 } 723 724 extern "C" fn C_EncryptFinal( 725 _hSession: CK_SESSION_HANDLE, 726 _pLastEncryptedPart: CK_BYTE_PTR, 727 _pulLastEncryptedPartLen: CK_ULONG_PTR, 728 ) -> CK_RV { 729 log_with_thread_id!(error, "C_EncryptFinal: CKR_FUNCTION_NOT_SUPPORTED"); 730 CKR_FUNCTION_NOT_SUPPORTED 731 } 732 733 extern "C" fn C_DecryptInit( 734 _hSession: CK_SESSION_HANDLE, 735 _pMechanism: CK_MECHANISM_PTR, 736 _hKey: CK_OBJECT_HANDLE, 737 ) -> CK_RV { 738 log_with_thread_id!(error, "C_DecryptInit: CKR_FUNCTION_NOT_SUPPORTED"); 739 CKR_FUNCTION_NOT_SUPPORTED 740 } 741 742 extern "C" fn C_Decrypt( 743 _hSession: CK_SESSION_HANDLE, 744 _pEncryptedData: CK_BYTE_PTR, 745 _ulEncryptedDataLen: CK_ULONG, 746 _pData: CK_BYTE_PTR, 747 _pulDataLen: CK_ULONG_PTR, 748 ) -> CK_RV { 749 log_with_thread_id!(error, "C_Decrypt: CKR_FUNCTION_NOT_SUPPORTED"); 750 CKR_FUNCTION_NOT_SUPPORTED 751 } 752 753 extern "C" fn C_DecryptUpdate( 754 _hSession: CK_SESSION_HANDLE, 755 _pEncryptedPart: CK_BYTE_PTR, 756 _ulEncryptedPartLen: CK_ULONG, 757 _pPart: CK_BYTE_PTR, 758 _pulPartLen: CK_ULONG_PTR, 759 ) -> CK_RV { 760 log_with_thread_id!(error, "C_DecryptUpdate: CKR_FUNCTION_NOT_SUPPORTED"); 761 CKR_FUNCTION_NOT_SUPPORTED 762 } 763 764 extern "C" fn C_DecryptFinal( 765 _hSession: CK_SESSION_HANDLE, 766 _pLastPart: CK_BYTE_PTR, 767 _pulLastPartLen: CK_ULONG_PTR, 768 ) -> CK_RV { 769 log_with_thread_id!(error, "C_DecryptFinal: CKR_FUNCTION_NOT_SUPPORTED"); 770 CKR_FUNCTION_NOT_SUPPORTED 771 } 772 773 extern "C" fn C_DigestInit( 774 _hSession: CK_SESSION_HANDLE, 775 _pMechanism: CK_MECHANISM_PTR, 776 ) -> CK_RV { 777 log_with_thread_id!(error, "C_DigestInit: CKR_FUNCTION_NOT_SUPPORTED"); 778 CKR_FUNCTION_NOT_SUPPORTED 779 } 780 781 extern "C" fn C_Digest( 782 _hSession: CK_SESSION_HANDLE, 783 _pData: CK_BYTE_PTR, 784 _ulDataLen: CK_ULONG, 785 _pDigest: CK_BYTE_PTR, 786 _pulDigestLen: CK_ULONG_PTR, 787 ) -> CK_RV { 788 log_with_thread_id!(error, "C_Digest: CKR_FUNCTION_NOT_SUPPORTED"); 789 CKR_FUNCTION_NOT_SUPPORTED 790 } 791 792 extern "C" fn C_DigestUpdate( 793 _hSession: CK_SESSION_HANDLE, 794 _pPart: CK_BYTE_PTR, 795 _ulPartLen: CK_ULONG, 796 ) -> CK_RV { 797 log_with_thread_id!(error, "C_DigestUpdate: CKR_FUNCTION_NOT_SUPPORTED"); 798 CKR_FUNCTION_NOT_SUPPORTED 799 } 800 801 extern "C" fn C_DigestKey(_hSession: CK_SESSION_HANDLE, _hKey: CK_OBJECT_HANDLE) -> CK_RV { 802 log_with_thread_id!(error, "C_DigestKey: CKR_FUNCTION_NOT_SUPPORTED"); 803 CKR_FUNCTION_NOT_SUPPORTED 804 } 805 806 extern "C" fn C_DigestFinal( 807 _hSession: CK_SESSION_HANDLE, 808 _pDigest: CK_BYTE_PTR, 809 _pulDigestLen: CK_ULONG_PTR, 810 ) -> CK_RV { 811 log_with_thread_id!(error, "C_DigestFinal: CKR_FUNCTION_NOT_SUPPORTED"); 812 CKR_FUNCTION_NOT_SUPPORTED 813 } 814 815 extern "C" fn C_SignUpdate( 816 _hSession: CK_SESSION_HANDLE, 817 _pPart: CK_BYTE_PTR, 818 _ulPartLen: CK_ULONG, 819 ) -> CK_RV { 820 log_with_thread_id!(error, "C_SignUpdate: CKR_FUNCTION_NOT_SUPPORTED"); 821 CKR_FUNCTION_NOT_SUPPORTED 822 } 823 824 extern "C" fn C_SignFinal( 825 _hSession: CK_SESSION_HANDLE, 826 _pSignature: CK_BYTE_PTR, 827 _pulSignatureLen: CK_ULONG_PTR, 828 ) -> CK_RV { 829 log_with_thread_id!(error, "C_SignFinal: CKR_FUNCTION_NOT_SUPPORTED"); 830 CKR_FUNCTION_NOT_SUPPORTED 831 } 832 833 extern "C" fn C_SignRecoverInit( 834 _hSession: CK_SESSION_HANDLE, 835 _pMechanism: CK_MECHANISM_PTR, 836 _hKey: CK_OBJECT_HANDLE, 837 ) -> CK_RV { 838 log_with_thread_id!(error, "C_SignRecoverInit: CKR_FUNCTION_NOT_SUPPORTED"); 839 CKR_FUNCTION_NOT_SUPPORTED 840 } 841 842 extern "C" fn C_SignRecover( 843 _hSession: CK_SESSION_HANDLE, 844 _pData: CK_BYTE_PTR, 845 _ulDataLen: CK_ULONG, 846 _pSignature: CK_BYTE_PTR, 847 _pulSignatureLen: CK_ULONG_PTR, 848 ) -> CK_RV { 849 log_with_thread_id!(error, "C_SignRecover: CKR_FUNCTION_NOT_SUPPORTED"); 850 CKR_FUNCTION_NOT_SUPPORTED 851 } 852 853 extern "C" fn C_VerifyInit( 854 _hSession: CK_SESSION_HANDLE, 855 _pMechanism: CK_MECHANISM_PTR, 856 _hKey: CK_OBJECT_HANDLE, 857 ) -> CK_RV { 858 log_with_thread_id!(error, "C_VerifyInit: CKR_FUNCTION_NOT_SUPPORTED"); 859 CKR_FUNCTION_NOT_SUPPORTED 860 } 861 862 extern "C" fn C_Verify( 863 _hSession: CK_SESSION_HANDLE, 864 _pData: CK_BYTE_PTR, 865 _ulDataLen: CK_ULONG, 866 _pSignature: CK_BYTE_PTR, 867 _ulSignatureLen: CK_ULONG, 868 ) -> CK_RV { 869 log_with_thread_id!(error, "C_Verify: CKR_FUNCTION_NOT_SUPPORTED"); 870 CKR_FUNCTION_NOT_SUPPORTED 871 } 872 873 extern "C" fn C_VerifyUpdate( 874 _hSession: CK_SESSION_HANDLE, 875 _pPart: CK_BYTE_PTR, 876 _ulPartLen: CK_ULONG, 877 ) -> CK_RV { 878 log_with_thread_id!(error, "C_VerifyUpdate: CKR_FUNCTION_NOT_SUPPORTED"); 879 CKR_FUNCTION_NOT_SUPPORTED 880 } 881 882 extern "C" fn C_VerifyFinal( 883 _hSession: CK_SESSION_HANDLE, 884 _pSignature: CK_BYTE_PTR, 885 _ulSignatureLen: CK_ULONG, 886 ) -> CK_RV { 887 log_with_thread_id!(error, "C_VerifyFinal: CKR_FUNCTION_NOT_SUPPORTED"); 888 CKR_FUNCTION_NOT_SUPPORTED 889 } 890 891 extern "C" fn C_VerifyRecoverInit( 892 _hSession: CK_SESSION_HANDLE, 893 _pMechanism: CK_MECHANISM_PTR, 894 _hKey: CK_OBJECT_HANDLE, 895 ) -> CK_RV { 896 log_with_thread_id!(error, "C_VerifyRecoverInit: CKR_FUNCTION_NOT_SUPPORTED"); 897 CKR_FUNCTION_NOT_SUPPORTED 898 } 899 900 extern "C" fn C_VerifyRecover( 901 _hSession: CK_SESSION_HANDLE, 902 _pSignature: CK_BYTE_PTR, 903 _ulSignatureLen: CK_ULONG, 904 _pData: CK_BYTE_PTR, 905 _pulDataLen: CK_ULONG_PTR, 906 ) -> CK_RV { 907 log_with_thread_id!(error, "C_VerifyRecover: CKR_FUNCTION_NOT_SUPPORTED"); 908 CKR_FUNCTION_NOT_SUPPORTED 909 } 910 911 extern "C" fn C_DigestEncryptUpdate( 912 _hSession: CK_SESSION_HANDLE, 913 _pPart: CK_BYTE_PTR, 914 _ulPartLen: CK_ULONG, 915 _pEncryptedPart: CK_BYTE_PTR, 916 _pulEncryptedPartLen: CK_ULONG_PTR, 917 ) -> CK_RV { 918 log_with_thread_id!(error, "C_DigestEncryptUpdate: CKR_FUNCTION_NOT_SUPPORTED"); 919 CKR_FUNCTION_NOT_SUPPORTED 920 } 921 922 extern "C" fn C_DecryptDigestUpdate( 923 _hSession: CK_SESSION_HANDLE, 924 _pEncryptedPart: CK_BYTE_PTR, 925 _ulEncryptedPartLen: CK_ULONG, 926 _pPart: CK_BYTE_PTR, 927 _pulPartLen: CK_ULONG_PTR, 928 ) -> CK_RV { 929 log_with_thread_id!(error, "C_DecryptDigestUpdate: CKR_FUNCTION_NOT_SUPPORTED"); 930 CKR_FUNCTION_NOT_SUPPORTED 931 } 932 933 extern "C" fn C_SignEncryptUpdate( 934 _hSession: CK_SESSION_HANDLE, 935 _pPart: CK_BYTE_PTR, 936 _ulPartLen: CK_ULONG, 937 _pEncryptedPart: CK_BYTE_PTR, 938 _pulEncryptedPartLen: CK_ULONG_PTR, 939 ) -> CK_RV { 940 log_with_thread_id!(error, "C_SignEncryptUpdate: CKR_FUNCTION_NOT_SUPPORTED"); 941 CKR_FUNCTION_NOT_SUPPORTED 942 } 943 944 extern "C" fn C_DecryptVerifyUpdate( 945 _hSession: CK_SESSION_HANDLE, 946 _pEncryptedPart: CK_BYTE_PTR, 947 _ulEncryptedPartLen: CK_ULONG, 948 _pPart: CK_BYTE_PTR, 949 _pulPartLen: CK_ULONG_PTR, 950 ) -> CK_RV { 951 log_with_thread_id!(error, "C_DecryptVerifyUpdate: CKR_FUNCTION_NOT_SUPPORTED"); 952 CKR_FUNCTION_NOT_SUPPORTED 953 } 954 955 extern "C" fn C_GenerateKey( 956 _hSession: CK_SESSION_HANDLE, 957 _pMechanism: CK_MECHANISM_PTR, 958 _pTemplate: CK_ATTRIBUTE_PTR, 959 _ulCount: CK_ULONG, 960 _phKey: CK_OBJECT_HANDLE_PTR, 961 ) -> CK_RV { 962 log_with_thread_id!(error, "C_GenerateKey: CKR_FUNCTION_NOT_SUPPORTED"); 963 CKR_FUNCTION_NOT_SUPPORTED 964 } 965 966 extern "C" fn C_GenerateKeyPair( 967 _hSession: CK_SESSION_HANDLE, 968 _pMechanism: CK_MECHANISM_PTR, 969 _pPublicKeyTemplate: CK_ATTRIBUTE_PTR, 970 _ulPublicKeyAttributeCount: CK_ULONG, 971 _pPrivateKeyTemplate: CK_ATTRIBUTE_PTR, 972 _ulPrivateKeyAttributeCount: CK_ULONG, 973 _phPublicKey: CK_OBJECT_HANDLE_PTR, 974 _phPrivateKey: CK_OBJECT_HANDLE_PTR, 975 ) -> CK_RV { 976 log_with_thread_id!(error, "C_GenerateKeyPair: CKR_FUNCTION_NOT_SUPPORTED"); 977 CKR_FUNCTION_NOT_SUPPORTED 978 } 979 980 extern "C" fn C_WrapKey( 981 _hSession: CK_SESSION_HANDLE, 982 _pMechanism: CK_MECHANISM_PTR, 983 _hWrappingKey: CK_OBJECT_HANDLE, 984 _hKey: CK_OBJECT_HANDLE, 985 _pWrappedKey: CK_BYTE_PTR, 986 _pulWrappedKeyLen: CK_ULONG_PTR, 987 ) -> CK_RV { 988 log_with_thread_id!(error, "C_WrapKey: CKR_FUNCTION_NOT_SUPPORTED"); 989 CKR_FUNCTION_NOT_SUPPORTED 990 } 991 992 extern "C" fn C_UnwrapKey( 993 _hSession: CK_SESSION_HANDLE, 994 _pMechanism: CK_MECHANISM_PTR, 995 _hUnwrappingKey: CK_OBJECT_HANDLE, 996 _pWrappedKey: CK_BYTE_PTR, 997 _ulWrappedKeyLen: CK_ULONG, 998 _pTemplate: CK_ATTRIBUTE_PTR, 999 _ulAttributeCount: CK_ULONG, 1000 _phKey: CK_OBJECT_HANDLE_PTR, 1001 ) -> CK_RV { 1002 log_with_thread_id!(error, "C_UnwrapKey: CKR_FUNCTION_NOT_SUPPORTED"); 1003 CKR_FUNCTION_NOT_SUPPORTED 1004 } 1005 1006 extern "C" fn C_DeriveKey( 1007 _hSession: CK_SESSION_HANDLE, 1008 _pMechanism: CK_MECHANISM_PTR, 1009 _hBaseKey: CK_OBJECT_HANDLE, 1010 _pTemplate: CK_ATTRIBUTE_PTR, 1011 _ulAttributeCount: CK_ULONG, 1012 _phKey: CK_OBJECT_HANDLE_PTR, 1013 ) -> CK_RV { 1014 log_with_thread_id!(error, "C_DeriveKey: CKR_FUNCTION_NOT_SUPPORTED"); 1015 CKR_FUNCTION_NOT_SUPPORTED 1016 } 1017 1018 extern "C" fn C_SeedRandom( 1019 _hSession: CK_SESSION_HANDLE, 1020 _pSeed: CK_BYTE_PTR, 1021 _ulSeedLen: CK_ULONG, 1022 ) -> CK_RV { 1023 log_with_thread_id!(error, "C_SeedRandom: CKR_FUNCTION_NOT_SUPPORTED"); 1024 CKR_FUNCTION_NOT_SUPPORTED 1025 } 1026 1027 extern "C" fn C_GenerateRandom( 1028 _hSession: CK_SESSION_HANDLE, 1029 _RandomData: CK_BYTE_PTR, 1030 _ulRandomLen: CK_ULONG, 1031 ) -> CK_RV { 1032 log_with_thread_id!(error, "C_GenerateRandom: CKR_FUNCTION_NOT_SUPPORTED"); 1033 CKR_FUNCTION_NOT_SUPPORTED 1034 } 1035 1036 extern "C" fn C_GetFunctionStatus(_hSession: CK_SESSION_HANDLE) -> CK_RV { 1037 log_with_thread_id!(error, "C_GetFunctionStatus: CKR_FUNCTION_NOT_SUPPORTED"); 1038 CKR_FUNCTION_NOT_SUPPORTED 1039 } 1040 1041 extern "C" fn C_CancelFunction(_hSession: CK_SESSION_HANDLE) -> CK_RV { 1042 log_with_thread_id!(error, "C_CancelFunction: CKR_FUNCTION_NOT_SUPPORTED"); 1043 CKR_FUNCTION_NOT_SUPPORTED 1044 } 1045 1046 extern "C" fn C_WaitForSlotEvent( 1047 _flags: CK_FLAGS, 1048 _pSlot: CK_SLOT_ID_PTR, 1049 _pRserved: CK_VOID_PTR, 1050 ) -> CK_RV { 1051 log_with_thread_id!(error, "C_WaitForSlotEvent: CKR_FUNCTION_NOT_SUPPORTED"); 1052 CKR_FUNCTION_NOT_SUPPORTED 1053 } 1054 }; 1055 }