skf_rs/engine/
app.rs

1use crate::engine::crypto::ManagedKeyImpl;
2use crate::engine::symbol::{ModApp, ModContainer};
3use crate::error::{SkfErr, SkfPinVerifyError};
4use crate::helper::{mem, param};
5use crate::{
6    AppSecurity, ContainerManager, ECCEncryptedData, EnvelopedKeyData, Error, FileAttr,
7    FileAttrBuilder, FileManager, ManagedKey, PinInfo, SkfApp, SkfContainer, FILE_PERM_NONE,
8};
9use skf_api::native::error::{SAR_OK, SAR_PIN_INCORRECT};
10use skf_api::native::types::{
11    ECCCipherBlob, ECCPublicKeyBlob, ECCSignatureBlob, EnvelopedKeyBlob, FileAttribute, BOOL, BYTE,
12    CHAR, FALSE, HANDLE, LPSTR, TRUE, ULONG,
13};
14use std::fmt::Debug;
15use std::sync::Arc;
16use tracing::{instrument, trace};
17
18pub(crate) struct SkfAppImpl {
19    lib: Arc<libloading::Library>,
20    symbols: ModApp,
21    handle: HANDLE,
22    name: String,
23}
24
25impl SkfAppImpl {
26    /// Initialize
27    ///
28    /// [handle] - The application handle
29    ///
30    /// [lib] - The library handle
31    pub fn new(handle: HANDLE, name: &str, lib: &Arc<libloading::Library>) -> crate::Result<Self> {
32        let lc = Arc::clone(lib);
33        let symbols = ModApp::load_symbols(lib)?;
34        Ok(Self {
35            lib: lc,
36            symbols,
37            handle,
38            name: name.to_string(),
39        })
40    }
41
42    pub fn close(&mut self) -> crate::Result<()> {
43        if let Some(ref func) = self.symbols.app_close {
44            let ret = unsafe { func(self.handle) };
45            trace!("[SKF_CloseApplication]: ret = {}", ret);
46            if ret != SAR_OK {
47                return Err(Error::Skf(SkfErr::of_code(ret)));
48            }
49            self.handle = std::ptr::null();
50        }
51        Ok(())
52    }
53}
54
55impl Debug for SkfAppImpl {
56    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
57        write!(f, "SkfAppImpl({})", &self.name)
58    }
59}
60impl Drop for SkfAppImpl {
61    fn drop(&mut self) {
62        let _ = self.close();
63    }
64}
65impl AppSecurity for SkfAppImpl {
66    #[instrument(skip(old_pin, new_pin))]
67    fn change_pin(&self, pin_type: u8, old_pin: &str, new_pin: &str) -> crate::Result<()> {
68        let func = self.symbols.pin_change.as_ref().expect("Symbol not load");
69        let old_pin = param::as_cstring("old_pin", old_pin)?;
70        let new_pin = param::as_cstring("new_pin", new_pin)?;
71        let mut count: ULONG = 0;
72        let ret = unsafe {
73            func(
74                self.handle,
75                pin_type as ULONG,
76                old_pin.as_ptr() as LPSTR,
77                new_pin.as_ptr() as LPSTR,
78                &mut count,
79            )
80        };
81        trace!("[SKF_ChangePIN]: ret = {}", ret);
82        match ret {
83            SAR_OK => Ok(()),
84            SAR_PIN_INCORRECT => {
85                let source = SkfErr::of_code(ret);
86                Err(Error::PinVerifyFail(SkfPinVerifyError::new(
87                    count,
88                    "old pin incorrect",
89                    source,
90                )))
91            }
92            _ => Err(Error::Skf(SkfErr::of_code(ret))),
93        }
94    }
95
96    #[instrument(skip(pin))]
97    fn verify_pin(&self, pin_type: u8, pin: &str) -> crate::Result<()> {
98        let func = self.symbols.pin_verify.as_ref().expect("Symbol not load");
99        let pin = param::as_cstring("pin", pin)?;
100        let mut count: ULONG = 0;
101        let ret = unsafe {
102            func(
103                self.handle,
104                pin_type as ULONG,
105                pin.as_ptr() as LPSTR,
106                &mut count,
107            )
108        };
109        trace!("[SKF_VerifyPIN]: ret = {}", ret);
110        match ret {
111            SAR_OK => Ok(()),
112            SAR_PIN_INCORRECT => {
113                let source = SkfErr::of_code(ret);
114                Err(Error::PinVerifyFail(SkfPinVerifyError::new(
115                    count,
116                    "pin incorrect",
117                    source,
118                )))
119            }
120            _ => Err(Error::Skf(SkfErr::of_code(ret))),
121        }
122    }
123
124    #[instrument]
125    fn pin_info(&self, pin_type: u8) -> crate::Result<PinInfo> {
126        let func = self.symbols.pin_get_info.as_ref().expect("Symbol not load");
127
128        let mut max_retry_count: ULONG = 0;
129        let mut remain_retry_count: ULONG = 0;
130        let mut default_pin: BOOL = FALSE;
131
132        let ret = unsafe {
133            func(
134                self.handle,
135                pin_type as ULONG,
136                &mut max_retry_count,
137                &mut remain_retry_count,
138                &mut default_pin,
139            )
140        };
141        trace!("[SKF_GetPINInfo]: ret = {}", ret);
142        match ret {
143            SAR_OK => Ok(PinInfo {
144                max_retry_count,
145                remain_retry_count,
146                default_pin: default_pin != FALSE,
147            }),
148            _ => Err(Error::Skf(SkfErr::of_code(ret))),
149        }
150    }
151
152    #[instrument(skip(admin_pin, new_pin))]
153    fn unblock_pin(&self, admin_pin: &str, new_pin: &str) -> crate::Result<()> {
154        let func = self.symbols.pin_unblock.as_ref().expect("Symbol not load");
155        let admin_pin = param::as_cstring("admin_pin", admin_pin)?;
156        let new_pin = param::as_cstring("new_pin", new_pin)?;
157        let mut count: ULONG = 0;
158        let ret = unsafe {
159            func(
160                self.handle,
161                admin_pin.as_ptr() as LPSTR,
162                new_pin.as_ptr() as LPSTR,
163                &mut count,
164            )
165        };
166        trace!("[SKF_UnblockPIN]: ret = {}", ret);
167        match ret {
168            SAR_OK => Ok(()),
169            SAR_PIN_INCORRECT => {
170                let source = SkfErr::of_code(ret);
171                Err(Error::PinVerifyFail(SkfPinVerifyError::new(
172                    count,
173                    "admin pin incorrect",
174                    source,
175                )))
176            }
177            _ => Err(Error::Skf(SkfErr::of_code(ret))),
178        }
179    }
180
181    #[instrument]
182    fn clear_secure_state(&self) -> crate::Result<()> {
183        let func = self
184            .symbols
185            .app_clear_secure_state
186            .as_ref()
187            .expect("Symbol not load");
188        let ret = unsafe { func(self.handle) };
189        trace!("[SKF_ClearSecureState]: ret = {}", ret);
190        match ret {
191            SAR_OK => Ok(()),
192            _ => Err(Error::Skf(SkfErr::of_code(ret))),
193        }
194    }
195}
196
197impl FileManager for SkfAppImpl {
198    #[instrument]
199    fn enumerate_file_name(&self) -> crate::Result<Vec<String>> {
200        let func = self
201            .symbols
202            .file_get_list
203            .as_ref()
204            .expect("Symbol not load");
205        let mut len: ULONG = 0;
206        let ret = unsafe { func(self.handle, std::ptr::null_mut(), &mut len) };
207        if ret != SAR_OK {
208            return Err(Error::Skf(SkfErr::of_code(ret)));
209        }
210        trace!("[SKF_EnumFiles]: desired len = {}", len);
211        if len == 0 {
212            return Ok(vec![]);
213        }
214        let mut buff = Vec::<CHAR>::with_capacity(len as usize);
215        let ret = unsafe { func(self.handle, buff.as_mut_ptr(), &mut len) };
216        trace!("[SKF_EnumFiles]: ret = {}", ret);
217        if ret != SAR_OK {
218            return Err(Error::Skf(SkfErr::of_code(ret)));
219        }
220        unsafe { buff.set_len(len as usize) };
221        trace!(
222            "[SKF_EnumFiles]: file list = {}",
223            String::from_utf8_lossy(&buff)
224        );
225        // The spec says string list end with two '\0',but vendor may not do it
226        let list = unsafe { mem::parse_cstr_list_lossy(buff.as_ptr(), buff.len()) };
227        Ok(list)
228    }
229
230    #[instrument]
231    fn create_file(&self, attr: &FileAttr) -> crate::Result<()> {
232        let func = self.symbols.file_create.as_ref().expect("Symbol not load");
233        let file_name = param::as_cstring("FileAttr.file_name", &attr.file_name)?;
234        let ret = unsafe {
235            func(
236                self.handle,
237                file_name.as_ptr() as LPSTR,
238                attr.file_size as ULONG,
239                attr.read_rights,
240                attr.write_rights,
241            )
242        };
243        trace!("[SKF_CreateFile]: ret = {}", ret);
244        match ret {
245            SAR_OK => Ok(()),
246            _ => Err(Error::Skf(SkfErr::of_code(ret))),
247        }
248    }
249
250    #[instrument]
251    fn delete_file(&self, name: &str) -> crate::Result<()> {
252        let func = self.symbols.file_delete.as_ref().expect("Symbol not load");
253        let name = param::as_cstring("name", name)?;
254        let ret = unsafe { func(self.handle, name.as_ptr() as LPSTR) };
255        trace!("[SKF_DeleteFile]: ret = {}", ret);
256        match ret {
257            SAR_OK => Ok(()),
258            _ => Err(Error::Skf(SkfErr::of_code(ret))),
259        }
260    }
261
262    #[instrument]
263    fn read_file(&self, name: &str, offset: u32, size: usize) -> crate::Result<Vec<u8>> {
264        let func = self.symbols.file_read.as_ref().expect("Symbol not load");
265        let name = param::as_cstring("name", name)?;
266        let mut buff = vec![0u8; size];
267        let mut has_read = size as ULONG;
268        let ret = unsafe {
269            func(
270                self.handle,
271                name.as_ptr() as LPSTR,
272                offset,
273                size as ULONG,
274                buff.as_mut_ptr() as *mut BYTE,
275                &mut has_read,
276            )
277        };
278        trace!("[SKF_ReadFile]: ret = {}", ret);
279        if ret != SAR_OK {
280            return Err(Error::Skf(SkfErr::of_code(ret)));
281        }
282        trace!("[SKF_ReadFile]: len = {}", has_read);
283        unsafe { buff.set_len(has_read as usize) };
284        Ok(buff)
285    }
286
287    #[instrument(skip(data))]
288    fn write_file(&self, name: &str, offset: u32, data: &[u8]) -> crate::Result<()> {
289        let func = self.symbols.file_write.as_ref().expect("Symbol not load");
290        let name = param::as_cstring("name", name)?;
291        let ret = unsafe {
292            func(
293                self.handle,
294                name.as_ptr() as LPSTR,
295                offset,
296                data.as_ptr() as *const BYTE,
297                data.len() as ULONG,
298            )
299        };
300        trace!("[SKF_WriteFile]: ret = {}", ret);
301        match ret {
302            SAR_OK => Ok(()),
303            _ => Err(Error::Skf(SkfErr::of_code(ret))),
304        }
305    }
306
307    #[instrument]
308    fn get_file_info(&self, name: &str) -> crate::Result<FileAttr> {
309        let func = self
310            .symbols
311            .file_get_info
312            .as_ref()
313            .expect("Symbol not load");
314        let name = param::as_cstring("name", name)?;
315        let mut attr = FileAttribute::default();
316        let ret = unsafe { func(self.handle, name.as_ptr() as LPSTR, &mut attr) };
317        trace!("[SKF_GetFileInfo]: ret = {}", ret);
318        match ret {
319            SAR_OK => Ok(FileAttr::from(&attr)),
320            _ => Err(Error::Skf(SkfErr::of_code(ret))),
321        }
322    }
323}
324
325impl ContainerManager for SkfAppImpl {
326    #[instrument]
327    fn enumerate_container_name(&self) -> crate::Result<Vec<String>> {
328        let func = self
329            .symbols
330            .container_get_list
331            .as_ref()
332            .expect("Symbol not load");
333        let mut len: ULONG = 0;
334        let ret = unsafe { func(self.handle, std::ptr::null_mut(), &mut len) };
335        if ret != SAR_OK {
336            return Err(Error::Skf(SkfErr::of_code(ret)));
337        }
338        trace!("[SKF_EnumContainer]: desired len = {}", len);
339        if len == 0 {
340            return Ok(vec![]);
341        }
342        let mut buff = Vec::<CHAR>::with_capacity(len as usize);
343        let ret = unsafe { func(self.handle, buff.as_mut_ptr(), &mut len) };
344        trace!("[SKF_EnumContainer]: ret = {}", ret);
345        if ret != SAR_OK {
346            return Err(Error::Skf(SkfErr::of_code(ret)));
347        }
348        unsafe { buff.set_len(len as usize) };
349        trace!(
350            "[SKF_EnumContainer]: file list = {}",
351            String::from_utf8_lossy(&buff)
352        );
353        // The spec says string list end with two '\0',but vendor may not do it
354        let list = unsafe { mem::parse_cstr_list_lossy(buff.as_ptr(), buff.len()) };
355        Ok(list)
356    }
357
358    #[instrument]
359    fn create_container(&self, name: &str) -> crate::Result<Box<dyn SkfContainer>> {
360        let func = self
361            .symbols
362            .container_create
363            .as_ref()
364            .expect("Symbol not load");
365        let container_name = param::as_cstring("name", name)?;
366
367        let mut handle: HANDLE = std::ptr::null_mut();
368        let ret = unsafe { func(self.handle, container_name.as_ptr() as LPSTR, &mut handle) };
369        trace!("[SKF_CreateContainer]: ret = {}", ret);
370        match ret {
371            SAR_OK => Ok(Box::new(SkfContainerImpl::new(handle, name, &self.lib)?)),
372            _ => Err(Error::Skf(SkfErr::of_code(ret))),
373        }
374    }
375
376    #[instrument]
377    fn open_container(&self, name: &str) -> crate::Result<Box<dyn SkfContainer>> {
378        let func = self
379            .symbols
380            .container_open
381            .as_ref()
382            .expect("Symbol not load");
383        let container_name = param::as_cstring("name", name)?;
384
385        let mut handle: HANDLE = std::ptr::null_mut();
386        let ret = unsafe { func(self.handle, container_name.as_ptr() as LPSTR, &mut handle) };
387        trace!("[SKF_OpenContainer]: ret = {}", ret);
388        match ret {
389            SAR_OK => Ok(Box::new(SkfContainerImpl::new(handle, name, &self.lib)?)),
390            _ => Err(Error::Skf(SkfErr::of_code(ret))),
391        }
392    }
393
394    #[instrument]
395    fn delete_container(&self, name: &str) -> crate::Result<()> {
396        let func = self
397            .symbols
398            .container_delete
399            .as_ref()
400            .expect("Symbol not load");
401        let container_name = param::as_cstring("name", name)?;
402
403        let ret = unsafe { func(self.handle, container_name.as_ptr() as LPSTR) };
404        trace!("[SKF_DeleteContainer]: ret = {}", ret);
405        match ret {
406            SAR_OK => Ok(()),
407            _ => Err(Error::Skf(SkfErr::of_code(ret))),
408        }
409    }
410}
411
412impl SkfApp for SkfAppImpl {
413    fn name(&self) -> &str {
414        &self.name
415    }
416}
417impl From<&FileAttribute> for FileAttr {
418    fn from(value: &FileAttribute) -> Self {
419        let file_name: String = unsafe {
420            mem::parse_cstr_lossy(value.file_name.as_ptr(), value.file_name.len())
421                .unwrap_or("".to_string())
422        };
423        FileAttr {
424            file_name,
425            file_size: value.file_size as usize,
426            read_rights: value.read_rights,
427            write_rights: value.write_rights,
428        }
429    }
430}
431
432impl FileAttr {
433    pub fn builder() -> FileAttrBuilder {
434        FileAttrBuilder::default()
435    }
436}
437
438impl Default for FileAttrBuilder {
439    fn default() -> Self {
440        Self {
441            file_name: "".into(),
442            file_size: 0,
443            read_rights: FILE_PERM_NONE,
444            write_rights: FILE_PERM_NONE,
445        }
446    }
447}
448impl FileAttrBuilder {
449    pub fn file_name(mut self, val: impl Into<String>) -> Self {
450        self.file_name = val.into();
451        self
452    }
453    pub fn file_size(mut self, val: usize) -> Self {
454        self.file_size = val;
455        self
456    }
457    pub fn read_rights(mut self, val: u32) -> Self {
458        self.read_rights = val;
459        self
460    }
461    pub fn write_rights(mut self, val: u32) -> Self {
462        self.write_rights = val;
463        self
464    }
465    pub fn build(self) -> FileAttr {
466        FileAttr {
467            file_name: self.file_name,
468            file_size: self.file_size,
469            read_rights: self.read_rights,
470            write_rights: self.write_rights,
471        }
472    }
473}
474pub(crate) struct SkfContainerImpl {
475    lib: Arc<libloading::Library>,
476    symbols: ModContainer,
477    handle: HANDLE,
478    name: String,
479}
480
481impl SkfContainerImpl {
482    /// Initialize
483    ///
484    /// [handle] - The application handle
485    ///
486    /// [lib] - The library handle
487    pub fn new(handle: HANDLE, name: &str, lib: &Arc<libloading::Library>) -> crate::Result<Self> {
488        let lc = Arc::clone(lib);
489        let symbols = ModContainer::load_symbols(lib)?;
490        Ok(Self {
491            symbols,
492            handle,
493            lib: lc,
494            name: name.to_string(),
495        })
496    }
497
498    pub fn close(&mut self) -> crate::Result<()> {
499        if let Some(ref func) = self.symbols.ct_close {
500            let ret = unsafe { func(self.handle) };
501            trace!("[SKF_CloseContainer]: ret = {}", ret);
502            if ret != SAR_OK {
503                return Err(Error::Skf(SkfErr::of_code(ret)));
504            }
505            self.handle = std::ptr::null();
506        }
507        Ok(())
508    }
509}
510
511impl Debug for SkfContainerImpl {
512    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
513        write!(f, "SkfContainerImpl({})", &self.name)
514    }
515}
516impl Drop for SkfContainerImpl {
517    fn drop(&mut self) {
518        let _ = self.close();
519    }
520}
521impl SkfContainer for SkfContainerImpl {
522    fn name(&self) -> &str {
523        &self.name
524    }
525
526    #[instrument]
527    fn get_type(&self) -> crate::Result<u32> {
528        let func = self.symbols.ct_get_type.as_ref().expect("Symbol not load");
529        let mut type_value = 0 as ULONG;
530
531        let ret = unsafe { func(self.handle, &mut type_value) };
532        trace!("[SKF_GetContainerType]: ret = {}", ret);
533        match ret {
534            SAR_OK => Ok(type_value as u32),
535            _ => Err(Error::Skf(SkfErr::of_code(ret))),
536        }
537    }
538
539    #[instrument]
540    fn import_certificate(&self, signer: bool, data: &[u8]) -> crate::Result<()> {
541        let func = self.symbols.ct_imp_cert.as_ref().expect("Symbol not load");
542        let signer = match signer {
543            true => TRUE,
544            false => FALSE,
545        };
546
547        let ret = unsafe {
548            func(
549                self.handle,
550                signer,
551                data.as_ptr() as *const BYTE,
552                data.len() as ULONG,
553            )
554        };
555        trace!("[SKF_ImportCertificate]: ret = {}", ret);
556        match ret {
557            SAR_OK => Ok(()),
558            _ => Err(Error::Skf(SkfErr::of_code(ret))),
559        }
560    }
561
562    #[instrument]
563    fn export_certificate(&self, signer: bool) -> crate::Result<Vec<u8>> {
564        let func = self.symbols.ct_exp_cert.as_ref().expect("Symbol not load");
565        let signer = match signer {
566            true => TRUE,
567            false => FALSE,
568        };
569        let mut len: ULONG = 0;
570        let ret = unsafe { func(self.handle, signer, std::ptr::null_mut(), &mut len) };
571        if ret != SAR_OK {
572            return Err(Error::Skf(SkfErr::of_code(ret)));
573        }
574        trace!("[SKF_ExportCertificate]: desired len = {}", len);
575        let mut buff = Vec::<CHAR>::with_capacity(len as usize);
576        let ret = unsafe { func(self.handle, signer, buff.as_mut_ptr(), &mut len) };
577        trace!("[SKF_ExportCertificate]: ret = {}", ret);
578        if ret != SAR_OK {
579            return Err(Error::Skf(SkfErr::of_code(ret)));
580        }
581        unsafe { buff.set_len(len as usize) };
582        Ok(buff)
583    }
584
585    #[instrument]
586    fn ecc_gen_key_pair(&self, alg_id: u32) -> crate::Result<ECCPublicKeyBlob> {
587        let func = self
588            .symbols
589            .ct_ecc_gen_pair
590            .as_ref()
591            .expect("Symbol not load");
592        let mut blob = ECCPublicKeyBlob::default();
593        let ret = unsafe { func(self.handle, alg_id, &mut blob) };
594        trace!("[SKF_GenECCKeyPair]: ret = {}", ret);
595        match ret {
596            SAR_OK => Ok(blob),
597            _ => Err(Error::Skf(SkfErr::of_code(ret))),
598        }
599    }
600
601    #[instrument]
602    fn ecc_import_key_pair(&self, enveloped_key: &EnvelopedKeyData) -> crate::Result<()> {
603        let func = self
604            .symbols
605            .ct_ecc_imp_pair
606            .as_ref()
607            .expect("Symbol not load");
608        let raw_bytes = enveloped_key.blob_bytes();
609        let ret = unsafe { func(self.handle, raw_bytes.as_ptr() as *const EnvelopedKeyBlob) };
610        trace!("[SKF_ImportECCKeyPair]: ret = {}", ret);
611        match ret {
612            SAR_OK => Ok(()),
613            _ => Err(Error::Skf(SkfErr::of_code(ret))),
614        }
615    }
616
617    #[instrument]
618    fn ecc_export_public_key(&self, sign_part: bool) -> crate::Result<Vec<u8>> {
619        let func = self
620            .symbols
621            .ct_ecc_exp_pub_key
622            .as_ref()
623            .expect("Symbol not load");
624        let mut len: ULONG = 0;
625        let ret = unsafe {
626            func(
627                self.handle,
628                sign_part as BOOL,
629                std::ptr::null_mut(),
630                &mut len,
631            )
632        };
633        if ret != SAR_OK {
634            return Err(Error::Skf(SkfErr::of_code(ret)));
635        }
636        trace!("[SKF_EccExportPublicKey]: desired len = {}", len);
637        let mut buff = Vec::<u8>::with_capacity(len as usize);
638        let ret = unsafe {
639            func(
640                self.handle,
641                sign_part as BOOL,
642                buff.as_mut_ptr() as *mut BYTE,
643                &mut len,
644            )
645        };
646        trace!("[SKF_EccExportPublicKey]: ret = {}", ret);
647        if ret != SAR_OK {
648            return Err(Error::Skf(SkfErr::of_code(ret)));
649        }
650        unsafe { buff.set_len(len as usize) };
651        Ok(buff)
652    }
653
654    #[instrument]
655    fn ecc_sign(&self, hash: &[u8]) -> crate::Result<ECCSignatureBlob> {
656        let func = self.symbols.ct_ecc_sign.as_ref().expect("Symbol not load");
657        let mut blob = ECCSignatureBlob::default();
658        let ret = unsafe {
659            func(
660                self.handle,
661                hash.as_ptr() as *const BYTE,
662                hash.len() as ULONG,
663                &mut blob,
664            )
665        };
666        trace!("[SKF_ECCSignData]: ret = {}", ret);
667        match ret {
668            SAR_OK => Ok(blob),
669            _ => Err(Error::Skf(SkfErr::of_code(ret))),
670        }
671    }
672
673    #[instrument]
674    fn sk_gen_agreement_data(
675        &self,
676        alg_id: u32,
677        id: &[u8],
678    ) -> crate::Result<(ECCPublicKeyBlob, Box<dyn ManagedKey>)> {
679        let func = self
680            .symbols
681            .ct_sk_gen_agreement
682            .as_ref()
683            .expect("Symbol not load");
684        let mut handle: HANDLE = std::ptr::null_mut();
685        let mut pub_key = ECCPublicKeyBlob::default();
686        let ret = unsafe {
687            func(
688                self.handle,
689                alg_id as ULONG,
690                &mut pub_key,
691                id.as_ptr() as *const BYTE,
692                id.len() as ULONG,
693                &mut handle,
694            )
695        };
696        trace!("[SKF_GenerateAgreementDataWithECC]: ret = {}", ret);
697        let managed_key = ManagedKeyImpl::try_new(handle, &self.lib)?;
698        match ret {
699            SAR_OK => Ok((pub_key, Box::new(managed_key))),
700            _ => Err(Error::Skf(SkfErr::of_code(ret))),
701        }
702    }
703
704    #[instrument]
705    fn sk_gen_agreement_data_and_key(
706        &self,
707        alg_id: u32,
708        initiator_key: &ECCPublicKeyBlob,
709        initiator_tmp_key: &ECCPublicKeyBlob,
710        initiator_id: &[u8],
711        responder_id: &[u8],
712    ) -> crate::Result<(ECCPublicKeyBlob, Box<dyn ManagedKey>)> {
713        let func = self
714            .symbols
715            .ct_sk_gen_agreement_and_key
716            .as_ref()
717            .expect("Symbol not load");
718        let mut handle: HANDLE = std::ptr::null_mut();
719        let mut pub_key = ECCPublicKeyBlob::default();
720        let ret = unsafe {
721            func(
722                self.handle,
723                alg_id as ULONG,
724                initiator_key,
725                initiator_tmp_key,
726                &mut pub_key,
727                responder_id.as_ptr() as *const BYTE,
728                responder_id.len() as ULONG,
729                initiator_id.as_ptr() as *const BYTE,
730                initiator_id.len() as ULONG,
731                &mut handle,
732            )
733        };
734        trace!("[SKF_GenerateAgreementDataAndKeyWithECC]: ret = {}", ret);
735        let managed_key = ManagedKeyImpl::try_new(handle, &self.lib)?;
736        match ret {
737            SAR_OK => Ok((pub_key, Box::new(managed_key))),
738            _ => Err(Error::Skf(SkfErr::of_code(ret))),
739        }
740    }
741
742    #[instrument]
743    fn sk_import(&self, alg_id: u32, key_data: &[u8]) -> crate::Result<Box<dyn ManagedKey>> {
744        let func = self.symbols.ct_sk_imp.as_ref().expect("Symbol not load");
745        let mut handle: HANDLE = std::ptr::null_mut();
746        let ret = unsafe {
747            func(
748                self.handle,
749                alg_id as ULONG,
750                key_data.as_ptr() as *const BYTE,
751                key_data.len() as ULONG,
752                &mut handle,
753            )
754        };
755        trace!("[SKF_ImportSessionKey]: ret = {}", ret);
756        let managed_key = ManagedKeyImpl::try_new(handle, &self.lib)?;
757        match ret {
758            SAR_OK => Ok(Box::new(managed_key)),
759            _ => Err(Error::Skf(SkfErr::of_code(ret))),
760        }
761    }
762
763    #[instrument]
764    fn sk_export(
765        &self,
766        alg_id: u32,
767        key: &ECCPublicKeyBlob,
768    ) -> crate::Result<(Box<dyn ManagedKey>, ECCEncryptedData)> {
769        let func = self.symbols.ct_sk_exp.as_ref().expect("Symbol not load");
770        let mut handle: HANDLE = std::ptr::null_mut();
771        // guess 256 is big enough
772        let buff_size = ECCCipherBlob::size_of(256);
773        let mut buff: Vec<u8> = vec![0; buff_size];
774
775        let ret = unsafe {
776            func(
777                self.handle,
778                alg_id as ULONG,
779                key as *const ECCPublicKeyBlob,
780                buff.as_mut_ptr() as *mut ECCCipherBlob,
781                &mut handle,
782            )
783        };
784        trace!("[SKF_ECCExportSessionKey]: ret = {}", ret);
785        if ret != SAR_OK {
786            return Err(Error::Skf(SkfErr::of_code(ret)));
787        }
788        let blob = unsafe {
789            let cb = &*(buff.as_ptr() as *const ECCCipherBlob);
790            let mut cipher: Vec<u8> = vec![];
791            if cb.cipher_len > 0 {
792                let len = cb.cipher_len as usize;
793                cipher = vec![0; len];
794                std::ptr::copy(cb.cipher.as_ptr(), cipher.as_mut_ptr(), len);
795            }
796            ECCEncryptedData {
797                ec_x: cb.x_coordinate,
798                ec_y: cb.y_coordinate,
799                hash: cb.hash,
800                cipher,
801            }
802        };
803        let managed_key = ManagedKeyImpl::try_new(handle, &self.lib)?;
804        Ok((Box::new(managed_key), blob))
805    }
806}