Skip to main content

security/
key.rs

1use serde_json::Value;
2
3use crate::bridge::{self, Handle};
4use crate::certificate::PublicKey;
5use crate::error::Result;
6
7#[repr(u32)]
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9pub enum ExternalFormat {
10    Unknown = 0,
11    OpenSsl = 1,
12    Ssh = 2,
13    Bsafe = 3,
14    RawKey = 4,
15    WrappedPkcs8 = 5,
16    WrappedOpenSsl = 6,
17    WrappedSsh = 7,
18    WrappedLsh = 8,
19    X509Certificate = 9,
20    PemSequence = 10,
21    Pkcs7 = 11,
22    Pkcs12 = 12,
23    NetscapeCertificateSequence = 13,
24    SshV2 = 14,
25}
26
27#[repr(u32)]
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
29pub enum ExternalItemType {
30    Unknown = 0,
31    PrivateKey = 1,
32    PublicKey = 2,
33    SessionKey = 3,
34    Certificate = 4,
35    Aggregate = 5,
36}
37
38#[repr(u32)]
39#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
40pub enum KeyType {
41    Rsa = 0,
42    EcSecPrimeRandom = 1,
43}
44
45#[repr(u32)]
46#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
47pub enum SignatureAlgorithm {
48    RsaSignatureMessagePkcs1v15Sha256 = 0,
49    RsaSignatureDigestPkcs1v15Sha256 = 1,
50    RsaSignatureMessagePssSha256 = 2,
51    EcdsaSignatureMessageX962Sha256 = 3,
52    EcdsaSignatureDigestX962Sha256 = 4,
53}
54
55#[repr(u32)]
56#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
57pub enum EncryptionAlgorithm {
58    RsaEncryptionRaw = 0,
59    RsaEncryptionPkcs1 = 1,
60    RsaEncryptionOaepSha1 = 2,
61    RsaEncryptionOaepSha224 = 3,
62    RsaEncryptionOaepSha256 = 4,
63    RsaEncryptionOaepSha384 = 5,
64    RsaEncryptionOaepSha512 = 6,
65    RsaEncryptionOaepSha1AesGcm = 7,
66    RsaEncryptionOaepSha224AesGcm = 8,
67    RsaEncryptionOaepSha256AesGcm = 9,
68    RsaEncryptionOaepSha384AesGcm = 10,
69    RsaEncryptionOaepSha512AesGcm = 11,
70}
71
72pub(crate) fn key_type_id() -> usize {
73    unsafe { bridge::security_key_get_type_id() }
74}
75
76pub(crate) fn key_block_size(handle: &Handle) -> usize {
77    usize::try_from(unsafe { bridge::security_key_get_block_size(handle.as_ptr()) })
78        .unwrap_or_default()
79}
80
81pub(crate) fn key_external_representation(handle: &Handle) -> Result<Vec<u8>> {
82    let mut status = 0;
83    let mut error = std::ptr::null_mut();
84    let raw = unsafe {
85        bridge::security_key_copy_external_representation(handle.as_ptr(), &mut status, &mut error)
86    };
87    bridge::required_data(
88        "security_key_copy_external_representation",
89        raw,
90        status,
91        error,
92    )
93}
94
95pub(crate) fn encrypt_with_public_key(
96    handle: &Handle,
97    algorithm: EncryptionAlgorithm,
98    plaintext: &[u8],
99) -> Result<Vec<u8>> {
100    let mut status = 0;
101    let mut error = std::ptr::null_mut();
102    let raw = unsafe {
103        bridge::security_public_key_create_encrypted_data(
104            handle.as_ptr(),
105            algorithm as u32,
106            plaintext.as_ptr().cast(),
107            bridge::len_to_isize(plaintext.len())?,
108            &mut status,
109            &mut error,
110        )
111    };
112    bridge::required_data(
113        "security_public_key_create_encrypted_data",
114        raw,
115        status,
116        error,
117    )
118}
119
120pub(crate) fn decrypt_with_private_key(
121    handle: &Handle,
122    algorithm: EncryptionAlgorithm,
123    ciphertext: &[u8],
124) -> Result<Vec<u8>> {
125    let mut status = 0;
126    let mut error = std::ptr::null_mut();
127    let raw = unsafe {
128        bridge::security_private_key_create_decrypted_data(
129            handle.as_ptr(),
130            algorithm as u32,
131            ciphertext.as_ptr().cast(),
132            bridge::len_to_isize(ciphertext.len())?,
133            &mut status,
134            &mut error,
135        )
136    };
137    bridge::required_data(
138        "security_private_key_create_decrypted_data",
139        raw,
140        status,
141        error,
142    )
143}
144
145#[derive(Debug)]
146pub struct PrivateKey {
147    handle: Handle,
148}
149
150impl PrivateKey {
151    pub fn type_id() -> usize {
152        key_type_id()
153    }
154
155    pub(crate) fn from_handle(handle: Handle) -> Self {
156        Self { handle }
157    }
158
159    pub(crate) fn handle(&self) -> &Handle {
160        &self.handle
161    }
162
163    pub fn from_data(data: &[u8], key_type: KeyType, key_size_bits: usize) -> Result<Self> {
164        let mut status = 0;
165        let mut error = std::ptr::null_mut();
166        let raw = unsafe {
167            bridge::security_private_key_create_with_data(
168                data.as_ptr().cast(),
169                bridge::len_to_isize(data.len())?,
170                key_type as u32,
171                bridge::len_to_isize(key_size_bits)?,
172                &mut status,
173                &mut error,
174            )
175        };
176        bridge::required_handle("security_private_key_create_with_data", raw, status, error)
177            .map(Self::from_handle)
178    }
179
180    pub fn import_item(
181        data: &[u8],
182        file_name_or_extension: Option<&str>,
183        format: ExternalFormat,
184        item_type: ExternalItemType,
185    ) -> Result<Self> {
186        let file_name_or_extension = file_name_or_extension.map(bridge::cstring).transpose()?;
187        let mut status = 0;
188        let mut error = std::ptr::null_mut();
189        let raw = unsafe {
190            bridge::security_private_key_import_item(
191                data.as_ptr().cast(),
192                bridge::len_to_isize(data.len())?,
193                file_name_or_extension
194                    .as_ref()
195                    .map_or(std::ptr::null(), |value| value.as_ptr()),
196                format as u32,
197                item_type as u32,
198                &mut status,
199                &mut error,
200            )
201        };
202        bridge::required_handle("security_private_key_import_item", raw, status, error)
203            .map(Self::from_handle)
204    }
205
206    pub fn import_pem(pem: &[u8]) -> Result<Self> {
207        Self::import_item(
208            pem,
209            Some(".pem"),
210            ExternalFormat::Unknown,
211            ExternalItemType::PrivateKey,
212        )
213    }
214
215    pub fn public_key(&self) -> Result<PublicKey> {
216        let mut status = 0;
217        let mut error = std::ptr::null_mut();
218        let raw = unsafe {
219            bridge::security_key_copy_public_key(self.handle.as_ptr(), &mut status, &mut error)
220        };
221        bridge::required_handle("security_key_copy_public_key", raw, status, error)
222            .map(PublicKey::from_handle)
223    }
224
225    pub fn attributes(&self) -> Result<Value> {
226        let mut status = 0;
227        let mut error = std::ptr::null_mut();
228        let raw = unsafe {
229            bridge::security_key_copy_attributes(self.handle.as_ptr(), &mut status, &mut error)
230        };
231        bridge::required_json("security_key_copy_attributes", raw, status, error)
232    }
233
234    pub fn block_size(&self) -> usize {
235        key_block_size(&self.handle)
236    }
237
238    pub fn external_representation(&self) -> Result<Vec<u8>> {
239        key_external_representation(&self.handle)
240    }
241
242    pub fn sign(&self, algorithm: SignatureAlgorithm, data: &[u8]) -> Result<Vec<u8>> {
243        let mut status = 0;
244        let mut error = std::ptr::null_mut();
245        let raw = unsafe {
246            bridge::security_private_key_create_signature(
247                self.handle.as_ptr(),
248                algorithm as u32,
249                data.as_ptr().cast(),
250                bridge::len_to_isize(data.len())?,
251                &mut status,
252                &mut error,
253            )
254        };
255        bridge::required_data("security_private_key_create_signature", raw, status, error)
256    }
257
258    pub fn decrypt(&self, algorithm: EncryptionAlgorithm, ciphertext: &[u8]) -> Result<Vec<u8>> {
259        decrypt_with_private_key(&self.handle, algorithm, ciphertext)
260    }
261}