Vision Pro is getting MDM support, which is good for companies that want to bring them into the enterprise, but security needs to be addressed. Does anyone know what cryptographic module VisionOS uses? I didn't see any info here: https://support.apple.com/en-us/103688 or https://support.apple.com/guide/certifications/welcome/web
General
RSS for tagPrioritize user privacy and data security in your app. Discuss best practices for data handling, user consent, and security measures to protect user information.
Post
Replies
Boosts
Views
Activity
I have verified a PIN in a smart card and I'd like to delete this internal state of the card. Unfortunately, the card doesn't support this with a dedicated command, which is why I'd like to reset the card (cold/warm reset as described in PC/SC, for example).
The CryptoTokenKit documentation doesn't seem to have an API for that.
Does anyone have an idea how to implement this?
Note, that if the smart card is not reset and does not support logout, then the card is permanently in an authenticated state so that related keys can be misused by any other CTK session or even via the PC/SC interface.
When performing biometric authentication, some times we are getting these kind of errors when i try to sign the data with private key that we get it from keychain. I was searching for document related to this but i could not.Can someone help me on this?
Error message and error code
Remote alert invalidated -4
UI canceled by system -4
unable to sign digest -3
Canceled by another authentication -4
Caller is not running foreground -1004
Caller moved to background -4
No identities are enrolled -7
User has denied the use of biometry for this app -1018
Application retry limit exceeded -1
Face ID interlocked -8
Biometry lost -4
match failed -1
// To get signed data using private key
SecKeyRef privateKeyReferences = [self getPrivateKey:keyNames];
if(!privateKeyReferences) {
NSLog(@"Error retrieving private key");
return nil;
}
NSError *error;
NSData *signature = CFBridgingRelease(SecKeyCreateSignature(privateKeyReferences, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, (CFDataRef) data, (void *)&error));
if(!signature) {
NSString *errorMessage = [NSString stringWithFormat:@"Error signing data %@.", error];
NSLog(@"%@", errorMessage);
return nil;
}
return signature;
Problem Situation
User membership withdrawal request → revoke API call
It always returns status code 200, but once out of 5~10, it remains an app linked to the user's Apple ID.
Re-request user Apple login → Email is returned as null
Currently, the only solution is for users to manually delete apps linked to their Apple ID. Email sent when re-requesting Apple login
When the above problem occurs, even if the Revoke API is called multiple times, the app linked to the user's Apple ID is not deleted, and when requesting Refresh Token validation, it has already expired.
Releated Issues
https://forums.developer.apple.com/forums/thread/707181
Hi,
I encounter a problem about the permission using Flutter.
I already add the following items in iOS/Runner/Info.plist
<key>NSCameraUsageDescription</key>
<string>We need access to your camera to take photos.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We need to access your current location for manage the dispatching routing.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>We need to access your current location for manage the dispatching routing.</string>
<key>NSMicrophoneUsageDescription</key>
<string>We need access your microphone to talk to driver.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>For uploading driver's report including dispatch and clock in/out</string>
And call this in my code:
Map<Permission, PermissionStatus> statuses = await [
Permission.camera,
Permission.locationWhenInUse,
Permission.locationAlways,
Permission.microphone,
].request();
But why there is no any dialog asking for permission and when going to settings-> "App name", and there are no items in "Allow {App Name} to Access" for setting permission manually. Can anyone help me?
Thanks a lot.
Here is the information of flutter doctor
``[✓] Flutter (Channel stable, 3.10.6, on macOS 13.6.4 22G513 darwin-x64, locale zh-Hant-TW)
[✗] Android toolchain - develop for Android devices
✗ Unable to locate Android SDK.
Install Android Studio from: https://developer.android.com/studio/index.html
On first launch it will assist you in installing the Android SDK components.
(or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
If the Android SDK has been installed to a custom location, please use
`flutter config --android-sdk` to update to that location.
[✓] Xcode - develop for iOS and macOS (Xcode 15.2)
[✗] Chrome - develop for the web (Cannot find Chrome executable at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome)
! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.
[!] Android Studio (not installed)
[✓] VS Code (version 1.62.0)
[✓] VS Code (version 1.86.1)
[✓] Connected device (2 available)
[✓] Network resources``
I recently inherited a project to port an app bundle to arm64, and some of the design decisions in the app bundle are undocumented. I'd like to structure the bundle as canonically as possible, to minimize future problems as much as possible.
In particular, there are two areas where I would like some clarification. I have read all of eskimo's guides (what a godsend!), but have not been able to find an explanation for these yet.
We have some helper executables that allow us to run jobs in the background, etc... Historically, these have always been in Contents/Resources, for some reason; that seems to be a bad idea. I have seen conflicting advice suggesting to use Helpers or just MacOS. What are the advantages or disadvantages of using each folder? Would dumping all the executables in MacOS be an adequate solution and, if not, why should I use Helpers?
Our app contains "compiled extensions" in Contents/SharedSupport, which consist of small intel-based apps (with their own app bundle) that our app can interact with. They are supposed to be a demo of extensions that the users could code and compile themselves, thus justifying their location. Should these be signed in any special way? Our app used to employ the --deep flag for code signing, but following eskimo's guidelines I have removed that, and it is not clear to me how these should be signed.
Thank you.
Hi!
I am trying to make a UI Testing target in Xcode for my Application (Client). It works with Keychain items that are created during installation, so in order to mock this installation behavior I am creating the items like this:
security add-generic-password -U -D "[item_kind]" -a "[account]" -l "[label]" -s [service] -w "[value]" -T path/to/UITest-runner.app -T path/to/Client-app.app
However, during UI Testing, the application is still prompted to access or modify the Keychain Items as seen in the bottom half of this screenshot:
These application paths have been obtained by the find terminal command inside DerivedData/.../Build/Products/... so they are the correct paths (which is also proven I guess by the fact that the apps are correctly listed in the ACL window of Keychain Access as seen on the top half of the screenshot).
I also tried using the -A option instead of -T but the result is exactly the same.
Why doesn't this approach work during UI Testing? I am using the same approach in my installation script for the real application installation process with the -T parameters and there is no issue in that case. This issue kills my UI Tests because I am constantly prompted when I want to read of modify the contents of these Keychain Items.
I understand that the passkey is stored on iCloud Keychain. That means you need an Apple ID account. Can I use passkey without Apple ID account? I checked on the simulator and even though I don't need to log in to my Apple ID account, I can still use the passkey. Please help me. Thank you.
for ios sdk,
only NSPrivacyAccessedAPITypes is required?
Note
You only need to supply NSPrivacyAccessedAPITypes for apps and third-party SDKs on iOS, iPadOS, tvOS, visionOS, and watchOS.
https://developer.apple.com/documentation/bundleresources/privacy_manifest_files?language=objc
i have a code only static library framework and added PrivacyInfo.xcprivacy file inside.
because there are no resources required in runtime,
app using that framework can build without embedding.
finally there are no PrivacyInfo.xcprivacy file in app bundle.
is this correct intended operation?
some steps to propagate and merge static framework's privacy manifest to app's privacy manifest not needed?
Hi,
I've implemented the Privacy Manifest in my app and specified my tracking domain as required, setting NSPrivacyTracking to true and listing my domain under NSPrivacyTrackingDomains However, on iOS17 when I decline the App Tracking Transparency (ATT) request, the specified tracking domain isn't blocked by iOS, contrary to my expectations. Shouldn't Apple's framework automatically block the domain and indicate this action in Instruments, allowing developers to verify the domain is indeed blocked when tracking is denied?
<key>NSPrivacyTracking</key>
<true/>
<key>NSPrivacyTrackingDomains</key>
<array>
<string>traking.example.com</string>
</array>
As the new requirement for Privacy manifests is coming this Spring 2024 (https://developer.apple.com/news/?id=r1henawx), Apple released a list of SDK's that need to comply with this requirement and provide a privacy manifest file: https://developer.apple.com/support/third-party-SDK-requirements/
I have a SDK project that does not fall under the mentioned requirements。
collects data
uses of required reason API
includes listed Third-party SDK
I have some questions:
Do I need to include a privacy manifest file in my SDK project?
if so, is a blank privacy manifest file included in the SDK?
if not, is it possible to publish an App that use my SDK, without a privacy manifest file?
Hello.We provide our customer with a SDK which we developed.
Our customer demands us that our SDK supports privacy manifest requirement.
We check if our SDK uses data,APIs and third party SDKs on the list Apple released.
When our SDK don't use any data,APIs and third party SDKs,
Should we add the privacy manifest file to our SDK?
Hello,
Regarding authorization plugins, I am trying to display a user interface in the fast user switching (fus) scenario. I have implemented the SFAuthorizationPluginView class that theoretically would help me show a user interface in this context. doing tests, I see that my plugin window is displayed behind the fus background screen. This window in screen lock scenario is displayed correctly. Is there any limitation in fus that prevents displaying a UI above the background screen where the user enters the password?
I show how I have system.login.fus configured(My plugin is MyTestPlugin):
...
mechanisms
<string>builtin:smartcard-sniffer,privileged</string>
<string>loginwindow:login</string>
<string>builtin:reset-password,privileged</string>
<string>builtin:auto-login,privileged</string>
<string>builtin:authenticate-nocred,privileged</string>
<string>MyTestPlugin:invoke</string>
<string>loginwindow:success</string>
<string>loginwindow:done</string>
I have tried placing my puglin in a different order compared to other mechanisms and it did not get the window to display above the background screen. Another option I've tried is to place my plugin on top of loginwindow:login. In this case, my plugin interface is displayed correctly but I do not have username information. Is there a way to obtain this information?
All the best.
Quick Summary
I'm having trouble using SecKeyCreateSignature(deviceSigningKeyRef, .ecdsaSignatureMessageX962SHA256, digest, &error) but when using SecureEnclave.P256.KeyAgreement.PrivateKey().signature(for: digest) the other code I'm using to verify succeeds.
Full use case and code
If I just initiate a SecureEnclave.P256.KeyAgreement.PrivateKey() class variable and then later use signature(for: digest).rawRepresentation to generate a signature, I get a signature value that can be passed to the verifying code
class MyClass {
var myPrivateKey: SecureEnclave.P256.KeyAgreement.PrivateKey?
init() {
myPrivateKey = SecureEnclave.P256.KeyAgreement.PrivateKey()
let myPublicKey = myPrivateKey?.publicKey.rawRepresentation
}
func createAndSendSignature(_ digest: Data) {
let signature = try? myPrivateKey?.signature(for: digest).rawRepresentation // 64 bytes
sendSignatureWithDigest(signature, digest)
}
}
But if I create my key in keychain via Secure Enclave with the way the documentation recommends (here's a few links to start Signing/Verifying, Keys for encryption), and then retrieve the key representation and use SecKeyCreateSignature, the resulting signature (which I manipulate a little more because it is DER encoded and does not comes back as 64 bytes) fails against the verifying code.
class MyClass {
var myKeyTag: String = "myKeyTag"
func createAndStoreKey() {
let access = SecAccessControlCreateWithFlags(
kCFAllocatorDefault,
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
.privateKeyUsage,
nil)! // Ignore errors.
let attributes: NSDictionary = [
kSecClass as String: kSecClassKey,
kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
kSecAttrKeySizeInBits as String: 256,
kSecAttrTokenID: kSecAttrTokenIDSecureEnclave,
kSecPrivateKeyAttrs as String: [
kSecAttrIsPermanent as String: true,
kSecAttrApplicationTag as String: myKeyTag,
kSecAttrAccessControl as String: access,
kSecAttrCanSign as String: true,
]
]
var error: Unmanaged<CFError>?
guard let keyRef: SecKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
throw error!.takeRetainedValue() as Error
}
return keyRef as SecKey!
}
func getKey(){
let query: [String: Any] = [
kSecClass as String: kSecClassKey,
kSecAttrApplicationTag as String: myKeyTag,
kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
kSecReturnRef as String: true,
]
var item: CFTypeRef?
let status = SecItemCopyMatching(query as CFDictionary, &item)
guard status == errSecSuccess else {
throw KeyStoreError("Unable to retrieve key: \(status.message)")
}
return (item as! SecKey)
}
func createAndSendSignature(_ digest: Data) {
let privKey = getKey()
let signature = SecKeyCreateSignature(
privKey,
.ecdsaSignatureMessageX962SHA256,
digest as CFData,
&error) as Data? else {
print(error)
return
} // bytes varry due to DER encoding and R and S values
let ecdsaSignature = try P256.Signing.ECDSASignature(derRepresentation: signature)
let signatureBytes = ecdsaSignature.rawRepresentation
sendSignatureWithDigest(signatureBytes, digest)
}
}
An important note: digest is not an actual digest but a message that needs to be hashed to turn into a digest? Sorry if that sounds off, my security knowledge is limited.
Please forgive any syntax errors, I can't copy and paste the code and am just extracting the important elements.
Anything helps, thanks!
I am creating an app using flutter. When the application displays the passkey authentication dialog box, after the face id authentication is complete (the authentication dialog box has not yet closed), I press the power button to lock the screen. After that, when I unlock the screen, my application is still displayed but it is in inactive state. This means the interface is still visible but the user cannot interact.
In the context of a passkey authentication where a non apple desktop system relies on the ios device as an authenticator, je ios device requires the user to scan the qrcode of the desktop device every time an authentication on is required.
in the same context, and Android device will allow the user to « remember » the established link to allow subsequent authentications to reuse the link without having to scan the qrcode each time.
The android device behaviour is specified by FIDO at https://fidoalliance.org/specs/fido-v2.2-rd-20230321/fido-client-to-authenticator-protocol-v2.2-rd-20230321.html
So my question is: when will ios support CTAP 2.2 hybrid transport state assisted transaction?
The absence of it is a major obstacle to the general adoption of passkeys among ios users.
We have an App that displays a WKWebWiew. The page being loaded in the WebView loads a snippet with a button that when clicked, initiates WebAuthN Flow. The App throws he following
[WebAuthn] Request cancelled after error: The operation couldn’t be completed. Application with identifier 123ABCDEF4.com.exmaple.app.staging is not associated with domain example.co.za.
In the above quote, 123ABCDEF4 would represent the TeamID, com.exmaple.app.staging is the bundle identifier and example.co.za is the main/root domain while the WKWebView actually loads a URL at staging.example.co.za.
in Xcode, the App's Associated Domains contains the following
webcredentials:staging.example.co.za
The AASA file hosted at https://staging.example.co.za/.well-known/apple-app-site-association returns the following
{
"applinks": {
"details": [
{
"appIDs": [
"123ABCDEF4.com.example.app",
"123ABCDEF4.com.example.app.staging"
],
"paths": [
"*"
]
}
]
},
"webcredentials": {
"apps": [
"123ABCDEF4.com.example.app",
"123ABCDEF4.com.example.app.staging"
]
},
"appclips": {
"apps": []
}
}
May you kindly advise what we may be doing wrong? The message being thrown refers to the fact that the Staging app is not associated with the root/main domain. If it's any consolation, we've updated both example.co.za and staging.exmaple.co.za to return the exact same AASA file where they both registers both Prod & Staging AppIds
I am integrating Apple's iOS implementation of WebAuthN using the ASAuthorization APIS provided by Apple. I am integrating with the Django py_webauthn host backend. I have the entire registration & account creations process working. And I almost have the account authentication process working. But there seems to be an issue between the version of authenticationData generated by iOS subsequent to the client (iPhone) authentication process and what py_webauthn is expecting. It results in a consistent
"Leftover bytes detected while parsing authentication data" error
on the host. According to the documentation, this error is generated when all the authenticatorData has been parsed but there are leftover bytes in the data.
I believe if I get past this issue everything will be working.
I could use some help here and provide code/logs below. But in the hopes that someone from the Authentication development team at Apple is watching for these posts, I have a related question.
Can we assume that the generated private key AND sign_count data is shared across an iOS user's devices through KeyChain cloud? Do we have to advise our users that they should enable this??
Here is code (OBJ C) and logs, in the hopes that someone can advise... and hoping that the code can help others trying to implement this capability.
Thanks.....
iPhone Client
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization
//Check to make sure that we are authenticating user after receiving authorization challenge from host
NSLog(@"%s retrieve public/private key",__FUNCTION__);
NSDictionary *pubKeyDict = [NSDictionary dictionary];
ASAuthorizationPlatformPublicKeyCredentialAssertion *appleCred = (ASAuthorizationPlatformPublicKeyCredentialAssertion *)authorization.credential;
NSDictionary *clientJSON = [NSJSONSerialization JSONObjectWithData:appleCred.rawClientDataJSON options:NSJSONReadingMutableContainers error:nil];
NSLog(@"%s clientJSON = %@",__FUNCTION__,clientJSON);
NSString *clientJSONString = [ServerUtilities encodeBase64URLData:appleCred.rawClientDataJSON];
NSString *authenticatorString = [ServerUtilities encodeBase64URLData:appleCred.rawAuthenticatorData];
NSString *signatureString = [ServerUtilities encodeBase64URLData:appleCred.signature];
NSDictionary *respDict = [NSDictionary dictionaryWithObjectsAndKeys clientJSONString, @"clientDataJSON",
authenticatorString, @"signature",
signatureString, @"authenticatorData", nil];
NSLog(@"%s respDict - %@",__FUNCTION__,respDict);
NSString *credIDString = [ServerUtilities encodeBase64URLData:appleCred.credentialID];
NSDictionary *regDict = [NSDictionary dictionaryWithObjectsAndKeys: credIDString, @"id",
respDict, @"response",
@"public-key",@"type", nil];
pubKeyDict = [NSDictionary dictionaryWithObjectsAndKeys: credentialEmail, kEMAIL,
regDict, @"auth_cred", nil];
NSLog(@"%s pubKeyDict - %@",__FUNCTION__,pubKeyDict);
//Post JSON serialized version of pubKeyDict to host
Xcode log
pubKeyDict - {
"auth_cred" = {
id = "JNMBbZF_PQM7O64RY_MXQqhAyKk";
response = {
authenticatorData = "MEYCIQDgVFINihy9nPuuRrZWkLPahEfLy3huCV9_seOuM5gSlgIhAP_99EVQjXhyJy37ccRxQenSxt7oPNrQ4VjVDSW5Ej8l";
clientDataJSON = eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoidkhYcTdKTG05Z2dNU1BienNpZThFWUJsVW16V2N3WXlvOFBnT0FKMlR1b0VBbGVBbkQ0NGFNVDg3RG93YnZaZUNxLWxTdC1uNTFkUWJpVzgxNVhZRlEiLCJvcmlnaW4iOiJodHRwczovL2FuY2hvci1hd2F5LmNvbSJ9;
signature = "WJ3tJNMYfNST99x-EAdNDrnsUOCxqFzvDgXCyTcTg6sdAAAAAA";
};
type = "public-key";
};
email = "my@email.com";
}
Django Python Host
auth_cred_json - {'id': 'JNMBbZF_PQM7O64RY_MXQqhAyKk', 'response': {'clientDataJSON': 'eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoidkhYcTdKTG05Z2dNU1BienNpZThFWUJsVW16V2N3WXlvOFBnT0FKMlR1b0VBbGVBbkQ0NGFNVDg3RG93YnZaZUNxLWxTdC1uNTFkUWJpVzgxNVhZRlEiLCJvcmlnaW4iOiJodHRwczovL2FuY2hvci1hd2F5LmNvbSJ9', 'signature': 'WJ3tJNMYfNST99x-EAdNDrnsUOCxqFzvDgXCyTcTg6sdAAAAAA', 'authenticatorData': 'MEYCIQDgVFINihy9nPuuRrZWkLPahEfLy3huCV9_seOuM5gSlgIhAP_99EVQjXhyJy37ccRxQenSxt7oPNrQ4VjVDSW5Ej8l'}, 'type': 'public-key', 'rawId': 'JNMBbZF_PQM7O64RY_MXQqhAyKk'}
AuthorizationCredential generated by 'parse_authentication_credential_json'
id='JNMBbZF_PQM7O64RY_MXQqhAyKk'
raw_id=b'$\\xd3\\x01m\\x91\\x7f=\\x03;;\\xae\\x11c\\xf3\\x17B\\xa8@\\xc8\\xa9' response=AuthenticatorAssertionResponse(
client_data_json=b'{
"type":"webauthn.get",
"challenge":"vHXq7JLm9ggMSPbzsie8EYBlUmzWcwYyo8PgOAJ2TuoEAleAnD44aMT87DowbvZeCq-lSt-n51dQbiW815XYFQ",
"origin":"https://anchor-away.com"
}',
authenticator_data=b"0F\\x02!\\x00\\xe0TR\\r\\x8a\\x1c\\xbd\\x9c\\xfb\\xaeF\\xb6V\\x90\\xb3\\xda\\x84G\\xcb\\xcbxn\\t_\\x7f\\xb1\\xe3\\xae3\\x98\\x12\\x96\\x02!\\x00\\xff\\xfd\\xf4EP\\x8dxr'-\\xfbq\\xc4qA\\xe9\\xd2\\xc6\\xde\\xe8<\\xda\\xd0\\xe1X\\xd5\\r%\\xb9\\x12?%",
signature=b'X\\x9d\\xed$\\xd3\\x18|\\xd4\\x93\\xf7\\xdc~\\x10\\x07M\\x0e\\xb9\\xecP\\xe0\\xb1\\xa8\\\\\\xef\\x0e\\x05\\xc2\\xc97\\x13\\x83\\xab\\x1d\\x00\\x00\\x00\\x00',
user_handle=None
)
"kSecTrustResultProceed indicates that the user has explicitly trusted a certificate."
Problem: kSecTrustResultProceed returned from 'SecTrustEvaluate' for some users(733/million), while their cert chain contains non explicitly trusted certs:
cert chain:
***.***.com
Go Daddy Secure Certificate Authority - G2
Go Daddy Root Certificate Authority - G2
(Go Daddy is trusted on iOS, not explicitly trusted)
I cannot reproduce this on my phone, but it does exist, for some users, including iOS 17.
Any thoughts?
SecTrustResultType res = kSecTrustResultInvalid;
SecTrustEvaluate(secTrust, &res);
if (res == kSecTrustResultUnspecified) {
return YES;
}
if (res == kSecTrustResultProceed) {
// some check... found this question
return YES;
}
if (res != kSecTrustResultRecoverableTrustFailure) {
return NO;
}
// some recover...
return recovered;