Skip to content

Commit 7c0839c

Browse files
jhshannon17jack-shannon-ripple
authored andcommitted
Add pub unsafe accessors for object/session handles and ObjectHandle new
Signed-off-by: Jack Shannon <[email protected]>
1 parent 3ac2766 commit 7c0839c

File tree

4 files changed

+204
-2
lines changed

4 files changed

+204
-2
lines changed

cryptoki/src/object.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,9 +1029,23 @@ impl ObjectHandle {
10291029
ObjectHandle { handle }
10301030
}
10311031

1032+
/// Create a new object handle from a raw handle.
1033+
/// # Safety
1034+
/// Considered unsafe due to ability for client to arbitrarily create object handles.
1035+
pub unsafe fn new_from_raw(handle: CK_OBJECT_HANDLE) -> Self {
1036+
ObjectHandle { handle }
1037+
}
1038+
10321039
pub(crate) fn handle(&self) -> CK_OBJECT_HANDLE {
10331040
self.handle
10341041
}
1042+
1043+
/// Get the raw handle of the object.
1044+
/// # Safety
1045+
/// Considered unsafe because of pub access to the underlying handle type.
1046+
pub unsafe fn raw_handle(&self) -> CK_OBJECT_HANDLE {
1047+
self.handle
1048+
}
10351049
}
10361050

