Skip to content

Commit e0a9e17

Browse files
authored
Merge pull request #215 from keldonin/implement_session_copy_object
Implement Session.copy_object()
2 parents d6c47a5 + 484de47 commit e0a9e17

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

cryptoki/src/session/object_management.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,42 @@ impl Session {
9494
}
9595
}
9696

97+
/// Copy an object
98+
///
99+
/// A template can be provided to change some attributes of the new object, when allowed.
100+
///
101+
/// # Arguments
102+
///
103+
/// * `object` - The [ObjectHandle] used to reference the object to copy
104+
/// * `template` - new values for any attributes of the object that can ordinarily be modified
105+
/// check out [PKCS#11 documentation](https://docs.oasis-open.org/pkcs11/pkcs11-spec/v3.1/cs01/pkcs11-spec-v3.1-cs01.html#_Toc111203284) for details
106+
///
107+
/// # Returns
108+
///
109+
/// This function will return a new [ObjectHandle] that references the newly created object.
110+
///
111+
pub fn copy_object(
112+
&self,
113+
object: ObjectHandle,
114+
template: &[Attribute],
115+
) -> Result<ObjectHandle> {
116+
let mut template: Vec<CK_ATTRIBUTE> = template.iter().map(|attr| attr.into()).collect();
117+
let mut object_handle = 0;
118+
119+
unsafe {
120+
Rv::from(get_pkcs11!(self.client(), C_CopyObject)(
121+
self.handle(),
122+
object.handle(),
123+
template.as_mut_ptr(),
124+
template.len().try_into()?,
125+
&mut object_handle as CK_OBJECT_HANDLE_PTR,
126+
))
127+
.into_result(Function::CopyObject)?;
128+
}
129+
130+
Ok(ObjectHandle::new(object_handle))
131+
}
132+
97133
/// Get the attribute info of an object: if the attribute is present and its size.
98134
///
99135
/// # Arguments

cryptoki/tests/basic.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,56 @@ fn ro_rw_session_test() -> TestResult {
893893
Ok(())
894894
}
895895

896+
#[test]
897+
#[serial]
898+
fn session_copy_object() -> TestResult {
899+
let aes128_template = [
900+
Attribute::Class(ObjectClass::SECRET_KEY),
901+
Attribute::KeyType(KeyType::AES),
902+
Attribute::Encrypt(true),
903+
Attribute::Token(false),
904+
Attribute::Private(true),
905+
Attribute::Sensitive(true),
906+
Attribute::Extractable(false),
907+
Attribute::ValueLen(16.into()),
908+
Attribute::Label("original".as_bytes().to_vec()),
909+
];
910+
911+
let copy_template = vec![Attribute::Label("copy".as_bytes().to_vec())];
912+
913+
let insecure_copy_template = vec![Attribute::Extractable(true)];
914+
915+
let (pkcs11, slot) = init_pins();
916+
917+
// open a session
918+
let rw_session = pkcs11.open_rw_session(slot)?;
919+
920+
// log in the session
921+
rw_session.login(UserType::User, Some(&AuthPin::new(USER_PIN.into())))?;
922+
923+
// create a key object
924+
let object = rw_session.generate_key(&Mechanism::AesKeyGen, &aes128_template)?;
925+
926+
// copy the object without a template
927+
let copy = rw_session.copy_object(object, &[])?;
928+
rw_session.destroy_object(copy)?;
929+
930+
// copy the object with a template
931+
let copy = rw_session.copy_object(object, &copy_template)?;
932+
rw_session.destroy_object(copy)?;
933+
934+
// try the copy with the insecure template. It should fail. Returning CKR_OK is considered a failure.
935+
rw_session
936+
.copy_object(object, &insecure_copy_template)
937+
.unwrap_err();
938+
939+
// delete keys
940+
rw_session.destroy_object(object)?;
941+
rw_session.logout()?;
942+
943+
Ok(())
944+
}
945+
896946
#[test]
897947
#[serial]
898948
fn aes_cbc_encrypt() -> TestResult {

0 commit comments

Comments
 (0)