@@ -6,13 +6,13 @@ use libparsec_platform_async::future::FutureExt as _;
6
6
use std:: path:: { Path , PathBuf } ;
7
7
use uuid:: Uuid ;
8
8
9
- use libparsec_types:: prelude:: * ;
10
-
11
9
use crate :: {
12
- get_device_archive_path, ArchiveDeviceError , ListAvailableDeviceError , LoadCiphertextKeyError ,
13
- LoadDeviceError , ReadFileError , RemoveDeviceError , SaveDeviceError , UpdateDeviceError ,
14
- DEVICE_FILE_EXT ,
10
+ encrypt_device , get_device_archive_path, ArchiveDeviceError , ListAvailableDeviceError ,
11
+ LoadCiphertextKeyError , LoadDeviceError , ReadFileError , RemoveDeviceError , SaveDeviceError ,
12
+ UpdateDeviceError , DEVICE_FILE_EXT ,
15
13
} ;
14
+ use libparsec_platform_pki:: { decrypt_secret_key, encrypt_secret_key} ;
15
+ use libparsec_types:: prelude:: * ;
16
16
17
17
const KEYRING_SERVICE : & str = "parsec" ;
18
18
@@ -152,9 +152,16 @@ pub(super) async fn load_ciphertext_key(
152
152
Ok ( key)
153
153
}
154
154
155
- ( DeviceAccessStrategy :: Smartcard { .. } , DeviceFile :: Smartcard ( _) ) => {
156
- todo ! ( "Load smartcard device" )
157
- }
155
+ (
156
+ DeviceAccessStrategy :: Smartcard {
157
+ certificate_reference,
158
+ ..
159
+ } ,
160
+ DeviceFile :: Smartcard ( device) ,
161
+ ) => Ok (
162
+ decrypt_secret_key ( & device. encrypted_key , certificate_reference)
163
+ . map_err ( |_| LoadCiphertextKeyError :: InvalidData ) ?,
164
+ ) ,
158
165
159
166
(
160
167
DeviceAccessStrategy :: AccountVault { ciphertext_key, .. } ,
@@ -303,8 +310,48 @@ pub(super) async fn save_device(
303
310
save_content ( key_file, & file_content) . await ?;
304
311
}
305
312
306
- DeviceAccessStrategy :: Smartcard { .. } => {
307
- todo ! ( "Save smartcard device" )
313
+ DeviceAccessStrategy :: Smartcard {
314
+ key_file,
315
+ certificate_reference,
316
+ } => {
317
+ // Generate a random key
318
+ let secret_key = SecretKey :: generate ( ) ;
319
+
320
+ // Encrypt the key using the public key related to a certificate from the store
321
+
322
+ let ( encrypted_key, certificate_id, certificate_sha1) =
323
+ encrypt_secret_key ( & secret_key, certificate_reference)
324
+ . map_err ( |e| SaveDeviceError :: Internal ( e. into ( ) ) ) ?;
325
+
326
+ // May check if we are able to decrypt the encrypted key from the previous step
327
+ assert_eq ! (
328
+ decrypt_secret_key( & encrypted_key, certificate_reference)
329
+ . map_err( |e| SaveDeviceError :: Internal ( e. into( ) ) ) ?,
330
+ secret_key
331
+ ) ;
332
+
333
+ // Use the generated key to encrypt the device content
334
+ let ciphertext = encrypt_device ( device, & secret_key) ;
335
+
336
+ // Save
337
+ let file_content = DeviceFile :: Smartcard ( DeviceFileSmartcard {
338
+ created_on,
339
+ protected_on,
340
+ server_url : server_url. clone ( ) ,
341
+ organization_id : device. organization_id ( ) . to_owned ( ) ,
342
+ user_id : device. user_id ,
343
+ device_id : device. device_id ,
344
+ human_handle : device. human_handle . to_owned ( ) ,
345
+ device_label : device. device_label . to_owned ( ) ,
346
+ certificate_id,
347
+ certificate_sha1 : Some ( Bytes :: copy_from_slice ( certificate_sha1. as_ref ( ) ) ) ,
348
+ encrypted_key,
349
+ ciphertext,
350
+ } ) ;
351
+
352
+ let file_content = file_content. dump ( ) ;
353
+
354
+ save_content ( key_file, & file_content) . await ?;
308
355
}
309
356
310
357
DeviceAccessStrategy :: AccountVault {
0 commit comments