1use crate::engine::app::SkfAppImpl;
2use crate::engine::crypto;
3use crate::engine::crypto::ManagedKeyImpl;
4use crate::engine::symbol::ModDev;
5use crate::error::SkfErr;
6use crate::helper::{mem, param};
7use crate::{
8 AppAttr, AppManager, DeviceAuth, DeviceCrypto, DeviceCtl, DeviceInformation, ECCEncryptedData,
9 ECCPrivateKeyBlob, ECCPublicKeyBlob, ECCSignatureBlob, ManagedKey, SkfApp, SkfBlockCipher,
10 SkfDevice, Version,
11};
12use crate::{Error, Result};
13use skf_api::native::error::SAR_OK;
14use skf_api::native::types::{
15 DeviceInfo, ECCCipherBlob, BYTE, CHAR, DEV_LOCK_FOREVER, DWORD, HANDLE, LPSTR, ULONG,
16};
17use std::fmt::Debug;
18use std::sync::Arc;
19use std::time::Duration;
20use tracing::{instrument, trace};
21
22pub(crate) struct SkfDeviceImpl {
23 lib: Arc<libloading::Library>,
24 symbols: ModDev,
25 handle: HANDLE,
26 name: String,
27}
28
29impl SkfDeviceImpl {
30 pub fn new(handle: HANDLE, name: &str, lib: &Arc<libloading::Library>) -> Result<Self> {
36 let lc = Arc::clone(lib);
37 let symbols = ModDev::load_symbols(lib)?;
38 Ok(Self {
39 lib: lc,
40 symbols,
41 handle,
42 name: name.to_string(),
43 })
44 }
45
46 #[instrument]
47 fn disconnect(&mut self) -> Result<()> {
48 if let Some(ref func) = self.symbols.dev_dis_connect {
49 let ret = unsafe { func(self.handle) };
50 trace!("[SKF_DisConnectDev]: ret = {}", ret);
51 if ret != SAR_OK {
52 return Err(Error::Skf(SkfErr::of_code(ret)));
53 }
54 self.handle = std::ptr::null();
55 }
56 Ok(())
57 }
58}
59
60impl Debug for SkfDeviceImpl {
61 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
62 write!(f, "SkfDeviceImpl({})", &self.name)
63 }
64}
65
66impl DeviceAuth for SkfDeviceImpl {
67 #[instrument(skip(data))]
68 fn device_auth(&self, data: &[u8]) -> Result<()> {
69 let func = self.symbols.dev_auth.as_ref().expect("Symbol not load");
70 let ret = unsafe {
71 func(
72 self.handle,
73 data.as_ptr() as *const BYTE,
74 data.len() as ULONG,
75 )
76 };
77 trace!("[SKF_DevAuth]: ret = {}", ret);
78 if ret != SAR_OK {
79 return Err(Error::Skf(SkfErr::of_code(ret)));
80 }
81 Ok(())
82 }
83
84 #[instrument(skip(key))]
85 fn change_device_auth_key(&self, key: &[u8]) -> Result<()> {
86 let func = self
87 .symbols
88 .dev_change_auth_key
89 .as_ref()
90 .expect("Symbol not load");
91 let ret = unsafe { func(self.handle, key.as_ptr() as *const BYTE, key.len() as ULONG) };
92 trace!("[SKF_ChangeDevAuthKey]: ret = {}", ret);
93 if ret != SAR_OK {
94 return Err(Error::Skf(SkfErr::of_code(ret)));
95 }
96 Ok(())
97 }
98}
99
100impl DeviceCtl for SkfDeviceImpl {
101 #[instrument]
102 fn set_label(&self, label: &str) -> Result<()> {
103 let func = self
104 .symbols
105 .dev_set_label
106 .as_ref()
107 .expect("Symbol not load");
108 let label = param::as_cstring("label", label)?;
109 let ret = unsafe { func(self.handle, label.as_ptr() as *const CHAR) };
110 trace!("[SKF_SetLabel]: ret = {}", ret);
111 if ret != SAR_OK {
112 return Err(Error::Skf(SkfErr::of_code(ret)));
113 }
114 Ok(())
115 }
116
117 #[instrument]
118 fn info(&self) -> Result<DeviceInformation> {
119 let func = self.symbols.dev_get_info.as_ref().expect("Symbol not load");
120 let mut data = DeviceInfo::default();
121 let ret = unsafe { func(self.handle, &mut data) };
122 trace!("[SKF_GetDevInfo]: ret = {}", ret);
123 if ret != SAR_OK {
124 return Err(Error::Skf(SkfErr::of_code(ret)));
125 }
126 Ok(DeviceInformation::from(&data))
127 }
128
129 #[instrument]
130 fn lock(&self, timeout: Option<Duration>) -> Result<()> {
131 let func = self.symbols.dev_lock.as_ref().expect("Symbol not load");
132 let timeout = timeout
133 .map(|ref v| v.as_millis() as ULONG)
134 .unwrap_or(DEV_LOCK_FOREVER);
135 let ret = unsafe { func(self.handle, timeout) };
136 trace!("[SKF_LockDev]: ret = {}", ret);
137 if ret != SAR_OK {
138 return Err(Error::Skf(SkfErr::of_code(ret)));
139 }
140 Ok(())
141 }
142
143 #[instrument]
144 fn unlock(&self) -> Result<()> {
145 let func = self.symbols.dev_unlock.as_ref().expect("Symbol not load");
146 let ret = unsafe { func(self.handle) };
147 trace!("[SKF_UnlockDev]: ret = {}", ret);
148 if ret != SAR_OK {
149 return Err(Error::Skf(SkfErr::of_code(ret)));
150 }
151 Ok(())
152 }
153 #[instrument]
154 fn transmit(&self, command: &[u8], recv_capacity: usize) -> Result<Vec<u8>> {
155 let func = self.symbols.dev_transmit.as_ref().expect("Symbol not load");
156 let mut len: ULONG = recv_capacity as ULONG;
157 let mut buffer = Vec::<u8>::with_capacity(recv_capacity);
158 let ret = unsafe {
159 func(
160 self.handle,
161 command.as_ptr() as *const BYTE,
162 command.len() as ULONG,
163 buffer.as_mut_ptr() as *mut BYTE,
164 &mut len,
165 )
166 };
167 trace!("[SKF_Transmit]: ret = {}", ret);
168 if ret != SAR_OK {
169 return Err(Error::Skf(SkfErr::of_code(ret)));
170 }
171 trace!("[SKF_Transmit]: output len = {}", len);
172 unsafe { buffer.set_len(len as usize) };
173 Ok(buffer)
174 }
175}
176
177impl DeviceCrypto for SkfDeviceImpl {
178 #[instrument]
179 fn gen_random(&self, len: usize) -> Result<Vec<u8>> {
180 let func = self.symbols.gen_random.as_ref().expect("Symbol not load");
181 let mut buffer = Vec::<u8>::with_capacity(len);
182 let ret = unsafe { func(self.handle, buffer.as_mut_ptr() as *mut BYTE, len as ULONG) };
183 trace!("[SKF_GenRandom]: ret = {}", ret);
184 if ret != SAR_OK {
185 return Err(Error::Skf(SkfErr::of_code(ret)));
186 }
187 unsafe { buffer.set_len(len) };
188 Ok(buffer)
189 }
190
191 #[instrument(skip(key))]
192 fn set_symmetric_key(&self, alg_id: u32, key: &[u8]) -> Result<Box<dyn ManagedKey>> {
193 let func = self
194 .symbols
195 .sym_key_import
196 .as_ref()
197 .expect("Symbol not load");
198 let mut handle: HANDLE = std::ptr::null_mut();
199 let ret = unsafe {
200 func(
201 self.handle,
202 key.as_ptr() as *const BYTE,
203 alg_id,
204 &mut handle,
205 )
206 };
207 trace!("[SKF_SetSymmKey]: ret = {}", ret);
208 if ret != SAR_OK {
209 return Err(Error::Skf(SkfErr::of_code(ret)));
210 }
211 let managed_key = ManagedKeyImpl::try_new(handle, &self.lib)?;
212 Ok(Box::new(managed_key))
213 }
214
215 #[instrument(skip(key, data))]
216 fn ext_ecc_encrypt(&self, key: &ECCPublicKeyBlob, data: &[u8]) -> Result<ECCEncryptedData> {
217 let func = self
218 .symbols
219 .ecc_ext_encrypt
220 .as_ref()
221 .expect("Symbol not load");
222 let buff_size = ECCCipherBlob::size_of(data.len());
223 let mut buff: Vec<u8> = vec![0; buff_size];
224
225 let ret = unsafe {
226 func(
227 self.handle,
228 key as *const ECCPublicKeyBlob,
229 data.as_ptr() as *const BYTE,
230 data.len() as ULONG,
231 buff.as_mut_ptr() as *mut ECCCipherBlob,
232 )
233 };
234 trace!("[SKF_ExtECCEncrypt]: ret = {}", ret);
235 if ret != SAR_OK {
236 return Err(Error::Skf(SkfErr::of_code(ret)));
237 }
238 let blob = unsafe {
239 let cb = &*(buff.as_ptr() as *const ECCCipherBlob);
240 let mut cipher: Vec<u8> = vec![];
241 if cb.cipher_len > 0 {
242 let len = cb.cipher_len as usize;
243 cipher = vec![0; len];
244 std::ptr::copy(cb.cipher.as_ptr(), cipher.as_mut_ptr(), len);
245 }
246 ECCEncryptedData {
247 ec_x: cb.x_coordinate,
248 ec_y: cb.y_coordinate,
249 hash: cb.hash,
250 cipher,
251 }
252 };
253 Ok(blob)
254 }
255
256 #[instrument(skip(key, cipher))]
257 fn ext_ecc_decrypt(
258 &self,
259 key: &ECCPrivateKeyBlob,
260 cipher: &ECCEncryptedData,
261 ) -> Result<Vec<u8>> {
262 let func = self
263 .symbols
264 .ecc_ext_decrypt
265 .as_ref()
266 .expect("Symbol not load");
267 let cipher_mem = cipher.blob_bytes();
268 let mut buff: Vec<u8> = Vec::with_capacity(cipher.cipher.len());
269 let mut buff_len: ULONG = buff.capacity() as ULONG;
270
271 let ret = unsafe {
272 func(
273 self.handle,
274 key as *const ECCPrivateKeyBlob,
275 cipher_mem.as_ptr() as *const ECCCipherBlob,
276 buff.as_mut_ptr() as *mut BYTE,
277 &mut buff_len,
278 )
279 };
280 trace!("[SKF_ExtECCDecrypt]: ret = {}", ret);
281 if ret != SAR_OK {
282 return Err(Error::Skf(SkfErr::of_code(ret)));
283 }
284
285 trace!("[SKF_ExtECCDecrypt]: len = {}", buff_len);
286 unsafe { buff.set_len(buff_len as usize) };
287
288 Ok(buff)
289 }
290
291 #[instrument(skip(key, data))]
292 fn ext_ecc_sign(&self, key: &ECCPrivateKeyBlob, data: &[u8]) -> Result<ECCSignatureBlob> {
293 let func = self.symbols.ecc_ext_sign.as_ref().expect("Symbol not load");
294
295 let mut sign = ECCSignatureBlob::default();
296 let ret = unsafe {
297 func(
298 self.handle,
299 key as *const ECCPrivateKeyBlob,
300 data.as_ptr() as *const BYTE,
301 data.len() as ULONG,
302 &mut sign,
303 )
304 };
305 trace!("[SKF_ExtECCSign]: ret = {}", ret);
306 if ret != SAR_OK {
307 return Err(Error::Skf(SkfErr::of_code(ret)));
308 }
309
310 Ok(sign)
311 }
312
313 #[instrument(skip(key, data, signature))]
314 fn ext_ecc_verify(
315 &self,
316 key: &ECCPublicKeyBlob,
317 data: &[u8],
318 signature: &ECCSignatureBlob,
319 ) -> Result<()> {
320 let func = self
321 .symbols
322 .ecc_ext_verify
323 .as_ref()
324 .expect("Symbol not load");
325
326 let ret = unsafe {
327 func(
328 self.handle,
329 key as *const ECCPublicKeyBlob,
330 data.as_ptr() as *const BYTE,
331 data.len() as ULONG,
332 signature as *const ECCSignatureBlob,
333 )
334 };
335 trace!("[SKF_ExtECCVerify]: ret = {}", ret);
336 if ret != SAR_OK {
337 return Err(Error::Skf(SkfErr::of_code(ret)));
338 }
339 Ok(())
340 }
341
342 #[instrument(skip(key, hash, signature))]
343 fn ecc_verify(
344 &self,
345 key: &ECCPublicKeyBlob,
346 hash: &[u8],
347 signature: &ECCSignatureBlob,
348 ) -> Result<()> {
349 let func = self.symbols.ecc_verify.as_ref().expect("Symbol not load");
350
351 let ret = unsafe {
352 func(
353 self.handle,
354 key as *const ECCPublicKeyBlob,
355 hash.as_ptr() as *const BYTE,
356 hash.len() as ULONG,
357 signature as *const ECCSignatureBlob,
358 )
359 };
360 trace!("[SKF_ECCVerify]: ret = {}", ret);
361 if ret != SAR_OK {
362 return Err(Error::Skf(SkfErr::of_code(ret)));
363 }
364 Ok(())
365 }
366
367 #[instrument(skip(agreement_key, responder_key, responder_tmp_key, responder_id))]
368 fn ecc_gen_session_key(
369 &self,
370 agreement_key: &dyn ManagedKey,
371 responder_key: &ECCPublicKeyBlob,
372 responder_tmp_key: &ECCPublicKeyBlob,
373 responder_id: &[u8],
374 ) -> Result<Box<dyn ManagedKey>> {
375 let func = self.symbols.ecc_gen_sk.as_ref().expect("Symbol not load");
376
377 let mut handle: HANDLE = std::ptr::null_mut();
378 let ret = unsafe {
379 func(
380 *agreement_key.as_ref(),
381 responder_key,
382 responder_tmp_key,
383 responder_id.as_ptr() as *const BYTE,
384 responder_id.len() as ULONG,
385 &mut handle,
386 )
387 };
388 trace!("[SKF_GenerateKeyWithECC]: ret = {}", ret);
389 if ret != SAR_OK {
390 return Err(Error::Skf(SkfErr::of_code(ret)));
391 }
392 let managed_key = ManagedKeyImpl::try_new(handle, &self.lib)?;
393 Ok(Box::new(managed_key))
394 }
395}
396impl AppManager for SkfDeviceImpl {
397 #[instrument]
398 fn enumerate_app_name(&self) -> Result<Vec<String>> {
399 let func = self.symbols.app_enum.as_ref().expect("Symbol not load");
400 let mut len: ULONG = 0;
401 let ret = unsafe { func(self.handle, std::ptr::null_mut(), &mut len) };
402 if ret != SAR_OK {
403 return Err(Error::Skf(SkfErr::of_code(ret)));
404 }
405 trace!("[SKF_EnumApplication]: desired len = {}", len);
406 if len == 0 {
407 return Ok(vec![]);
408 }
409 let mut buff = Vec::<CHAR>::with_capacity(len as usize);
410 let ret = unsafe { func(self.handle, buff.as_mut_ptr(), &mut len) };
411 trace!("[SKF_EnumApplication]: ret = {}", ret);
412 if ret != SAR_OK {
413 return Err(Error::Skf(SkfErr::of_code(ret)));
414 }
415 unsafe { buff.set_len(len as usize) };
416 trace!(
417 "[SKF_EnumApplication]: app list = {}",
418 String::from_utf8_lossy(&buff)
419 );
420 let list = unsafe { mem::parse_cstr_list_lossy(buff.as_ptr(), buff.len()) };
422 Ok(list)
423 }
424
425 #[instrument(skip(attr))]
426 fn create_app(&self, name: &str, attr: &AppAttr) -> Result<Box<dyn SkfApp>> {
427 let func = self.symbols.app_create.as_ref().expect("Symbol not load");
428 let c_name = param::as_cstring("name", name)?;
429 let admin_pin = param::as_cstring("AppAttr.admin_pin", &attr.admin_pin)?;
430 let user_pin = param::as_cstring("AppAttr.user_pin", &attr.user_pin)?;
431 let mut handle: HANDLE = std::ptr::null_mut();
432 let ret = unsafe {
433 func(
434 self.handle,
435 c_name.as_ptr() as *const CHAR,
436 admin_pin.as_ptr() as *const CHAR,
437 attr.admin_pin_retry_count as DWORD,
438 user_pin.as_ptr() as *const CHAR,
439 attr.user_pin_retry_count as DWORD,
440 attr.create_file_rights as DWORD,
441 &mut handle,
442 )
443 };
444 trace!("[SKF_CreateApplication]: ret = {}", ret);
445 if ret != SAR_OK {
446 return Err(Error::Skf(SkfErr::of_code(ret)));
447 }
448 let app = SkfAppImpl::new(handle, name, &self.lib)?;
449 Ok(Box::new(app))
450 }
451
452 #[instrument]
453 fn open_app(&self, name: &str) -> Result<Box<dyn SkfApp>> {
454 let func = self.symbols.app_open.as_ref().expect("Symbol not load");
455 let c_name = param::as_cstring("name", name)?;
456 let mut handle: HANDLE = std::ptr::null_mut();
457 let ret = unsafe { func(self.handle, c_name.as_ptr() as LPSTR, &mut handle) };
458 trace!("[SKF_OpenApplication]: ret = {}", ret);
459 if ret != SAR_OK {
460 return Err(Error::Skf(SkfErr::of_code(ret)));
461 }
462 let app = SkfAppImpl::new(handle, name, &self.lib)?;
463 Ok(Box::new(app))
464 }
465
466 #[instrument]
467 fn delete_app(&self, name: &str) -> Result<()> {
468 let func = self.symbols.app_delete.as_ref().expect("Symbol not load");
469 let name = param::as_cstring("name", name)?;
470 let ret = unsafe { func(self.handle, name.as_ptr() as LPSTR) };
471 trace!("[SKF_DeleteApplication]: ret = {}", ret);
472 if ret != SAR_OK {
473 return Err(Error::Skf(SkfErr::of_code(ret)));
474 }
475 Ok(())
476 }
477}
478
479impl SkfDevice for SkfDeviceImpl {
480 fn block_cipher(&self) -> Result<Box<dyn SkfBlockCipher + Send + Sync>> {
481 let crypto = crypto::SkfBlockCipherImpl::new(&self.lib)?;
482 Ok(Box::new(crypto))
483 }
484
485 fn name(&self) -> &str {
486 &self.name
487 }
488}
489impl Drop for SkfDeviceImpl {
490 fn drop(&mut self) {
491 let _ = self.disconnect();
492 }
493}
494
495impl From<&DeviceInfo> for DeviceInformation {
496 fn from(value: &DeviceInfo) -> Self {
497 let version = Version {
498 major: value.version.major,
499 minor: value.version.minor,
500 };
501 let manufacturer: String = unsafe {
502 mem::parse_cstr_lossy(value.manufacturer.as_ptr(), value.manufacturer.len())
503 .unwrap_or("".to_string())
504 };
505 let issuer: String = unsafe {
506 mem::parse_cstr_lossy(value.issuer.as_ptr(), value.issuer.len())
507 .unwrap_or("".to_string())
508 };
509 let label: String = unsafe {
510 mem::parse_cstr_lossy(value.label.as_ptr(), value.label.len()).unwrap_or("".to_string())
511 };
512 let serial_number = unsafe {
513 mem::parse_cstr_lossy(value.serial_number.as_ptr(), value.serial_number.len())
514 .unwrap_or("".to_string())
515 };
516 let hw_version = Version {
517 major: value.hw_version.major,
518 minor: value.hw_version.minor,
519 };
520 let firmware_version = Version {
521 major: value.firmware_version.major,
522 minor: value.firmware_version.minor,
523 };
524 let alg_sym_cap = value.alg_sym_cap;
525 let alg_asym_cap = value.alg_asym_cap;
526 let alg_hash_cap = value.alg_hash_cap;
527 let dev_auth_alg_id = value.dev_auth_alg_id;
528 let total_space = value.total_space;
529 let free_space = value.free_space;
530 let max_ecc_buffer_size = value.max_ecc_buffer_size;
531 let max_buffer_size = value.max_buffer_size;
532 let reserved = value.reserved;
533 Self {
534 version,
535 manufacturer,
536 issuer,
537 label,
538 serial_number,
539 hw_version,
540 firmware_version,
541 alg_sym_cap,
542 alg_asym_cap,
543 alg_hash_cap,
544 dev_auth_alg_id,
545 total_space,
546 free_space,
547 max_ecc_buffer_size,
548 max_buffer_size,
549 reserved,
550 }
551 }
552}