diff --git a/security-framework-sys/src/item.rs b/security-framework-sys/src/item.rs index 9fbfc128..4b4c52ed 100644 --- a/security-framework-sys/src/item.rs +++ b/security-framework-sys/src/item.rs @@ -66,6 +66,8 @@ extern "C" { pub static kSecAttrAccessGroupToken: CFStringRef; pub static kSecAttrAuthenticationType: CFStringRef; + pub static kSecAttrComment: CFStringRef; + pub static kSecAttrDescription: CFStringRef; pub static kSecAttrPath: CFStringRef; pub static kSecAttrPort: CFStringRef; pub static kSecAttrProtocol: CFStringRef; diff --git a/security-framework/src/item.rs b/security-framework/src/item.rs index b23c170b..0c17e154 100644 --- a/security-framework/src/item.rs +++ b/security-framework/src/item.rs @@ -240,6 +240,12 @@ impl ItemSearchOptions { self } + /// Search for an item with a specific access group. + pub fn access_group(&mut self, access_group: &str) -> &mut Self { + self.access_group = Some(CFString::new(access_group)); + self + } + /// Sets `kSecAttrAccessGroup` to `kSecAttrAccessGroupToken` #[inline(always)] pub fn access_group_token(&mut self) -> &mut Self { @@ -536,8 +542,18 @@ impl SearchResult { pub struct ItemAddOptions { /// The value (by ref or data) of the item to add, required. pub value: ItemAddValue, + /// Optional kSecAttrAccount attribute. + pub account_name: Option, + /// Optional kSecAttrAccessGroup attribute. + pub access_group: Option, + /// Optional kSecAttrComment attribute. + pub comment: Option, + /// Optional kSecAttrDescription attribute. + pub description: Option, /// Optional kSecAttrLabel attribute. pub label: Option, + /// Optional kSecAttrService attribute. + pub service: Option, /// Optional keychain location. pub location: Option, } @@ -545,7 +561,27 @@ pub struct ItemAddOptions { impl ItemAddOptions { /// Specifies the item to add. #[must_use] pub fn new(value: ItemAddValue) -> Self { - Self{ value, label: None, location: None } + Self{ value, label: None, location: None, service: None, account_name: None, comment: None, description: None, access_group: None } + } + /// Specifies the `kSecAttrAccount` attribute. + pub fn set_account_name(&mut self, account_name: impl Into) -> &mut Self { + self.account_name = Some(account_name.into()); + self + } + /// Specifies the `kSecAttrAccessGroup` attribute. + pub fn set_access_group(&mut self, access_group: impl Into) -> &mut Self { + self.access_group = Some(access_group.into()); + self + } + /// Specifies the `kSecAttrComment` attribute. + pub fn set_comment(&mut self, comment: impl Into) -> &mut Self { + self.comment = Some(comment.into()); + self + } + /// Specifies the `kSecAttrDescription` attribute. + pub fn set_description(&mut self, description: impl Into) -> &mut Self { + self.description = Some(description.into()); + self } /// Specifies the `kSecAttrLabel` attribute. pub fn set_label(&mut self, label: impl Into) -> &mut Self { @@ -557,6 +593,11 @@ impl ItemAddOptions { self.location = Some(location); self } + /// Specifies the `kSecAttrService` attribute. + pub fn set_service(&mut self, service: impl Into) -> &mut Self { + self.service = Some(service.into()); + self + } /// Populates a `CFDictionary` to be passed to pub fn to_dictionary(&self) -> CFDictionary { let mut dict = CFMutableDictionary::from_CFType_pairs(&[]); @@ -592,11 +633,30 @@ impl ItemAddOptions { }, } } - + let account_name = self.account_name.as_deref().map(CFString::from); + if let Some(account_name) = &account_name { + dict.add(&unsafe { kSecAttrAccount }.to_void(), &account_name.to_void()); + } + let access_group = self.access_group.as_deref().map(CFString::from); + if let Some(access_group) = &access_group { + dict.add(&unsafe { kSecAttrAccessGroup }.to_void(), &access_group.to_void()); + } + let comment = self.comment.as_deref().map(CFString::from); + if let Some(comment) = &comment { + dict.add(&unsafe { kSecAttrComment }.to_void(), &comment.to_void()); + } + let description = self.description.as_deref().map(CFString::from); + if let Some(description) = &description { + dict.add(&unsafe { kSecAttrDescription }.to_void(), &description.to_void()); + } let label = self.label.as_deref().map(CFString::from); if let Some(label) = &label { dict.add(&unsafe { kSecAttrLabel }.to_void(), &label.to_void()); } + let service = self.service.as_deref().map(CFString::from); + if let Some(service) = &service { + dict.add(&unsafe { kSecAttrService }.to_void(), &service.to_void()); + } dict.to_immutable() }