10371051
impl std::fmt::Display for ObjectHandle {

cryptoki/src/session/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@ impl Session {
8080
self.handle
8181
}
8282

83+
/// Get the raw handle of the session.
84+
/// # Safety
85+
/// Considered unsafe because of pub access to the underlying handle type.
86+
pub unsafe fn raw_handle(&self) -> CK_SESSION_HANDLE {
87+
self.handle
88+
}
89+
8390
pub(crate) fn client(&self) -> &Pkcs11 {
8491
&self.client
8592
}

cryptoki/tests/common/mod.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub static USER_PIN: &str = "fedcba";
1111
// The default SO pin
1212
pub static SO_PIN: &str = "abcdef";
1313

14-
fn get_pkcs11_path() -> String {
14+
pub fn get_pkcs11_path() -> String {
1515
env::var("TEST_PKCS11_MODULE")
1616
.unwrap_or_else(|_| "/usr/local/lib/softhsm/libsofthsm2.so".to_string())
1717
}
@@ -26,13 +26,26 @@ pub fn is_kryoptic() -> bool {
2626
get_pkcs11_path().contains("kryoptic")
2727
}
2828

29+
#[allow(dead_code)]
2930
pub fn get_pkcs11() -> Pkcs11 {
3031
Pkcs11::new(get_pkcs11_path()).unwrap()
3132
}
3233

34+
#[allow(dead_code)]
35+
pub fn get_pkcs11_from_self() -> Pkcs11 {
36+
Pkcs11::new_from_self().unwrap()
37+
}
38+
39+
#[allow(dead_code)]
3340
pub fn init_pins() -> (Pkcs11, Slot) {
3441
let pkcs11 = get_pkcs11();
3542

43+
let slot = init_pins_from_pkcs11(&pkcs11);
44+
45+
(pkcs11, slot)
46+
}
47+
48+
pub fn init_pins_from_pkcs11(pkcs11: &Pkcs11) -> Slot {
3649
// initialize the library
3750
pkcs11.initialize(CInitializeArgs::OsThreads).unwrap();
3851

@@ -50,7 +63,7 @@ pub fn init_pins() -> (Pkcs11, Slot) {
5063
session.init_pin(&AuthPin::new(USER_PIN.into())).unwrap();
5164
}
5265

53-
(pkcs11, slot)
66+
slot
5467
}
5568

5669
#[allow(dead_code)]
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
// Copyright 2021 Contributors to the Parsec project.
2+
// SPDX-License-Identifier: Apache-2.0
3+
#![allow(non_camel_case_types)]
4+
#![allow(non_snake_case)]
5+
6+
mod common;
7+
8+
use crate::common::{get_pkcs11_path, USER_PIN};
9+
use common::{get_pkcs11_from_self, init_pins_from_pkcs11};
10+
use cryptoki::context::Function;
11+
use cryptoki::error::{Result, Rv};
12+
use cryptoki::mechanism::Mechanism;
13+
use cryptoki::object::{Attribute, AttributeType, KeyType, ObjectClass, ObjectHandle};
14+
use cryptoki::session::{Session, UserType};
15+
use cryptoki::types::AuthPin;
16+
use cryptoki_sys::{
17+
CK_ATTRIBUTE, CK_MECHANISM, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_RV, CK_SESSION_HANDLE,
18+
CK_ULONG,
19+
};
20+
use libloading::os::unix::{RTLD_GLOBAL, RTLD_NOW};
21+
use serial_test::serial;
22+
23+
use testresult::TestResult;
24+
25+
type C_DeriveKey = unsafe extern "C" fn(
26+
arg1: CK_SESSION_HANDLE,
27+
arg2: *mut CK_MECHANISM,
28+
arg3: CK_OBJECT_HANDLE,
29+
arg4: *mut CK_ATTRIBUTE,
30+
arg5: CK_ULONG,
31+
arg6: *mut CK_OBJECT_HANDLE,
32+
) -> CK_RV;
33+
34+
fn load_from_library(library_path: String) -> Result<(libloading::Library, C_DeriveKey)> {
35+
let library = unsafe {
36+
libloading::os::unix::Library::open(Some(library_path), RTLD_NOW | RTLD_GLOBAL)
37+
.expect("this should never fail")
38+
};
39+
40+
let C_DeriveKey = unsafe { library.get(b"C_DeriveKey\0").map(|sym| *sym) }?;
41+
42+
Ok((library.into(), C_DeriveKey))
43+
}
44+
45+
trait VendorDeriveKey {
46+
fn vendor_derive_key(
47+
&self,
48+
vendor_fn: C_DeriveKey,
49+
mechanism: &Mechanism,
50+
base_key: ObjectHandle,
51+
template: &[Attribute],
52+
) -> Result<ObjectHandle>;
53+
}
54+
55+
impl VendorDeriveKey for Session {
56+
/// re-implement derive_key to test unsafe accessors for vendor extensions
57+
fn vendor_derive_key(
58+
&self,
59+
vendor_fn: C_DeriveKey,
60+
mechanism: &Mechanism,
61+
base_key: ObjectHandle,
62+
template: &[Attribute],
63+
) -> Result<ObjectHandle> {
64+
let mut mechanism: CK_MECHANISM = mechanism.into();
65+
let mut template: Vec<CK_ATTRIBUTE> = template.iter().map(|attr| attr.into()).collect();
66+
let mut handle = 0;
67+
unsafe {
68+
Rv::from(vendor_fn(
69+
self.raw_handle(),
70+
&mut mechanism as CK_MECHANISM_PTR,
71+
base_key.raw_handle(),
72+
template.as_mut_ptr(),
73+
template.len().try_into()?,
74+
&mut handle,
75+
))
76+
.into_result(Function::DeriveKey)?;
77+
78+
Ok(ObjectHandle::new_from_raw(handle))
79+
}
80+
}
81+
}
82+
83+
#[test]
84+
#[serial]
85+
fn unsafe_accessors_for_vendor_extension() -> TestResult {
86+
let (_library, C_DeriveKey) = load_from_library(get_pkcs11_path())?;
87+
let pkcs11 = get_pkcs11_from_self();
88+
let slot = init_pins_from_pkcs11(&pkcs11);
89+
90+
// open a session
91+
let session = pkcs11.open_rw_session(slot)?;
92+
93+
// log in the session
94+
session.login(UserType::User, Some(&AuthPin::new(USER_PIN.into())))?;
95+
96+
// get mechanism
97+
let mechanism = Mechanism::EccKeyPairGen;
98+
99+
let secp256r1_oid: Vec<u8> = vec![0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07];
100+
101+
// pub key template
102+
let pub_key_template = vec![
103+
Attribute::Token(true),
104+
Attribute::Private(false),
105+
Attribute::Derive(true),
106+
Attribute::KeyType(KeyType::EC),
107+
Attribute::Verify(true),
108+
Attribute::EcParams(secp256r1_oid),
109+
];
110+
111+
// priv key template
112+
let priv_key_template = vec![
113+
Attribute::Token(true),
114+
Attribute::Private(true),
115+
Attribute::Sensitive(true),
116+
Attribute::Extractable(false),
117+
Attribute::Derive(true),
118+
Attribute::Sign(true),
119+
];
120+
121+
// generate a key pair
122+
let (public, private) =
123+
session.generate_key_pair(&mechanism, &pub_key_template, &priv_key_template)?;
124+
125+
let ec_point_attribute = session
126+
.get_attributes(public, &[AttributeType::EcPoint])?
127+
.remove(0);
128+
129+
let ec_point = if let Attribute::EcPoint(point) = ec_point_attribute {
130+
point
131+
} else {
132+
panic!("Expected EC point attribute.");
133+
};
134+
135+
use cryptoki::mechanism::elliptic_curve::*;
136+
137+
let params = Ecdh1DeriveParams::new(EcKdf::null(), &ec_point);
138+
139+
let shared_secret = session.vendor_derive_key(
140+
C_DeriveKey,
141+
&Mechanism::Ecdh1Derive(params),
142+
private,
143+
&[
144+
Attribute::Class(ObjectClass::SECRET_KEY),
145+
Attribute::KeyType(KeyType::GENERIC_SECRET),
146+
Attribute::Sensitive(false),
147+
Attribute::Extractable(true),
148+
Attribute::Token(false),
149+
],
150+
)?;
151+
152+
let value_attribute = session
153+
.get_attributes(shared_secret, &[AttributeType::Value])?
154+
.remove(0);
155+
let value = if let Attribute::Value(value) = value_attribute {
156+
value
157+
} else {
158+
panic!("Expected value attribute.");
159+
};
160+
161+
assert_eq!(value.len(), 32);
162+
163+
// delete keys
164+
session.destroy_object(public)?;
165+
session.destroy_object(private)?;
166+
167+
Ok(())
168+
}

0 commit comments

Comments
 (0)