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 #![allow(non_snake_case)]
7
8 extern crate byteorder;
9 #[cfg(target_os = "macos")]
10 #[macro_use]
11 extern crate core_foundation;
12 extern crate env_logger;
13 #[macro_use]
14 extern crate lazy_static;
15 #[cfg(target_os = "macos")]
16 extern crate libloading;
17 #[macro_use]
18 extern crate log;
19 extern crate pkcs11;
20 #[cfg(target_os = "macos")]
21 #[macro_use]
22 extern crate rental;
23 extern crate sha2;
24 #[cfg(target_os = "windows")]
25 extern crate winapi;
26
27 use pkcs11::types::*;
28 use std::sync::Mutex;
29 use std::thread;
30
31 mod manager;
32 #[macro_use]
33 mod util;
34 #[cfg(target_os = "macos")]
35 mod backend_macos;
36 #[cfg(target_os = "windows")]
37 mod backend_windows;
38
39 use manager::{ManagerProxy, SlotType};
40
41 lazy_static! {
42 /// The singleton `ManagerProxy` that handles state with respect to PKCS #11. Only one thread
43 /// may use it at a time, but there is no restriction on which threads may use it. However, as
44 /// OS APIs being used are not necessarily thread-safe (e.g. they may be using
45 /// thread-local-storage), the `ManagerProxy` forwards calls from any thread to a single thread
46 /// where the real `Manager` does the actual work.
47 static ref MANAGER_PROXY: Mutex<Option<ManagerProxy>> = Mutex::new(None);
48 }
49
50 // Obtaining a handle on the manager proxy is a two-step process. First the mutex must be locked,
51 // which (if successful), results in a mutex guard object. We must then get a mutable refence to the
52 // underlying manager proxy (if set - otherwise we return an error). This can't happen all in one
53 // macro without dropping a reference that needs to live long enough for this to be safe. In
54 // practice, this looks like:
55 // let mut manager_guard = try_to_get_manager_guard!();
56 // let manager = manager_guard_to_manager!(manager_guard);
57 macro_rules! try_to_get_manager_guard {
58 () => {
59 match MANAGER_PROXY.lock() {
60 Ok(maybe_manager_proxy) => maybe_manager_proxy,
61 Err(poison_error) => {
62 log_with_thread_id!(
63 error,
64 "previous thread panicked acquiring manager lock: {}",
65 poison_error
66 );
67 return CKR_DEVICE_ERROR;
68 }
69 }
70 };
71 }
72
73 macro_rules! manager_guard_to_manager {
74 ($manager_guard:ident) => {
75 match $manager_guard.as_mut() {
76 Some(manager_proxy) => manager_proxy,
77 None => {
78 log_with_thread_id!(error, "manager expected to be set, but it is not");
79 return CKR_DEVICE_ERROR;
80 }
81 }
82 };
83 }
84
85 // Helper macro to prefix log messages with the current thread ID.
86 macro_rules! log_with_thread_id {
87 ($log_level:ident, $($message:expr),*) => {
88 let message = format!($($message),*);
89 $log_level!("{:?} {}", thread::current().id(), message);
90 };
91 }
92
93 /// This gets called to initialize the module. For this implementation, this consists of
94 /// instantiating the `ManagerProxy`.
C_Initialize(_pInitArgs: CK_C_INITIALIZE_ARGS_PTR) -> CK_RV95 extern "C" fn C_Initialize(_pInitArgs: CK_C_INITIALIZE_ARGS_PTR) -> CK_RV {
96 // This will fail if this has already been called, but this isn't a problem because either way,
97 // logging has been initialized.
98 let _ = env_logger::try_init();
99 let mut manager_guard = try_to_get_manager_guard!();
100 let manager_proxy = match ManagerProxy::new() {
101 Ok(p) => p,
102 Err(()) => return CKR_DEVICE_ERROR,
103 };
104 match manager_guard.replace(manager_proxy) {
105 Some(_unexpected_previous_manager) => {
106 #[cfg(target_os = "macos")]
107 {
108 log_with_thread_id!(info, "C_Initialize: manager previously set (this is expected on macOS - replacing it)");
109 }
110 #[cfg(target_os = "windows")]
111 {
112 log_with_thread_id!(warn, "C_Initialize: manager unexpectedly previously set (bravely continuing by replacing it)");
113 }
114 }
115 None => {}
116 }
117 log_with_thread_id!(debug, "C_Initialize: CKR_OK");
118 CKR_OK
119 }
120
C_Finalize(_pReserved: CK_VOID_PTR) -> CK_RV121 extern "C" fn C_Finalize(_pReserved: CK_VOID_PTR) -> CK_RV {
122 let mut manager_guard = try_to_get_manager_guard!();
123 let manager = manager_guard_to_manager!(manager_guard);
124 match manager.stop() {
125 Ok(()) => {
126 log_with_thread_id!(debug, "C_Finalize: CKR_OK");
127 CKR_OK
128 }
129 Err(()) => {
130 log_with_thread_id!(error, "C_Finalize: CKR_DEVICE_ERROR");
131 CKR_DEVICE_ERROR
132 }
133 }
134 }
135
136 // The specification mandates that these strings be padded with spaces to the appropriate length.
137 // Since the length of fixed-size arrays in rust is part of the type, the compiler enforces that
138 // these byte strings are of the correct length.
139 const MANUFACTURER_ID_BYTES: &[u8; 32] = b"Mozilla Corporation ";
140 const LIBRARY_DESCRIPTION_BYTES: &[u8; 32] = b"OS Client Cert Module ";
141
142 /// This gets called to gather some information about the module. In particular, this implementation
143 /// supports (portions of) cryptoki (PKCS #11) version 2.2.
C_GetInfo(pInfo: CK_INFO_PTR) -> CK_RV144 extern "C" fn C_GetInfo(pInfo: CK_INFO_PTR) -> CK_RV {
145 if pInfo.is_null() {
146 log_with_thread_id!(error, "C_GetInfo: CKR_ARGUMENTS_BAD");
147 return CKR_ARGUMENTS_BAD;
148 }
149 log_with_thread_id!(debug, "C_GetInfo: CKR_OK");
150 let mut info = CK_INFO::default();
151 info.cryptokiVersion.major = 2;
152 info.cryptokiVersion.minor = 2;
153 info.manufacturerID = *MANUFACTURER_ID_BYTES;
154 info.libraryDescription = *LIBRARY_DESCRIPTION_BYTES;
155 unsafe {
156 *pInfo = info;
157 }
158 CKR_OK
159 }
160
161 /// This module has two slots.
162 const SLOT_COUNT: CK_ULONG = 2;
163 /// The slot with ID 1 supports modern mechanisms like RSA-PSS.
164 const SLOT_ID_MODERN: CK_SLOT_ID = 1;
165 /// The slot with ID 2 only supports legacy mechanisms.
166 const SLOT_ID_LEGACY: CK_SLOT_ID = 2;
167
168 /// This gets called twice: once with a null `pSlotList` to get the number of slots (returned via
169 /// `pulCount`) and a second time to get the ID for each slot.
C_GetSlotList( _tokenPresent: CK_BBOOL, pSlotList: CK_SLOT_ID_PTR, pulCount: CK_ULONG_PTR, ) -> CK_RV170 extern "C" fn C_GetSlotList(
171 _tokenPresent: CK_BBOOL,
172 pSlotList: CK_SLOT_ID_PTR,
173 pulCount: CK_ULONG_PTR,
174 ) -> CK_RV {
175 if pulCount.is_null() {
176 log_with_thread_id!(error, "C_GetSlotList: CKR_ARGUMENTS_BAD");
177 return CKR_ARGUMENTS_BAD;
178 }
179 if !pSlotList.is_null() {
180 if unsafe { *pulCount } < SLOT_COUNT {
181 log_with_thread_id!(error, "C_GetSlotList: CKR_BUFFER_TOO_SMALL");
182 return CKR_BUFFER_TOO_SMALL;
183 }
184 unsafe {
185 *pSlotList = SLOT_ID_MODERN;
186 *pSlotList.offset(1) = SLOT_ID_LEGACY;
187 }
188 };
189 unsafe {
190 *pulCount = SLOT_COUNT;
191 }
192 log_with_thread_id!(debug, "C_GetSlotList: CKR_OK");
193 CKR_OK
194 }
195
196 const SLOT_DESCRIPTION_MODERN_BYTES: &[u8; 64] =
197 b"OS Client Cert Slot (Modern) ";
198 const SLOT_DESCRIPTION_LEGACY_BYTES: &[u8; 64] =
199 b"OS Client Cert Slot (Legacy) ";
200
201 /// This gets called to obtain information about slots. In this implementation, the tokens are
202 /// always present in the slots.
C_GetSlotInfo(slotID: CK_SLOT_ID, pInfo: CK_SLOT_INFO_PTR) -> CK_RV203 extern "C" fn C_GetSlotInfo(slotID: CK_SLOT_ID, pInfo: CK_SLOT_INFO_PTR) -> CK_RV {
204 if (slotID != SLOT_ID_MODERN && slotID != SLOT_ID_LEGACY) || pInfo.is_null() {
205 log_with_thread_id!(error, "C_GetSlotInfo: CKR_ARGUMENTS_BAD");
206 return CKR_ARGUMENTS_BAD;
207 }
208 let description = if slotID == SLOT_ID_MODERN {
209 SLOT_DESCRIPTION_MODERN_BYTES
210 } else {
211 SLOT_DESCRIPTION_LEGACY_BYTES
212 };
213 let slot_info = CK_SLOT_INFO {
214 slotDescription: *description,
215 manufacturerID: *MANUFACTURER_ID_BYTES,
216 flags: CKF_TOKEN_PRESENT,
217 hardwareVersion: CK_VERSION::default(),
218 firmwareVersion: CK_VERSION::default(),
219 };
220 unsafe {
221 *pInfo = slot_info;
222 }
223 log_with_thread_id!(debug, "C_GetSlotInfo: CKR_OK");
224 CKR_OK
225 }
226
227 const TOKEN_LABEL_MODERN_BYTES: &[u8; 32] = b"OS Client Cert Token (Modern) ";
228 const TOKEN_LABEL_LEGACY_BYTES: &[u8; 32] = b"OS Client Cert Token (Legacy) ";
229 const TOKEN_MODEL_BYTES: &[u8; 16] = b"osclientcerts ";
230 const TOKEN_SERIAL_NUMBER_BYTES: &[u8; 16] = b"0000000000000000";
231
232 /// This gets called to obtain some information about tokens. This implementation has two slots,
233 /// so it has two tokens. This information is primarily for display purposes.
C_GetTokenInfo(slotID: CK_SLOT_ID, pInfo: CK_TOKEN_INFO_PTR) -> CK_RV234 extern "C" fn C_GetTokenInfo(slotID: CK_SLOT_ID, pInfo: CK_TOKEN_INFO_PTR) -> CK_RV {
235 if (slotID != SLOT_ID_MODERN && slotID != SLOT_ID_LEGACY) || pInfo.is_null() {
236 log_with_thread_id!(error, "C_GetTokenInfo: CKR_ARGUMENTS_BAD");
237 return CKR_ARGUMENTS_BAD;
238 }
239 let mut token_info = CK_TOKEN_INFO::default();
240 let label = if slotID == SLOT_ID_MODERN {
241 TOKEN_LABEL_MODERN_BYTES
242 } else {
243 TOKEN_LABEL_LEGACY_BYTES
244 };
245 token_info.label = *label;
246 token_info.manufacturerID = *MANUFACTURER_ID_BYTES;
247 token_info.model = *TOKEN_MODEL_BYTES;
248 token_info.serialNumber = *TOKEN_SERIAL_NUMBER_BYTES;
249 unsafe {
250 *pInfo = token_info;
251 }
252 log_with_thread_id!(debug, "C_GetTokenInfo: CKR_OK");
253 CKR_OK
254 }
255
256 /// This gets called to determine what mechanisms a slot supports. The modern slot supports ECDSA,
257 /// RSA PKCS, and RSA PSS. The legacy slot only supports RSA PKCS.
C_GetMechanismList( slotID: CK_SLOT_ID, pMechanismList: CK_MECHANISM_TYPE_PTR, pulCount: CK_ULONG_PTR, ) -> CK_RV258 extern "C" fn C_GetMechanismList(
259 slotID: CK_SLOT_ID,
260 pMechanismList: CK_MECHANISM_TYPE_PTR,
261 pulCount: CK_ULONG_PTR,
262 ) -> CK_RV {
263 if (slotID != SLOT_ID_MODERN && slotID != SLOT_ID_LEGACY) || pulCount.is_null() {
264 log_with_thread_id!(error, "C_GetMechanismList: CKR_ARGUMENTS_BAD");
265 return CKR_ARGUMENTS_BAD;
266 }
267 let mechanisms = if slotID == SLOT_ID_MODERN {
268 vec![CKM_ECDSA, CKM_RSA_PKCS, CKM_RSA_PKCS_PSS]
269 } else {
270 vec![CKM_RSA_PKCS]
271 };
272 if !pMechanismList.is_null() {
273 if unsafe { *pulCount as usize } < mechanisms.len() {
274 log_with_thread_id!(error, "C_GetMechanismList: CKR_ARGUMENTS_BAD");
275 return CKR_ARGUMENTS_BAD;
276 }
277 for i in 0..mechanisms.len() {
278 unsafe {
279 *pMechanismList.offset(i as isize) = mechanisms[i];
280 }
281 }
282 }
283 unsafe {
284 *pulCount = mechanisms.len() as CK_ULONG;
285 }
286 log_with_thread_id!(debug, "C_GetMechanismList: CKR_OK");
287 CKR_OK
288 }
289
C_GetMechanismInfo( _slotID: CK_SLOT_ID, _type: CK_MECHANISM_TYPE, _pInfo: CK_MECHANISM_INFO_PTR, ) -> CK_RV290 extern "C" fn C_GetMechanismInfo(
291 _slotID: CK_SLOT_ID,
292 _type: CK_MECHANISM_TYPE,
293 _pInfo: CK_MECHANISM_INFO_PTR,
294 ) -> CK_RV {
295 log_with_thread_id!(error, "C_GetMechanismInfo: CKR_FUNCTION_NOT_SUPPORTED");
296 CKR_FUNCTION_NOT_SUPPORTED
297 }
298
C_InitToken( _slotID: CK_SLOT_ID, _pPin: CK_UTF8CHAR_PTR, _ulPinLen: CK_ULONG, _pLabel: CK_UTF8CHAR_PTR, ) -> CK_RV299 extern "C" fn C_InitToken(
300 _slotID: CK_SLOT_ID,
301 _pPin: CK_UTF8CHAR_PTR,
302 _ulPinLen: CK_ULONG,
303 _pLabel: CK_UTF8CHAR_PTR,
304 ) -> CK_RV {
305 log_with_thread_id!(error, "C_InitToken: CKR_FUNCTION_NOT_SUPPORTED");
306 CKR_FUNCTION_NOT_SUPPORTED
307 }
308
C_InitPIN( _hSession: CK_SESSION_HANDLE, _pPin: CK_UTF8CHAR_PTR, _ulPinLen: CK_ULONG, ) -> CK_RV309 extern "C" fn C_InitPIN(
310 _hSession: CK_SESSION_HANDLE,
311 _pPin: CK_UTF8CHAR_PTR,
312 _ulPinLen: CK_ULONG,
313 ) -> CK_RV {
314 log_with_thread_id!(error, "C_InitPIN: CKR_FUNCTION_NOT_SUPPORTED");
315 CKR_FUNCTION_NOT_SUPPORTED
316 }
317
C_SetPIN( _hSession: CK_SESSION_HANDLE, _pOldPin: CK_UTF8CHAR_PTR, _ulOldLen: CK_ULONG, _pNewPin: CK_UTF8CHAR_PTR, _ulNewLen: CK_ULONG, ) -> CK_RV318 extern "C" fn C_SetPIN(
319 _hSession: CK_SESSION_HANDLE,
320 _pOldPin: CK_UTF8CHAR_PTR,
321 _ulOldLen: CK_ULONG,
322 _pNewPin: CK_UTF8CHAR_PTR,
323 _ulNewLen: CK_ULONG,
324 ) -> CK_RV {
325 log_with_thread_id!(error, "C_SetPIN: CKR_FUNCTION_NOT_SUPPORTED");
326 CKR_FUNCTION_NOT_SUPPORTED
327 }
328
329 /// This gets called to create a new session. This module defers to the `ManagerProxy` to implement
330 /// this.
C_OpenSession( slotID: CK_SLOT_ID, _flags: CK_FLAGS, _pApplication: CK_VOID_PTR, _Notify: CK_NOTIFY, phSession: CK_SESSION_HANDLE_PTR, ) -> CK_RV331 extern "C" fn C_OpenSession(
332 slotID: CK_SLOT_ID,
333 _flags: CK_FLAGS,
334 _pApplication: CK_VOID_PTR,
335 _Notify: CK_NOTIFY,
336 phSession: CK_SESSION_HANDLE_PTR,
337 ) -> CK_RV {
338 if (slotID != SLOT_ID_MODERN && slotID != SLOT_ID_LEGACY) || phSession.is_null() {
339 log_with_thread_id!(error, "C_OpenSession: CKR_ARGUMENTS_BAD");
340 return CKR_ARGUMENTS_BAD;
341 }
342 let mut manager_guard = try_to_get_manager_guard!();
343 let manager = manager_guard_to_manager!(manager_guard);
344 let slot_type = if slotID == SLOT_ID_MODERN {
345 SlotType::Modern
346 } else {
347 SlotType::Legacy
348 };
349 let session_handle = match manager.open_session(slot_type) {
350 Ok(session_handle) => session_handle,
351 Err(()) => {
352 log_with_thread_id!(error, "C_OpenSession: open_session failed");
353 return CKR_DEVICE_ERROR;
354 }
355 };
356 unsafe {
357 *phSession = session_handle;
358 }
359 log_with_thread_id!(debug, "C_OpenSession: CKR_OK");
360 CKR_OK
361 }
362
363 /// This gets called to close a session. This is handled by the `ManagerProxy`.
C_CloseSession(hSession: CK_SESSION_HANDLE) -> CK_RV364 extern "C" fn C_CloseSession(hSession: CK_SESSION_HANDLE) -> CK_RV {
365 let mut manager_guard = try_to_get_manager_guard!();
366 let manager = manager_guard_to_manager!(manager_guard);
367 if manager.close_session(hSession).is_err() {
368 log_with_thread_id!(error, "C_CloseSession: CKR_SESSION_HANDLE_INVALID");
369 return CKR_SESSION_HANDLE_INVALID;
370 }
371 log_with_thread_id!(debug, "C_CloseSession: CKR_OK");
372 CKR_OK
373 }
374
375 /// This gets called to close all open sessions at once. This is handled by the `ManagerProxy`.
C_CloseAllSessions(slotID: CK_SLOT_ID) -> CK_RV376 extern "C" fn C_CloseAllSessions(slotID: CK_SLOT_ID) -> CK_RV {
377 if slotID != SLOT_ID_MODERN && slotID != SLOT_ID_LEGACY {
378 log_with_thread_id!(error, "C_CloseAllSessions: CKR_ARGUMENTS_BAD");
379 return CKR_ARGUMENTS_BAD;
380 }
381 let mut manager_guard = try_to_get_manager_guard!();
382 let manager = manager_guard_to_manager!(manager_guard);
383 let slot_type = if slotID == SLOT_ID_MODERN {
384 SlotType::Modern
385 } else {
386 SlotType::Legacy
387 };
388 match manager.close_all_sessions(slot_type) {
389 Ok(()) => {
390 log_with_thread_id!(debug, "C_CloseAllSessions: CKR_OK");
391 CKR_OK
392 }
393 Err(()) => {
394 log_with_thread_id!(error, "C_CloseAllSessions: close_all_sessions failed");
395 CKR_DEVICE_ERROR
396 }
397 }
398 }
399
C_GetSessionInfo(_hSession: CK_SESSION_HANDLE, _pInfo: CK_SESSION_INFO_PTR) -> CK_RV400 extern "C" fn C_GetSessionInfo(_hSession: CK_SESSION_HANDLE, _pInfo: CK_SESSION_INFO_PTR) -> CK_RV {
401 log_with_thread_id!(error, "C_GetSessionInfo: CKR_FUNCTION_NOT_SUPPORTED");
402 CKR_FUNCTION_NOT_SUPPORTED
403 }
404
C_GetOperationState( _hSession: CK_SESSION_HANDLE, _pOperationState: CK_BYTE_PTR, _pulOperationStateLen: CK_ULONG_PTR, ) -> CK_RV405 extern "C" fn C_GetOperationState(
406 _hSession: CK_SESSION_HANDLE,
407 _pOperationState: CK_BYTE_PTR,
408 _pulOperationStateLen: CK_ULONG_PTR,
409 ) -> CK_RV {
410 log_with_thread_id!(error, "C_GetOperationState: CKR_FUNCTION_NOT_SUPPORTED");
411 CKR_FUNCTION_NOT_SUPPORTED
412 }
413
C_SetOperationState( _hSession: CK_SESSION_HANDLE, _pOperationState: CK_BYTE_PTR, _ulOperationStateLen: CK_ULONG, _hEncryptionKey: CK_OBJECT_HANDLE, _hAuthenticationKey: CK_OBJECT_HANDLE, ) -> CK_RV414 extern "C" fn C_SetOperationState(
415 _hSession: CK_SESSION_HANDLE,
416 _pOperationState: CK_BYTE_PTR,
417 _ulOperationStateLen: CK_ULONG,
418 _hEncryptionKey: CK_OBJECT_HANDLE,
419 _hAuthenticationKey: CK_OBJECT_HANDLE,
420 ) -> CK_RV {
421 log_with_thread_id!(error, "C_SetOperationState: CKR_FUNCTION_NOT_SUPPORTED");
422 CKR_FUNCTION_NOT_SUPPORTED
423 }
424
C_Login( _hSession: CK_SESSION_HANDLE, _userType: CK_USER_TYPE, _pPin: CK_UTF8CHAR_PTR, _ulPinLen: CK_ULONG, ) -> CK_RV425 extern "C" fn C_Login(
426 _hSession: CK_SESSION_HANDLE,
427 _userType: CK_USER_TYPE,
428 _pPin: CK_UTF8CHAR_PTR,
429 _ulPinLen: CK_ULONG,
430 ) -> CK_RV {
431 log_with_thread_id!(error, "C_Login: CKR_FUNCTION_NOT_SUPPORTED");
432 CKR_FUNCTION_NOT_SUPPORTED
433 }
434
435 /// This gets called to log out and drop any authenticated resources. Because this module does not
436 /// hold on to authenticated resources, this module "implements" this by doing nothing and
437 /// returning a success result.
C_Logout(_hSession: CK_SESSION_HANDLE) -> CK_RV438 extern "C" fn C_Logout(_hSession: CK_SESSION_HANDLE) -> CK_RV {
439 log_with_thread_id!(debug, "C_Logout: CKR_OK");
440 CKR_OK
441 }
442
C_CreateObject( _hSession: CK_SESSION_HANDLE, _pTemplate: CK_ATTRIBUTE_PTR, _ulCount: CK_ULONG, _phObject: CK_OBJECT_HANDLE_PTR, ) -> CK_RV443 extern "C" fn C_CreateObject(
444 _hSession: CK_SESSION_HANDLE,
445 _pTemplate: CK_ATTRIBUTE_PTR,
446 _ulCount: CK_ULONG,
447 _phObject: CK_OBJECT_HANDLE_PTR,
448 ) -> CK_RV {
449 log_with_thread_id!(error, "C_CreateObject: CKR_FUNCTION_NOT_SUPPORTED");
450 CKR_FUNCTION_NOT_SUPPORTED
451 }
452
C_CopyObject( _hSession: CK_SESSION_HANDLE, _hObject: CK_OBJECT_HANDLE, _pTemplate: CK_ATTRIBUTE_PTR, _ulCount: CK_ULONG, _phNewObject: CK_OBJECT_HANDLE_PTR, ) -> CK_RV453 extern "C" fn C_CopyObject(
454 _hSession: CK_SESSION_HANDLE,
455 _hObject: CK_OBJECT_HANDLE,
456 _pTemplate: CK_ATTRIBUTE_PTR,
457 _ulCount: CK_ULONG,
458 _phNewObject: CK_OBJECT_HANDLE_PTR,
459 ) -> CK_RV {
460 log_with_thread_id!(error, "C_CopyObject: CKR_FUNCTION_NOT_SUPPORTED");
461 CKR_FUNCTION_NOT_SUPPORTED
462 }
463
C_DestroyObject(_hSession: CK_SESSION_HANDLE, _hObject: CK_OBJECT_HANDLE) -> CK_RV464 extern "C" fn C_DestroyObject(_hSession: CK_SESSION_HANDLE, _hObject: CK_OBJECT_HANDLE) -> CK_RV {
465 log_with_thread_id!(error, "C_DestroyObject: CKR_FUNCTION_NOT_SUPPORTED");
466 CKR_FUNCTION_NOT_SUPPORTED
467 }
468
C_GetObjectSize( _hSession: CK_SESSION_HANDLE, _hObject: CK_OBJECT_HANDLE, _pulSize: CK_ULONG_PTR, ) -> CK_RV469 extern "C" fn C_GetObjectSize(
470 _hSession: CK_SESSION_HANDLE,
471 _hObject: CK_OBJECT_HANDLE,
472 _pulSize: CK_ULONG_PTR,
473 ) -> CK_RV {
474 log_with_thread_id!(error, "C_GetObjectSize: CKR_FUNCTION_NOT_SUPPORTED");
475 CKR_FUNCTION_NOT_SUPPORTED
476 }
477
478 /// This gets called to obtain the values of a number of attributes of an object identified by the
479 /// given handle. This module implements this by requesting that the `ManagerProxy` find the object
480 /// and attempt to get the value of each attribute. If a specified attribute is not defined on the
481 /// object, the length of that attribute is set to -1 to indicate that it is not available.
482 /// This gets called twice: once to obtain the lengths of the attributes and again to get the
483 /// values.
C_GetAttributeValue( _hSession: CK_SESSION_HANDLE, hObject: CK_OBJECT_HANDLE, pTemplate: CK_ATTRIBUTE_PTR, ulCount: CK_ULONG, ) -> CK_RV484 extern "C" fn C_GetAttributeValue(
485 _hSession: CK_SESSION_HANDLE,
486 hObject: CK_OBJECT_HANDLE,
487 pTemplate: CK_ATTRIBUTE_PTR,
488 ulCount: CK_ULONG,
489 ) -> CK_RV {
490 if pTemplate.is_null() {
491 log_with_thread_id!(error, "C_GetAttributeValue: CKR_ARGUMENTS_BAD");
492 return CKR_ARGUMENTS_BAD;
493 }
494 let mut attr_types = Vec::with_capacity(ulCount as usize);
495 for i in 0..ulCount {
496 let attr = unsafe { &*pTemplate.offset(i as isize) };
497 attr_types.push(attr.attrType);
498 }
499 let mut manager_guard = try_to_get_manager_guard!();
500 let manager = manager_guard_to_manager!(manager_guard);
501 let values = match manager.get_attributes(hObject, attr_types) {
502 Ok(values) => values,
503 Err(()) => {
504 log_with_thread_id!(error, "C_GetAttributeValue: CKR_ARGUMENTS_BAD");
505 return CKR_ARGUMENTS_BAD;
506 }
507 };
508 if values.len() != ulCount as usize {
509 log_with_thread_id!(
510 error,
511 "C_GetAttributeValue: manager.get_attributes didn't return the right number of values"
512 );
513 return CKR_DEVICE_ERROR;
514 }
515 for i in 0..ulCount as usize {
516 let mut attr = unsafe { &mut *pTemplate.offset(i as isize) };
517 // NB: the safety of this array access depends on the length check above
518 if let Some(attr_value) = &values[i] {
519 if attr.pValue.is_null() {
520 attr.ulValueLen = attr_value.len() as CK_ULONG;
521 } else {
522 let ptr: *mut u8 = attr.pValue as *mut u8;
523 if attr_value.len() != attr.ulValueLen as usize {
524 log_with_thread_id!(error, "C_GetAttributeValue: incorrect attr size");
525 return CKR_ARGUMENTS_BAD;
526 }
527 unsafe {
528 std::ptr::copy_nonoverlapping(attr_value.as_ptr(), ptr, attr_value.len());
529 }
530 }
531 } else {
532 attr.ulValueLen = (0 - 1) as CK_ULONG;
533 }
534 }
535 log_with_thread_id!(debug, "C_GetAttributeValue: CKR_OK");
536 CKR_OK
537 }
538
C_SetAttributeValue( _hSession: CK_SESSION_HANDLE, _hObject: CK_OBJECT_HANDLE, _pTemplate: CK_ATTRIBUTE_PTR, _ulCount: CK_ULONG, ) -> CK_RV539 extern "C" fn C_SetAttributeValue(
540 _hSession: CK_SESSION_HANDLE,
541 _hObject: CK_OBJECT_HANDLE,
542 _pTemplate: CK_ATTRIBUTE_PTR,
543 _ulCount: CK_ULONG,
544 ) -> CK_RV {
545 log_with_thread_id!(error, "C_SetAttributeValue: CKR_FUNCTION_NOT_SUPPORTED");
546 CKR_FUNCTION_NOT_SUPPORTED
547 }
548
trace_attr(prefix: &str, attr: &CK_ATTRIBUTE)549 fn trace_attr(prefix: &str, attr: &CK_ATTRIBUTE) {
550 let typ = match unsafe_packed_field_access!(attr.attrType) {
551 CKA_CLASS => "CKA_CLASS".to_string(),
552 CKA_TOKEN => "CKA_TOKEN".to_string(),
553 CKA_LABEL => "CKA_LABEL".to_string(),
554 CKA_ID => "CKA_ID".to_string(),
555 CKA_VALUE => "CKA_VALUE".to_string(),
556 CKA_ISSUER => "CKA_ISSUER".to_string(),
557 CKA_SERIAL_NUMBER => "CKA_SERIAL_NUMBER".to_string(),
558 CKA_SUBJECT => "CKA_SUBJECT".to_string(),
559 CKA_PRIVATE => "CKA_PRIVATE".to_string(),
560 CKA_KEY_TYPE => "CKA_KEY_TYPE".to_string(),
561 CKA_MODULUS => "CKA_MODULUS".to_string(),
562 CKA_EC_PARAMS => "CKA_EC_PARAMS".to_string(),
563 _ => format!("0x{:x}", unsafe_packed_field_access!(attr.attrType)),
564 };
565 let value =
566 unsafe { std::slice::from_raw_parts(attr.pValue as *const u8, attr.ulValueLen as usize) };
567 log_with_thread_id!(
568 trace,
569 "{}CK_ATTRIBUTE {{ attrType: {}, pValue: {:?}, ulValueLen: {} }}",
570 prefix,
571 typ,
572 value,
573 unsafe_packed_field_access!(attr.ulValueLen)
574 );
575 }
576
577 /// This gets called to initialize a search for objects matching a given list of attributes. This
578 /// module implements this by gathering the attributes and passing them to the `ManagerProxy` to
579 /// start the search.
C_FindObjectsInit( hSession: CK_SESSION_HANDLE, pTemplate: CK_ATTRIBUTE_PTR, ulCount: CK_ULONG, ) -> CK_RV580 extern "C" fn C_FindObjectsInit(
581 hSession: CK_SESSION_HANDLE,
582 pTemplate: CK_ATTRIBUTE_PTR,
583 ulCount: CK_ULONG,
584 ) -> CK_RV {
585 if pTemplate.is_null() {
586 log_with_thread_id!(error, "C_FindObjectsInit: CKR_ARGUMENTS_BAD");
587 return CKR_ARGUMENTS_BAD;
588 }
589 let mut attrs = Vec::new();
590 log_with_thread_id!(trace, "C_FindObjectsInit:");
591 for i in 0..ulCount {
592 let attr = unsafe { &*pTemplate.offset(i as isize) };
593 trace_attr(" ", &attr);
594 let slice = unsafe {
595 std::slice::from_raw_parts(attr.pValue as *const u8, attr.ulValueLen as usize)
596 };
597 attrs.push((attr.attrType, slice.to_owned()));
598 }
599 let mut manager_guard = try_to_get_manager_guard!();
600 let manager = manager_guard_to_manager!(manager_guard);
601 match manager.start_search(hSession, attrs) {
602 Ok(()) => {}
603 Err(()) => {
604 log_with_thread_id!(error, "C_FindObjectsInit: CKR_ARGUMENTS_BAD");
605 return CKR_ARGUMENTS_BAD;
606 }
607 }
608 log_with_thread_id!(debug, "C_FindObjectsInit: CKR_OK");
609 CKR_OK
610 }
611
612 /// This gets called after `C_FindObjectsInit` to get the results of a search. This module
613 /// implements this by looking up the search in the `ManagerProxy` and copying out the matching
614 /// object handles.
C_FindObjects( hSession: CK_SESSION_HANDLE, phObject: CK_OBJECT_HANDLE_PTR, ulMaxObjectCount: CK_ULONG, pulObjectCount: CK_ULONG_PTR, ) -> CK_RV615 extern "C" fn C_FindObjects(
616 hSession: CK_SESSION_HANDLE,
617 phObject: CK_OBJECT_HANDLE_PTR,
618 ulMaxObjectCount: CK_ULONG,
619 pulObjectCount: CK_ULONG_PTR,
620 ) -> CK_RV {
621 if phObject.is_null() || pulObjectCount.is_null() || ulMaxObjectCount == 0 {
622 log_with_thread_id!(error, "C_FindObjects: CKR_ARGUMENTS_BAD");
623 return CKR_ARGUMENTS_BAD;
624 }
625 let mut manager_guard = try_to_get_manager_guard!();
626 let manager = manager_guard_to_manager!(manager_guard);
627 let handles = match manager.search(hSession, ulMaxObjectCount as usize) {
628 Ok(handles) => handles,
629 Err(()) => {
630 log_with_thread_id!(error, "C_FindObjects: CKR_ARGUMENTS_BAD");
631 return CKR_ARGUMENTS_BAD;
632 }
633 };
634 log_with_thread_id!(debug, "C_FindObjects: found handles {:?}", handles);
635 if handles.len() > ulMaxObjectCount as usize {
636 log_with_thread_id!(error, "C_FindObjects: manager returned too many handles");
637 return CKR_DEVICE_ERROR;
638 }
639 unsafe {
640 *pulObjectCount = handles.len() as CK_ULONG;
641 }
642 for (index, handle) in handles.iter().enumerate() {
643 if index < ulMaxObjectCount as usize {
644 unsafe {
645 *(phObject.add(index)) = *handle;
646 }
647 }
648 }
649 log_with_thread_id!(debug, "C_FindObjects: CKR_OK");
650 CKR_OK
651 }
652
653 /// This gets called after `C_FindObjectsInit` and `C_FindObjects` to finish a search. The module
654 /// tells the `ManagerProxy` to clear the search.
C_FindObjectsFinal(hSession: CK_SESSION_HANDLE) -> CK_RV655 extern "C" fn C_FindObjectsFinal(hSession: CK_SESSION_HANDLE) -> CK_RV {
656 let mut manager_guard = try_to_get_manager_guard!();
657 let manager = manager_guard_to_manager!(manager_guard);
658 // It would be an error if there were no search for this session, but we can be permissive here.
659 match manager.clear_search(hSession) {
660 Ok(()) => {
661 log_with_thread_id!(debug, "C_FindObjectsFinal: CKR_OK");
662 CKR_OK
663 }
664 Err(()) => {
665 log_with_thread_id!(error, "C_FindObjectsFinal: clear_search failed");
666 CKR_DEVICE_ERROR
667 }
668 }
669 }
670
C_EncryptInit( _hSession: CK_SESSION_HANDLE, _pMechanism: CK_MECHANISM_PTR, _hKey: CK_OBJECT_HANDLE, ) -> CK_RV671 extern "C" fn C_EncryptInit(
672 _hSession: CK_SESSION_HANDLE,
673 _pMechanism: CK_MECHANISM_PTR,
674 _hKey: CK_OBJECT_HANDLE,
675 ) -> CK_RV {
676 log_with_thread_id!(error, "C_EncryptInit: CKR_FUNCTION_NOT_SUPPORTED");
677 CKR_FUNCTION_NOT_SUPPORTED
678 }
679
C_Encrypt( _hSession: CK_SESSION_HANDLE, _pData: CK_BYTE_PTR, _ulDataLen: CK_ULONG, _pEncryptedData: CK_BYTE_PTR, _pulEncryptedDataLen: CK_ULONG_PTR, ) -> CK_RV680 extern "C" fn C_Encrypt(
681 _hSession: CK_SESSION_HANDLE,
682 _pData: CK_BYTE_PTR,
683 _ulDataLen: CK_ULONG,
684 _pEncryptedData: CK_BYTE_PTR,
685 _pulEncryptedDataLen: CK_ULONG_PTR,
686 ) -> CK_RV {
687 log_with_thread_id!(error, "C_Encrypt: CKR_FUNCTION_NOT_SUPPORTED");
688 CKR_FUNCTION_NOT_SUPPORTED
689 }
690
C_EncryptUpdate( _hSession: CK_SESSION_HANDLE, _pPart: CK_BYTE_PTR, _ulPartLen: CK_ULONG, _pEncryptedPart: CK_BYTE_PTR, _pulEncryptedPartLen: CK_ULONG_PTR, ) -> CK_RV691 extern "C" fn C_EncryptUpdate(
692 _hSession: CK_SESSION_HANDLE,
693 _pPart: CK_BYTE_PTR,
694 _ulPartLen: CK_ULONG,
695 _pEncryptedPart: CK_BYTE_PTR,
696 _pulEncryptedPartLen: CK_ULONG_PTR,
697 ) -> CK_RV {
698 log_with_thread_id!(error, "C_EncryptUpdate: CKR_FUNCTION_NOT_SUPPORTED");
699 CKR_FUNCTION_NOT_SUPPORTED
700 }
701
C_EncryptFinal( _hSession: CK_SESSION_HANDLE, _pLastEncryptedPart: CK_BYTE_PTR, _pulLastEncryptedPartLen: CK_ULONG_PTR, ) -> CK_RV702 extern "C" fn C_EncryptFinal(
703 _hSession: CK_SESSION_HANDLE,
704 _pLastEncryptedPart: CK_BYTE_PTR,
705 _pulLastEncryptedPartLen: CK_ULONG_PTR,
706 ) -> CK_RV {
707 log_with_thread_id!(error, "C_EncryptFinal: CKR_FUNCTION_NOT_SUPPORTED");
708 CKR_FUNCTION_NOT_SUPPORTED
709 }
710
C_DecryptInit( _hSession: CK_SESSION_HANDLE, _pMechanism: CK_MECHANISM_PTR, _hKey: CK_OBJECT_HANDLE, ) -> CK_RV711 extern "C" fn C_DecryptInit(
712 _hSession: CK_SESSION_HANDLE,
713 _pMechanism: CK_MECHANISM_PTR,
714 _hKey: CK_OBJECT_HANDLE,
715 ) -> CK_RV {
716 log_with_thread_id!(error, "C_DecryptInit: CKR_FUNCTION_NOT_SUPPORTED");
717 CKR_FUNCTION_NOT_SUPPORTED
718 }
719
C_Decrypt( _hSession: CK_SESSION_HANDLE, _pEncryptedData: CK_BYTE_PTR, _ulEncryptedDataLen: CK_ULONG, _pData: CK_BYTE_PTR, _pulDataLen: CK_ULONG_PTR, ) -> CK_RV720 extern "C" fn C_Decrypt(
721 _hSession: CK_SESSION_HANDLE,
722 _pEncryptedData: CK_BYTE_PTR,
723 _ulEncryptedDataLen: CK_ULONG,
724 _pData: CK_BYTE_PTR,
725 _pulDataLen: CK_ULONG_PTR,
726 ) -> CK_RV {
727 log_with_thread_id!(error, "C_Decrypt: CKR_FUNCTION_NOT_SUPPORTED");
728 CKR_FUNCTION_NOT_SUPPORTED
729 }
730
C_DecryptUpdate( _hSession: CK_SESSION_HANDLE, _pEncryptedPart: CK_BYTE_PTR, _ulEncryptedPartLen: CK_ULONG, _pPart: CK_BYTE_PTR, _pulPartLen: CK_ULONG_PTR, ) -> CK_RV731 extern "C" fn C_DecryptUpdate(
732 _hSession: CK_SESSION_HANDLE,
733 _pEncryptedPart: CK_BYTE_PTR,
734 _ulEncryptedPartLen: CK_ULONG,
735 _pPart: CK_BYTE_PTR,
736 _pulPartLen: CK_ULONG_PTR,
737 ) -> CK_RV {
738 log_with_thread_id!(error, "C_DecryptUpdate: CKR_FUNCTION_NOT_SUPPORTED");
739 CKR_FUNCTION_NOT_SUPPORTED
740 }
741
C_DecryptFinal( _hSession: CK_SESSION_HANDLE, _pLastPart: CK_BYTE_PTR, _pulLastPartLen: CK_ULONG_PTR, ) -> CK_RV742 extern "C" fn C_DecryptFinal(
743 _hSession: CK_SESSION_HANDLE,
744 _pLastPart: CK_BYTE_PTR,
745 _pulLastPartLen: CK_ULONG_PTR,
746 ) -> CK_RV {
747 log_with_thread_id!(error, "C_DecryptFinal: CKR_FUNCTION_NOT_SUPPORTED");
748 CKR_FUNCTION_NOT_SUPPORTED
749 }
750
C_DigestInit(_hSession: CK_SESSION_HANDLE, _pMechanism: CK_MECHANISM_PTR) -> CK_RV751 extern "C" fn C_DigestInit(_hSession: CK_SESSION_HANDLE, _pMechanism: CK_MECHANISM_PTR) -> CK_RV {
752 log_with_thread_id!(error, "C_DigestInit: CKR_FUNCTION_NOT_SUPPORTED");
753 CKR_FUNCTION_NOT_SUPPORTED
754 }
755
C_Digest( _hSession: CK_SESSION_HANDLE, _pData: CK_BYTE_PTR, _ulDataLen: CK_ULONG, _pDigest: CK_BYTE_PTR, _pulDigestLen: CK_ULONG_PTR, ) -> CK_RV756 extern "C" fn C_Digest(
757 _hSession: CK_SESSION_HANDLE,
758 _pData: CK_BYTE_PTR,
759 _ulDataLen: CK_ULONG,
760 _pDigest: CK_BYTE_PTR,
761 _pulDigestLen: CK_ULONG_PTR,
762 ) -> CK_RV {
763 log_with_thread_id!(error, "C_Digest: CKR_FUNCTION_NOT_SUPPORTED");
764 CKR_FUNCTION_NOT_SUPPORTED
765 }
766
C_DigestUpdate( _hSession: CK_SESSION_HANDLE, _pPart: CK_BYTE_PTR, _ulPartLen: CK_ULONG, ) -> CK_RV767 extern "C" fn C_DigestUpdate(
768 _hSession: CK_SESSION_HANDLE,
769 _pPart: CK_BYTE_PTR,
770 _ulPartLen: CK_ULONG,
771 ) -> CK_RV {
772 log_with_thread_id!(error, "C_DigestUpdate: CKR_FUNCTION_NOT_SUPPORTED");
773 CKR_FUNCTION_NOT_SUPPORTED
774 }
775
C_DigestKey(_hSession: CK_SESSION_HANDLE, _hKey: CK_OBJECT_HANDLE) -> CK_RV776 extern "C" fn C_DigestKey(_hSession: CK_SESSION_HANDLE, _hKey: CK_OBJECT_HANDLE) -> CK_RV {
777 log_with_thread_id!(error, "C_DigestKey: CKR_FUNCTION_NOT_SUPPORTED");
778 CKR_FUNCTION_NOT_SUPPORTED
779 }
780
C_DigestFinal( _hSession: CK_SESSION_HANDLE, _pDigest: CK_BYTE_PTR, _pulDigestLen: CK_ULONG_PTR, ) -> CK_RV781 extern "C" fn C_DigestFinal(
782 _hSession: CK_SESSION_HANDLE,
783 _pDigest: CK_BYTE_PTR,
784 _pulDigestLen: CK_ULONG_PTR,
785 ) -> CK_RV {
786 log_with_thread_id!(error, "C_DigestFinal: CKR_FUNCTION_NOT_SUPPORTED");
787 CKR_FUNCTION_NOT_SUPPORTED
788 }
789
790 /// This gets called to set up a sign operation. The module essentially defers to the
791 /// `ManagerProxy`.
C_SignInit( hSession: CK_SESSION_HANDLE, pMechanism: CK_MECHANISM_PTR, hKey: CK_OBJECT_HANDLE, ) -> CK_RV792 extern "C" fn C_SignInit(
793 hSession: CK_SESSION_HANDLE,
794 pMechanism: CK_MECHANISM_PTR,
795 hKey: CK_OBJECT_HANDLE,
796 ) -> CK_RV {
797 if pMechanism.is_null() {
798 log_with_thread_id!(error, "C_SignInit: CKR_ARGUMENTS_BAD");
799 return CKR_ARGUMENTS_BAD;
800 }
801 // Presumably we should validate the mechanism against hKey, but the specification doesn't
802 // actually seem to require this.
803 let mechanism = unsafe { *pMechanism };
804 log_with_thread_id!(debug, "C_SignInit: mechanism is {:?}", mechanism);
805 let mechanism_params = if mechanism.mechanism == CKM_RSA_PKCS_PSS {
806 if mechanism.ulParameterLen as usize != std::mem::size_of::<CK_RSA_PKCS_PSS_PARAMS>() {
807 log_with_thread_id!(
808 error,
809 "C_SignInit: bad ulParameterLen for CKM_RSA_PKCS_PSS: {}",
810 unsafe_packed_field_access!(mechanism.ulParameterLen)
811 );
812 return CKR_ARGUMENTS_BAD;
813 }
814 Some(unsafe { *(mechanism.pParameter as *const CK_RSA_PKCS_PSS_PARAMS) })
815 } else {
816 None
817 };
818 let mut manager_guard = try_to_get_manager_guard!();
819 let manager = manager_guard_to_manager!(manager_guard);
820 match manager.start_sign(hSession, hKey, mechanism_params) {
821 Ok(()) => {}
822 Err(()) => {
823 log_with_thread_id!(error, "C_SignInit: CKR_GENERAL_ERROR");
824 return CKR_GENERAL_ERROR;
825 }
826 };
827 log_with_thread_id!(debug, "C_SignInit: CKR_OK");
828 CKR_OK
829 }
830
831 /// NSS calls this after `C_SignInit` (there are more ways in the PKCS #11 specification to sign
832 /// data, but this is the only way supported by this module). The module essentially defers to the
833 /// `ManagerProxy` and copies out the resulting signature.
C_Sign( hSession: CK_SESSION_HANDLE, pData: CK_BYTE_PTR, ulDataLen: CK_ULONG, pSignature: CK_BYTE_PTR, pulSignatureLen: CK_ULONG_PTR, ) -> CK_RV834 extern "C" fn C_Sign(
835 hSession: CK_SESSION_HANDLE,
836 pData: CK_BYTE_PTR,
837 ulDataLen: CK_ULONG,
838 pSignature: CK_BYTE_PTR,
839 pulSignatureLen: CK_ULONG_PTR,
840 ) -> CK_RV {
841 if pData.is_null() || pulSignatureLen.is_null() {
842 log_with_thread_id!(error, "C_Sign: CKR_ARGUMENTS_BAD");
843 return CKR_ARGUMENTS_BAD;
844 }
845 let data = unsafe { std::slice::from_raw_parts(pData, ulDataLen as usize) };
846 if pSignature.is_null() {
847 let mut manager_guard = try_to_get_manager_guard!();
848 let manager = manager_guard_to_manager!(manager_guard);
849 match manager.get_signature_length(hSession, data.to_vec()) {
850 Ok(signature_length) => unsafe {
851 *pulSignatureLen = signature_length as CK_ULONG;
852 },
853 Err(()) => {
854 log_with_thread_id!(error, "C_Sign: get_signature_length failed");
855 return CKR_GENERAL_ERROR;
856 }
857 }
858 } else {
859 let mut manager_guard = try_to_get_manager_guard!();
860 let manager = manager_guard_to_manager!(manager_guard);
861 match manager.sign(hSession, data.to_vec()) {
862 Ok(signature) => {
863 let signature_capacity = unsafe { *pulSignatureLen } as usize;
864 if signature_capacity < signature.len() {
865 log_with_thread_id!(error, "C_Sign: CKR_ARGUMENTS_BAD");
866 return CKR_ARGUMENTS_BAD;
867 }
868 let ptr: *mut u8 = pSignature as *mut u8;
869 unsafe {
870 std::ptr::copy_nonoverlapping(signature.as_ptr(), ptr, signature.len());
871 *pulSignatureLen = signature.len() as CK_ULONG;
872 }
873 }
874 Err(()) => {
875 log_with_thread_id!(error, "C_Sign: sign failed");
876 return CKR_GENERAL_ERROR;
877 }
878 }
879 }
880 log_with_thread_id!(debug, "C_Sign: CKR_OK");
881 CKR_OK
882 }
883
C_SignUpdate( _hSession: CK_SESSION_HANDLE, _pPart: CK_BYTE_PTR, _ulPartLen: CK_ULONG, ) -> CK_RV884 extern "C" fn C_SignUpdate(
885 _hSession: CK_SESSION_HANDLE,
886 _pPart: CK_BYTE_PTR,
887 _ulPartLen: CK_ULONG,
888 ) -> CK_RV {
889 log_with_thread_id!(error, "C_SignUpdate: CKR_FUNCTION_NOT_SUPPORTED");
890 CKR_FUNCTION_NOT_SUPPORTED
891 }
892
C_SignFinal( _hSession: CK_SESSION_HANDLE, _pSignature: CK_BYTE_PTR, _pulSignatureLen: CK_ULONG_PTR, ) -> CK_RV893 extern "C" fn C_SignFinal(
894 _hSession: CK_SESSION_HANDLE,
895 _pSignature: CK_BYTE_PTR,
896 _pulSignatureLen: CK_ULONG_PTR,
897 ) -> CK_RV {
898 log_with_thread_id!(error, "C_SignFinal: CKR_FUNCTION_NOT_SUPPORTED");
899 CKR_FUNCTION_NOT_SUPPORTED
900 }
901
C_SignRecoverInit( _hSession: CK_SESSION_HANDLE, _pMechanism: CK_MECHANISM_PTR, _hKey: CK_OBJECT_HANDLE, ) -> CK_RV902 extern "C" fn C_SignRecoverInit(
903 _hSession: CK_SESSION_HANDLE,
904 _pMechanism: CK_MECHANISM_PTR,
905 _hKey: CK_OBJECT_HANDLE,
906 ) -> CK_RV {
907 log_with_thread_id!(error, "C_SignRecoverInit: CKR_FUNCTION_NOT_SUPPORTED");
908 CKR_FUNCTION_NOT_SUPPORTED
909 }
910
C_SignRecover( _hSession: CK_SESSION_HANDLE, _pData: CK_BYTE_PTR, _ulDataLen: CK_ULONG, _pSignature: CK_BYTE_PTR, _pulSignatureLen: CK_ULONG_PTR, ) -> CK_RV911 extern "C" fn C_SignRecover(
912 _hSession: CK_SESSION_HANDLE,
913 _pData: CK_BYTE_PTR,
914 _ulDataLen: CK_ULONG,
915 _pSignature: CK_BYTE_PTR,
916 _pulSignatureLen: CK_ULONG_PTR,
917 ) -> CK_RV {
918 log_with_thread_id!(error, "C_SignRecover: CKR_FUNCTION_NOT_SUPPORTED");
919 CKR_FUNCTION_NOT_SUPPORTED
920 }
921
C_VerifyInit( _hSession: CK_SESSION_HANDLE, _pMechanism: CK_MECHANISM_PTR, _hKey: CK_OBJECT_HANDLE, ) -> CK_RV922 extern "C" fn C_VerifyInit(
923 _hSession: CK_SESSION_HANDLE,
924 _pMechanism: CK_MECHANISM_PTR,
925 _hKey: CK_OBJECT_HANDLE,
926 ) -> CK_RV {
927 log_with_thread_id!(error, "C_VerifyInit: CKR_FUNCTION_NOT_SUPPORTED");
928 CKR_FUNCTION_NOT_SUPPORTED
929 }
930
C_Verify( _hSession: CK_SESSION_HANDLE, _pData: CK_BYTE_PTR, _ulDataLen: CK_ULONG, _pSignature: CK_BYTE_PTR, _ulSignatureLen: CK_ULONG, ) -> CK_RV931 extern "C" fn C_Verify(
932 _hSession: CK_SESSION_HANDLE,
933 _pData: CK_BYTE_PTR,
934 _ulDataLen: CK_ULONG,
935 _pSignature: CK_BYTE_PTR,
936 _ulSignatureLen: CK_ULONG,
937 ) -> CK_RV {
938 log_with_thread_id!(error, "C_Verify: CKR_FUNCTION_NOT_SUPPORTED");
939 CKR_FUNCTION_NOT_SUPPORTED
940 }
941
C_VerifyUpdate( _hSession: CK_SESSION_HANDLE, _pPart: CK_BYTE_PTR, _ulPartLen: CK_ULONG, ) -> CK_RV942 extern "C" fn C_VerifyUpdate(
943 _hSession: CK_SESSION_HANDLE,
944 _pPart: CK_BYTE_PTR,
945 _ulPartLen: CK_ULONG,
946 ) -> CK_RV {
947 log_with_thread_id!(error, "C_VerifyUpdate: CKR_FUNCTION_NOT_SUPPORTED");
948 CKR_FUNCTION_NOT_SUPPORTED
949 }
950
C_VerifyFinal( _hSession: CK_SESSION_HANDLE, _pSignature: CK_BYTE_PTR, _ulSignatureLen: CK_ULONG, ) -> CK_RV951 extern "C" fn C_VerifyFinal(
952 _hSession: CK_SESSION_HANDLE,
953 _pSignature: CK_BYTE_PTR,
954 _ulSignatureLen: CK_ULONG,
955 ) -> CK_RV {
956 log_with_thread_id!(error, "C_VerifyFinal: CKR_FUNCTION_NOT_SUPPORTED");
957 CKR_FUNCTION_NOT_SUPPORTED
958 }
959
C_VerifyRecoverInit( _hSession: CK_SESSION_HANDLE, _pMechanism: CK_MECHANISM_PTR, _hKey: CK_OBJECT_HANDLE, ) -> CK_RV960 extern "C" fn C_VerifyRecoverInit(
961 _hSession: CK_SESSION_HANDLE,
962 _pMechanism: CK_MECHANISM_PTR,
963 _hKey: CK_OBJECT_HANDLE,
964 ) -> CK_RV {
965 log_with_thread_id!(error, "C_VerifyRecoverInit: CKR_FUNCTION_NOT_SUPPORTED");
966 CKR_FUNCTION_NOT_SUPPORTED
967 }
968
C_VerifyRecover( _hSession: CK_SESSION_HANDLE, _pSignature: CK_BYTE_PTR, _ulSignatureLen: CK_ULONG, _pData: CK_BYTE_PTR, _pulDataLen: CK_ULONG_PTR, ) -> CK_RV969 extern "C" fn C_VerifyRecover(
970 _hSession: CK_SESSION_HANDLE,
971 _pSignature: CK_BYTE_PTR,
972 _ulSignatureLen: CK_ULONG,
973 _pData: CK_BYTE_PTR,
974 _pulDataLen: CK_ULONG_PTR,
975 ) -> CK_RV {
976 log_with_thread_id!(error, "C_VerifyRecover: CKR_FUNCTION_NOT_SUPPORTED");
977 CKR_FUNCTION_NOT_SUPPORTED
978 }
979
C_DigestEncryptUpdate( _hSession: CK_SESSION_HANDLE, _pPart: CK_BYTE_PTR, _ulPartLen: CK_ULONG, _pEncryptedPart: CK_BYTE_PTR, _pulEncryptedPartLen: CK_ULONG_PTR, ) -> CK_RV980 extern "C" fn C_DigestEncryptUpdate(
981 _hSession: CK_SESSION_HANDLE,
982 _pPart: CK_BYTE_PTR,
983 _ulPartLen: CK_ULONG,
984 _pEncryptedPart: CK_BYTE_PTR,
985 _pulEncryptedPartLen: CK_ULONG_PTR,
986 ) -> CK_RV {
987 log_with_thread_id!(error, "C_DigestEncryptUpdate: CKR_FUNCTION_NOT_SUPPORTED");
988 CKR_FUNCTION_NOT_SUPPORTED
989 }
990
C_DecryptDigestUpdate( _hSession: CK_SESSION_HANDLE, _pEncryptedPart: CK_BYTE_PTR, _ulEncryptedPartLen: CK_ULONG, _pPart: CK_BYTE_PTR, _pulPartLen: CK_ULONG_PTR, ) -> CK_RV991 extern "C" fn C_DecryptDigestUpdate(
992 _hSession: CK_SESSION_HANDLE,
993 _pEncryptedPart: CK_BYTE_PTR,
994 _ulEncryptedPartLen: CK_ULONG,
995 _pPart: CK_BYTE_PTR,
996 _pulPartLen: CK_ULONG_PTR,
997 ) -> CK_RV {
998 log_with_thread_id!(error, "C_DecryptDigestUpdate: CKR_FUNCTION_NOT_SUPPORTED");
999 CKR_FUNCTION_NOT_SUPPORTED
1000 }
1001
C_SignEncryptUpdate( _hSession: CK_SESSION_HANDLE, _pPart: CK_BYTE_PTR, _ulPartLen: CK_ULONG, _pEncryptedPart: CK_BYTE_PTR, _pulEncryptedPartLen: CK_ULONG_PTR, ) -> CK_RV1002 extern "C" fn C_SignEncryptUpdate(
1003 _hSession: CK_SESSION_HANDLE,
1004 _pPart: CK_BYTE_PTR,
1005 _ulPartLen: CK_ULONG,
1006 _pEncryptedPart: CK_BYTE_PTR,
1007 _pulEncryptedPartLen: CK_ULONG_PTR,
1008 ) -> CK_RV {
1009 log_with_thread_id!(error, "C_SignEncryptUpdate: CKR_FUNCTION_NOT_SUPPORTED");
1010 CKR_FUNCTION_NOT_SUPPORTED
1011 }
1012
C_DecryptVerifyUpdate( _hSession: CK_SESSION_HANDLE, _pEncryptedPart: CK_BYTE_PTR, _ulEncryptedPartLen: CK_ULONG, _pPart: CK_BYTE_PTR, _pulPartLen: CK_ULONG_PTR, ) -> CK_RV1013 extern "C" fn C_DecryptVerifyUpdate(
1014 _hSession: CK_SESSION_HANDLE,
1015 _pEncryptedPart: CK_BYTE_PTR,
1016 _ulEncryptedPartLen: CK_ULONG,
1017 _pPart: CK_BYTE_PTR,
1018 _pulPartLen: CK_ULONG_PTR,
1019 ) -> CK_RV {
1020 log_with_thread_id!(error, "C_DecryptVerifyUpdate: CKR_FUNCTION_NOT_SUPPORTED");
1021 CKR_FUNCTION_NOT_SUPPORTED
1022 }
1023
C_GenerateKey( _hSession: CK_SESSION_HANDLE, _pMechanism: CK_MECHANISM_PTR, _pTemplate: CK_ATTRIBUTE_PTR, _ulCount: CK_ULONG, _phKey: CK_OBJECT_HANDLE_PTR, ) -> CK_RV1024 extern "C" fn C_GenerateKey(
1025 _hSession: CK_SESSION_HANDLE,
1026 _pMechanism: CK_MECHANISM_PTR,
1027 _pTemplate: CK_ATTRIBUTE_PTR,
1028 _ulCount: CK_ULONG,
1029 _phKey: CK_OBJECT_HANDLE_PTR,
1030 ) -> CK_RV {
1031 log_with_thread_id!(error, "C_GenerateKey: CKR_FUNCTION_NOT_SUPPORTED");
1032 CKR_FUNCTION_NOT_SUPPORTED
1033 }
1034
C_GenerateKeyPair( _hSession: CK_SESSION_HANDLE, _pMechanism: CK_MECHANISM_PTR, _pPublicKeyTemplate: CK_ATTRIBUTE_PTR, _ulPublicKeyAttributeCount: CK_ULONG, _pPrivateKeyTemplate: CK_ATTRIBUTE_PTR, _ulPrivateKeyAttributeCount: CK_ULONG, _phPublicKey: CK_OBJECT_HANDLE_PTR, _phPrivateKey: CK_OBJECT_HANDLE_PTR, ) -> CK_RV1035 extern "C" fn C_GenerateKeyPair(
1036 _hSession: CK_SESSION_HANDLE,
1037 _pMechanism: CK_MECHANISM_PTR,
1038 _pPublicKeyTemplate: CK_ATTRIBUTE_PTR,
1039 _ulPublicKeyAttributeCount: CK_ULONG,
1040 _pPrivateKeyTemplate: CK_ATTRIBUTE_PTR,
1041 _ulPrivateKeyAttributeCount: CK_ULONG,
1042 _phPublicKey: CK_OBJECT_HANDLE_PTR,
1043 _phPrivateKey: CK_OBJECT_HANDLE_PTR,
1044 ) -> CK_RV {
1045 log_with_thread_id!(error, "C_GenerateKeyPair: CKR_FUNCTION_NOT_SUPPORTED");
1046 CKR_FUNCTION_NOT_SUPPORTED
1047 }
1048
C_WrapKey( _hSession: CK_SESSION_HANDLE, _pMechanism: CK_MECHANISM_PTR, _hWrappingKey: CK_OBJECT_HANDLE, _hKey: CK_OBJECT_HANDLE, _pWrappedKey: CK_BYTE_PTR, _pulWrappedKeyLen: CK_ULONG_PTR, ) -> CK_RV1049 extern "C" fn C_WrapKey(
1050 _hSession: CK_SESSION_HANDLE,
1051 _pMechanism: CK_MECHANISM_PTR,
1052 _hWrappingKey: CK_OBJECT_HANDLE,
1053 _hKey: CK_OBJECT_HANDLE,
1054 _pWrappedKey: CK_BYTE_PTR,
1055 _pulWrappedKeyLen: CK_ULONG_PTR,
1056 ) -> CK_RV {
1057 log_with_thread_id!(error, "C_WrapKey: CKR_FUNCTION_NOT_SUPPORTED");
1058 CKR_FUNCTION_NOT_SUPPORTED
1059 }
1060
C_UnwrapKey( _hSession: CK_SESSION_HANDLE, _pMechanism: CK_MECHANISM_PTR, _hUnwrappingKey: CK_OBJECT_HANDLE, _pWrappedKey: CK_BYTE_PTR, _ulWrappedKeyLen: CK_ULONG, _pTemplate: CK_ATTRIBUTE_PTR, _ulAttributeCount: CK_ULONG, _phKey: CK_OBJECT_HANDLE_PTR, ) -> CK_RV1061 extern "C" fn C_UnwrapKey(
1062 _hSession: CK_SESSION_HANDLE,
1063 _pMechanism: CK_MECHANISM_PTR,
1064 _hUnwrappingKey: CK_OBJECT_HANDLE,
1065 _pWrappedKey: CK_BYTE_PTR,
1066 _ulWrappedKeyLen: CK_ULONG,
1067 _pTemplate: CK_ATTRIBUTE_PTR,
1068 _ulAttributeCount: CK_ULONG,
1069 _phKey: CK_OBJECT_HANDLE_PTR,
1070 ) -> CK_RV {
1071 log_with_thread_id!(error, "C_UnwrapKey: CKR_FUNCTION_NOT_SUPPORTED");
1072 CKR_FUNCTION_NOT_SUPPORTED
1073 }
1074
C_DeriveKey( _hSession: CK_SESSION_HANDLE, _pMechanism: CK_MECHANISM_PTR, _hBaseKey: CK_OBJECT_HANDLE, _pTemplate: CK_ATTRIBUTE_PTR, _ulAttributeCount: CK_ULONG, _phKey: CK_OBJECT_HANDLE_PTR, ) -> CK_RV1075 extern "C" fn C_DeriveKey(
1076 _hSession: CK_SESSION_HANDLE,
1077 _pMechanism: CK_MECHANISM_PTR,
1078 _hBaseKey: CK_OBJECT_HANDLE,
1079 _pTemplate: CK_ATTRIBUTE_PTR,
1080 _ulAttributeCount: CK_ULONG,
1081 _phKey: CK_OBJECT_HANDLE_PTR,
1082 ) -> CK_RV {
1083 log_with_thread_id!(error, "C_DeriveKey: CKR_FUNCTION_NOT_SUPPORTED");
1084 CKR_FUNCTION_NOT_SUPPORTED
1085 }
1086
C_SeedRandom( _hSession: CK_SESSION_HANDLE, _pSeed: CK_BYTE_PTR, _ulSeedLen: CK_ULONG, ) -> CK_RV1087 extern "C" fn C_SeedRandom(
1088 _hSession: CK_SESSION_HANDLE,
1089 _pSeed: CK_BYTE_PTR,
1090 _ulSeedLen: CK_ULONG,
1091 ) -> CK_RV {
1092 log_with_thread_id!(error, "C_SeedRandom: CKR_FUNCTION_NOT_SUPPORTED");
1093 CKR_FUNCTION_NOT_SUPPORTED
1094 }
1095
C_GenerateRandom( _hSession: CK_SESSION_HANDLE, _RandomData: CK_BYTE_PTR, _ulRandomLen: CK_ULONG, ) -> CK_RV1096 extern "C" fn C_GenerateRandom(
1097 _hSession: CK_SESSION_HANDLE,
1098 _RandomData: CK_BYTE_PTR,
1099 _ulRandomLen: CK_ULONG,
1100 ) -> CK_RV {
1101 log_with_thread_id!(error, "C_GenerateRandom: CKR_FUNCTION_NOT_SUPPORTED");
1102 CKR_FUNCTION_NOT_SUPPORTED
1103 }
1104
C_GetFunctionStatus(_hSession: CK_SESSION_HANDLE) -> CK_RV1105 extern "C" fn C_GetFunctionStatus(_hSession: CK_SESSION_HANDLE) -> CK_RV {
1106 log_with_thread_id!(error, "C_GetFunctionStatus: CKR_FUNCTION_NOT_SUPPORTED");
1107 CKR_FUNCTION_NOT_SUPPORTED
1108 }
1109
C_CancelFunction(_hSession: CK_SESSION_HANDLE) -> CK_RV1110 extern "C" fn C_CancelFunction(_hSession: CK_SESSION_HANDLE) -> CK_RV {
1111 log_with_thread_id!(error, "C_CancelFunction: CKR_FUNCTION_NOT_SUPPORTED");
1112 CKR_FUNCTION_NOT_SUPPORTED
1113 }
1114
C_WaitForSlotEvent( _flags: CK_FLAGS, _pSlot: CK_SLOT_ID_PTR, _pRserved: CK_VOID_PTR, ) -> CK_RV1115 extern "C" fn C_WaitForSlotEvent(
1116 _flags: CK_FLAGS,
1117 _pSlot: CK_SLOT_ID_PTR,
1118 _pRserved: CK_VOID_PTR,
1119 ) -> CK_RV {
1120 log_with_thread_id!(error, "C_WaitForSlotEvent: CKR_FUNCTION_NOT_SUPPORTED");
1121 CKR_FUNCTION_NOT_SUPPORTED
1122 }
1123
1124 /// To be a valid PKCS #11 module, this list of functions must be supported. At least cryptoki 2.2
1125 /// must be supported for this module to work in NSS.
1126 static mut FUNCTION_LIST: CK_FUNCTION_LIST = CK_FUNCTION_LIST {
1127 version: CK_VERSION { major: 2, minor: 2 },
1128 C_Initialize: Some(C_Initialize),
1129 C_Finalize: Some(C_Finalize),
1130 C_GetInfo: Some(C_GetInfo),
1131 C_GetFunctionList: None,
1132 C_GetSlotList: Some(C_GetSlotList),
1133 C_GetSlotInfo: Some(C_GetSlotInfo),
1134 C_GetTokenInfo: Some(C_GetTokenInfo),
1135 C_GetMechanismList: Some(C_GetMechanismList),
1136 C_GetMechanismInfo: Some(C_GetMechanismInfo),
1137 C_InitToken: Some(C_InitToken),
1138 C_InitPIN: Some(C_InitPIN),
1139 C_SetPIN: Some(C_SetPIN),
1140 C_OpenSession: Some(C_OpenSession),
1141 C_CloseSession: Some(C_CloseSession),
1142 C_CloseAllSessions: Some(C_CloseAllSessions),
1143 C_GetSessionInfo: Some(C_GetSessionInfo),
1144 C_GetOperationState: Some(C_GetOperationState),
1145 C_SetOperationState: Some(C_SetOperationState),
1146 C_Login: Some(C_Login),
1147 C_Logout: Some(C_Logout),
1148 C_CreateObject: Some(C_CreateObject),
1149 C_CopyObject: Some(C_CopyObject),
1150 C_DestroyObject: Some(C_DestroyObject),
1151 C_GetObjectSize: Some(C_GetObjectSize),
1152 C_GetAttributeValue: Some(C_GetAttributeValue),
1153 C_SetAttributeValue: Some(C_SetAttributeValue),
1154 C_FindObjectsInit: Some(C_FindObjectsInit),
1155 C_FindObjects: Some(C_FindObjects),
1156 C_FindObjectsFinal: Some(C_FindObjectsFinal),
1157 C_EncryptInit: Some(C_EncryptInit),
1158 C_Encrypt: Some(C_Encrypt),
1159 C_EncryptUpdate: Some(C_EncryptUpdate),
1160 C_EncryptFinal: Some(C_EncryptFinal),
1161 C_DecryptInit: Some(C_DecryptInit),
1162 C_Decrypt: Some(C_Decrypt),
1163 C_DecryptUpdate: Some(C_DecryptUpdate),
1164 C_DecryptFinal: Some(C_DecryptFinal),
1165 C_DigestInit: Some(C_DigestInit),
1166 C_Digest: Some(C_Digest),
1167 C_DigestUpdate: Some(C_DigestUpdate),
1168 C_DigestKey: Some(C_DigestKey),
1169 C_DigestFinal: Some(C_DigestFinal),
1170 C_SignInit: Some(C_SignInit),
1171 C_Sign: Some(C_Sign),
1172 C_SignUpdate: Some(C_SignUpdate),
1173 C_SignFinal: Some(C_SignFinal),
1174 C_SignRecoverInit: Some(C_SignRecoverInit),
1175 C_SignRecover: Some(C_SignRecover),
1176 C_VerifyInit: Some(C_VerifyInit),
1177 C_Verify: Some(C_Verify),
1178 C_VerifyUpdate: Some(C_VerifyUpdate),
1179 C_VerifyFinal: Some(C_VerifyFinal),
1180 C_VerifyRecoverInit: Some(C_VerifyRecoverInit),
1181 C_VerifyRecover: Some(C_VerifyRecover),
1182 C_DigestEncryptUpdate: Some(C_DigestEncryptUpdate),
1183 C_DecryptDigestUpdate: Some(C_DecryptDigestUpdate),
1184 C_SignEncryptUpdate: Some(C_SignEncryptUpdate),
1185 C_DecryptVerifyUpdate: Some(C_DecryptVerifyUpdate),
1186 C_GenerateKey: Some(C_GenerateKey),
1187 C_GenerateKeyPair: Some(C_GenerateKeyPair),
1188 C_WrapKey: Some(C_WrapKey),
1189 C_UnwrapKey: Some(C_UnwrapKey),
1190 C_DeriveKey: Some(C_DeriveKey),
1191 C_SeedRandom: Some(C_SeedRandom),
1192 C_GenerateRandom: Some(C_GenerateRandom),
1193 C_GetFunctionStatus: Some(C_GetFunctionStatus),
1194 C_CancelFunction: Some(C_CancelFunction),
1195 C_WaitForSlotEvent: Some(C_WaitForSlotEvent),
1196 };
1197
1198 /// This is the only function this module exposes. NSS calls it to obtain the list of functions
1199 /// comprising this module.
1200 #[no_mangle]
C_GetFunctionList(ppFunctionList: CK_FUNCTION_LIST_PTR_PTR) -> CK_RV1201 pub extern "C" fn C_GetFunctionList(ppFunctionList: CK_FUNCTION_LIST_PTR_PTR) -> CK_RV {
1202 if ppFunctionList.is_null() {
1203 return CKR_ARGUMENTS_BAD;
1204 }
1205 unsafe {
1206 *ppFunctionList = &mut FUNCTION_LIST;
1207 }
1208 CKR_OK
1209 }
1210
1211 #[cfg_attr(target_os = "macos", link(name = "Security", kind = "framework"))]
1212 extern "C" {}
1213