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#[derive(Debug)]
56pub struct PrivateKey {
57    handle: Handle,
58}
59
60impl PrivateKey {
61    pub(crate) fn from_handle(handle: Handle) -> Self {
62        Self { handle }
63    }
64
65    pub fn from_data(data: &[u8], key_type: KeyType, key_size_bits: usize) -> Result<Self> {
66        let mut status = 0;
67        let mut error = std::ptr::null_mut();
68        let raw = unsafe {
69            bridge::security_private_key_create_with_data(
70                data.as_ptr().cast(),
71                bridge::len_to_isize(data.len())?,
72                key_type as u32,
73                bridge::len_to_isize(key_size_bits)?,
74                &mut status,
75                &mut error,
76            )
77        };
78        bridge::required_handle("security_private_key_create_with_data", raw, status, error)
79            .map(Self::from_handle)
80    }
81
82    pub fn import_item(
83        data: &[u8],
84        file_name_or_extension: Option<&str>,
85        format: ExternalFormat,
86        item_type: ExternalItemType,
87    ) -> Result<Self> {
88        let file_name_or_extension = file_name_or_extension.map(bridge::cstring).transpose()?;
89        let mut status = 0;
90        let mut error = std::ptr::null_mut();
91        let raw = unsafe {
92            bridge::security_private_key_import_item(
93                data.as_ptr().cast(),
94                bridge::len_to_isize(data.len())?,
95                file_name_or_extension
96                    .as_ref()
97                    .map_or(std::ptr::null(), |value| value.as_ptr()),
98                format as u32,
99                item_type as u32,
100                &mut status,
101                &mut error,
102            )
103        };
104        bridge::required_handle("security_private_key_import_item", raw, status, error)
105            .map(Self::from_handle)
106    }
107
108    pub fn import_pem(pem: &[u8]) -> Result<Self> {
109        Self::import_item(
110            pem,
111            Some(".pem"),
112            ExternalFormat::Unknown,
113            ExternalItemType::PrivateKey,
114        )
115    }
116
117    pub fn public_key(&self) -> Result<PublicKey> {
118        let mut status = 0;
119        let mut error = std::ptr::null_mut();
120        let raw = unsafe {
121            bridge::security_key_copy_public_key(self.handle.as_ptr(), &mut status, &mut error)
122        };
123        bridge::required_handle("security_key_copy_public_key", raw, status, error)
124            .map(PublicKey::from_handle)
125    }
126
127    pub fn attributes(&self) -> Result<Value> {
128        let mut status = 0;
129        let mut error = std::ptr::null_mut();
130        let raw = unsafe {
131            bridge::security_key_copy_attributes(self.handle.as_ptr(), &mut status, &mut error)
132        };
133        bridge::required_json("security_key_copy_attributes", raw, status, error)
134    }
135
136    pub fn sign(&self, algorithm: SignatureAlgorithm, data: &[u8]) -> Result<Vec<u8>> {
137        let mut status = 0;
138        let mut error = std::ptr::null_mut();
139        let raw = unsafe {
140            bridge::security_private_key_create_signature(
141                self.handle.as_ptr(),
142                algorithm as u32,
143                data.as_ptr().cast(),
144                bridge::len_to_isize(data.len())?,
145                &mut status,
146                &mut error,
147            )
148        };
149        bridge::required_data("security_private_key_create_signature", raw, status, error)
150    }
151}