Respond to CR.

This commit is contained in:
Matthew Chen 2018-07-20 10:32:15 -04:00
parent 97eb405a9e
commit 75c3b385b2
7 changed files with 56 additions and 24 deletions

View File

@ -200,13 +200,19 @@ NS_ASSUME_NONNULL_BEGIN
+ (nullable NSArray<NSData *> *)anchorCertificates
{
// We need to use an Intel certificate as the anchor for IAS verification.
NSData *_Nullable anchorCertificate = [self certificateDataForService:@"ias-root"];
if (!anchorCertificate) {
OWSProdLogAndFail(@"%@ could not load anchor certificate.", self.logTag);
return nil;
}
return @[ anchorCertificate ];
static NSArray<NSData *> *anchorCertificates = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// We need to use an Intel certificate as the anchor for IAS verification.
NSData *_Nullable anchorCertificate = [self certificateDataForService:@"ias-root"];
if (!anchorCertificate) {
OWSProdLogAndFail(@"%@ could not load anchor certificate.", self.logTag);
OWSRaiseException(@"OWSSignalService_CouldNotLoadCertificate", @"%s", __PRETTY_FUNCTION__);
} else {
anchorCertificates = @[ anchorCertificate ];
}
});
return anchorCertificates;
}
+ (nullable NSData *)certificateDataForService:(NSString *)service

View File

