Skip to content

Commit

Permalink
Improved authenticateUsingBiometry() on iOS (#496)
Browse files Browse the repository at this point in the history
* Android: Upgrade NDK to latest LTS
* Apple: Fix #495: Use LAContext in authenticateUsingBiometry()
* Apple: Fix #495: Added PowerAuthErrorCode_BiometryFallback error code.
  • Loading branch information
hvge committed Nov 3, 2022
1 parent a0201bd commit 778efd1
Show file tree
Hide file tree
Showing 10 changed files with 269 additions and 88 deletions.
19 changes: 17 additions & 2 deletions docs/Migration-from-1.6-to-1.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ PowerAuth Mobile SDK in version `1.7.0` is a maintenance release that brings mul

- `IOException` is no longer reported from SDK's internal networking. Now all such exceptions are wrapped into `PowerAuthErrorException` with `NETWORK_ERROR` code set.

- Please read also changes introduced in [1.7.2](#changes-in-172) and [1.7.3](#changes-in-173) versions.
- Please read also changes introduced in [1.7.2](#changes-in-172), [1.7.3](#changes-in-173) and [1.7.5](#changes-in-175) versions.

## iOS & tvOS

Expand Down Expand Up @@ -198,4 +198,19 @@ If you still have to compile our SDK for older operating systems, then you need
./scripts/ios-build-extensions.sh extensions watchos --legacy-archs --use-bitcode --out-dir ./Build
```

If you use cocoapds for PowerAuth mobile SDK integration, then please let us know and we'll prepare a special release branch for you.
If you use cocoapds for PowerAuth mobile SDK integration, then please let us know and we'll prepare a special release branch for you.

## Changes in 1.7.5+

### iOS

The behavior of `PowerAuthSDK.authenticateUsingBiometry()` has been slightly changed and improved:

- Function now properly treat biometry lockout and increase failed attempts counter on the server, See [Biometry lockout](PowerAuth-SDK-for-iOS.md#biometry-lockout) chapter.
- Function now returns new `PowerAuthErrorCode_BiometryFallback` error code in case that user tap on the fallback button.
- As a benefit, function now properly handles situations when the user press home or power button during the biometric authentication.
- You can also cancel the pending authentication with using `LAContext.invalidate()` method.

### tvOS

The `PowerAuthSDK.authenticateUsingBiometry()` function is no longer available on tvOS platform.
32 changes: 31 additions & 1 deletion docs/PowerAuth-SDK-for-iOS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1116,6 +1116,32 @@ context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason
}
```

Be aware that the example above doesn't handle all quirks related to the PowerAuth protocol, so you should prefer to use `authenticateUsingBiometry()` function instead:

```swift
let context = LAContext()
context.localizedReason = "Please authenticate with biometry"
PowerAuthSDK.sharedInstance().authenticateUsingBiometry(withContext: context) { authentication, error in
guard let authentication = authentication else {
if let nsError = error as? NSError {
if nsError.domain == PowerAuthErrorDomain {
if nsError.powerAuthErrorCode == .biometryCancel {
// cancel, app cancel, system cancel...
} else if nsError.powerAuthErrorCode == .biometryFallback {
// fallback button pressed
}
// If you're interested in exact failure reason, then extract
// the underlying LAError.
if let laError = nsError.userInfo[NSUnderlyingErrorKey] as? LAError {
// Investigate error codes...
}
}
}
return
}
// Now use authentication in other APIs
}
```

## Activation Removal

Expand Down Expand Up @@ -1785,7 +1811,10 @@ if error == nil {

case .biometryCancel:
print("Error code for TouchID/FaceID action cancel error")


case .biometryFallback:
print("Error code for TouchID/FaceID fallback action")

case .biometryFailed:
print("Error code for TouchID/FaceID action failure")

Expand Down Expand Up @@ -1825,6 +1854,7 @@ Note that you typically don't need to handle all error codes reported in the `Er
Here's the list of important error codes, which the application should properly handle:

- `PowerAuthErrorCode.biometryCancel` is reported when the user cancels the biometric authentication dialog
- `PowerAuthErrorCode.biometryFallback` is reported when the user cancels the biometric authentication dialog with a fallback button
- `PowerAuthErrorCode.protocolUpgrade` is reported when SDK failed to upgrade itself to a newer protocol version. The code may be reported from `PowerAuthSDK.fetchActivationStatus()`. This is an unrecoverable error resulting in the broken activation on the device, so the best situation is to inform the user about the situation and remove the activation locally.
- `PowerAuthErrorCode.pendingProtocolUpgrade` is reported when the requested SDK operation cannot be completed due to a pending PowerAuth protocol upgrade. You can retry the operation later. The code is typically reported in the situations when SDK is performing protocol upgrade on the background (as a part of activation status fetch), and the application want's to calculate PowerAuth signature in parallel operation. Such kind of concurrency is forbidden since SDK version `1.0.0`
- `PowerAuthErrorCode.externalPendingOperation` is reported when the requested operation collide with the same operation type already started in the external application.
Expand Down
2 changes: 1 addition & 1 deletion proj-android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ ext {
minSdkVersion = 19
buildToolsVersion = "30.0.3"
// NDK, check https://developer.android.com/ndk/downloads for updates
ndkVersion = "25.0.8775105" // r25
ndkVersion = "25.1.8937393" // r25b
}

allprojects {
Expand Down
4 changes: 4 additions & 0 deletions proj-xcode/PowerAuth2/PowerAuthErrorConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ typedef NS_ENUM(NSInteger, PowerAuthErrorCode) {
object available via `NSError.powerAuthExternalPendingOperation` property.
*/
PowerAuthErrorCode_ExternalPendingOperation = 18,
/**
User canceled the biometric authentication dialog with a fallback button.
*/
PowerAuthErrorCode_BiometryFallback = 19,
};

@interface NSError (PowerAuthErrorCode)
Expand Down
3 changes: 2 additions & 1 deletion proj-xcode/PowerAuth2/PowerAuthErrorConstants.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
_CODE_DESC(PowerAuthErrorCode_ActivationPending, @"Pending activation")
_CODE_DESC(PowerAuthErrorCode_BiometryNotAvailable, @"Biometry is not supported or is unavailable")
_CODE_DESC(PowerAuthErrorCode_BiometryCancel, @"User did cancel biometry authentication dialog")
_CODE_DESC(PowerAuthErrorCode_BiometryFallback, @"Used did press fallback at biometry authentication dialog")
_CODE_DESC(PowerAuthErrorCode_BiometryFailed, @"Biometry authentication failed")
_CODE_DESC(PowerAuthErrorCode_OperationCancelled, @"Operation was cancelled by SDK")
_CODE_DESC(PowerAuthErrorCode_Encryption, @"General encryption failure")
Expand All @@ -66,7 +67,7 @@

NSError * PA2MakeErrorInfo(NSInteger errorCode, NSString * message, NSDictionary * info)
{
NSMutableDictionary * mutableInfo = [info mutableCopy];
NSMutableDictionary * mutableInfo = info ? [info mutableCopy] : [NSMutableDictionary dictionary];
mutableInfo[NSLocalizedDescriptionKey] = PA2MakeDefaultErrorDescription(errorCode, message);
return [NSError errorWithDomain:PowerAuthErrorDomain code:errorCode userInfo:mutableInfo];
}
Expand Down
6 changes: 4 additions & 2 deletions proj-xcode/PowerAuth2/PowerAuthSDK.h
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,8 @@
*/
- (void) authenticateUsingBiometryWithPrompt:(nonnull NSString *)prompt
callback:(nonnull void(^)(PowerAuthAuthentication * _Nullable authentication, NSError * _Nullable error))callback
NS_SWIFT_NAME(authenticateUsingBiometry(withPrompt:callback:));
NS_SWIFT_NAME(authenticateUsingBiometry(withPrompt:callback:))
API_UNAVAILABLE(tvos);

/** Prepare PowerAuthAuthentication object for future PowerAuth signature calculation with a biometry and possession factors involved.
Expand All @@ -539,7 +540,8 @@
*/
- (void) unlockBiometryKeysWithPrompt:(nonnull NSString*)prompt
withBlock:(nonnull void(^)(NSDictionary<NSString*, NSData*> * _Nullable keys, BOOL userCanceled))block
NS_SWIFT_NAME(unlockBiometryKeys(withPrompt:callback:));
NS_SWIFT_NAME(unlockBiometryKeys(withPrompt:callback:))
API_UNAVAILABLE(tvos);

/** Unlock all keys stored in a biometry related keychain and keeps them cached for the scope of the block.
Expand Down
Loading

0 comments on commit 778efd1

Please sign in to comment.