Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Session.copy_object() #215

Merged
merged 6 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
keldonin marked this conversation as resolved.
Show resolved Hide resolved
///
/// # 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
Loading