If I have a valid x509 certificate on MacOS that has paired public key, can I use it to dynamically create SecClassIdentity object for TLS challenge as below?
The server that we sent the TLS request to was able to recognize the challenge request and returned HTTP code 200.
SecClassCertificate Cert = [I have a valid cert here]
NSArray *certs = [NSArray arrayWithObjects:(__bridge id)Cert, nil];
SecIdentityRef newBornIdentity = nil;
SecIdentityCreateWithCertificate(nil, Cert, &newBornIdentity);
if (newBornIdentity)
{
NSURLCredential *cred = [NSURLCredential credentialWithIdentity:newBornIdentity
certificates:certs
persistence:NSURLCredentialPersistenceForSession];
completionHandler(NSURLSessionAuthChallengeUseCredential,cred);
}
Post
Replies
Boosts
Views
Activity
Hello,
I am hoping to test iOS-style keychain sharing on my MacOS test app via
kSecAttrAccessGroup
kSecUseDataProtectionKeychain
attributes
I understand that I first need to enable keychain sharing under "Signing & Capabilities", which also creates a new entitlement file. (Otherwise it will throw -34018 = errSecMissingEntitlementerror)
Then I added the keychain access group that I am interested in using also.
However, after doing so, the test app would no longer build with an error "Message from debugger: no such process."
Here's my setup Xcode 12.4
Provisioning Profile: XCODE Managed Profile
(Mac Team Provisioning Profile) this profile says keychain sharing is enabling under capabilities & entitlement also contains keychain-access-group Enable hardened runtime: NO
Code Signing Inject Base Entitlement: YES
Code Signing Style: Automatic
Other Code Signing Flags: --deep
Would you by any chance know what steps I am missing to enable iOS style keychain sharing on MacOS as above?
Thank you!
Peter
I know that traditional ACL-style MacOS keychain objects are stored in login keychain.
When I enable kSecUseDataProtectionKeychain (I don't want to sync this to iCloud) & specify kSecAttrAccessGroup during keychain write through SecItemAdd, status returns errSecSuccess,
and I can retrieve this keychain object later on using SecItemCopyMatching.
However, I can't seem to find them in the keychain access - whether it be login keychain or system keychain.
where do these MacOS keychain items go when we enable iOS-style keychain sharing on them? I know that above attribute allows you to use iOS-style keychain without syncing to iCloud.
Thank you,
Peter
Hello,
When I use Setup Assistance to backup from old device to new device, I would like to make certain keychain objects non-exportable/extractable.
I know I can make key non-exportable/extractable on kSecClassKey object by setting kSecKeyExtractable = NO. and I verified that my private keys that have kSecKeyExtractable set to NO don't get migrated from backup to the new device.
Is there any way I can do the same for metadata objects?
where we can make them non-exportable so they don't get moved from backup to new device?
Thanks,
Peter
Hello,
In our legacy code, we used to generate private and public key pair using SecKeyGeneratePair API on MacOS login keychain.
We don't enable iOS-style keychain and still rely on login keychain/ACL on MacOS for backward compatibility.
Recently, we encountered error code -25295 (errSecInvalidKeychain) and -25307(errSecNoDefaultKeychain) while doing SecKeyGeneratePair.
I looked up those error codes online, but I was unable to find much information on those two error codes.
Could you please help me to understand possible root causes for each error code and how to address them?
Thank you!
Since Apple is deprecating support for ACL on MacOS 10.15+, if we were to store private key - x509 cert in iOS style keychain using keychain access group, will Safari browser be able to recognize that and prompt for cert picker?
Thanks,
Peter
It looks like Apple API SecIdentitySetPreferred appends
bundleID suffix to all newly created identity preference objects on all the paths that are fed into the API
Before MacOS 11.3:
https://device.login.microsoftonline.com/
After MacOS 11.3:
https://device.login.microsoftonline.com/ (UBF8T346G9.com.microsoft.CompanyPortalMac)
This results in some people getting prompted for cert pickers on Safari when they hit endpoints that start with device.login.microsoftonline.com/ prefix.
Is there any way to make SecIdentitySetPreferred to behave like before MacOS 11.3?
Hello,
We have a kSecClassKey object and on MacOS, we have been setting the key non-extractable in the following manner, but many of the attributes seem to be deprecated.
Is there a better/recommended way of doing this on MacOS for private keys on login keychain using newer keychain attributes?
Thanks,
Peter
(ex: kSecKeyExtractable)
Current legacy code on MacOS:
int attributeListSize = 1;
int attributeIndex = 0;
unsigned int falseValue = 0;
SecKeychainAttributeList privateKeyAttrList;
SecKeychainAttribute privateKeyKeyChainAttributes[attributeListSize];
privateKeyKeyChainAttributes[attributeIndex].tag = kSecKeyExtractable;
privateKeyKeyChainAttributes[attributeIndex].data = &falseValue;
privateKeyKeyChainAttributes[attributeIndex].length = sizeof(falseValue);
privateKeyAttrList.count = attributeListSize;
privateKeyAttrList.attr = privateKeyKeyChainAttributes;
OSStatus status = SecKeychainItemModifyAttributesAndData((SecKeychainItemRef) keyRef, &privateKeyAttrList, 0, NULL);
if (status != errSecSuccess)
{
NSString *errMessage = [NSString stringWithFormat: @"Failed to modify kSecKeyExtractable attribute for key, status: %d", status];
*error = [self buildNSErrorForDomain:errorDomain
errorCode:keychainFailure
errorMessage: errMessage
underlyingError:[NSError errorWithDomain:keychainErrorDomain code:status userInfo:nil]
shouldRetry:false];
}
On MacOS,
let's say I am using Big Sur Version 11.6 (20G165)
Is there any API on Xcode that would allow me to retrieve the build number programmatically, (in this case 20G165)?
For version, I can use [[NSProcessInfo processInfo] operatingSystemVersion], but can't seem to be able to find the API for the build number.
Thanks!
In older MacOS versions, below API would create access ref object of the app running the code and store it into SectrustedApplicationRef mySelf object.
SecTrustedApplicationRef mySelf = NULL;
SecTrustedApplicationCreateFromPath(NULL, &mySelf);
Then I can store mySelf in an array - allTrustedApps, and create SecAccessRef object
SecAccessRef accessRef = NULL;
status = SecAccessCreate((CFStringRef)accessLabel, (__bridge CFArrayRef)allTrustedApps, &accessRef);
Finally, I would then add this access ref object into kSecAttrAccess field of the query dictionary before feeding it into SecItemAdd.
However, on MacOS 10.15+ SecTrustedApplicationCreateFromPath is deprecated.
As I was playing around with ACL, and when I tried to add a kSecClassGenericPassword object into login keychain using SecItemAdd, without 'KSecAttrAccess' in the write query dictionary. (nothing but kSecAttrAccount and kSecAttrService) - I've noticed that the final object in the login keychain still has ACL containing the hosting app that ran the keychain add op.
Is this by design?
Thanks,
Peter
Let's say I have a login keychain with ACL that contains trusted application list.
Now I want to add a new SecTrustedApplicationRef to this existing list, and hence update the ACL of this object.
Here's the steps I took, but doesn't seem to be working
retrieve keychain item reference of kSecClassGenericPassword object
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)queryDictionary,(CFTypeRef *)&attributeDictionary);
Then get existing access ref
SecKeychainItemRef itemRef = (SecKeychainItemRef) CFBridgingRetain([bridgedDict objectForKey:(__bridge id)kSecValueRef]);
SecAccessRef accessRef = NULL;
status = SecKeychainItemCopyAccess(itemRef,&accessRef);
Update this existing Access Ref by appending a new ACL that contains new trusted apps info
status = SecACLCreateWithSimpleContents(accessRef, (__bridge CFArrayRef)microsoftTrustedApps, (__bridge CFStringRef)tenantIdentifier, kSecKeychainPromptRequirePassphase, &newAcl);
Finally, update access ref using SecItemUpdate
NSMutableDictionary *origQuery = [NSMutableDictionary new];
[origQuery setObject:tenantIdentifier forKey:(__bridge id)kSecAttrService];
[origQuery setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
NSMutableDictionary *updateQuery = [NSMutableDictionary new];
[updateQuery setObject:(__bridge id)accessRef forKey:(__bridge id)kSecAttrAccess];
status = SecItemUpdate((CFDictionaryRef)origQuery, (CFDictionaryRef)updateQuery);
It does return errSecSuccess, and I get prompted for passphrase during SecItemUpdate, but the resultant login keychain object in keychain access still doesn't show the new app under "always allow access by these applications" under "Access Control" tab.
Any help would be appreciated. Thanks!