Created http response class and added error checking

This commit is contained in:
Diego Waxemberg
2015-01-31 01:57:23 -05:00
parent 4224d02eae
commit e3e95c29f6
10 changed files with 401 additions and 313 deletions
+61 -35
View File
@@ -9,6 +9,7 @@
#import "PairManager.h"
#import "CryptoManager.h"
#import "Utils.h"
#import "HttpResponse.h"
#include <dispatch/dispatch.h>
@@ -27,18 +28,19 @@
}
- (void) main {
NSData* serverInfo = [_httpManager executeRequestSynchronously:[_httpManager newServerInfoRequest]];
if (serverInfo == NULL) {
HttpResponse* serverInfo = [_httpManager executeRequestSynchronously:[_httpManager newServerInfoRequest]];
if (serverInfo == nil) {
[_callback pairFailed:@"Unable to connect to PC"];
return;
}
if (![[HttpManager getStringFromXML:serverInfo tag:@"currentgame"] isEqual:@"0"]) {
[_callback pairFailed:@"You must stop streaming before attempting to pair."];
}
else if (![[HttpManager getStringFromXML:serverInfo tag:@"PairStatus"] isEqual:@"1"]) {
[self initiatePair];
} else {
[_callback alreadyPaired];
if ([serverInfo isStatusOk]) {
if (![[serverInfo parseStringTag:@"currentgame"] isEqual:@"0"]) {
[_callback pairFailed:@"You must stop streaming before attempting to pair."];
} else if (![[serverInfo parseStringTag:@"PairStatus"] isEqual:@"1"]) {
[self initiatePair];
} else {
[_callback alreadyPaired];
}
}
}
@@ -48,16 +50,18 @@
NSLog(@"PIN: %@, saltedPIN: %@", PIN, salt);
[_callback showPIN:PIN];
NSData* pairResp = [_httpManager executeRequestSynchronously:[_httpManager newPairRequest:salt]];
NSString* pairedString;
pairedString = [HttpManager getStringFromXML:pairResp tag:@"paired"];
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
HttpResponse* pairResp = [_httpManager executeRequestSynchronously:[_httpManager newPairRequest:salt]];
if (![self verifyResponseStatus:pairResp]) {
return;
}
NSInteger* pairedStatus;
if (![pairResp parseIntTag:@"paired" value:pairedStatus] || !pairedStatus) {
[_httpManager executeRequest:[_httpManager newUnpairRequest]];
[_callback pairFailed:@"Pairing was declined by the target."];
return;
}
NSString* plainCert = [HttpManager getStringFromXML:pairResp tag:@"plaincert"];
NSString* plainCert = [pairResp parseStringTag:@"plaincert"];
CryptoManager* cryptoMan = [[CryptoManager alloc] init];
NSData* aesKey = [cryptoMan createAESKeyFromSalt:salt];
@@ -65,15 +69,17 @@
NSData* randomChallenge = [Utils randomBytes:16];
NSData* encryptedChallenge = [cryptoMan aesEncrypt:randomChallenge withKey:aesKey];
NSData* challengeResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRequest:encryptedChallenge]];
pairedString = [HttpManager getStringFromXML:challengeResp tag:@"paired"];
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
HttpResponse* challengeResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRequest:encryptedChallenge]];
if (![self verifyResponseStatus:challengeResp]) {
return;
}
if (![challengeResp parseIntTag:@"paired" value:pairedStatus] || !pairedStatus) {
[_httpManager executeRequest:[_httpManager newUnpairRequest]];
[_callback pairFailed:@"Pairing stage #2 failed"];
return;
}
NSData* encServerChallengeResp = [Utils hexToBytes:[HttpManager getStringFromXML:challengeResp tag:@"challengeresponse"]];
NSData* encServerChallengeResp = [Utils hexToBytes:[challengeResp parseStringTag:@"challengeresponse"]];
NSData* decServerChallengeResp = [cryptoMan aesDecrypt:encServerChallengeResp withKey:aesKey];
NSData* serverResponse = [decServerChallengeResp subdataWithRange:NSMakeRange(0, 20)];
@@ -83,50 +89,70 @@
NSData* challengeRespHash = [cryptoMan SHA1HashData:[self concatData:[self concatData:serverChallenge with:[CryptoManager getSignatureFromCert:_cert]] with:clientSecret]];
NSData* challengeRespEncrypted = [cryptoMan aesEncrypt:challengeRespHash withKey:aesKey];
NSData* secretResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRespRequest:challengeRespEncrypted]];
pairedString = [HttpManager getStringFromXML:secretResp tag:@"paired"];
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
HttpResponse* secretResp = [_httpManager executeRequestSynchronously:[_httpManager newChallengeRespRequest:challengeRespEncrypted]];
if (![self verifyResponseStatus:secretResp]) {
return;
}
if (![secretResp parseIntTag:@"paired" value:pairedStatus] || !pairedStatus) {
[_httpManager executeRequest:[_httpManager newUnpairRequest]];
[_callback pairFailed:@"Pairing stage #3 failed"];
return;
}
NSData* serverSecretResp = [Utils hexToBytes:[HttpManager getStringFromXML:secretResp tag:@"pairingsecret"]];
NSData* serverSecretResp = [Utils hexToBytes:[secretResp parseStringTag:@"pairingsecret"]];
NSData* serverSecret = [serverSecretResp subdataWithRange:NSMakeRange(0, 16)];
NSData* serverSignature = [serverSecretResp subdataWithRange:NSMakeRange(16, 256)];
if (![cryptoMan verifySignature:serverSecret withSignature:serverSignature andCert:[Utils hexToBytes:plainCert]]) {
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
[_httpManager executeRequest:[_httpManager newUnpairRequest]];
[_callback pairFailed:@"Server certificate invalid"];
return;
}
NSData* serverChallengeRespHash = [cryptoMan SHA1HashData:[self concatData:[self concatData:randomChallenge with:[CryptoManager getSignatureFromCert:[Utils hexToBytes:plainCert]]] with:serverSecret]];
if (![serverChallengeRespHash isEqual:serverResponse]) {
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
[_httpManager executeRequest:[_httpManager newUnpairRequest]];
[_callback pairFailed:@"Incorrect PIN"];
return;
}
NSData* clientPairingSecret = [self concatData:clientSecret with:[cryptoMan signData:clientSecret withKey:[CryptoManager readKeyFromFile]]];
NSData* clientSecretResp = [_httpManager executeRequestSynchronously:[_httpManager newClientSecretRespRequest:[Utils bytesToHex:clientPairingSecret]]];
pairedString = [HttpManager getStringFromXML:clientSecretResp tag:@"paired"];
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
HttpResponse* clientSecretResp = [_httpManager executeRequestSynchronously:[_httpManager newClientSecretRespRequest:[Utils bytesToHex:clientPairingSecret]]];
if (![self verifyResponseStatus:clientSecretResp]) {
return;
}
if ([clientSecretResp parseIntTag:@"paired" value:pairedStatus] || !pairedStatus) {
[_httpManager executeRequest:[_httpManager newUnpairRequest]];
[_callback pairFailed:@"Pairing stage #4 failed"];
return;
}
NSData* clientPairChallenge = [_httpManager executeRequestSynchronously:[_httpManager newPairChallenge]];
pairedString = [HttpManager getStringFromXML:clientPairChallenge tag:@"paired"];
if (pairedString == NULL || ![pairedString isEqualToString:@"1"]) {
[_httpManager executeRequestSynchronously:[_httpManager newUnpairRequest]];
HttpResponse* clientPairChallengeResp = [_httpManager executeRequestSynchronously:[_httpManager newPairChallenge]];
if (![self verifyResponseStatus:clientPairChallengeResp]) {
return;
}
if (![clientPairChallengeResp parseIntTag:@"paired" value:pairedStatus] || !pairedStatus) {
[_httpManager executeRequest:[_httpManager newUnpairRequest]];
[_callback pairFailed:@"Pairing stage #5 failed"];
return;
}
[_callback pairSuccessful];
}
- (BOOL) verifyResponseStatus:(HttpResponse*)resp {
if (resp == nil) {
[_httpManager executeRequest:[_httpManager newUnpairRequest]];
[_callback pairFailed:@"Network error occured."];
return false;
} else if (![resp isStatusOk]) {
[_httpManager executeRequest:[_httpManager newUnpairRequest]];
[_callback pairFailed:resp.statusMessage];
return false;
} else {
return true;
}
}
- (NSData*) concatData:(NSData*)data with:(NSData*)moreData {
NSMutableData* concatData = [[NSMutableData alloc] initWithData:data];
[concatData appendData:moreData];