static unsafe string GetUsernameFromKeychainItemRef(IntPtr itemRef) { int[] formatConstants = { (int)CssmDbAttributeFormat.String }; int[] attributeTags = { (int)SecItemAttr.Account }; fixed(int *tags = attributeTags, formats = formatConstants) { var attributeInfo = new SecKeychainAttributeInfo { Count = 1, Tag = tags, Format = formats }; SecKeychainAttributeList *attributeList = null; SecItemClass itemClass = 0; try { SecStatusCode status = SecKeychainItemCopyAttributesAndData(itemRef, &attributeInfo, ref itemClass, &attributeList, IntPtr.Zero, IntPtr.Zero); if (status == SecStatusCode.ItemNotFound) { throw new Exception("Could not add internet password to keychain: " + status.GetStatusDescription()); } if (status != SecStatusCode.Success) { throw new Exception("Could not find internet username and password: " + status.GetStatusDescription()); } var userNameAttr = (SecKeychainAttribute *)attributeList->Attrs; if (userNameAttr->Length == 0) { return(null); } return(Marshal.PtrToStringAuto(userNameAttr->Data, (int)userNameAttr->Length)); } finally { SecKeychainItemFreeAttributesAndData(attributeList, IntPtr.Zero); } } }
static unsafe string GetUsernameFromKeychainItemRef(IntPtr itemRef) { int[] formatConstants = { (int)CssmDbAttributeFormat.String }; int[] attributeTags = { (int)SecItemAttr.Account }; fixed(int *tags = attributeTags, formats = formatConstants) { var attributeInfo = new SecKeychainAttributeInfo { Count = 1, Tag = tags, Format = formats }; SecKeychainAttributeList *attributeList; IntPtr outData = IntPtr.Zero; SecItemClass itemClass = 0; uint length = 0; OSStatus status = SecKeychainItemCopyAttributesAndData(itemRef, &attributeInfo, ref itemClass, &attributeList, ref length, ref outData); if (status == OSStatus.ItemNotFound) { throw new Exception("Could not add internet password to keychain: " + GetError(status)); } if (status != OSStatus.Ok) { throw new Exception("Could not find internet username and password: " + GetError(status)); } var userNameAttr = (SecKeychainAttribute *)attributeList->Attrs; if (userNameAttr->Length == 0) { return(null); } return(Marshal.PtrToStringAuto(userNameAttr->Data, (int)userNameAttr->Length)); } }
public static unsafe bool ContainsCertificate(X509Certificate2 certificate) { // Note: we don't have to use an alias attribute, it's just that it might be faster to use it (fewer certificates we have to compare raw data for) byte[] alias = Encoding.UTF8.GetBytes(GetCertificateCommonName(certificate)); IntPtr searchRef, itemRef; bool found = false; byte[] certData; OSStatus status; fixed(byte *aliasPtr = alias) { SecKeychainAttribute *attrs = stackalloc SecKeychainAttribute [1]; int n = 0; if (alias != null) { attrs[n++] = new SecKeychainAttribute(SecItemAttr.Alias, (uint)alias.Length, (IntPtr)aliasPtr); } SecKeychainAttributeList attrList = new SecKeychainAttributeList(n, (IntPtr)attrs); status = SecKeychainSearchCreateFromAttributes(CurrentKeychain, SecItemClass.Certificate, &attrList, out searchRef); if (status != OSStatus.Ok) { throw new Exception("Could not enumerate certificates from the keychain. Error:\n" + GetError(status)); } // we cache certificate.RawData to avoid unneccessary duplication (X509Certificate2.RawData clones the byte[] each time) certData = certificate.RawData; while (!found && (status = SecKeychainSearchCopyNext(searchRef, out itemRef)) == OSStatus.Ok) { SecItemClass itemClass = 0; IntPtr data = IntPtr.Zero; uint length = 0; status = SecKeychainItemCopyContent(itemRef, ref itemClass, IntPtr.Zero, ref length, ref data); if (status == OSStatus.Ok) { if (certData.Length == (int)length) { byte[] rawData = new byte[(int)length]; Marshal.Copy(data, rawData, 0, (int)length); found = true; for (int i = 0; i < rawData.Length; i++) { if (rawData[i] != certData[i]) { found = false; break; } } } SecKeychainItemFreeContent(IntPtr.Zero, data); } CFRelease(itemRef); } CFRelease(searchRef); } return(found); }
static extern OSStatus SecKeychainItemCopyContent(IntPtr itemRef, ref SecItemClass itemClass, IntPtr attrList, ref uint length, ref IntPtr data);
static extern unsafe OSStatus SecKeychainItemCopyAttributesAndData(IntPtr itemRef, SecKeychainAttributeInfo *info, ref SecItemClass itemClass, SecKeychainAttributeList **attrList, ref uint length, ref IntPtr outData);
static extern unsafe OSStatus SecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAttributeList *attrList, uint passwordLength, byte[] password, IntPtr keychain, IntPtr initialAccess, ref IntPtr itemRef);
static extern unsafe OSStatus SecKeychainSearchCreateFromAttributes(IntPtr keychainOrArray, SecItemClass itemClass, SecKeychainAttributeList *attrList, out IntPtr searchRef);
static unsafe extern OSStatus SecKeychainSearchCreateFromAttributes(IntPtr keychainOrArray, SecItemClass itemClass, SecKeychainAttributeList *attrList, out IntPtr searchRef);
static unsafe extern OSStatus SecKeychainItemCreateFromContent(SecItemClass itemClass, SecKeychainAttributeList *attrList, uint passwordLength, byte[] password, IntPtr keychain, IntPtr initialAccess, ref IntPtr itemRef);
static extern unsafe OSStatus SecKeychainItemCopyAttributesAndData (IntPtr itemRef, SecKeychainAttributeInfo* info, ref SecItemClass itemClass, SecKeychainAttributeList** attrList, ref uint length, ref IntPtr outData);
static extern unsafe SecStatusCode SecKeychainItemCopyAttributesAndData(IntPtr itemRef, SecKeychainAttributeInfo *info, ref SecItemClass itemClass, SecKeychainAttributeList **attrList, IntPtr lengthRef, IntPtr outDataRef);