From a99ad88cf2bcf5ed7bf892b114b54cec67fcf50c Mon Sep 17 00:00:00 2001 From: Jack Shannon Date: Tue, 14 Oct 2025 15:20:19 -0400 Subject: [PATCH] Add pub accessors for object/session handles and unsafe ObjectHandle new_from_raw Signed-off-by: Jack Shannon --- cryptoki/src/object.rs | 10 ++++++- cryptoki/src/session/mod.rs | 3 ++- cryptoki/tests/basic.rs | 52 +++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/cryptoki/src/object.rs b/cryptoki/src/object.rs index b242fa06..8ec7e11e 100644 --- a/cryptoki/src/object.rs +++ b/cryptoki/src/object.rs @@ -1193,7 +1193,15 @@ impl ObjectHandle { ObjectHandle { handle } } - pub(crate) fn handle(&self) -> CK_OBJECT_HANDLE { + /// Create a new object handle from a raw handle. + /// # Safety + /// Considered unsafe due to ability for client to arbitrarily create object handles. + pub unsafe fn new_from_raw(handle: CK_OBJECT_HANDLE) -> Self { + ObjectHandle { handle } + } + + /// Get the raw handle of the object. + pub fn handle(&self) -> CK_OBJECT_HANDLE { self.handle } } diff --git a/cryptoki/src/session/mod.rs b/cryptoki/src/session/mod.rs index 119e73d0..d71dab05 100644 --- a/cryptoki/src/session/mod.rs +++ b/cryptoki/src/session/mod.rs @@ -78,7 +78,8 @@ impl Session { /// This will be called on drop as well. pub fn close(self) {} - pub(crate) fn handle(&self) -> CK_SESSION_HANDLE { + /// Get the raw handle of the session. + pub fn handle(&self) -> CK_SESSION_HANDLE { self.handle } diff --git a/cryptoki/tests/basic.rs b/cryptoki/tests/basic.rs index 4ec739bc..927d56d4 100644 --- a/cryptoki/tests/basic.rs +++ b/cryptoki/tests/basic.rs @@ -4296,3 +4296,55 @@ fn validation() -> TestResult { Ok(()) } + +#[test] +#[serial] +fn object_handle_new_from_raw() -> TestResult { + let (pkcs11, slot) = init_pins(); + + // open a session + let session = pkcs11.open_rw_session(slot)?; + + // log in the session + session.login(UserType::User, Some(&AuthPin::new(USER_PIN.into())))?; + + // get mechanism + let mechanism = Mechanism::RsaPkcsKeyPairGen; + + let public_exponent: Vec = vec![0x01, 0x00, 0x01]; + let modulus_bits = 2048; + + // pub key template + let pub_key_template = vec![ + Attribute::Token(true), + Attribute::Private(false), + Attribute::PublicExponent(public_exponent), + Attribute::ModulusBits(modulus_bits.into()), + Attribute::Verify(true), + ]; + + // priv key template + let priv_key_template = vec![Attribute::Token(true), Attribute::Sign(true)]; + + // generate a key pair + let (public, private) = + session.generate_key_pair(&mechanism, &pub_key_template, &priv_key_template)?; + + let private_cloned = unsafe { ObjectHandle::new_from_raw(private.handle()) }; + let public_cloned = unsafe { ObjectHandle::new_from_raw(public.handle()) }; + + // data to sign + let data = [0xFF, 0x55, 0xDD]; + + // sign something with it + let signature = session.sign(&Mechanism::RsaPkcs, private_cloned, &data)?; + + // verify the signature + session.verify(&Mechanism::RsaPkcs, public_cloned, &data, &signature)?; + + // delete keys + session.destroy_object(public)?; + session.destroy_object(private)?; + + Ok(()) +}