From 5bd3664d4fd286b5da92e784729b7a26aaad1f59 Mon Sep 17 00:00:00 2001 From: Eric Devolder Date: Wed, 28 Aug 2024 09:06:28 +0200 Subject: [PATCH 1/4] Implement Session.copy_object() Signed-off-by: Eric Devolder --- cryptoki/src/session/object_management.rs | 35 +++++++++++++++ cryptoki/tests/basic.rs | 53 +++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/cryptoki/src/session/object_management.rs b/cryptoki/src/session/object_management.rs index dae2b611..5d686fd6 100644 --- a/cryptoki/src/session/object_management.rs +++ b/cryptoki/src/session/object_management.rs @@ -96,6 +96,41 @@ impl Session { } } + /// Copy an object + /// A optional 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` - an optional reference to a slice of attributes, in the form of `Some(&[Attribute])`, + /// or set to `None`` if not needed. + /// + /// # Returns + /// + /// This function will return a new [ObjectHandle] that references the newly created object. + /// + pub fn copy_object(&self, object: ObjectHandle, template: Option<&[Attribute]>) -> Result { + let mut template: Vec = match template { + Some(template) => template.iter().map(|attr| attr.into()).collect(), + None => Vec::new(), + }; + + 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::CreateObject)?; + } + + Ok(ObjectHandle::new(object_handle)) + } + /// Get the attribute info of an object: if the attribute is present and its size. /// /// # Arguments diff --git a/cryptoki/tests/basic.rs b/cryptoki/tests/basic.rs index dbb6084e..432a413a 100644 --- a/cryptoki/tests/basic.rs +++ b/cryptoki/tests/basic.rs @@ -838,6 +838,59 @@ 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, None)?; + rw_session.destroy_object(copy)?; + + // copy the object with a template + let copy = rw_session.copy_object(object, Some(©_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, Some(&insecure_copy_template)).unwrap_err(); + + // delete keys + rw_session.destroy_object(object)?; + rw_session.logout()?; + + Ok(()) +} + + #[test] #[serial] fn aes_cbc_encrypt() -> TestResult { From 9fe0885e645a9ba58b9c38cf51c28883e4d2266e Mon Sep 17 00:00:00 2001 From: Eric Devolder Date: Wed, 28 Aug 2024 10:13:03 +0200 Subject: [PATCH 2/4] Adjusted interface to remove `Option<>` enum around template Signed-off-by: Eric Devolder --- cryptoki/src/session/object_management.rs | 13 ++++--------- cryptoki/tests/basic.rs | 6 +++--- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/cryptoki/src/session/object_management.rs b/cryptoki/src/session/object_management.rs index 5d686fd6..09ee9ea2 100644 --- a/cryptoki/src/session/object_management.rs +++ b/cryptoki/src/session/object_management.rs @@ -97,24 +97,19 @@ impl Session { } /// Copy an object - /// A optional template can be provided to change some attributes of the new object, when allowed. + /// 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` - an optional reference to a slice of attributes, in the form of `Some(&[Attribute])`, - /// or set to `None`` if not needed. + /// * `template` - a reference to a slice of attributes /// /// # Returns /// /// This function will return a new [ObjectHandle] that references the newly created object. /// - pub fn copy_object(&self, object: ObjectHandle, template: Option<&[Attribute]>) -> Result { - let mut template: Vec = match template { - Some(template) => template.iter().map(|attr| attr.into()).collect(), - None => Vec::new(), - }; - + pub fn copy_object(&self, object: ObjectHandle, template: &[Attribute]) -> Result { + let mut template: Vec = template.iter().map(|attr| attr.into()).collect(); let mut object_handle = 0; unsafe { diff --git a/cryptoki/tests/basic.rs b/cryptoki/tests/basic.rs index 432a413a..2a45e714 100644 --- a/cryptoki/tests/basic.rs +++ b/cryptoki/tests/basic.rs @@ -873,15 +873,15 @@ fn session_copy_object() -> TestResult { let object = rw_session.generate_key(&Mechanism::AesKeyGen, &aes128_template)?; // copy the object without a template - let copy = rw_session.copy_object(object, None)?; + 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, Some(©_template))?; + let copy = rw_session.copy_object(object, ©_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, Some(&insecure_copy_template)).unwrap_err(); + rw_session.copy_object(object, &insecure_copy_template).unwrap_err(); // delete keys rw_session.destroy_object(object)?; From 1df96238913beae89abffa88fb12545f2f95e4d1 Mon Sep 17 00:00:00 2001 From: Eric Devolder Date: Wed, 28 Aug 2024 13:31:31 +0200 Subject: [PATCH 3/4] fixing formatting issues reported by fmt Signed-off-by: Eric Devolder --- cryptoki/src/session/object_management.rs | 6 +++++- cryptoki/tests/basic.rs | 13 +++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/cryptoki/src/session/object_management.rs b/cryptoki/src/session/object_management.rs index 09ee9ea2..782d42cb 100644 --- a/cryptoki/src/session/object_management.rs +++ b/cryptoki/src/session/object_management.rs @@ -108,7 +108,11 @@ impl Session { /// /// This function will return a new [ObjectHandle] that references the newly created object. /// - pub fn copy_object(&self, object: ObjectHandle, template: &[Attribute]) -> Result { + pub fn copy_object( + &self, + object: ObjectHandle, + template: &[Attribute], + ) -> Result { let mut template: Vec = template.iter().map(|attr| attr.into()).collect(); let mut object_handle = 0; diff --git a/cryptoki/tests/basic.rs b/cryptoki/tests/basic.rs index 2a45e714..2a3233b9 100644 --- a/cryptoki/tests/basic.rs +++ b/cryptoki/tests/basic.rs @@ -853,13 +853,9 @@ fn session_copy_object() -> TestResult { Attribute::Label("original".as_bytes().to_vec()), ]; - let copy_template = vec![ - Attribute::Label("copy".as_bytes().to_vec()), - ]; + let copy_template = vec![Attribute::Label("copy".as_bytes().to_vec())]; - let insecure_copy_template = vec![ - Attribute::Extractable(true), - ]; + let insecure_copy_template = vec![Attribute::Extractable(true)]; let (pkcs11, slot) = init_pins(); @@ -881,7 +877,9 @@ fn session_copy_object() -> TestResult { 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(); + rw_session + .copy_object(object, &insecure_copy_template) + .unwrap_err(); // delete keys rw_session.destroy_object(object)?; @@ -890,7 +888,6 @@ fn session_copy_object() -> TestResult { Ok(()) } - #[test] #[serial] fn aes_cbc_encrypt() -> TestResult { From 0f70d42a58f5215d0adf335d9832ea77bd32db07 Mon Sep 17 00:00:00 2001 From: Eric Devolder Date: Fri, 30 Aug 2024 21:21:24 +0200 Subject: [PATCH 4/4] small changes following review Signed-off-by: Eric Devolder --- cryptoki/src/session/object_management.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cryptoki/src/session/object_management.rs b/cryptoki/src/session/object_management.rs index 782d42cb..cffed5e4 100644 --- a/cryptoki/src/session/object_management.rs +++ b/cryptoki/src/session/object_management.rs @@ -97,12 +97,14 @@ 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` - a reference to a slice of attributes + /// * `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 /// @@ -124,7 +126,7 @@ impl Session { template.len().try_into()?, &mut object_handle as CK_OBJECT_HANDLE_PTR, )) - .into_result(Function::CreateObject)?; + .into_result(Function::CopyObject)?; } Ok(ObjectHandle::new(object_handle))