diff options
Diffstat (limited to 'vendor/security-framework/src/key.rs')
| -rw-r--r-- | vendor/security-framework/src/key.rs | 398 |
1 files changed, 0 insertions, 398 deletions
diff --git a/vendor/security-framework/src/key.rs b/vendor/security-framework/src/key.rs deleted file mode 100644 index a244de8c..00000000 --- a/vendor/security-framework/src/key.rs +++ /dev/null @@ -1,398 +0,0 @@ -//! Encryption key support - -use crate::cvt; -use core_foundation::{ - base::TCFType, string::{CFStringRef, CFString}, - dictionary::CFMutableDictionary, -}; -use core_foundation::base::ToVoid; -#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] -use core_foundation::boolean::CFBoolean; -#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] -use core_foundation::data::CFData; -#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] -use core_foundation::dictionary::CFDictionary; -#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] -use core_foundation::number::CFNumber; -#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] -use core_foundation::error::{CFError, CFErrorRef}; - -use security_framework_sys::{ - item::{kSecAttrKeyTypeRSA, kSecValueRef}, - keychain_item::SecItemDelete -}; -#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] -use security_framework_sys::{item::{ - kSecAttrIsPermanent, kSecAttrLabel, kSecAttrKeyType, - kSecAttrKeySizeInBits, kSecPrivateKeyAttrs, kSecAttrAccessControl -}}; -#[cfg(target_os="macos")] -use security_framework_sys::item::{ - kSecAttrKeyType3DES, kSecAttrKeyTypeDSA, kSecAttrKeyTypeAES, - kSecAttrKeyTypeDES, kSecAttrKeyTypeRC4, kSecAttrKeyTypeCAST, -}; - -use security_framework_sys::key::SecKeyGetTypeID; -use security_framework_sys::base::SecKeyRef; - -#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] -pub use security_framework_sys::key::Algorithm; - -#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] -use security_framework_sys::key::{ - SecKeyCopyAttributes, SecKeyCopyExternalRepresentation, - SecKeyCreateSignature, SecKeyCreateRandomKey, - SecKeyCopyPublicKey, -}; -#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] -use security_framework_sys::item::kSecAttrApplicationLabel; -use std::fmt; - - -use crate::base::Error; -#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] -use crate::item::Location; -#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] -use crate::access_control::SecAccessControl; -/// Types of `SecKey`s. -#[derive(Debug, Copy, Clone)] -pub struct KeyType(CFStringRef); - -#[allow(missing_docs)] -impl KeyType { - #[inline(always)] - #[must_use] - pub fn rsa() -> Self { - unsafe { Self(kSecAttrKeyTypeRSA) } - } - - #[cfg(target_os = "macos")] - #[inline(always)] - #[must_use] - pub fn dsa() -> Self { - unsafe { Self(kSecAttrKeyTypeDSA) } - } - - #[cfg(target_os = "macos")] - #[inline(always)] - #[must_use] - pub fn aes() -> Self { - unsafe { Self(kSecAttrKeyTypeAES) } - } - - #[cfg(target_os = "macos")] - #[inline(always)] - #[must_use] - pub fn des() -> Self { - unsafe { Self(kSecAttrKeyTypeDES) } - } - - #[cfg(target_os = "macos")] - #[inline(always)] - #[must_use] - pub fn triple_des() -> Self { - unsafe { Self(kSecAttrKeyType3DES) } - } - - #[cfg(target_os = "macos")] - #[inline(always)] - #[must_use] - pub fn rc4() -> Self { - unsafe { Self(kSecAttrKeyTypeRC4) } - } - - #[cfg(target_os = "macos")] - #[inline(always)] - #[must_use] - pub fn cast() -> Self { - unsafe { Self(kSecAttrKeyTypeCAST) } - } - - #[inline(always)] - #[must_use] - pub fn ec() -> Self { - use security_framework_sys::item::kSecAttrKeyTypeEC; - - unsafe { Self(kSecAttrKeyTypeEC) } - } - - pub(crate) fn to_str(self) -> CFString { - unsafe { CFString::wrap_under_get_rule(self.0) } - } -} - -declare_TCFType! { - /// A type representing an encryption key. - SecKey, SecKeyRef -} -impl_TCFType!(SecKey, SecKeyRef, SecKeyGetTypeID); - -unsafe impl Sync for SecKey {} -unsafe impl Send for SecKey {} - -impl SecKey { - #[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] - /// Translates to `SecKeyCreateRandomKey` - /// `GenerateKeyOptions` provides a helper to create an attribute - /// `CFDictionary`. - pub fn generate(attributes: CFDictionary) -> Result<Self, CFError> { - let mut error: CFErrorRef = ::std::ptr::null_mut(); - let sec_key = unsafe { SecKeyCreateRandomKey(attributes.as_concrete_TypeRef(), &mut error)}; - if !error.is_null() { - Err(unsafe { CFError::wrap_under_create_rule(error) }) - } else { - Ok(unsafe { SecKey::wrap_under_create_rule(sec_key) }) - } - } - - /// Returns the programmatic identifier for the key. For keys of class - /// kSecAttrKeyClassPublic and kSecAttrKeyClassPrivate, the value is the - /// hash of the public key. - #[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] - pub fn application_label(&self) -> Option<Vec<u8>> { - self.attributes() - .find(unsafe { kSecAttrApplicationLabel.to_void() }) - .map(|v| unsafe { CFData::wrap_under_get_rule(v.cast()) }.to_vec()) - } - - #[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] - /// Translates to `SecKeyCopyAttributes` - #[must_use] - pub fn attributes(&self) -> CFDictionary { - let pka = unsafe { SecKeyCopyAttributes(self.to_void() as _) }; - unsafe { CFDictionary::wrap_under_create_rule(pka) } - } - - #[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] - /// Translates to `SecKeyCopyExternalRepresentation` - #[must_use] - pub fn external_representation(&self) -> Option<CFData> { - let mut error: CFErrorRef = ::std::ptr::null_mut(); - let data = unsafe { SecKeyCopyExternalRepresentation(self.to_void() as _, &mut error) }; - if data.is_null() { - return None; - } - Some(unsafe { CFData::wrap_under_create_rule(data) }) - } - - #[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] - /// Translates to `SecKeyCopyPublicKey` - #[must_use] - pub fn public_key(&self) -> Option<Self> { - let pub_seckey = unsafe { SecKeyCopyPublicKey(self.0.cast()) }; - if pub_seckey.is_null() { - return None; - } - - Some(unsafe { SecKey::wrap_under_create_rule(pub_seckey) }) - } - - #[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] - /// Creates the cryptographic signature for a block of data using a private - /// key and specified algorithm. - pub fn create_signature(&self, algorithm: Algorithm, input: &[u8]) -> Result<Vec<u8>, CFError> { - let mut error: CFErrorRef = std::ptr::null_mut(); - - let output = unsafe { - SecKeyCreateSignature( - self.as_concrete_TypeRef(), - algorithm.into(), - CFData::from_buffer(input).as_concrete_TypeRef(), - &mut error, - ) - }; - - if !error.is_null() { - Err(unsafe { CFError::wrap_under_create_rule(error) }) - } else { - let output = unsafe { CFData::wrap_under_create_rule(output) }; - Ok(output.to_vec()) - } - } - - /// Verifies the cryptographic signature for a block of data using a public - /// key and specified algorithm. - #[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] - pub fn verify_signature(&self, algorithm: Algorithm, signed_data: &[u8], signature: &[u8]) -> Result<bool, CFError> { - use security_framework_sys::key::SecKeyVerifySignature; - let mut error: CFErrorRef = std::ptr::null_mut(); - - let valid = unsafe { - SecKeyVerifySignature( - self.as_concrete_TypeRef(), - algorithm.into(), - CFData::from_buffer(signed_data).as_concrete_TypeRef(), - CFData::from_buffer(signature).as_concrete_TypeRef(), - &mut error, - ) - }; - - if !error.is_null() { - return Err(unsafe { CFError::wrap_under_create_rule(error) })?; - } - Ok(valid != 0) - } - - /// Translates to `SecItemDelete`, passing in the `SecKeyRef` - pub fn delete(&self) -> Result<(), Error> { - let query = CFMutableDictionary::from_CFType_pairs(&[( - unsafe { kSecValueRef }.to_void(), - self.to_void(), - )]); - - cvt(unsafe { SecItemDelete(query.as_concrete_TypeRef()) }) - } -} - -/// Where to generate the key. -pub enum Token { - /// Generate the key in software, compatible with all `KeyType`s. - Software, - /// Generate the key in the Secure Enclave such that the private key is not - /// extractable. Only compatible with `KeyType::ec()`. - SecureEnclave, -} - -/// Helper for creating `CFDictionary` attributes for `SecKey::generate` -/// Recommended reading: -/// <https://developer.apple.com/documentation/technotes/tn3137-on-mac-keychains> -#[derive(Default)] -#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] -pub struct GenerateKeyOptions { - /// kSecAttrKeyType - pub key_type: Option<KeyType>, - /// kSecAttrKeySizeInBits - pub size_in_bits: Option<u32>, - /// kSecAttrLabel - pub label: Option<String>, - /// kSecAttrTokenID - pub token: Option<Token>, - /// Which keychain to store the key in, if any. - pub location: Option<Location>, - /// Access control - pub access_control: Option<SecAccessControl>, -} - -#[cfg(any(feature = "OSX_10_12", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] -impl GenerateKeyOptions { - /// Set `key_type` - pub fn set_key_type(&mut self, key_type: KeyType) -> &mut Self { - self.key_type = Some(key_type); - self - } - /// Set `size_in_bits` - pub fn set_size_in_bits(&mut self, size_in_bits: u32) -> &mut Self { - self.size_in_bits = Some(size_in_bits); - self - } - /// Set `label` - pub fn set_label(&mut self, label: impl Into<String>) -> &mut Self { - self.label = Some(label.into()); - self - } - /// Set `token` - pub fn set_token(&mut self, token: Token) -> &mut Self { - self.token = Some(token); - self - } - /// Set `location` - pub fn set_location(&mut self, location: Location) -> &mut Self { - self.location = Some(location); - self - } - /// Set `access_control` - pub fn set_access_control(&mut self, access_control: SecAccessControl) -> &mut Self { - self.access_control = Some(access_control); - self - } - - /// Collect options into a `CFDictioanry` - pub fn to_dictionary(&self) -> CFDictionary { - #[cfg(target_os = "macos")] - use security_framework_sys::item::kSecUseKeychain; - use security_framework_sys::item::{ - kSecAttrTokenID, kSecAttrTokenIDSecureEnclave, kSecPublicKeyAttrs, - }; - - let is_permanent = CFBoolean::from(self.location.is_some()); - let mut private_attributes = CFMutableDictionary::from_CFType_pairs(&[( - unsafe { kSecAttrIsPermanent }.to_void(), - is_permanent.to_void(), - )]); - if let Some(access_control) = &self.access_control { - private_attributes.set(unsafe { kSecAttrAccessControl }.to_void(), access_control.to_void()); - } - - let public_attributes = CFMutableDictionary::from_CFType_pairs(&[( - unsafe { kSecAttrIsPermanent }.to_void(), - is_permanent.to_void(), - )]); - - let key_type = self.key_type.unwrap_or_else(KeyType::rsa).to_str(); - - let size_in_bits = self.size_in_bits.unwrap_or(match () { - _ if key_type == KeyType::rsa().to_str() => 2048, - _ if key_type == KeyType::ec().to_str() => 256, - _ => 256, - }); - let size_in_bits = CFNumber::from(size_in_bits as i32); - - let mut attribute_key_values = vec![ - (unsafe { kSecAttrKeyType }.to_void(), key_type.to_void()), - ( - unsafe { kSecAttrKeySizeInBits }.to_void(), - size_in_bits.to_void(), - ), - ( - unsafe { kSecPrivateKeyAttrs }.to_void(), - private_attributes.to_void(), - ), - ( - unsafe { kSecPublicKeyAttrs }.to_void(), - public_attributes.to_void(), - ), - ]; - let label = self.label.as_deref().map(CFString::new); - if let Some(label) = &label { - attribute_key_values.push((unsafe { kSecAttrLabel }.to_void(), label.to_void())); - } - - #[cfg(target_os = "macos")] - match &self.location { - #[cfg(feature = "OSX_10_15")] - Some(Location::DataProtectionKeychain) => { - use security_framework_sys::item::kSecUseDataProtectionKeychain; - attribute_key_values.push(( - unsafe { kSecUseDataProtectionKeychain }.to_void(), - CFBoolean::true_value().to_void(), - )); - } - Some(Location::FileKeychain(keychain)) => { - attribute_key_values.push(( - unsafe { kSecUseKeychain }.to_void(), - keychain.as_concrete_TypeRef().to_void(), - )); - } - _ => {} - } - - match self.token.as_ref().unwrap_or(&Token::Software) { - Token::Software => {}, - Token::SecureEnclave => { - attribute_key_values.push(( - unsafe { kSecAttrTokenID }.to_void(), - unsafe { kSecAttrTokenIDSecureEnclave }.to_void(), - )); - } - } - - CFMutableDictionary::from_CFType_pairs(&attribute_key_values).to_immutable() - } -} - -impl fmt::Debug for SecKey { - #[cold] - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_struct("SecKey").finish_non_exhaustive() - } -} |
