Skip to content

Commit

Permalink
Merge pull request #215 from keldonin/implement_session_copy_object
Browse files Browse the repository at this point in the history
Implement Session.copy_object()
  • Loading branch information
hug-dev authored Sep 2, 2024
2 parents d6c47a5 + 484de47 commit e0a9e17
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 0 deletions.
36 changes: 36 additions & 0 deletions cryptoki/src/session/object_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,42 @@ impl Session {
}
}

/// Copy an object
///
/// A template can be provided to change some attributes of the new object, when allowed.
///
/// # Arguments
///
/// * `object` - The [ObjectHandle] used to reference the object to copy
/// * `template` - new values for any attributes of the object that can ordinarily be modified
/// 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
///
/// # Returns
///
/// This function will return a new [ObjectHandle] that references the newly created object.
///
pub fn copy_object(
&self,
object: ObjectHandle,
template: &[Attribute],
) -> Result<ObjectHandle> {
let mut template: Vec<CK_ATTRIBUTE> = template.iter().map(|attr| attr.into()).collect();
let mut object_handle = 0;

unsafe {
Rv::from(get_pkcs11!(self.client(), C_CopyObject)(
self.handle(),
object.handle(),
template.as_mut_ptr(),
template.len().try_into()?,
&mut object_handle as CK_OBJECT_HANDLE_PTR,
))
.into_result(Function::CopyObject)?;
}

Ok(ObjectHandle::new(object_handle))
}

/// Get the attribute info of an object: if the attribute is present and its size.
///
/// # Arguments
Expand Down
50 changes: 50 additions & 0 deletions cryptoki/tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,56 @@ fn ro_rw_session_test() -> TestResult {
Ok(())
}

#[test]
#[serial]
fn session_copy_object() -> TestResult {
let aes128_template = [
Attribute::Class(ObjectClass::SECRET_KEY),
Attribute::KeyType(KeyType::AES),
Attribute::Encrypt(true),
Attribute::Token(false),
Attribute::Private(true),
Attribute::Sensitive(true),
Attribute::Extractable(false),
Attribute::ValueLen(16.into()),
Attribute::Label("original".as_bytes().to_vec()),
];

let copy_template = vec![Attribute::Label("copy".as_bytes().to_vec())];

let insecure_copy_template = vec![Attribute::Extractable(true)];

let (pkcs11, slot) = init_pins();

// open a session
let rw_session = pkcs11.open_rw_session(slot)?;

// log in the session
rw_session.login(UserType::User, Some(&AuthPin::new(USER_PIN.into())))?;

// create a key object
let object = rw_session.generate_key(&Mechanism::AesKeyGen, &aes128_template)?;

// copy the object without a template
let copy = rw_session.copy_object(object, &[])?;
rw_session.destroy_object(copy)?;

// copy the object with a template
let copy = rw_session.copy_object(object, &copy_template)?;
rw_session.destroy_object(copy)?;

// try the copy with the insecure template. It should fail. Returning CKR_OK is considered a failure.
rw_session
.copy_object(object, &insecure_copy_template)
.unwrap_err();

// delete keys
rw_session.destroy_object(object)?;
rw_session.logout()?;

Ok(())
}

#[test]
#[serial]
fn aes_cbc_encrypt() -> TestResult {
Expand Down

0 comments on commit e0a9e17

Please sign in to comment.