Files
firebase-ios-sdk/FirebaseAppCheck/Sources/DebugProvider/API/FIRAppCheckDebugProviderAPIService.m
T
Maksym MalyhinandNick Cooke 302f91e1ed App Check: App Attest provider (#8133)
* 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 69eb00dfe2.

* 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>
2021-06-01 10:47:57 -04:00

118 lines
4.1 KiB
Objective-C

/*
* Copyright 2020 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 "FirebaseAppCheck/Sources/DebugProvider/API/FIRAppCheckDebugProviderAPIService.h"
#if __has_include(<FBLPromises/FBLPromises.h>)
#import <FBLPromises/FBLPromises.h>
#else
#import "FBLPromises.h"
#endif
#import <GoogleUtilities/GULURLSessionDataResponse.h>
#import <GoogleUtilities/NSURLSession+GULPromises.h>
#import "FirebaseAppCheck/Sources/Core/APIService/FIRAppCheckAPIService.h"
#import "FirebaseAppCheck/Sources/Core/APIService/FIRAppCheckToken+APIResponse.h"
#import "FirebaseAppCheck/Sources/Core/Errors/FIRAppCheckErrorUtil.h"
#import "FirebaseAppCheck/Sources/Core/FIRAppCheckLogger.h"
#import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h"
NS_ASSUME_NONNULL_BEGIN
static NSString *const kContentTypeKey = @"Content-Type";
static NSString *const kJSONContentType = @"application/json";
static NSString *const kDebugTokenField = @"debug_token";
@interface FIRAppCheckDebugProviderAPIService ()
@property(nonatomic, readonly) id<FIRAppCheckAPIServiceProtocol> APIService;
@property(nonatomic, readonly) NSString *projectID;
@property(nonatomic, readonly) NSString *appID;
@end
@implementation FIRAppCheckDebugProviderAPIService
- (instancetype)initWithAPIService:(id<FIRAppCheckAPIServiceProtocol>)APIService
projectID:(NSString *)projectID
appID:(NSString *)appID {
self = [super init];
if (self) {
_APIService = APIService;
_projectID = projectID;
_appID = appID;
}
return self;
}
#pragma mark - Public API
- (FBLPromise<FIRAppCheckToken *> *)appCheckTokenWithDebugToken:(NSString *)debugToken {
NSString *URLString =
[NSString stringWithFormat:@"%@/projects/%@/apps/%@:exchangeDebugToken",
self.APIService.baseURL, self.projectID, self.appID];
NSURL *URL = [NSURL URLWithString:URLString];
return [self HTTPBodyWithDebugToken:debugToken]
.then(^FBLPromise<GULURLSessionDataResponse *> *(NSData *HTTPBody) {
return [self.APIService sendRequestWithURL:URL
HTTPMethod:@"POST"
body:HTTPBody
additionalHeaders:@{kContentTypeKey : kJSONContentType}];
})
.then(^id _Nullable(GULURLSessionDataResponse *_Nullable response) {
return [self.APIService appCheckTokenWithAPIResponse:response];
});
}
#pragma mark - Helpers
- (FBLPromise<NSData *> *)HTTPBodyWithDebugToken:(NSString *)debugToken {
if (debugToken.length <= 0) {
FBLPromise *rejectedPromise = [FBLPromise pendingPromise];
[rejectedPromise
reject:[FIRAppCheckErrorUtil errorWithFailureReason:@"Debug token must not be empty."]];
return rejectedPromise;
}
return [FBLPromise onQueue:[self backgroundQueue]
do:^id _Nullable {
NSError *encodingError;
NSData *payloadJSON = [NSJSONSerialization
dataWithJSONObject:@{kDebugTokenField : debugToken}
options:0
error:&encodingError];
if (payloadJSON != nil) {
return payloadJSON;
} else {
return [FIRAppCheckErrorUtil JSONSerializationError:encodingError];
}
}];
}
- (dispatch_queue_t)backgroundQueue {
return dispatch_get_global_queue(QOS_CLASS_UTILITY, 0);
}
@end
NS_ASSUME_NONNULL_END