DeviceCheck

RSS for tag

Access per-device, per-developer data that your associated server can use in its business logic using DeviceCheck.

Posts under DeviceCheck tag

96 Posts

Post

Replies

Boosts

Views

Activity

App Attest Server Validations
I'm following the attestation object validation guide to check my attestation server validations, but having a different output of that it's expected in the documentation. Everything goes well until the step 2, where it's created the SHA256 hash of the one-time challenge, then this hash it's appended to the end of the authenticator data from the decoded attestation object. Here the generated client data hash is different from the one in the documentation, which also causes a different nonce value. Full implementation at Go Playground: https://go.dev/play/p/DpL_H3L8yWV // generate the SHA256 hash of the one-time challenge challengeHash := sha256.Sum256([]byte(serverChallenge)) // append the one-time challenge hash to the end of the authenticator data clientDataHash := append([]byte(att.AuthData), challengeHash[:]...) // create a SHA256 hash of the composite item to create nonce nonce := sha256.Sum256(clientDataHash) Then I noticed that if the one-time challenge value it's just appended to the end of the authenticator data, the value it's correctly according to the documentation. Full implementation at Go Playground: https://go.dev/play/p/qqN97SevJAB // append the one-time challenge byte array to the end of the authenticator data // this time not generating the SHA256 hash of the one-time challenge clientDataHash := append([]byte(att.AuthData), []byte(serverChallenge)...) // create a SHA256 hash of the composite item to create nonce nonce := sha256.Sum256(clientDataHash) My question is which of the implementations is correct, because if I didn't get it wrong it should be the first one and we would have an error in the documentation.
2
1
1.3k
Jul ’24
Unwanted Communication Reporting Extension - error with classificationreport url
Hi, I'm having headaches with the debugging of my Unwanted Communication Reporting extension. iPhone log says: com.apple.IdentityLookup.MessageFilter[1774] <Error>: Extension's containing app (appID <private>) unauthorized to defer requests to host <private> So I guess I have something wrong with my apple-app-site-association. The AASA file I get with swcutil dl -d services.mydomain.com { classificationreport = { apps = ( "<MYTEAMID>.com.mydomain.myapp", "<MYTEAMID>.com.mydomain.myapp.unwanted" ); }; } where .com.mydomain.myapp is my containing app (bundle id). and .com.mydomain.myapp.unwanted is my extension The AASA file on the server is obviously in JSON format and correctly served from the server : services.mydomain.com In the extension Info.plist I've set the following : <key>NSExtension</key> <dict> <key>NSExtensionAttributes</key> <dict> <key>ILClassificationExtensionNetworkReportDestination</key> <string>https://services.mydomain.com/path/unwanted/report</string> </dict> <key>NSExtensionMainStoryboard</key> <string>MainInterface</string> <key>NSExtensionPointIdentifier</key> <string>com.apple.identitylookup.classification-ui</string> </dict> I suppose the reply from classificationResponse method is correct since MessageFilter "tries" to send the request. Where am I mistakening ? Difficult to debug... MessageFilter's log keeps interesting data as private (so there is no way to check what it's actually doing). And I've found no way to go deeper in the debug process. Many thanks Emmanuel
3
1
1.1k
Jun ’24
Undocumented behavior about risk metric refresh
Hello, I'm developing a server that uses the app attestation feature. During the development, I found the behavior that are not written in the document, I would like to inquire this. When Apple server returns 404 for risk metric refresh request? A month after the attestation, receipt is not past expiration time, but 404 is returned from Apple server when I try refresh. And this receipt succeeded in refreshing the risk metric normally if the attestation proceeds again. This behavior is not in the document, but I wonder if it is intended. Is there a case where an attestation has occurred but the risk metric value does not increase? I found a case where attestation occurred twice on one device, but when both receipts were refreshed, the risk metric returned 1. Is this an expected behavior? If it is, I would like to know the detailed conditions under which it occurs. Thank you.
3
0
1.4k
Jun ’24
[Device Check]Get SSL connection timeout when connect https://api.devicecheck.apple.com
Our service is using Apple device check api to prevent fraud happening. https://developer.apple.com/documentation/devicecheck/accessing-and-modifying-per-device-data But there is SSL connection timeout happen from June 1st. /app $ curl --connect-timeout 5 -v https://api.devicecheck.apple.com Trying 17.33.193.105:443... Connected to api.devicecheck.apple.com (17.33.193.105) port 443 (#0) ALPN, offering h2 ALPN, offering http/1.1 successfully set certificate verify locations: CAfile: /etc/ssl/certs/ca-certificates.crt CApath: none TLSv1.3 (OUT), TLS handshake, Client hello (1): SSL connection timeout Closing connection 0 curl: (28) SSL connection timeout Does apply add access limitation for specific ips?
1
0
774
Jun ’24
DeviceCheck tokens are "single-use" - How do I read and update the bits (2 calls) within the same backend request?
Hey, the documentation for the generateToken() method states: Your server uses the generated token in its requests to get or set the persistent bits for the current device. You should treat the token you receive in the completion block as single-use. Although the token remains valid long enough for your server to retry a specific request if necessary, you should not use a token multiple times. Instead, use this method to generate a new token. Now, what I want to do in my backend is: Read the current bits to decide if an action is allowed If the action is allowed, update the bits That's 2 calls to the DeviceCheck API, so I would need 2 tokens, right? But I want to do this in a single call to my backend. Is it fine for the device to generate send 2 tokens at the same time? Or can I actually use a single token for both calls, and "single-use" just means I should not store it? Thanks!
0
0
802
Apr ’24
Increase in latency in DeviceCheck attestationData endpoint
Hello, Since the 21st of March 2024 around 6PM UTC I've been observing a very significant an increase (more than quadrupled) in P99 and P95 latency on https://data.appattest.apple.com/v1/attestationData I'm calling other endpoints of the same API, and I'm not observing a similar increase there. I tried submitting a report in Feedback Assistant but it's not working for me at the moment.
0
0
957
Mar ’24
App Attest server implementation
I'm trying to verify attestations from Apple devices on my server, and I'm finding it difficult to implement some of the steps outlined here. This is the current state of my implementation. I'm stuck on the step where the credCert extension is decoded and compared with the nonce. I'd be grateful for any help anyone can provide.
3
0
1.8k
Oct ’23
Reference example of AppTest server-side implementation
Hi, We have a multi-platform application that requires integrity attestation before the backend will enable supporting services (fairly common scenario). I've read the documentation for DeviceCheck and AppAttest, as well as SafetyNet on the Android side. The Android documentation includes lots of examples of use, including server-side (though oddly in C# and Javascript... which I don't see as being server-side languages, but... oh, well). Anyway, maybe there's a server-side example of using an application attestation on the server when validating a client, as well as validating individual requests with assertions, but I've not been able to find it. It seems like a relatively important bit of functionality to ensure that apps aren't being compromised, while at the same time requiring a correct implementation... Why not give a reference implementation as a starting point to make sure developers are on the right path? Can anyone point me at an example as a Gist, etc? Thanks.
4
1
4.4k
Oct ’23
DeviceCheck working fine for the development environment but giving error on production environment
Hello everyone, I am using Apple's DeviceCheck API in my Swift application which will check if the device is registered on Apple's server or not and based on the bits I have set I am updating the values in my own database. These values will help me to differentiate the new devices through which the users are getting logged in to my application and I will give them some digital reward poits to use my application on their new devices. Everything is working fine for me in the development environment as I get the right response when I am using the development API i.e. https://api.development.devicecheck.apple.com but it do not work as intended when I am using the production API i.e. https://api.devicecheck.apple.com/
0
0
917
Sep ’23
403 Error During Specific Time Period with DeviceCheck API Usage
I have a question regarding the usage of the DeviceCheck API. We have been using https://api.development.devicecheck.apple.com/v1/validate_device_token for checking device tokens. However, we encountered frequent HTTP response status code 403 between 16:50 and 17:15 Japan time on June 29th. According to the official documentation at https://developer.apple.com/documentation/devicecheck/accessing_and_modifying_per-device_data, I understand that a 403 error indicates "The specified action isn't allowed". Yet, I would like to clarify under what specific circumstances this error would be returned. Please note that we do not encounter a 403 error outside the aforementioned timeframe, which leads us to believe there is no issue with our basic implementation.
1
2
1.1k
Jul ’23
Unable to renew developer program & showing 2 different expiry dates
HI, Since more than a Month i am trying to solve the issue. Issue is as under Developer program end dates on apple developer account / app and in mac book's setting> manage subscription are different. In developer application not showing renew button. When i am trying to renew from mac book manage subscription option (When wrong date is mentioned) Its giving an error that could not purchase subscription. I got 7 days extension from apple and my corrected date (in apple account on website) got properly extended. Please solve this issue on priority. I am attaching screenshots for your reference.
1
0
1.1k
Jul ’23
X and Y coordinates in App Attestation public key has mismatching length
There seem to be an issue with the DeviceCheck Framework where in rare cases the public key (ECC P-256) embedded inside the attestation object returned from DCAppAttestService.attestKey(_:clientDataHash:completionHandler:) has X and Y coordinates with mismatching length. Sometimes X or Y has 31 bytes instead of the expected 32 bytes. This can easily be reproduced by generating and attesting multiple keys using DCAppAttestService.generateKey(completionHandler:) and DCAppAttestService.attestKey(_:clientDataHash:completionHandler:). Every now and then the public key embedded inside the attestation object has X and Y coordinates with mismatching length (number of bytes). Added a Swift snippet at the bottom that shows example on how to generate and detect this. I would expect the ECC P-256 public key X and Y coordinates to always be 32 bytes long. As mentioned in the Web Authentication spec for example. I've attached an example attestation object (in base64 encoded CBOR) that has an embedded public key with mismatching X and Y coordinate length (Y is 31 bits, and not the expected 32 bits). The file was generated using the Swift snippet below. The snippet was built using Xcode 14.3 (14E222b) and ran on iPhone XR with iOS 15.7.1 (19H117). A feedback ticket has also been submitted regarding this issue: FB12235865 Swift snippet to generate and check attestation objects: import DeviceCheck import CryptoKit import SwiftCBOR // https://github.com/valpackett/SwiftCBOR ​ func generateAttestationObjects() { for i in 0..<1000 { DispatchQueue.main.asyncAfter(deadline: .now() + TimeInterval(i)) { DCAppAttestService.shared.generateKey { keyId, error in guard let keyId else { print("\(i): Failed to generate key: \(error)") return } ​ print("\(i): Generated keyId: \(keyId)") ​ DCAppAttestService.shared.attestKey( keyId, clientDataHash: Data(hex: "01020304")! ) { attestationObject, error in guard let attestationObject else { print("\(i): Failed to get attestation: \(error)") return } ​ do { let attestationObjectBytes = [UInt8](attestationObject) ​ if case let .map(decodedAttestationObject) = try CBOR.decode(attestationObjectBytes) { print("\(i): Successfully decoded Attestation object (CBOR)") ​ if case let .byteString(authData) = decodedAttestationObject["authData"] { ​ let attestedCredentialData = [UInt8](authData.dropFirst(37)) ​ let credentialIdLengthBuffer = [UInt8](attestedCredentialData[16..<18]) let credentialIdLength = Int(credentialIdLengthBuffer.reversed().withUnsafeBytes { $0.load(as: UInt16.self) }) let credentialId = [UInt8](attestedCredentialData[18..<(18 + credentialIdLength)]) let credentialPublicKeyBuffer = [UInt8](attestedCredentialData.dropFirst(18 + credentialIdLength)) ​ if let decodedCredentialPublicKey = try CBOR.decode(credentialPublicKeyBuffer) { ​ if case let .byteString(xCoordinateBuffer) = decodedCredentialPublicKey[-2], case let .byteString(yCoordinateBuffer) = decodedCredentialPublicKey[-3] { let xCoordinateLength = xCoordinateBuffer.count let yCoordinateLength = yCoordinateBuffer.count ​ if xCoordinateLength != yCoordinateLength { print("\(i): X/Y Coordinate length mismatch! X: \(xCoordinateLength), Y: \(yCoordinateLength)") } else if xCoordinateLength != 32 || yCoordinateLength != 32 { print("\(i): X/Y Coordinate length mismatch! X: \(xCoordinateLength), Y: \(yCoordinateLength)") } else { print("\(i): X/Y Coordinates OK") } } } } } } catch { print("\(i): Error decoding Attestation object (CBOR): \(error)") } } } } } } An attestation object with a embedded public key with mismatching X and Y coordinate length (base64 encoded CBOR): appattest-object-mismatching-x-y-base64.txt
1
0
1.5k
Jul ’23
App Attest Server Validations
I'm following the attestation object validation guide to check my attestation server validations, but having a different output of that it's expected in the documentation. Everything goes well until the step 2, where it's created the SHA256 hash of the one-time challenge, then this hash it's appended to the end of the authenticator data from the decoded attestation object. Here the generated client data hash is different from the one in the documentation, which also causes a different nonce value. Full implementation at Go Playground: https://go.dev/play/p/DpL_H3L8yWV // generate the SHA256 hash of the one-time challenge challengeHash := sha256.Sum256([]byte(serverChallenge)) // append the one-time challenge hash to the end of the authenticator data clientDataHash := append([]byte(att.AuthData), challengeHash[:]...) // create a SHA256 hash of the composite item to create nonce nonce := sha256.Sum256(clientDataHash) Then I noticed that if the one-time challenge value it's just appended to the end of the authenticator data, the value it's correctly according to the documentation. Full implementation at Go Playground: https://go.dev/play/p/qqN97SevJAB // append the one-time challenge byte array to the end of the authenticator data // this time not generating the SHA256 hash of the one-time challenge clientDataHash := append([]byte(att.AuthData), []byte(serverChallenge)...) // create a SHA256 hash of the composite item to create nonce nonce := sha256.Sum256(clientDataHash) My question is which of the implementations is correct, because if I didn't get it wrong it should be the first one and we would have an error in the documentation.
Replies
2
Boosts
1
Views
1.3k
Activity
Jul ’24
Receiving 403 for all requests to /validate_device_token
Whenever we call this API enpoint https://api.development.devicecheck.apple.com/v1/validate_device_token we received an 403. The issue started yesterday around 2:00 PM (Brasil - Brasília time).
Replies
6
Boosts
4
Views
1.4k
Activity
Jun ’24
Unwanted Communication Reporting Extension - error with classificationreport url
Hi, I'm having headaches with the debugging of my Unwanted Communication Reporting extension. iPhone log says: com.apple.IdentityLookup.MessageFilter[1774] <Error>: Extension's containing app (appID <private>) unauthorized to defer requests to host <private> So I guess I have something wrong with my apple-app-site-association. The AASA file I get with swcutil dl -d services.mydomain.com { classificationreport = { apps = ( "<MYTEAMID>.com.mydomain.myapp", "<MYTEAMID>.com.mydomain.myapp.unwanted" ); }; } where .com.mydomain.myapp is my containing app (bundle id). and .com.mydomain.myapp.unwanted is my extension The AASA file on the server is obviously in JSON format and correctly served from the server : services.mydomain.com In the extension Info.plist I've set the following : <key>NSExtension</key> <dict> <key>NSExtensionAttributes</key> <dict> <key>ILClassificationExtensionNetworkReportDestination</key> <string>https://services.mydomain.com/path/unwanted/report</string> </dict> <key>NSExtensionMainStoryboard</key> <string>MainInterface</string> <key>NSExtensionPointIdentifier</key> <string>com.apple.identitylookup.classification-ui</string> </dict> I suppose the reply from classificationResponse method is correct since MessageFilter "tries" to send the request. Where am I mistakening ? Difficult to debug... MessageFilter's log keeps interesting data as private (so there is no way to check what it's actually doing). And I've found no way to go deeper in the debug process. Many thanks Emmanuel
Replies
3
Boosts
1
Views
1.1k
Activity
Jun ’24
Undocumented behavior about risk metric refresh
Hello, I'm developing a server that uses the app attestation feature. During the development, I found the behavior that are not written in the document, I would like to inquire this. When Apple server returns 404 for risk metric refresh request? A month after the attestation, receipt is not past expiration time, but 404 is returned from Apple server when I try refresh. And this receipt succeeded in refreshing the risk metric normally if the attestation proceeds again. This behavior is not in the document, but I wonder if it is intended. Is there a case where an attestation has occurred but the risk metric value does not increase? I found a case where attestation occurred twice on one device, but when both receipts were refreshed, the risk metric returned 1. Is this an expected behavior? If it is, I would like to know the detailed conditions under which it occurs. Thank you.
Replies
3
Boosts
0
Views
1.4k
Activity
Jun ’24
Create DeviceCheck key issue for Enterprise acccount
In our Enterprise account with Admin access, I can't see the option to create a DeviceCheck key needed for the App Attest functionality. Is there a limitation preventing this key from being generated on Enterprise accounts?
Replies
1
Boosts
0
Views
1.1k
Activity
Jun ’24
[Device Check]Get SSL connection timeout when connect https://api.devicecheck.apple.com
Our service is using Apple device check api to prevent fraud happening. https://developer.apple.com/documentation/devicecheck/accessing-and-modifying-per-device-data But there is SSL connection timeout happen from June 1st. /app $ curl --connect-timeout 5 -v https://api.devicecheck.apple.com Trying 17.33.193.105:443... Connected to api.devicecheck.apple.com (17.33.193.105) port 443 (#0) ALPN, offering h2 ALPN, offering http/1.1 successfully set certificate verify locations: CAfile: /etc/ssl/certs/ca-certificates.crt CApath: none TLSv1.3 (OUT), TLS handshake, Client hello (1): SSL connection timeout Closing connection 0 curl: (28) SSL connection timeout Does apply add access limitation for specific ips?
Replies
1
Boosts
0
Views
774
Activity
Jun ’24
DeviceCheck tokens are "single-use" - How do I read and update the bits (2 calls) within the same backend request?
Hey, the documentation for the generateToken() method states: Your server uses the generated token in its requests to get or set the persistent bits for the current device. You should treat the token you receive in the completion block as single-use. Although the token remains valid long enough for your server to retry a specific request if necessary, you should not use a token multiple times. Instead, use this method to generate a new token. Now, what I want to do in my backend is: Read the current bits to decide if an action is allowed If the action is allowed, update the bits That's 2 calls to the DeviceCheck API, so I would need 2 tokens, right? But I want to do this in a single call to my backend. Is it fine for the device to generate send 2 tokens at the same time? Or can I actually use a single token for both calls, and "single-use" just means I should not store it? Thanks!
Replies
0
Boosts
0
Views
802
Activity
Apr ’24
Increase in latency in DeviceCheck attestationData endpoint
Hello, Since the 21st of March 2024 around 6PM UTC I've been observing a very significant an increase (more than quadrupled) in P99 and P95 latency on https://data.appattest.apple.com/v1/attestationData I'm calling other endpoints of the same API, and I'm not observing a similar increase there. I tried submitting a report in Feedback Assistant but it's not working for me at the moment.
Replies
0
Boosts
0
Views
957
Activity
Mar ’24
App Attestation returns DCErrorInvalidKey 3
A lot of our customers experienced failed App attest and always return error "DCErrorInvalidKey 3" invalidKey error on these iOS versions: 16.7.2 - iPhone 8 17.1.1, 17.1.2 - iPhone X, iPhone XS, iPhone XR, iPhone SE 2. iPhone 12, iPhone 12 Pro, iPhone 12 Pro Ma
Replies
3
Boosts
1
Views
1.7k
Activity
Jan ’24
DeviceCheck 500 error
response body is "service discovery failure" It appeared by chance.. Does anyone know why?
Replies
0
Boosts
0
Views
686
Activity
Jan ’24
install an ipa file without apple id and offline mode
i need to install a ipa file without apple id and in offline mode for my users (and) by using usbmuxd i want command to enable the developer mode by using commands only not manually
Replies
0
Boosts
0
Views
1.2k
Activity
Dec ’23
App Attest server implementation
I'm trying to verify attestations from Apple devices on my server, and I'm finding it difficult to implement some of the steps outlined here. This is the current state of my implementation. I'm stuck on the step where the credCert extension is decoded and compared with the nonce. I'd be grateful for any help anyone can provide.
Replies
3
Boosts
0
Views
1.8k
Activity
Oct ’23
Reference example of AppTest server-side implementation
Hi, We have a multi-platform application that requires integrity attestation before the backend will enable supporting services (fairly common scenario). I've read the documentation for DeviceCheck and AppAttest, as well as SafetyNet on the Android side. The Android documentation includes lots of examples of use, including server-side (though oddly in C# and Javascript... which I don't see as being server-side languages, but... oh, well). Anyway, maybe there's a server-side example of using an application attestation on the server when validating a client, as well as validating individual requests with assertions, but I've not been able to find it. It seems like a relatively important bit of functionality to ensure that apps aren't being compromised, while at the same time requiring a correct implementation... Why not give a reference implementation as a starting point to make sure developers are on the right path? Can anyone point me at an example as a Gist, etc? Thanks.
Replies
4
Boosts
1
Views
4.4k
Activity
Oct ’23
DeviceCheck working fine for the development environment but giving error on production environment
Hello everyone, I am using Apple's DeviceCheck API in my Swift application which will check if the device is registered on Apple's server or not and based on the bits I have set I am updating the values in my own database. These values will help me to differentiate the new devices through which the users are getting logged in to my application and I will give them some digital reward poits to use my application on their new devices. Everything is working fine for me in the development environment as I get the right response when I am using the development API i.e. https://api.development.devicecheck.apple.com but it do not work as intended when I am using the production API i.e. https://api.devicecheck.apple.com/
Replies
0
Boosts
0
Views
917
Activity
Sep ’23
DCAppAttestService.generatekey() Key creation limit
Hi we are developing a appattestation devicecheck feature . we would like to is there a limit on creating a DCAppAttestService.generateKey() ? what happens to the cryptographic key in the Secure Enclave that already created when we call the DCAppAttestService.generateKey() again . Does it overrides the old keypair OR does it create a new key always
Replies
0
Boosts
0
Views
787
Activity
Sep ’23
403 Error During Specific Time Period with DeviceCheck API Usage
I have a question regarding the usage of the DeviceCheck API. We have been using https://api.development.devicecheck.apple.com/v1/validate_device_token for checking device tokens. However, we encountered frequent HTTP response status code 403 between 16:50 and 17:15 Japan time on June 29th. According to the official documentation at https://developer.apple.com/documentation/devicecheck/accessing_and_modifying_per-device_data, I understand that a 403 error indicates "The specified action isn't allowed". Yet, I would like to clarify under what specific circumstances this error would be returned. Please note that we do not encounter a 403 error outside the aforementioned timeframe, which leads us to believe there is no issue with our basic implementation.
Replies
1
Boosts
2
Views
1.1k
Activity
Jul ’23
Uniquely Identify iOS Device
How to uniquely identify the device to prevent fraudulent activity in any financial Apps? since UUID also gets changed on every installation, is there any option to track the device like how it is done with IMEI number ? Note: Our App is targeted for normal Appstore users.
Replies
2
Boosts
0
Views
1.7k
Activity
Jul ’23
Unable to renew developer program & showing 2 different expiry dates
HI, Since more than a Month i am trying to solve the issue. Issue is as under Developer program end dates on apple developer account / app and in mac book's setting> manage subscription are different. In developer application not showing renew button. When i am trying to renew from mac book manage subscription option (When wrong date is mentioned) Its giving an error that could not purchase subscription. I got 7 days extension from apple and my corrected date (in apple account on website) got properly extended. Please solve this issue on priority. I am attaching screenshots for your reference.
Replies
1
Boosts
0
Views
1.1k
Activity
Jul ’23
AppAttest assertion fails if user OS is updated
I have observed few users if their OS upgrades than the DeviceCheck generateAssertion API fails. Is it expected that we need to attest/register new key id iOS version is updated ?
Replies
0
Boosts
1
Views
916
Activity
Jul ’23
X and Y coordinates in App Attestation public key has mismatching length
There seem to be an issue with the DeviceCheck Framework where in rare cases the public key (ECC P-256) embedded inside the attestation object returned from DCAppAttestService.attestKey(_:clientDataHash:completionHandler:) has X and Y coordinates with mismatching length. Sometimes X or Y has 31 bytes instead of the expected 32 bytes. This can easily be reproduced by generating and attesting multiple keys using DCAppAttestService.generateKey(completionHandler:) and DCAppAttestService.attestKey(_:clientDataHash:completionHandler:). Every now and then the public key embedded inside the attestation object has X and Y coordinates with mismatching length (number of bytes). Added a Swift snippet at the bottom that shows example on how to generate and detect this. I would expect the ECC P-256 public key X and Y coordinates to always be 32 bytes long. As mentioned in the Web Authentication spec for example. I've attached an example attestation object (in base64 encoded CBOR) that has an embedded public key with mismatching X and Y coordinate length (Y is 31 bits, and not the expected 32 bits). The file was generated using the Swift snippet below. The snippet was built using Xcode 14.3 (14E222b) and ran on iPhone XR with iOS 15.7.1 (19H117). A feedback ticket has also been submitted regarding this issue: FB12235865 Swift snippet to generate and check attestation objects: import DeviceCheck import CryptoKit import SwiftCBOR // https://github.com/valpackett/SwiftCBOR ​ func generateAttestationObjects() { for i in 0..<1000 { DispatchQueue.main.asyncAfter(deadline: .now() + TimeInterval(i)) { DCAppAttestService.shared.generateKey { keyId, error in guard let keyId else { print("\(i): Failed to generate key: \(error)") return } ​ print("\(i): Generated keyId: \(keyId)") ​ DCAppAttestService.shared.attestKey( keyId, clientDataHash: Data(hex: "01020304")! ) { attestationObject, error in guard let attestationObject else { print("\(i): Failed to get attestation: \(error)") return } ​ do { let attestationObjectBytes = [UInt8](attestationObject) ​ if case let .map(decodedAttestationObject) = try CBOR.decode(attestationObjectBytes) { print("\(i): Successfully decoded Attestation object (CBOR)") ​ if case let .byteString(authData) = decodedAttestationObject["authData"] { ​ let attestedCredentialData = [UInt8](authData.dropFirst(37)) ​ let credentialIdLengthBuffer = [UInt8](attestedCredentialData[16..<18]) let credentialIdLength = Int(credentialIdLengthBuffer.reversed().withUnsafeBytes { $0.load(as: UInt16.self) }) let credentialId = [UInt8](attestedCredentialData[18..<(18 + credentialIdLength)]) let credentialPublicKeyBuffer = [UInt8](attestedCredentialData.dropFirst(18 + credentialIdLength)) ​ if let decodedCredentialPublicKey = try CBOR.decode(credentialPublicKeyBuffer) { ​ if case let .byteString(xCoordinateBuffer) = decodedCredentialPublicKey[-2], case let .byteString(yCoordinateBuffer) = decodedCredentialPublicKey[-3] { let xCoordinateLength = xCoordinateBuffer.count let yCoordinateLength = yCoordinateBuffer.count ​ if xCoordinateLength != yCoordinateLength { print("\(i): X/Y Coordinate length mismatch! X: \(xCoordinateLength), Y: \(yCoordinateLength)") } else if xCoordinateLength != 32 || yCoordinateLength != 32 { print("\(i): X/Y Coordinate length mismatch! X: \(xCoordinateLength), Y: \(yCoordinateLength)") } else { print("\(i): X/Y Coordinates OK") } } } } } } catch { print("\(i): Error decoding Attestation object (CBOR): \(error)") } } } } } } An attestation object with a embedded public key with mismatching X and Y coordinate length (base64 encoded CBOR): appattest-object-mismatching-x-y-base64.txt
Replies
1
Boosts
0
Views
1.5k
Activity
Jul ’23