@ -14,6 +14,21 @@
NS_ASSUME_NONNULL_BEGIN
@interface RemoteAttestationAuth : NSObject
@property (nonatomic) NSString *username;
@property (nonatomic) NSString *authToken;
@end
#pragma mark -
@implementation RemoteAttestationAuth
@end
#pragma mark -
@interface RemoteAttestationKeys : NSObject
@property (nonatomic) ECKeyPair *keyPair;
@ -195,12 +210,12 @@ NS_ASSUME_NONNULL_BEGIN
DDLogVerbose(@"%@ remote attestation auth success: %@", self.logTag, responseDict);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *_Nullable authToken = [self parseAuthToken:responseDict];
if (!authToken) {
DDLogError(@"%@ remote attestation auth missing token: %@", self.logTag, responseDict);
RemoteAttestationAuth *_Nullable auth = [self parseAuthToken:responseDict];
if (!auth) {
DDLogError(@"%@ remote attestation auth could not be parsed: %@", self.logTag, responseDict);
return;
}
[self performRemoteAttestationWithToken:authToken];
[self performRemoteAttestationWithAuth:auth];
});
}
failure:^(NSURLSessionDataTask *task, NSError *error) {
@ -209,7 +224,7 @@ NS_ASSUME_NONNULL_BEGIN
}];
}
- (nullable NSString *)parseAuthToken:(id)response
- (nullable RemoteAttestationAuth *)parseAuthToken:(id)response
{
if (![response isKindOfClass:[NSDictionary class]]) {
return nil;
@ -218,35 +233,41 @@ NS_ASSUME_NONNULL_BEGIN
NSDictionary *responseDict = response;
NSString *_Nullable token = responseDict[@"token"];
if (![token isKindOfClass:[NSString class]]) {
OWSProdLogAndFail(@"%@ missing or invalid token.", self.logTag);
return nil;
}
if (token.length < 1) {
OWSProdLogAndFail(@"%@ empty token.", self.logTag);
return nil;
}
NSString *_Nullable username = responseDict[@"username"];
if (![username isKindOfClass:[NSString class]]) {
OWSProdLogAndFail(@"%@ missing or invalid username.", self.logTag);
return nil;
}
if (username.length < 1) {
OWSProdLogAndFail(@"%@ empty username.", self.logTag);
return nil;
}
// To work around an idiosyncracy of the service implementation,
// we need to repeat the username twice in the token.
NSString *modifiedToken = [username stringByAppendingFormat:@":%@", token];
DDLogVerbose(@"%@ attestation modified token: %@", self.logTag, modifiedToken);
return modifiedToken;
RemoteAttestationAuth *result = [RemoteAttestationAuth new];
result.username = username;
result.authToken = token;
return result;
}
- (void)performRemoteAttestationWithToken:(NSString *)authToken
- (void)performRemoteAttestationWithAuth:(RemoteAttestationAuth *)auth
{
ECKeyPair *keyPair = [Curve25519 generateKeyPair];
// TODO:
NSString *enclaveId = @"cd6cfc342937b23b1bdd3bbf9721aa5615ac9ff50a75c5527d441cd3276826c9";
TSRequest *request = [OWSRequestFactory remoteAttestationRequest:keyPair enclaveId:enclaveId authToken:authToken];
TSRequest *request = [OWSRequestFactory remoteAttestationRequest:keyPair
enclaveId:enclaveId
username:auth.username
authToken:auth.authToken];
[[TSNetworkManager sharedManager] makeRequest:request
success:^(NSURLSessionDataTask *task, id responseJson) {
DDLogVerbose(@"%@ remote attestation success: %@", self.logTag, responseJson);

View File

@ -9,12 +9,14 @@ NS_ASSUME_NONNULL_BEGIN
@interface CDSAttestationRequest : TSRequest
@property (nonatomic, readonly) NSString *authToken;
@property (nonatomic, readonly) NSString *username;
- (instancetype)init NS_UNAVAILABLE;
- (TSRequest *)initWithURL:(NSURL *)URL
method:(NSString *)method
parameters:(nullable NSDictionary<NSString *, id> *)parameters
username:(NSString *)username
authToken:(NSString *)authToken;
@end

View File

@ -11,11 +11,13 @@ NS_ASSUME_NONNULL_BEGIN
- (TSRequest *)initWithURL:(NSURL *)URL
method:(NSString *)method
parameters:(nullable NSDictionary<NSString *, id> *)parameters
username:(NSString *)username
authToken:(NSString *)authToken
{
OWSAssert(authToken.length > 0);
if (self = [super initWithURL:URL method:method parameters:parameters]) {
_username = username;
_authToken = authToken;
}

View File

@ -72,6 +72,7 @@ typedef NS_ENUM(NSUInteger, TSVerificationTransport) { TSVerificationTransportVo
+ (TSRequest *)remoteAttestationRequest:(ECKeyPair *)keyPair
enclaveId:(NSString *)enclaveId
username:(NSString *)username
authToken:(NSString *)authToken;
+ (TSRequest *)remoteAttestationAuthRequest;

View File

@ -278,10 +278,12 @@ NS_ASSUME_NONNULL_BEGIN
+ (TSRequest *)remoteAttestationRequest:(ECKeyPair *)keyPair
enclaveId:(NSString *)enclaveId
username:(NSString *)username
authToken:(NSString *)authToken
{
OWSAssert(keyPair);
OWSAssert(enclaveId.length > 0);
OWSAssert(username.length > 0);
OWSAssert(authToken.length > 0);
NSString *path =
@ -292,6 +294,7 @@ NS_ASSUME_NONNULL_BEGIN
// We DO NOT prepend the "key type" byte.
@"clientPublic" : [keyPair.publicKey base64EncodedStringWithOptions:0],
}
username:username
authToken:authToken];
}

View File

@ -116,11 +116,8 @@ typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error);
} else {
if ([request isKindOfClass:[CDSAttestationRequest class]]) {
CDSAttestationRequest *attestationRequest = (CDSAttestationRequest *)request;
NSData *basicAuthCredentials = [attestationRequest.authToken dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64AuthCredentials =
[basicAuthCredentials base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)0];
[sessionManager.requestSerializer setValue:[NSString stringWithFormat:@"Basic %@", base64AuthCredentials]
forHTTPHeaderField:@"Authorization"];
[sessionManager.requestSerializer setAuthorizationHeaderFieldWithUsername:attestationRequest.username
password:attestationRequest.authToken];
} else if (request.shouldHaveAuthorizationHeaders) {
[sessionManager.requestSerializer
setAuthorizationHeaderFieldWithUsername:[TSAccountManager localNumber]