Merge pull request #655 from MultiColourPixel/main

Support FIDO2 authentication with devices that don’t have a PIN code
This commit is contained in:
Matt Kiazyk 2025-06-09 22:10:12 -05:00 committed by GitHub
commit b302365454
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 56 additions and 14 deletions

View file

@ -1493,7 +1493,7 @@
repositoryURL = "https://github.com/kinoroy/LibFido2Swift.git";
requirement = {
kind = upToNextMinorVersion;
minimumVersion = 0.1.0;
minimumVersion = 0.1.4;
};
};
CA9FF86B25951C6E00E47BAF /* XCRemoteSwiftPackageReference "data" */ = {

View file

@ -78,8 +78,8 @@
"repositoryURL": "https://github.com/kinoroy/LibFido2Swift.git",
"state": {
"branch": null,
"revision": "b77e5c6451bea69d15615d6578936b11777d9a6c",
"version": "0.1.2"
"revision": "94d496d6f850dcbb3e8c4a27cd7eeabfad9f14e3",
"version": "0.1.4"
}
},
{

View file

@ -305,11 +305,17 @@ class AppState: ObservableObject {
}
func handleTwoFactorOption(_ option: TwoFactorOption, authOptions: AuthOptionsResponse, serviceKey: String, sessionID: String, scnt: String) {
self.presentedSheet = .twoFactor(.init(
option: option,
authOptions: authOptions,
sessionData: AppleSessionData(serviceKey: serviceKey, sessionID: sessionID, scnt: scnt)
))
let sessionData = AppleSessionData(serviceKey: serviceKey, sessionID: sessionID, scnt: scnt)
if option == .securityKey, fido2DeviceIsPresent() && !fido2DeviceNeedsPin() {
createAndSubmitSecurityKeyAssertationWithPinCode(nil, sessionData: sessionData, authOptions: authOptions)
} else {
self.presentedSheet = .twoFactor(.init(
option: option,
authOptions: authOptions,
sessionData: sessionData
))
}
}
func requestSMS(to trustedPhoneNumber: AuthOptionsResponse.TrustedPhoneNumber, authOptions: AuthOptionsResponse, sessionData: AppleSessionData) {
@ -355,9 +361,9 @@ class AppState: ObservableObject {
.store(in: &cancellables)
}
var fido2: FIDO2?
private lazy var fido2 = FIDO2()
func createAndSubmitSecurityKeyAssertationWithPinCode(_ pinCode: String, sessionData: AppleSessionData, authOptions: AuthOptionsResponse) {
func createAndSubmitSecurityKeyAssertationWithPinCode(_ pinCode: String?, sessionData: AppleSessionData, authOptions: AuthOptionsResponse) {
self.presentedSheet = .securityKeyTouchToConfirm
guard let fsaChallenge = authOptions.fsaChallenge else {
@ -379,8 +385,6 @@ class AppState: ObservableObject {
Task {
do {
let fido2 = FIDO2()
self.fido2 = fido2
let response = try fido2.respondToChallenge(args: ChallengeArgs(rpId: rpId, validCredentials: validCreds, devPin: pinCode, challenge: challenge, origin: origin))
Task { @MainActor in
@ -407,13 +411,31 @@ class AppState: ObservableObject {
// we don't have to show an error
// because the sheet will already be dismissed
} catch {
authError = error
Task { @MainActor in
authError = error
}
}
}
}
func fido2DeviceIsPresent() -> Bool {
fido2.hasDeviceAttached()
}
func fido2DeviceNeedsPin() -> Bool {
do {
return try fido2.deviceHasPin()
} catch {
Task { @MainActor in
authError = error
}
return true
}
}
func cancelSecurityKeyAssertationRequest() {
self.fido2?.cancel()
self.fido2.cancel()
}
private func handleAuthenticationFlowCompletion(_ completion: Subscribers.Completion<Error>) {

View file

@ -32,6 +32,9 @@ struct SignInSecurityKeyPinView: View {
Button("Cancel", action: { isPresented = false })
.keyboardShortcut(.cancelAction)
Spacer()
Button("PIN not set", action: submitWithoutPinCode)
ProgressButton(isInProgress: appState.isProcessingAuthRequest,
action: submitPinCode) {
Text("Continue")
@ -50,6 +53,10 @@ struct SignInSecurityKeyPinView: View {
func submitPinCode() {
appState.createAndSubmitSecurityKeyAssertationWithPinCode(pin, sessionData: sessionData, authOptions: authOptions)
}
func submitWithoutPinCode() {
appState.createAndSubmitSecurityKeyAssertationWithPinCode(nil, sessionData: sessionData, authOptions: authOptions)
}
}
#Preview {

View file

@ -237,6 +237,16 @@
}
}
},
"%@ (%@)" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "%1$@ (%2$@)"
}
}
}
},
"%@ %@ %@" : {
"localizations" : {
"ar" : {
@ -17907,6 +17917,9 @@
}
}
}
},
"PIN not set" : {
},
"Platforms" : {
"localizations" : {