Skip to content

Commit 1eb4b10

Browse files
authored
Merge pull request parallaxsecond#59 from mjb3279/clone-context-for-session
Implemented new way of holding the context within the session
2 parents 5dd59e4 + a86a643 commit 1eb4b10

13 files changed

+78
-63
lines changed

cryptoki/src/context/general_purpose.rs

-8
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
use crate::context::{CInitializeArgs, Info, Pkcs11};
66
use crate::error::{Result, Rv};
77
use cryptoki_sys::{CK_C_INITIALIZE_ARGS, CK_INFO};
8-
use std::ptr;
98

109
// See public docs on stub in parent mod.rs
1110
#[inline(always)]
@@ -21,13 +20,6 @@ pub(super) fn initialize(ctx: &Pkcs11, init_args: CInitializeArgs) -> Result<()>
2120
}
2221
}
2322

24-
#[inline(always)]
25-
pub(super) fn finalize_private(ctx: &Pkcs11) -> Result<()> {
26-
// Safe because Session contain a reference to self so that this function can not be called
27-
// while there are live Session instances.
28-
unsafe { Rv::from(get_pkcs11!(ctx, C_Finalize)(ptr::null_mut())).into_result() }
29-
}
30-
3123
// See public docs on stub in parent mod.rs
3224
#[inline(always)]
3325
pub(super) fn get_library_info(ctx: &Pkcs11) -> Result<Info> {

cryptoki/src/context/mod.rs

+39-12
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
macro_rules! get_pkcs11 {
77
($pkcs11:expr, $func_name:ident) => {
88
($pkcs11
9+
.impl_
910
.function_list
1011
.$func_name
1112
.ok_or(crate::error::Error::NullFunctionPointer)?)
@@ -32,18 +33,50 @@ use derivative::Derivative;
3233
use log::error;
3334
use std::mem;
3435
use std::path::Path;
36+
use std::ptr;
37+
use std::sync::Arc;
3538

36-
/// Main PKCS11 context. Should usually be unique per application.
3739
#[derive(Derivative)]
3840
#[derivative(Debug)]
39-
pub struct Pkcs11 {
41+
// Implementation of Pkcs11 class that can be enclosed in a single Arc
42+
pub(crate) struct Pkcs11Impl {
4043
// Even if this field is never read, it is needed for the pointers in function_list to remain
4144
// valid.
4245
#[derivative(Debug = "ignore")]
4346
_pkcs11_lib: cryptoki_sys::Pkcs11,
4447
pub(crate) function_list: cryptoki_sys::_CK_FUNCTION_LIST,
4548
}
4649

50+
impl Pkcs11Impl {
51+
// Private finalize call
52+
#[inline(always)]
53+
fn finalize(&self) -> Result<()> {
54+
unsafe {
55+
Rv::from(self
56+
.function_list
57+
.C_Finalize
58+
.ok_or(Error::NullFunctionPointer)?(
59+
ptr::null_mut()
60+
))
61+
.into_result()
62+
}
63+
}
64+
}
65+
66+
impl Drop for Pkcs11Impl {
67+
fn drop(&mut self) {
68+
if let Err(e) = self.finalize() {
69+
error!("Failed to finalize: {}", e);
70+
}
71+
}
72+
}
73+
74+
/// Main PKCS11 context. Should usually be unique per application.
75+
#[derive(Clone, Debug)]
76+
pub struct Pkcs11 {
77+
pub(crate) impl_: Arc<Pkcs11Impl>,
78+
}
79+
4780
impl Pkcs11 {
4881
/// Instantiate a new context from the path of a PKCS11 dynamic llibrary implementation.
4982
pub fn new<P>(filename: P) -> Result<Self>
@@ -60,8 +93,10 @@ impl Pkcs11 {
6093
let list_ptr = *list.as_ptr();
6194

6295
Ok(Pkcs11 {
63-
_pkcs11_lib: pkcs11_lib,
64-
function_list: *list_ptr,
96+
impl_: Arc::new(Pkcs11Impl {
97+
_pkcs11_lib: pkcs11_lib,
98+
function_list: *list_ptr,
99+
}),
65100
})
66101
}
67102
}
@@ -127,11 +162,3 @@ impl Pkcs11 {
127162
session_management::open_session_no_callback(self, slot_id, flags)
128163
}
129164
}
130-
131-
impl Drop for Pkcs11 {
132-
fn drop(&mut self) {
133-
if let Err(e) = general_purpose::finalize_private(self) {
134-
error!("Failed to finalize: {}", e);
135-
}
136-
}
137-
}

cryptoki/src/context/session_management.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,5 @@ pub(super) fn open_session_no_callback(
2929
.into_result()?;
3030
}
3131

32-
Ok(Session::new(session_handle, ctx))
32+
Ok(Session::new(session_handle, ctx.clone()))
3333
}

cryptoki/src/session/decryption.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::convert::TryInto;
1212
// See public docs on stub in parent mod.rs
1313
#[inline(always)]
1414
pub(super) fn decrypt(
15-
session: &Session<'_>,
15+
session: &Session,
1616
mechanism: &Mechanism,
1717
key: ObjectHandle,
1818
encrypted_data: &[u8],

cryptoki/src/session/encryption.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::convert::TryInto;
1212
// See public docs on stub in parent mod.rs
1313
#[inline(always)]
1414
pub fn encrypt(
15-
session: &Session<'_>,
15+
session: &Session,
1616
mechanism: &Mechanism,
1717
key: ObjectHandle,
1818
data: &[u8],

cryptoki/src/session/key_management.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::convert::TryInto;
1212
// See public docs on stub in parent mod.rs
1313
#[inline(always)]
1414
pub(super) fn generate_key(
15-
session: &Session<'_>,
15+
session: &Session,
1616
mechanism: &Mechanism,
1717
template: &[Attribute],
1818
) -> Result<ObjectHandle> {
@@ -36,7 +36,7 @@ pub(super) fn generate_key(
3636
// See public docs on stub in parent mod.rs
3737
#[inline(always)]
3838
pub(super) fn generate_key_pair(
39-
session: &Session<'_>,
39+
session: &Session,
4040
mechanism: &Mechanism,
4141
pub_key_template: &[Attribute],
4242
priv_key_template: &[Attribute],
@@ -71,7 +71,7 @@ pub(super) fn generate_key_pair(
7171
// See public docs on stub in parent mod.rs
7272
#[inline(always)]
7373
pub(super) fn derive_key(
74-
session: &Session<'_>,
74+
session: &Session,
7575
mechanism: &Mechanism,
7676
base_key: ObjectHandle,
7777
template: &[Attribute],
@@ -97,7 +97,7 @@ pub(super) fn derive_key(
9797
// See public docs on stub in parent mod.rs
9898
#[inline(always)]
9999
pub(super) fn wrap_key(
100-
session: &Session<'_>,
100+
session: &Session,
101101
mechanism: &Mechanism,
102102
wrapping_key: ObjectHandle,
103103
key: ObjectHandle,
@@ -135,7 +135,7 @@ pub(super) fn wrap_key(
135135
// See public docs on stub in parent mod.rs
136136
#[inline(always)]
137137
pub(super) fn unwrap_key(
138-
session: &Session<'_>,
138+
session: &Session,
139139
mechanism: &Mechanism,
140140
unwrapping_key: ObjectHandle,
141141
wrapped_key: &[u8],

cryptoki/src/session/mod.rs

+14-13
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use log::error;
1414
use std::collections::HashMap;
1515
use std::convert::TryInto;
1616
use std::fmt::Formatter;
17+
use std::marker::PhantomData;
1718
use std::ops::Deref;
1819

1920
mod decryption;
@@ -35,46 +36,46 @@ pub use flags::*;
3536
/// threads. A Session needs to be created in its own thread or to be passed by ownership to
3637
/// another thread.
3738
#[derive(Debug)]
38-
pub struct Session<'a> {
39+
pub struct Session {
3940
handle: CK_SESSION_HANDLE,
40-
client: &'a Pkcs11,
41+
client: Pkcs11,
4142
// This is not used but to prevent Session to automatically implement Send and Sync
42-
_guard: *mut u32,
43+
_guard: PhantomData<*mut u32>,
4344
}
4445

45-
impl std::fmt::Display for Session<'_> {
46+
impl std::fmt::Display for Session {
4647
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
4748
write!(f, "{}", self.handle)
4849
}
4950
}
5051

51-
impl std::fmt::LowerHex for Session<'_> {
52+
impl std::fmt::LowerHex for Session {
5253
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
5354
write!(f, "{:08x}", self.handle)
5455
}
5556
}
5657

57-
impl std::fmt::UpperHex for Session<'_> {
58+
impl std::fmt::UpperHex for Session {
5859
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
5960
write!(f, "{:08X}", self.handle)
6061
}
6162
}
6263

6364
// Session does not implement Sync to prevent the same Session instance to be used from multiple
6465
// threads.
65-
unsafe impl<'a> Send for Session<'a> {}
66+
unsafe impl Send for Session {}
6667

67-
impl<'a> Session<'a> {
68-
pub(crate) fn new(handle: CK_SESSION_HANDLE, client: &'a Pkcs11) -> Self {
68+
impl Session {
69+
pub(crate) fn new(handle: CK_SESSION_HANDLE, client: Pkcs11) -> Self {
6970
Session {
7071
handle,
7172
client,
72-
_guard: std::ptr::null_mut::<u32>(),
73+
_guard: PhantomData,
7374
}
7475
}
7576
}
7677

77-
impl Session<'_> {
78+
impl Session {
7879
/// Initialize the normal user's pin for a token
7980
pub fn init_pin(&self, pin: &str) -> Result<()> {
8081
slot_token_management::init_pin(self, pin)
@@ -339,11 +340,11 @@ impl Session<'_> {
339340
}
340341

341342
pub(crate) fn client(&self) -> &Pkcs11 {
342-
self.client
343+
&self.client
343344
}
344345
}
345346

346-
impl Drop for Session<'_> {
347+
impl Drop for Session {
347348
fn drop(&mut self) {
348349
if let Err(e) = session_management::close_private(self) {
349350
error!("Failed to close session: {}", e);

cryptoki/src/session/object_management.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@ const MAX_OBJECT_COUNT: usize = 10;
1414

1515
// See public docs on stub in parent mod.rs
1616
#[inline(always)]
17-
pub(super) fn find_objects(
18-
session: &Session<'_>,
19-
template: &[Attribute],
20-
) -> Result<Vec<ObjectHandle>> {
17+
pub(super) fn find_objects(session: &Session, template: &[Attribute]) -> Result<Vec<ObjectHandle>> {
2118
let mut template: Vec<CK_ATTRIBUTE> = template.iter().map(|attr| attr.into()).collect();
2219

2320
unsafe {
@@ -71,7 +68,7 @@ pub(super) fn find_objects(
7168

7269
// See public docs on stub in parent mod.rs
7370
#[inline(always)]
74-
pub(super) fn create_object(session: &Session<'_>, template: &[Attribute]) -> Result<ObjectHandle> {
71+
pub(super) fn create_object(session: &Session, template: &[Attribute]) -> Result<ObjectHandle> {
7572
let mut template: Vec<CK_ATTRIBUTE> = template.iter().map(|attr| attr.into()).collect();
7673
let mut object_handle = 0;
7774

@@ -90,7 +87,7 @@ pub(super) fn create_object(session: &Session<'_>, template: &[Attribute]) -> Re
9087

9188
// See public docs on stub in parent mod.rs
9289
#[inline(always)]
93-
pub(super) fn destroy_object(session: &Session<'_>, object: ObjectHandle) -> Result<()> {
90+
pub(super) fn destroy_object(session: &Session, object: ObjectHandle) -> Result<()> {
9491
unsafe {
9592
Rv::from(get_pkcs11!(session.client(), C_DestroyObject)(
9693
session.handle(),
@@ -103,7 +100,7 @@ pub(super) fn destroy_object(session: &Session<'_>, object: ObjectHandle) -> Res
103100
// See public docs on stub in parent mod.rs
104101
#[inline(always)]
105102
pub(super) fn get_attribute_info(
106-
session: &Session<'_>,
103+
session: &Session,
107104
object: ObjectHandle,
108105
attributes: &[AttributeType],
109106
) -> Result<Vec<AttributeInfo>> {
@@ -136,7 +133,7 @@ pub(super) fn get_attribute_info(
136133
// See public docs on stub in parent mod.rs
137134
#[inline(always)]
138135
pub(super) fn get_attribute_info_map(
139-
session: &Session<'_>,
136+
session: &Session,
140137
object: ObjectHandle,
141138
attributes: Vec<AttributeType>,
142139
) -> Result<HashMap<AttributeType, AttributeInfo>> {
@@ -152,7 +149,7 @@ pub(super) fn get_attribute_info_map(
152149
// See public docs on stub in parent mod.rs
153150
#[inline(always)]
154151
pub(super) fn get_attributes(
155-
session: &Session<'_>,
152+
session: &Session,
156153
object: ObjectHandle,
157154
attributes: &[AttributeType],
158155
) -> Result<Vec<Attribute>> {

cryptoki/src/session/random.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::convert::TryInto;
88

99
// See public docs on stub in parent mod.rs
1010
#[inline(always)]
11-
pub(super) fn generate_random_slice(session: &Session<'_>, random_data: &mut [u8]) -> Result<()> {
11+
pub(super) fn generate_random_slice(session: &Session, random_data: &mut [u8]) -> Result<()> {
1212
unsafe {
1313
Rv::from(get_pkcs11!(session.client(), C_GenerateRandom)(
1414
session.handle(),
@@ -22,7 +22,7 @@ pub(super) fn generate_random_slice(session: &Session<'_>, random_data: &mut [u8
2222

2323
// See public docs on stub in parent mod.rs
2424
#[inline(always)]
25-
pub(super) fn generate_random_vec(session: &Session<'_>, random_len: u32) -> Result<Vec<u8>> {
25+
pub(super) fn generate_random_vec(session: &Session, random_len: u32) -> Result<Vec<u8>> {
2626
let mut result: Vec<u8> = vec![0; random_len as usize];
2727
unsafe {
2828
Rv::from(get_pkcs11!(session.client(), C_GenerateRandom)(
@@ -37,7 +37,7 @@ pub(super) fn generate_random_vec(session: &Session<'_>, random_len: u32) -> Res
3737

3838
// See public docs on stub in parent mod.rs
3939
#[inline(always)]
40-
pub(super) fn seed_random(session: &Session<'_>, seed: &[u8]) -> Result<()> {
40+
pub(super) fn seed_random(session: &Session, seed: &[u8]) -> Result<()> {
4141
unsafe {
4242
Rv::from(get_pkcs11!(session.client(), C_SeedRandom)(
4343
session.handle(),

cryptoki/src/session/session_management.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::convert::TryInto;
99

1010
// See public docs on close() in parent mod.rs
1111
#[inline(always)]
12-
pub(super) fn close_private(session: &Session<'_>) -> Result<()> {
12+
pub(super) fn close_private(session: &Session) -> Result<()> {
1313
unsafe {
1414
Rv::from(get_pkcs11!(session.client(), C_CloseSession)(
1515
session.handle(),
@@ -20,7 +20,7 @@ pub(super) fn close_private(session: &Session<'_>) -> Result<()> {
2020

2121
// See public docs on stub in parent mod.rs
2222
#[inline(always)]
23-
pub(super) fn login(session: &Session<'_>, user_type: UserType, pin: Option<&str>) -> Result<()> {
23+
pub(super) fn login(session: &Session, user_type: UserType, pin: Option<&str>) -> Result<()> {
2424
let (pin, pin_len) = match pin {
2525
Some(pin) => (pin.as_ptr() as *mut u8, pin.len()),
2626
None => (std::ptr::null_mut(), 0),
@@ -38,13 +38,13 @@ pub(super) fn login(session: &Session<'_>, user_type: UserType, pin: Option<&str
3838

3939
// See public docs on stub in parent mod.rs
4040
#[inline(always)]
41-
pub(super) fn logout(session: &Session<'_>) -> Result<()> {
41+
pub(super) fn logout(session: &Session) -> Result<()> {
4242
unsafe { Rv::from(get_pkcs11!(session.client(), C_Logout)(session.handle())).into_result() }
4343
}
4444

4545
// See public docs on stub in parent mod.rs
4646
#[inline(always)]
47-
pub(super) fn get_session_info(session: &Session<'_>) -> Result<SessionInfo> {
47+
pub(super) fn get_session_info(session: &Session) -> Result<SessionInfo> {
4848
let mut session_info = CK_SESSION_INFO::default();
4949
unsafe {
5050
Rv::from(get_pkcs11!(session.client(), C_GetSessionInfo)(

cryptoki/src/session/signing_macing.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::convert::TryInto;
1212
// See public docs on stub in parent mod.rs
1313
#[inline(always)]
1414
pub(super) fn sign(
15-
session: &Session<'_>,
15+
session: &Session,
1616
mechanism: &Mechanism,
1717
key: ObjectHandle,
1818
data: &[u8],
@@ -63,7 +63,7 @@ pub(super) fn sign(
6363
// See public docs on stub in parent mod.rs
6464
#[inline(always)]
6565
pub(super) fn verify(
66-
session: &Session<'_>,
66+
session: &Session,
6767
mechanism: &Mechanism,
6868
key: ObjectHandle,
6969
data: &[u8],

0 commit comments

Comments
 (0)