Hi everyone!
Will iOS platform authenticator have support for PRF passkeys extension?
https://github.com/w3c/webauthn/wiki/Explainer:-PRF-extension
As far as I know current implementation doesn't as we don't have access to private part of generated keys to perform some crypto operations
Post
Replies
Boosts
Views
Activity
Hi!
I'm generating assertions using DCAppAttestService.shared.generateAssertion. It's running for almost one and a half years and has the following issue.
Approx 6% of our users trying to generate assertions have issues and according to our analytics about half of them have invalid_input error during assertion process).
I've managed to reproduce this issue on test device and noticed some weird scenario:
(first app run)
The AppAttest key generated and attested at Apple side successfully. Key Identifier persisted.
Attestation object verification on backend and public key extraction is ok
Unlimited number of assertion can be generated this time
(second app run)
Key Identifier persisted on previous app run is read and passed to DCAppAttestService.shared.generateAssertion
Invalid input error received.
Regeneration of key and attestation works fine.
So looks like there is a kinda state in assertion process - it works well after key generation on first run, but fails with invalid_input on second run.
As invalid_input error cannot say much about the issue, I've swizzled some methods of DCAppAttestService (https://developer.limneos.net/index.php?ios=15.2.1&framework=DeviceCheck.framework&header=DCAppAttestService.h) - _rewrapAsDCError, _loadAppUUID, _saveAppUUID. Swizzling implementation attached (swizzling.swift). As the swizzling logs show - when invalid_input raises, a strange error is printed (Error Domain=com.apple.appattest.error Code=-2 "Invalid appUUID" UserInfo={NSLocalizedDescription=Invalid appUUID}).
What can be the issue? In another app this behaviour isn't reproducible but they share similar dependency with App Attest - wrapping logic
I've filed bug report no FB12205670. Thanks.
Logs:
ok case:
key generation:
swizzleLoadAppID
swizzleSaveAppID EDA165DC-0781-4891-A16D-0979FC4FEB84
swizzleRewrap
key attestation: (key_id: "XzTjW3V7944\/ljQ2C8LTpqug0t0gslVyhdWGUCnJXfY=")
swizzleLoadAppID EDA165DC-0781-4891-A16D-0979FC4FEB84
swizzleRewrap
key assertion: (input key_id = "XzTjW3V7944\/ljQ2C8LTpqug0t0gslVyhdWGUCnJXfY=" clientDataHash = "zUwl\/jiunewwd1ofhEOmgNGWM+oD7LmUGe6Te5Iv9pc=")
swizzleLoadAppID EDA165DC-0781-4891-A16D-0979FC4FEB84
swizzleRewrap
issue case (DCError.invalid_input):
key assertion: (input key_id = "XzTjW3V7944\/ljQ2C8LTpqug0t0gslVyhdWGUCnJXfY=" clientDataHash = "F8o5i+8PsZ5cTuyjlZoMe+kcbTG0\/R8Vw6tmjPlzlLc=")
swizzleLoadAppID
swizzleRewrap Error Domain=com.apple.appattest.error Code=-2 "Invalid appUUID" UserInfo={NSLocalizedDescription=Invalid appUUID}
Swizzling logic:
@objc func swizzleRewrap(obj: NSObject) -> NSObject {
let returnValue = swizzleRewrap(obj: obj)
print("swizzleRewrap \(obj)")
return returnValue
}
@objc func swizzleLoadAppID() -> NSObject {
let returnValue = swizzleLoadAppID()
print("swizzleLoadAppID \(returnValue.debugDescription)")
return returnValue
}
@objc func swizzleSaveAppID(app_id: NSObject) {
swizzleSaveAppID(app_id: app_id)
print("swizzleSaveAppID \(app_id)")
}
static func makeSwizzling() {
let sel = NSSelectorFromString("_rewrapAsDCError:")
DCAppAttestService.swizzleInstanceMethod(sel, #selector(DCAppAttestService.swizzleRewrap(obj:)))
let sel1 = NSSelectorFromString("_loadAppUUID")
DCAppAttestService.swizzleInstanceMethod(sel1, #selector(DCAppAttestService.swizzleLoadAppID))
let sel2 = NSSelectorFromString("_saveAppUUID:")
DCAppAttestService.swizzleInstanceMethod(sel2, #selector(DCAppAttestService.swizzleSaveAppID(app_id:)))
}
}
public extension NSObjectProtocol {
static func swizzleInstanceMethod(_ origin: Selector, _ replace: Selector) {
let origin = class_getInstanceMethod(self, origin)
let replace = class_getInstanceMethod(self, replace)
if let origin = origin, let replace = replace {
method_exchangeImplementations(origin, replace)
}
}
}
Hi!
Sometimes when calling
DCAppAttestService.shared.generateAssertion(key.id, clientDataHash: hash)
I'm getting DCError.Code.invalidInput. I am formatting clientDataHash usingSHA256.hash - so it is always 32 bytes long.
As I found out - this error depends on hash that I pass to generateAssertion method. But I could not find any system - which hashes are good and which are not.
Keys are always correct, otherwise invalidKey error would be risen.
What can cause the issue? I'm testing on iPhone 11, iOS 15.2.1
Hi!
We are using Device Check tokens to prove that HTTP request comes from iOS device.
We found out that both envs - prod and sandbox doesn't limit token lifetime
v1/validate_device_token always return true and can be reused for a long period of time per one DCDevice token.
v1/update_two_bits also can be reused unlimited number of times per one token (didn't measure the exact number)
Is it true - that lifetime of token generated via DCDevice.generateToken isn't short (minutes) and we should build our own infrastructure to prevent replay attacks?
Hi!
In the past few weeks we detected over 90 affected users with the following crush log:
std::__1::__shared_weak_count::lock()
CFNetwork
HTTPConnection::_onqueue_doNotAllowMoreRequests()
CFNetwork
HTTPConnectionCacheEntry::ConnectionArray::stopAndRemove(long)
CFNetwork
HTTPConnectionCacheEntry::_removeConnection(std::__1::shared_ptr<HTTPConnection>)
CFNetwork
HTTPConnectionCacheEntry::purgeIdleConnections(double, double)
CFNetwork
HTTPConnectionCache::performIdleSweep()
Unfortunately, our investigation haven't given any results. Did anyone experienced such crushes?
Top iOS versions for the crush:
12.5.4 30%
14.4.2 14%
12.5.3 6%