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}