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 {
11 Unknown = 0,
13 OpenSsl = 1,
15 Ssh = 2,
17 Bsafe = 3,
19 RawKey = 4,
21 WrappedPkcs8 = 5,
23 WrappedOpenSsl = 6,
25 WrappedSsh = 7,
27 WrappedLsh = 8,
29 X509Certificate = 9,
31 PemSequence = 10,
33 Pkcs7 = 11,
35 Pkcs12 = 12,
37 NetscapeCertificateSequence = 13,
39 SshV2 = 14,
41}
42
43#[repr(u32)]
44#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
45pub enum ExternalItemType {
47 Unknown = 0,
49 PrivateKey = 1,
51 PublicKey = 2,
53 SessionKey = 3,
55 Certificate = 4,
57 Aggregate = 5,
59}
60
61#[repr(u32)]
62#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
63pub enum KeyType {
65 Rsa = 0,
67 EcSecPrimeRandom = 1,
69}
70
71#[repr(u32)]
72#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
73pub enum SignatureAlgorithm {
75 RsaSignatureMessagePkcs1v15Sha256 = 0,
77 RsaSignatureDigestPkcs1v15Sha256 = 1,
79 RsaSignatureMessagePssSha256 = 2,
81 EcdsaSignatureMessageX962Sha256 = 3,
83 EcdsaSignatureDigestX962Sha256 = 4,
85}
86
87#[repr(u32)]
88#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
89pub enum EncryptionAlgorithm {
91 RsaEncryptionRaw = 0,
93 RsaEncryptionPkcs1 = 1,
95 RsaEncryptionOaepSha1 = 2,
97 RsaEncryptionOaepSha224 = 3,
99 RsaEncryptionOaepSha256 = 4,
101 RsaEncryptionOaepSha384 = 5,
103 RsaEncryptionOaepSha512 = 6,
105 RsaEncryptionOaepSha1AesGcm = 7,
107 RsaEncryptionOaepSha224AesGcm = 8,
109 RsaEncryptionOaepSha256AesGcm = 9,
111 RsaEncryptionOaepSha384AesGcm = 10,
113 RsaEncryptionOaepSha512AesGcm = 11,
115}
116
117pub(crate) fn key_type_id() -> usize {
118 unsafe { bridge::security_key_get_type_id() }
119}
120
121pub(crate) fn key_block_size(handle: &Handle) -> usize {
122 usize::try_from(unsafe { bridge::security_key_get_block_size(handle.as_ptr()) })
123 .unwrap_or_default()
124}
125
126pub(crate) fn key_external_representation(handle: &Handle) -> Result<Vec<u8>> {
127 let mut status = 0;
128 let mut error = std::ptr::null_mut();
129 let raw = unsafe {
130 bridge::security_key_copy_external_representation(handle.as_ptr(), &mut status, &mut error)
131 };
132 bridge::required_data(
133 "security_key_copy_external_representation",
134 raw,
135 status,
136 error,
137 )
138}
139
140pub(crate) fn encrypt_with_public_key(
141 handle: &Handle,
142 algorithm: EncryptionAlgorithm,
143 plaintext: &[u8],
144) -> Result<Vec<u8>> {
145 let mut status = 0;
146 let mut error = std::ptr::null_mut();
147 let raw = unsafe {
148 bridge::security_public_key_create_encrypted_data(
149 handle.as_ptr(),
150 algorithm as u32,
151 plaintext.as_ptr().cast(),
152 bridge::len_to_isize(plaintext.len())?,
153 &mut status,
154 &mut error,
155 )
156 };
157 bridge::required_data(
158 "security_public_key_create_encrypted_data",
159 raw,
160 status,
161 error,
162 )
163}
164
165pub(crate) fn decrypt_with_private_key(
166 handle: &Handle,
167 algorithm: EncryptionAlgorithm,
168 ciphertext: &[u8],
169) -> Result<Vec<u8>> {
170 let mut status = 0;
171 let mut error = std::ptr::null_mut();
172 let raw = unsafe {
173 bridge::security_private_key_create_decrypted_data(
174 handle.as_ptr(),
175 algorithm as u32,
176 ciphertext.as_ptr().cast(),
177 bridge::len_to_isize(ciphertext.len())?,
178 &mut status,
179 &mut error,
180 )
181 };
182 bridge::required_data(
183 "security_private_key_create_decrypted_data",
184 raw,
185 status,
186 error,
187 )
188}
189
190#[derive(Debug)]
191pub struct PrivateKey {
193 handle: Handle,
194}
195
196impl PrivateKey {
197 pub fn type_id() -> usize {
199 key_type_id()
200 }
201
202 pub(crate) fn from_handle(handle: Handle) -> Self {
203 Self { handle }
204 }
205
206 pub(crate) fn handle(&self) -> &Handle {
207 &self.handle
208 }
209
210 pub fn from_data(data: &[u8], key_type: KeyType, key_size_bits: usize) -> Result<Self> {
212 let mut status = 0;
213 let mut error = std::ptr::null_mut();
214 let raw = unsafe {
215 bridge::security_private_key_create_with_data(
216 data.as_ptr().cast(),
217 bridge::len_to_isize(data.len())?,
218 key_type as u32,
219 bridge::len_to_isize(key_size_bits)?,
220 &mut status,
221 &mut error,
222 )
223 };
224 bridge::required_handle("security_private_key_create_with_data", raw, status, error)
225 .map(Self::from_handle)
226 }
227
228 pub fn import_item(
230 data: &[u8],
231 file_name_or_extension: Option<&str>,
232 format: ExternalFormat,
233 item_type: ExternalItemType,
234 ) -> Result<Self> {
235 let file_name_or_extension = file_name_or_extension.map(bridge::cstring).transpose()?;
236 let mut status = 0;
237 let mut error = std::ptr::null_mut();
238 let raw = unsafe {
239 bridge::security_private_key_import_item(
240 data.as_ptr().cast(),
241 bridge::len_to_isize(data.len())?,
242 file_name_or_extension
243 .as_ref()
244 .map_or(std::ptr::null(), |value| value.as_ptr()),
245 format as u32,
246 item_type as u32,
247 &mut status,
248 &mut error,
249 )
250 };
251 bridge::required_handle("security_private_key_import_item", raw, status, error)
252 .map(Self::from_handle)
253 }
254
255 pub fn import_pem(pem: &[u8]) -> Result<Self> {
257 Self::import_item(
258 pem,
259 Some(".pem"),
260 ExternalFormat::Unknown,
261 ExternalItemType::PrivateKey,
262 )
263 }
264
265 pub fn public_key(&self) -> Result<PublicKey> {
267 let mut status = 0;
268 let mut error = std::ptr::null_mut();
269 let raw = unsafe {
270 bridge::security_key_copy_public_key(self.handle.as_ptr(), &mut status, &mut error)
271 };
272 bridge::required_handle("security_key_copy_public_key", raw, status, error)
273 .map(PublicKey::from_handle)
274 }
275
276 pub fn attributes(&self) -> Result<Value> {
278 let mut status = 0;
279 let mut error = std::ptr::null_mut();
280 let raw = unsafe {
281 bridge::security_key_copy_attributes(self.handle.as_ptr(), &mut status, &mut error)
282 };
283 bridge::required_json("security_key_copy_attributes", raw, status, error)
284 }
285
286 pub fn block_size(&self) -> usize {
288 key_block_size(&self.handle)
289 }
290
291 pub fn external_representation(&self) -> Result<Vec<u8>> {
293 key_external_representation(&self.handle)
294 }
295
296 pub fn sign(&self, algorithm: SignatureAlgorithm, data: &[u8]) -> Result<Vec<u8>> {
298 let mut status = 0;
299 let mut error = std::ptr::null_mut();
300 let raw = unsafe {
301 bridge::security_private_key_create_signature(
302 self.handle.as_ptr(),
303 algorithm as u32,
304 data.as_ptr().cast(),
305 bridge::len_to_isize(data.len())?,
306 &mut status,
307 &mut error,
308 )
309 };
310 bridge::required_data("security_private_key_create_signature", raw, status, error)
311 }
312
313 pub fn decrypt(&self, algorithm: EncryptionAlgorithm, ciphertext: &[u8]) -> Result<Vec<u8>> {
315 decrypt_with_private_key(&self.handle, algorithm, ciphertext)
316 }
317}