cryptoki/session/
key_management.rs

1// Copyright 2021 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3//! Key management functions
4
5use crate::context::Function;
6use crate::error::{Result, Rv};
7use crate::mechanism::Mechanism;
8use crate::object::{Attribute, ObjectHandle};
9use crate::session::Session;
10use cryptoki_sys::{CK_ATTRIBUTE, CK_MECHANISM, CK_MECHANISM_PTR};
11use std::convert::TryInto;
12
13impl Session {
14    /// Generate a secret key
15    pub fn generate_key(
16        &self,
17        mechanism: &Mechanism,
18        template: &[Attribute],
19    ) -> Result<ObjectHandle> {
20        let mut mechanism: CK_MECHANISM = mechanism.into();
21        let mut template: Vec<CK_ATTRIBUTE> = template.iter().map(|attr| attr.into()).collect();
22        let mut handle = 0;
23        unsafe {
24            Rv::from(get_pkcs11!(self.client(), C_GenerateKey)(
25                self.handle(),
26                &mut mechanism as CK_MECHANISM_PTR,
27                template.as_mut_ptr(),
28                template.len().try_into()?,
29                &mut handle,
30            ))
31            .into_result(Function::GenerateKey)?;
32        }
33
34        Ok(ObjectHandle::new(handle))
35    }
36
37    /// Generate a public/private key pair
38    pub fn generate_key_pair(
39        &self,
40        mechanism: &Mechanism,
41        pub_key_template: &[Attribute],
42        priv_key_template: &[Attribute],
43    ) -> Result<(ObjectHandle, ObjectHandle)> {
44        let mut mechanism: CK_MECHANISM = mechanism.into();
45        let mut pub_key_template: Vec<CK_ATTRIBUTE> =
46            pub_key_template.iter().map(|attr| attr.into()).collect();
47        let mut priv_key_template: Vec<CK_ATTRIBUTE> =
48            priv_key_template.iter().map(|attr| attr.into()).collect();
49        let mut pub_handle = 0;
50        let mut priv_handle = 0;
51        unsafe {
52            Rv::from(get_pkcs11!(self.client(), C_GenerateKeyPair)(
53                self.handle(),
54                &mut mechanism as CK_MECHANISM_PTR,
55                pub_key_template.as_mut_ptr(),
56                pub_key_template.len().try_into()?,
57                priv_key_template.as_mut_ptr(),
58                priv_key_template.len().try_into()?,
59                &mut pub_handle,
60                &mut priv_handle,
61            ))
62            .into_result(Function::GenerateKeyPair)?;
63        }
64
65        Ok((
66            ObjectHandle::new(pub_handle),
67            ObjectHandle::new(priv_handle),
68        ))
69    }
70
71    /// Derives a key from a base key
72    pub fn derive_key(
73        &self,
74        mechanism: &Mechanism,
75        base_key: ObjectHandle,
76        template: &[Attribute],
77    ) -> Result<ObjectHandle> {
78        let mut mechanism: CK_MECHANISM = mechanism.into();
79        let mut template: Vec<CK_ATTRIBUTE> = template.iter().map(|attr| attr.into()).collect();
80        let mut handle = 0;
81        unsafe {
82            Rv::from(get_pkcs11!(self.client(), C_DeriveKey)(
83                self.handle(),
84                &mut mechanism as CK_MECHANISM_PTR,
85                base_key.handle(),
86                template.as_mut_ptr(),
87                template.len().try_into()?,
88                &mut handle,
89            ))
90            .into_result(Function::DeriveKey)?;
91        }
92
93        Ok(ObjectHandle::new(handle))
94    }
95
96    /// Wrap key
97    pub fn wrap_key(
98        &self,
99        mechanism: &Mechanism,
100        wrapping_key: ObjectHandle,
101        key: ObjectHandle,
102    ) -> Result<Vec<u8>> {
103        let mut mechanism: CK_MECHANISM = mechanism.into();
104        unsafe {
105            let mut wrapped_key_len = 0;
106
107            Rv::from(get_pkcs11!(self.client(), C_WrapKey)(
108                self.handle(),
109                &mut mechanism as CK_MECHANISM_PTR,
110                wrapping_key.handle(),
111                key.handle(),
112                std::ptr::null_mut(),
113                &mut wrapped_key_len,
114            ))
115            .into_result(Function::WrapKey)?;
116
117            let mut wrapped_key = vec![0; wrapped_key_len.try_into()?];
118
119            Rv::from(get_pkcs11!(self.client(), C_WrapKey)(
120                self.handle(),
121                &mut mechanism as CK_MECHANISM_PTR,
122                wrapping_key.handle(),
123                key.handle(),
124                wrapped_key.as_mut_ptr(),
125                &mut wrapped_key_len,
126            ))
127            .into_result(Function::WrapKey)?;
128
129            Ok(wrapped_key)
130        }
131    }
132
133    /// Unwrap previously wrapped key
134    pub fn unwrap_key(
135        &self,
136        mechanism: &Mechanism,
137        unwrapping_key: ObjectHandle,
138        wrapped_key: &[u8],
139        template: &[Attribute],
140    ) -> Result<ObjectHandle> {
141        let mut mechanism: CK_MECHANISM = mechanism.into();
142        let mut template: Vec<CK_ATTRIBUTE> = template.iter().map(|attr| attr.into()).collect();
143        let mut handle = 0;
144        unsafe {
145            Rv::from(get_pkcs11!(self.client(), C_UnwrapKey)(
146                self.handle(),
147                &mut mechanism as CK_MECHANISM_PTR,
148                unwrapping_key.handle(),
149                wrapped_key.as_ptr() as *mut u8,
150                wrapped_key.len().try_into()?,
151                template.as_mut_ptr(),
152                template.len().try_into()?,
153                &mut handle,
154            ))
155            .into_result(Function::UnwrapKey)?;
156        }
157
158        Ok(ObjectHandle::new(handle))
159    }
160}