Skip to content

Commit

Permalink
App Check: App Attest provider (#8133)
Browse files Browse the repository at this point in the history
* App Attest provider: attestation sequence (#7971)

* App Attest provider: attestation sequence (#761)

* App Attest draft WIP

* FIRAppAttestProvider initializers

* ./scripts/style.sh

* FIRAppAttestProvider implementation draft

* Basic FIRAppAttestProviderTests and fixes

* style

* testGetTokenWhenAppAttestIsNotSupported

* More FIRAppAttestProviderTests

* Cleanup

* Remove unused file

* Availability annotations on DCAppAttestService category.

* Guard FIRAppAttestProvider with #if TARGET_OS_IOS

* Formatting

* Fix SPM

* app_check.yaml: Add diagnostics SPM builds

* fix yaml

* Fix Firebase-Package scheme bad merge

* Fix typo

* FIRAppAttestProvider: hide default init

* FIRAppAttestKeyIDStorage: methods placeholders

* Comments

* Fix updated block definition

* Implement app attest key ID storage (#8014)

* Implement FIRAppAttestKeyIDStorage

* Add FIRAppAttestKeyIDStorageTests

* Review [Draft]

* Style

* Docs updates

* Docs updates 2

* Review [Draft] 2

* Improve tests

* Improve test readability

* Improve test readability 2

* App Check App Attest workflow updates: initial handshake (#8032)

* Handshake adjustments (WIP)

* Introduce FIRAppAttestProviderState

* WIP: calculate attestation state

* WIP: calculate attestation state 2

* formatting

* Comments and moving code around

* Fix init in tests

* Fix state calculation flow

* Cleanup state calculation and fix tests.

* Cleanup and fixes.

* Comments

* formatting

* Fix import

* Typo fixes and additional comments

* FIRAppAttestInitialHandshakeResponse API

* Cleanup state calculation using FBLPromiseAwait

* Cleanup

* style

* FIRAppAttestArtifactStorage implementation and tests (#8041)

* Update comments

* FIRAppAttestArtifactStorage implementation and tests

* Fix init

* API docs

* Clean up storage in tests

* Comments

* Disable Keychain dependent tests for SPM

* Implement App Attest `getRandomChallenge` (#8033)

* Initial implementation

* Parse response body for challenge and stub test cases

* Review [Draft]

* Avoid encoding challenge again

* Add tests

* Revert "Avoid encoding challenge again" and add TODO

This reverts commit 69eb00d.

* Document tests; Add test

* Tests: Add URL validation check

* Review

* Define Exchange AppAttest Assertion for FAC token API (#8058)

* App Check App Attest: attestation request (#8059)

* App Attest provider API integration WIP

* update tests

* Draft attestation response parsing

* Attestation request draft

* style

* AppAttest Attestation API tests draft

* Error cases tests

* style

* Cleanup and API docs

* Merge fix

* Fix OCMock imports

* Fix nullability modifier

* Formatting

* comments

* App Check App Attest initial handshake adjustments (#8067)

* calculatre sha256 of random challenge for attestation

* Test app adjustments

* cleanup

* use trailing closures in the test app

* Implement API for ExchangeAppAttestAssertionRequest endpoint (#8065)

* Implement assertion exchange

* Tweak existing tests

* Add tests

* Rename JSON to better match gRPC  message

* Add HTTPBody helper

* Review

* Review 2

* Review 3

* App Check App Attest assertion flow (#8083)

* App Attest assertion workflow draft

* send request

* assertion flow tests

* style

* App Check: store App Attest artifact per key ID (#8097)

* Update artifact storage API and tests

* Artifact storage implementation update

* Save artifact for a key ID

* Style

* typos

* App Check: prevent concurrent token requests (#8117)

* App Attest multiple get token method invocation tests

* Ensure a single App Attest handshake sequence at the time

* FIRAppCheckTests: get token request merging tests

* FIRAppCheck: Ensure a single get token operation at the time

* formatting

* Test new request after merged requests

* Release finished operation promise

* Style

* Typos

* typo

* Request merging tests for error cases

* formatting

* Changelog

* App Check App Attest: handle attestation rejection (#8170)

* Remove/update outdated TODOs

* [WIP] Attestation rejection handling draft

* style

* retry tests draft

* reset key ID before retry

* Reset attestation

* test error and fixes

* style

* More details in the name

* Some debug logging

* style

* Use specific codes for log messages

* style

* Add FIRAppAttestProvider.h the umbrella header

Co-authored-by: Nick Cooke <36927374+ncooke3@users.noreply.github.com>
  • Loading branch information
maksymmalyhin and ncooke3 authored Jun 1, 2021
1 parent e43020e commit 302f91e
Show file tree
Hide file tree
Showing 55 changed files with 4,208 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()

guard let firebaseApp = FirebaseApp.app() else {
return true
}

FIRDeviceCheckProvider(app: firebaseApp)?.getToken(completion: { token, error in
if let token = token {
print("DeviceCheck token: \(token.token), expiration date: \(token.expirationDate)")
}

if let error = error {
print("DeviceCheck error: \((error as NSError).userInfo)")
}
})

if let debugProvider = FIRAppCheckDebugProvider(app: firebaseApp) {
print("Debug token: \(debugProvider.currentDebugToken())")
requestDeviceCheckToken()

debugProvider.getToken(completion: { token, error in
if let token = token {
print("Debug FAC token: \(token.token), expiration date: \(token.expirationDate)")
}
requestDebugToken()

if let error = error {
print("Debug error: \(error)")
}
})
if #available(iOS 14.0, *) {
requestAppAttestToken()
}

return true
Expand All @@ -76,4 +56,64 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}

// MARK: App Check providers

func requestDeviceCheckToken() {
guard let firebaseApp = FirebaseApp.app() else {
return
}

DeviceCheckProvider(app: firebaseApp)?.getToken { token, error in
if let token = token {
print("DeviceCheck token: \(token.token), expiration date: \(token.expirationDate)")
}

if let error = error {
print("DeviceCheck error: \((error as NSError).userInfo)")
}
}
}

func requestDebugToken() {
guard let firebaseApp = FirebaseApp.app() else {
return
}

if let debugProvider = AppCheckDebugProvider(app: firebaseApp) {
print("Debug token: \(debugProvider.currentDebugToken())")

debugProvider.getToken { token, error in
if let token = token {
print("Debug FAC token: \(token.token), expiration date: \(token.expirationDate)")
}

if let error = error {
print("Debug error: \(error)")
}
}
}
}

@available(iOS 14.0, *)
func requestAppAttestToken() {
guard let firebaseApp = FirebaseApp.app() else {
return
}

guard let appAttestProvider = AppAttestProvider(app: firebaseApp) else {
print("Failed to instantiate AppAttestProvider")
return
}

appAttestProvider.getToken { token, error in
if let token = token {
print("App Attest FAC token: \(token.token), expiration date: \(token.expirationDate)")
}

if let error = error {
print("App Attest error: \(error)")
}
}
}
}
2 changes: 0 additions & 2 deletions FirebaseAppCheck/Apps/FIRAppCheckTestApp/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,5 @@ target 'FIRAppCheckTestApp' do
pod 'FirebaseAppCheck', :path => '../../../'

pod 'FirebaseCore', :path => '../../../'
pod 'GoogleUtilities', :path => '../../../'
pod 'FirebaseCoreDiagnostics', :path => '../../../'
pod 'GoogleDataTransport', :path => '../../../'
end
2 changes: 2 additions & 0 deletions FirebaseAppCheck/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# 8.1.0 -- M97
- [added] Apple's App Attest attestation provider support. (#8133)
# v8.0.0 -- M95
- [added] Firebase abuse reduction support SDK. (#7928, #7937, #7948)
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2021 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#import <Foundation/Foundation.h>

@class FBLPromise<Result>;
@class FIRAppAttestAttestationResponse;
@class FIRAppCheckToken;
@protocol FIRAppCheckAPIServiceProtocol;

NS_ASSUME_NONNULL_BEGIN

/// Methods to send API requests required for App Attest based attestation sequence.
@protocol FIRAppAttestAPIServiceProtocol <NSObject>

/// Request a random challenge from server.
- (FBLPromise<NSData *> *)getRandomChallenge;

/// Sends attestation data to Firebase backend for validation.
/// @param attestation The App Attest key attestation data obtained from the method
/// `-[DCAppAttestService attestKey:clientDataHash:completionHandler:]` using the random challenge
/// received from Firebase backend.
/// @param keyID The key ID used to generate the attestation.
/// @param challenge The challenge used to generate the attestation.
/// @return A promise that is fulfilled with a response object with an encrypted attestation
/// artifact and an Firebase App Check token or rejected with an error.
- (FBLPromise<FIRAppAttestAttestationResponse *> *)attestKeyWithAttestation:(NSData *)attestation
keyID:(NSString *)keyID
challenge:(NSData *)challenge;

/// Exchanges attestation data (artifact & assertion) and a challenge for a FAC token.
- (FBLPromise<FIRAppCheckToken *> *)getAppCheckTokenWithArtifact:(NSData *)artifact
challenge:(NSData *)challenge
assertion:(NSData *)assertion;

@end

/// A default implementation of `FIRAppAttestAPIServiceProtocol`.
@interface FIRAppAttestAPIService : NSObject <FIRAppAttestAPIServiceProtocol>

/// Default initializer.
/// @param APIService An instance implementing `FIRAppCheckAPIServiceProtocol` to be used to send
/// network requests to Firebase App Check backend.
/// @param projectID A Firebase project ID for the requests (`FIRApp.options.projectID`).
/// @param appID A Firebase app ID for the requests (`FIRApp.options.googleAppID`).
- (instancetype)initWithAPIService:(id<FIRAppCheckAPIServiceProtocol>)APIService
projectID:(NSString *)projectID
appID:(NSString *)appID;

@end

NS_ASSUME_NONNULL_END
Loading

0 comments on commit 302f91e

Please sign in to comment.
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy