mirror of
https://github.com/moonlight-stream/moonlight-ios.git
synced 2025-07-03 08:15:31 +00:00
Add server cert pinning after pairing
This commit is contained in:
parent
791a5b1ea1
commit
fbae7f88b5
@ -13,7 +13,7 @@
|
|||||||
+ (NSData*) readKeyFromFile;
|
+ (NSData*) readKeyFromFile;
|
||||||
+ (NSData*) readP12FromFile;
|
+ (NSData*) readP12FromFile;
|
||||||
+ (NSData*) getSignatureFromCert:(NSData*)cert;
|
+ (NSData*) getSignatureFromCert:(NSData*)cert;
|
||||||
+ (NSData*) nullTerminateString:(NSData*)data;
|
+ (NSData*) pemToDer:(NSData*)pemCertBytes;
|
||||||
|
|
||||||
- (NSData*) createAESKeyFromSaltSHA1:(NSData*)saltedPIN;
|
- (NSData*) createAESKeyFromSaltSHA1:(NSData*)saltedPIN;
|
||||||
- (NSData*) createAESKeyFromSaltSHA256:(NSData*)saltedPIN;
|
- (NSData*) createAESKeyFromSaltSHA256:(NSData*)saltedPIN;
|
||||||
|
@ -87,17 +87,28 @@ static NSData* p12 = nil;
|
|||||||
return (((int)[data length] + 15) / 16) * 16;
|
return (((int)[data length] + 15) / 16) * 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSData*) nullTerminateString:(NSData*)data {
|
+ (NSData*) pemToDer:(NSData*)pemCertBytes {
|
||||||
NSMutableData* mutData = [NSMutableData dataWithData:data];
|
X509* x509;
|
||||||
[mutData appendBytes:"" length:1];
|
|
||||||
return mutData;
|
BIO* bio = BIO_new_mem_buf([pemCertBytes bytes], (int)[pemCertBytes length]);
|
||||||
|
x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
||||||
|
BIO_free(bio);
|
||||||
|
|
||||||
|
bio = BIO_new(BIO_s_mem());
|
||||||
|
i2d_X509_bio(bio, x509);
|
||||||
|
|
||||||
|
BUF_MEM* mem;
|
||||||
|
BIO_get_mem_ptr(bio, &mem);
|
||||||
|
|
||||||
|
NSData* ret = [[NSData alloc] initWithBytes:mem->data length:mem->length];
|
||||||
|
BIO_free(bio);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (bool) verifySignature:(NSData *)data withSignature:(NSData*)signature andCert:(NSData*)cert {
|
- (bool) verifySignature:(NSData *)data withSignature:(NSData*)signature andCert:(NSData*)cert {
|
||||||
const char* buffer = [[CryptoManager nullTerminateString:cert] bytes];
|
|
||||||
X509* x509;
|
X509* x509;
|
||||||
BIO* bio = BIO_new(BIO_s_mem());
|
BIO* bio = BIO_new_mem_buf([cert bytes], (int)[cert length]);
|
||||||
BIO_puts(bio, buffer);
|
|
||||||
x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
||||||
|
|
||||||
BIO_free(bio);
|
BIO_free(bio);
|
||||||
@ -122,9 +133,7 @@ static NSData* p12 = nil;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (NSData *)signData:(NSData *)data withKey:(NSData *)key {
|
- (NSData *)signData:(NSData *)data withKey:(NSData *)key {
|
||||||
const char* buffer = [[CryptoManager nullTerminateString:key] bytes];
|
BIO* bio = BIO_new_mem_buf([key bytes], (int)[key length]);
|
||||||
BIO* bio = BIO_new(BIO_s_mem());
|
|
||||||
BIO_puts(bio, buffer);
|
|
||||||
|
|
||||||
EVP_PKEY* pkey;
|
EVP_PKEY* pkey;
|
||||||
pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
|
pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
|
||||||
@ -211,11 +220,8 @@ static NSData* p12 = nil;
|
|||||||
}
|
}
|
||||||
|
|
||||||
+ (NSData *)getSignatureFromCert:(NSData *)cert {
|
+ (NSData *)getSignatureFromCert:(NSData *)cert {
|
||||||
const char* buffer = [[CryptoManager nullTerminateString:cert] bytes];
|
BIO* bio = BIO_new_mem_buf([cert bytes], (int)[cert length]);
|
||||||
X509* x509;
|
X509* x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
||||||
BIO* bio = BIO_new(BIO_s_mem());
|
|
||||||
BIO_puts(bio, buffer);
|
|
||||||
x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
if (!x509) {
|
if (!x509) {
|
||||||
Log(LOG_E, @"Unable to parse certificate in memory!");
|
Log(LOG_E, @"Unable to parse certificate in memory!");
|
||||||
|
@ -16,15 +16,17 @@
|
|||||||
@property (nonatomic, nullable) NSString * activeAddress;
|
@property (nonatomic, nullable) NSString * activeAddress;
|
||||||
@property (nonatomic, nullable) NSString * currentGame;
|
@property (nonatomic, nullable) NSString * currentGame;
|
||||||
|
|
||||||
|
@property (nonatomic, nullable, retain) NSData *serverCert;
|
||||||
|
@property (nonatomic, nullable, retain) NSString *address;
|
||||||
|
@property (nonatomic, nullable, retain) NSString *externalAddress;
|
||||||
|
@property (nonatomic, nullable, retain) NSString *localAddress;
|
||||||
|
@property (nonatomic, nullable, retain) NSString *mac;
|
||||||
|
@property (nonatomic) int serverCodecModeSupport;
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@property (nonatomic, retain) NSString *address;
|
|
||||||
@property (nonatomic, retain) NSString *externalAddress;
|
|
||||||
@property (nonatomic, retain) NSString *localAddress;
|
|
||||||
@property (nonatomic, retain) NSString *mac;
|
|
||||||
@property (nonatomic, retain) NSString *name;
|
@property (nonatomic, retain) NSString *name;
|
||||||
@property (nonatomic, retain) NSString *uuid;
|
@property (nonatomic, retain) NSString *uuid;
|
||||||
@property (nonatomic) int serverCodecModeSupport;
|
|
||||||
@property (nonatomic, retain) NSMutableSet *appList;
|
@property (nonatomic, retain) NSMutableSet *appList;
|
||||||
|
|
||||||
- (id) initFromHost:(Host*)host;
|
- (id) initFromHost:(Host*)host;
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
self.uuid = host.uuid;
|
self.uuid = host.uuid;
|
||||||
self.pairState = [host.pairState intValue];
|
self.pairState = [host.pairState intValue];
|
||||||
self.serverCodecModeSupport = host.serverCodecModeSupport;
|
self.serverCodecModeSupport = host.serverCodecModeSupport;
|
||||||
|
self.serverCert = host.serverCert;
|
||||||
|
|
||||||
NSMutableSet *appList = [[NSMutableSet alloc] init];
|
NSMutableSet *appList = [[NSMutableSet alloc] init];
|
||||||
|
|
||||||
@ -60,6 +61,9 @@
|
|||||||
if (self.mac != nil) {
|
if (self.mac != nil) {
|
||||||
parentHost.mac = self.mac;
|
parentHost.mac = self.mac;
|
||||||
}
|
}
|
||||||
|
if (self.serverCert != nil) {
|
||||||
|
parentHost.serverCert = self.serverCert;
|
||||||
|
}
|
||||||
parentHost.name = self.name;
|
parentHost.name = self.name;
|
||||||
parentHost.uuid = self.uuid;
|
parentHost.uuid = self.uuid;
|
||||||
parentHost.serverCodecModeSupport = self.serverCodecModeSupport;
|
parentHost.serverCodecModeSupport = self.serverCodecModeSupport;
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>_XCCurrentVersionName</key>
|
<key>_XCCurrentVersionName</key>
|
||||||
<string>Moonlight v1.2.xcdatamodel</string>
|
<string>Moonlight v1.3.xcdatamodel</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14460.32" systemVersion="18C54" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
|
||||||
|
<entity name="App" representedClassName="App" syncable="YES" codeGenerationType="class">
|
||||||
|
<attribute name="hdrSupported" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
|
||||||
|
<attribute name="id" attributeType="String" syncable="YES"/>
|
||||||
|
<attribute name="name" attributeType="String" syncable="YES"/>
|
||||||
|
<relationship name="host" maxCount="1" deletionRule="Nullify" destinationEntity="Host" inverseName="appList" inverseEntity="Host" syncable="YES"/>
|
||||||
|
</entity>
|
||||||
|
<entity name="Host" representedClassName="Host" syncable="YES" codeGenerationType="class">
|
||||||
|
<attribute name="address" optional="YES" attributeType="String" syncable="YES"/>
|
||||||
|
<attribute name="externalAddress" optional="YES" attributeType="String" syncable="YES"/>
|
||||||
|
<attribute name="localAddress" optional="YES" attributeType="String" syncable="YES"/>
|
||||||
|
<attribute name="mac" optional="YES" attributeType="String" syncable="YES"/>
|
||||||
|
<attribute name="name" attributeType="String" syncable="YES"/>
|
||||||
|
<attribute name="pairState" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
|
||||||
|
<attribute name="serverCert" optional="YES" attributeType="Binary" syncable="YES"/>
|
||||||
|
<attribute name="serverCodecModeSupport" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/>
|
||||||
|
<attribute name="uuid" optional="YES" attributeType="String" syncable="YES"/>
|
||||||
|
<relationship name="appList" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="App" inverseName="host" inverseEntity="App" syncable="YES"/>
|
||||||
|
</entity>
|
||||||
|
<entity name="Settings" representedClassName="Settings" syncable="YES" codeGenerationType="class">
|
||||||
|
<attribute name="bitrate" attributeType="Integer 32" defaultValueString="10000" usesScalarValueType="NO" syncable="YES"/>
|
||||||
|
<attribute name="enableHdr" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
|
||||||
|
<attribute name="framerate" attributeType="Integer 32" defaultValueString="60" usesScalarValueType="NO" syncable="YES"/>
|
||||||
|
<attribute name="height" attributeType="Integer 32" defaultValueString="720" usesScalarValueType="NO" syncable="YES"/>
|
||||||
|
<attribute name="multiController" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
|
||||||
|
<attribute name="onscreenControls" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
|
||||||
|
<attribute name="optimizeGames" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
|
||||||
|
<attribute name="playAudioOnPC" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
|
||||||
|
<attribute name="streamingRemotely" attributeType="Boolean" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/>
|
||||||
|
<attribute name="uniqueId" attributeType="String" syncable="YES"/>
|
||||||
|
<attribute name="useHevc" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
|
||||||
|
<attribute name="width" attributeType="Integer 32" defaultValueString="1280" usesScalarValueType="NO" syncable="YES"/>
|
||||||
|
</entity>
|
||||||
|
<elements>
|
||||||
|
<element name="App" positionX="0" positionY="54" width="128" height="105"/>
|
||||||
|
<element name="Host" positionX="0" positionY="0" width="128" height="195"/>
|
||||||
|
<element name="Settings" positionX="0" positionY="0" width="128" height="225"/>
|
||||||
|
</elements>
|
||||||
|
</model>
|
@ -20,7 +20,7 @@ static const int MAX_ATTEMPTS = 5;
|
|||||||
- (void) main {
|
- (void) main {
|
||||||
int attempts = 0;
|
int attempts = 0;
|
||||||
while (![self isCancelled] && attempts++ < MAX_ATTEMPTS) {
|
while (![self isCancelled] && attempts++ < MAX_ATTEMPTS) {
|
||||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_host.activeAddress uniqueId:[IdManager getUniqueId] deviceName:deviceName cert:[CryptoManager readCertFromFile]];
|
HttpManager* hMan = [[HttpManager alloc] initWithHost:_host.activeAddress uniqueId:[IdManager getUniqueId] serverCert:_host.serverCert];
|
||||||
AppAssetResponse* appAssetResp = [[AppAssetResponse alloc] init];
|
AppAssetResponse* appAssetResp = [[AppAssetResponse alloc] init];
|
||||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:appAssetResp withUrlRequest:[hMan newAppAssetRequestWithAppId:self.app.id]]];
|
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:appAssetResp withUrlRequest:[hMan newAppAssetRequestWithAppId:self.app.id]]];
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
@interface ConnectionHelper : NSObject
|
@interface ConnectionHelper : NSObject
|
||||||
|
|
||||||
+(AppListResponse*) getAppListForHostWithHostIP:(NSString*) hostIP deviceName:(NSString*)deviceName cert:(NSData*) cert uniqueID:(NSString*) uniqueId;
|
+(AppListResponse*) getAppListForHostWithHostIP:(NSString*) hostIP serverCert:(NSData*) serverCert uniqueID:(NSString*) uniqueId;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
@implementation ConnectionHelper
|
@implementation ConnectionHelper
|
||||||
|
|
||||||
+(AppListResponse*) getAppListForHostWithHostIP:(NSString*) hostIP deviceName:(NSString*)deviceName cert:(NSData*) cert uniqueID:(NSString*) uniqueId {
|
+(AppListResponse*) getAppListForHostWithHostIP:(NSString*) hostIP serverCert:(NSData*) cert uniqueID:(NSString*) uniqueId {
|
||||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:hostIP uniqueId:uniqueId deviceName:deviceName cert:cert];
|
HttpManager* hMan = [[HttpManager alloc] initWithHost:hostIP uniqueId:uniqueId serverCert:cert];
|
||||||
|
|
||||||
// Try up to 5 times to get the app list
|
// Try up to 5 times to get the app list
|
||||||
AppListResponse* appListResp;
|
AppListResponse* appListResp;
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void) discoverHost:(NSString *)hostAddress withCallback:(void (^)(TemporaryHost *, NSString*))callback {
|
- (void) discoverHost:(NSString *)hostAddress withCallback:(void (^)(TemporaryHost *, NSString*))callback {
|
||||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:hostAddress uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
HttpManager* hMan = [[HttpManager alloc] initWithHost:hostAddress uniqueId:_uniqueId serverCert:nil];
|
||||||
ServerInfoResponse* serverInfoResponse = [[ServerInfoResponse alloc] init];
|
ServerInfoResponse* serverInfoResponse = [[ServerInfoResponse alloc] init];
|
||||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResponse withUrlRequest:[hMan newServerInfoRequest:false] fallbackError:401 fallbackRequest:[hMan newHttpServerInfoRequest]]];
|
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResponse withUrlRequest:[hMan newServerInfoRequest:false] fallbackError:401 fallbackRequest:[hMan newHttpServerInfoRequest]]];
|
||||||
|
|
||||||
@ -183,7 +183,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (NSOperation*) createWorkerForHost:(TemporaryHost*)host {
|
- (NSOperation*) createWorkerForHost:(TemporaryHost*)host {
|
||||||
DiscoveryWorker* worker = [[DiscoveryWorker alloc] initWithHost:host uniqueId:_uniqueId cert:_cert];
|
DiscoveryWorker* worker = [[DiscoveryWorker alloc] initWithHost:host uniqueId:_uniqueId];
|
||||||
return worker;
|
return worker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
@interface DiscoveryWorker : NSOperation
|
@interface DiscoveryWorker : NSOperation
|
||||||
|
|
||||||
- (id) initWithHost:(TemporaryHost*)host uniqueId:(NSString*)uniqueId cert:(NSData*)cert;
|
- (id) initWithHost:(TemporaryHost*)host uniqueId:(NSString*)uniqueId;
|
||||||
- (void) discoverHost;
|
- (void) discoverHost;
|
||||||
- (TemporaryHost*) getHost;
|
- (TemporaryHost*) getHost;
|
||||||
|
|
||||||
|
@ -16,16 +16,14 @@
|
|||||||
@implementation DiscoveryWorker {
|
@implementation DiscoveryWorker {
|
||||||
TemporaryHost* _host;
|
TemporaryHost* _host;
|
||||||
NSString* _uniqueId;
|
NSString* _uniqueId;
|
||||||
NSData* _cert;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const float POLL_RATE = 2.0f; // Poll every 2 seconds
|
static const float POLL_RATE = 2.0f; // Poll every 2 seconds
|
||||||
|
|
||||||
- (id) initWithHost:(TemporaryHost*)host uniqueId:(NSString*)uniqueId cert:(NSData*)cert {
|
- (id) initWithHost:(TemporaryHost*)host uniqueId:(NSString*)uniqueId {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
_host = host;
|
_host = host;
|
||||||
_uniqueId = uniqueId;
|
_uniqueId = uniqueId;
|
||||||
_cert = cert;
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +96,7 @@ static const float POLL_RATE = 2.0f; // Poll every 2 seconds
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerInfoResponse* serverInfoResp = [self requestInfoAtAddress:address];
|
ServerInfoResponse* serverInfoResp = [self requestInfoAtAddress:address cert:_host.serverCert];
|
||||||
receivedResponse = [self checkResponse:serverInfoResp];
|
receivedResponse = [self checkResponse:serverInfoResp];
|
||||||
if (receivedResponse) {
|
if (receivedResponse) {
|
||||||
[serverInfoResp populateHost:_host];
|
[serverInfoResp populateHost:_host];
|
||||||
@ -123,11 +121,10 @@ static const float POLL_RATE = 2.0f; // Poll every 2 seconds
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (ServerInfoResponse*) requestInfoAtAddress:(NSString*)address {
|
- (ServerInfoResponse*) requestInfoAtAddress:(NSString*)address cert:(NSData*)cert {
|
||||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:address
|
HttpManager* hMan = [[HttpManager alloc] initWithHost:address
|
||||||
uniqueId:_uniqueId
|
uniqueId:_uniqueId
|
||||||
deviceName:deviceName
|
serverCert:cert];
|
||||||
cert:_cert];
|
|
||||||
ServerInfoResponse* response = [[ServerInfoResponse alloc] init];
|
ServerInfoResponse* response = [[ServerInfoResponse alloc] init];
|
||||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:response
|
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:response
|
||||||
withUrlRequest:[hMan newServerInfoRequest:true]
|
withUrlRequest:[hMan newServerInfoRequest:true]
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
@interface HttpManager : NSObject <NSURLSessionDelegate>
|
@interface HttpManager : NSObject <NSURLSessionDelegate>
|
||||||
|
|
||||||
- (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId deviceName:(NSString*) deviceName cert:(NSData*) cert;
|
- (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId serverCert:(NSData*) serverCert;
|
||||||
- (NSURLRequest*) newPairRequest:(NSData*)salt;
|
- (NSURLRequest*) newPairRequest:(NSData*)salt clientCert:(NSData*)clientCert;
|
||||||
- (NSURLRequest*) newUnpairRequest;
|
- (NSURLRequest*) newUnpairRequest;
|
||||||
- (NSURLRequest*) newChallengeRequest:(NSData*)challenge;
|
- (NSURLRequest*) newChallengeRequest:(NSData*)challenge;
|
||||||
- (NSURLRequest*) newChallengeRespRequest:(NSData*)challengeResp;
|
- (NSURLRequest*) newChallengeRespRequest:(NSData*)challengeResp;
|
||||||
|
@ -25,12 +25,12 @@
|
|||||||
NSString* _baseHTTPSURL;
|
NSString* _baseHTTPSURL;
|
||||||
NSString* _uniqueId;
|
NSString* _uniqueId;
|
||||||
NSString* _deviceName;
|
NSString* _deviceName;
|
||||||
NSData* _cert;
|
NSData* _serverCert;
|
||||||
NSMutableData* _respData;
|
NSMutableData* _respData;
|
||||||
NSData* _requestResp;
|
NSData* _requestResp;
|
||||||
dispatch_semaphore_t _requestLock;
|
dispatch_semaphore_t _requestLock;
|
||||||
|
|
||||||
BOOL _errorOccurred;
|
NSError* _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const NSString* HTTP_PORT = @"47989";
|
static const NSString* HTTP_PORT = @"47989";
|
||||||
@ -43,11 +43,11 @@ static const NSString* HTTPS_PORT = @"47984";
|
|||||||
return [xmlString dataUsingEncoding:NSUTF8StringEncoding];
|
return [xmlString dataUsingEncoding:NSUTF8StringEncoding];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId deviceName:(NSString*) deviceName cert:(NSData*) cert {
|
- (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId serverCert:(NSData*) serverCert {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
_uniqueId = uniqueId;
|
_uniqueId = uniqueId;
|
||||||
_deviceName = deviceName;
|
_deviceName = deviceName;
|
||||||
_cert = cert;
|
_serverCert = serverCert;
|
||||||
_requestLock = dispatch_semaphore_create(0);
|
_requestLock = dispatch_semaphore_create(0);
|
||||||
_respData = [[NSMutableData alloc] init];
|
_respData = [[NSMutableData alloc] init];
|
||||||
NSURLSessionConfiguration* config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
|
NSURLSessionConfiguration* config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
|
||||||
@ -68,13 +68,15 @@ static const NSString* HTTPS_PORT = @"47984";
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void) executeRequestSynchronously:(HttpRequest*)request {
|
- (void) executeRequestSynchronously:(HttpRequest*)request {
|
||||||
Log(LOG_D, @"Making Request: %@", request);
|
|
||||||
[_respData setLength:0];
|
[_respData setLength:0];
|
||||||
|
_error = nil;
|
||||||
|
|
||||||
|
Log(LOG_D, @"Making Request: %@", request);
|
||||||
[[_urlSession dataTaskWithRequest:request.request completionHandler:^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error) {
|
[[_urlSession dataTaskWithRequest:request.request completionHandler:^(NSData * __nullable data, NSURLResponse * __nullable response, NSError * __nullable error) {
|
||||||
|
|
||||||
if (error != NULL) {
|
if (error != NULL) {
|
||||||
Log(LOG_D, @"Connection error: %@", error);
|
Log(LOG_D, @"Connection error: %@", error);
|
||||||
self->_errorOccurred = true;
|
self->_error = error;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Log(LOG_D, @"Received response: %@", response);
|
Log(LOG_D, @"Received response: %@", response);
|
||||||
@ -94,7 +96,7 @@ static const NSString* HTTPS_PORT = @"47984";
|
|||||||
}] resume];
|
}] resume];
|
||||||
dispatch_semaphore_wait(_requestLock, DISPATCH_TIME_FOREVER);
|
dispatch_semaphore_wait(_requestLock, DISPATCH_TIME_FOREVER);
|
||||||
|
|
||||||
if (!_errorOccurred && request.response) {
|
if (!_error && request.response) {
|
||||||
[request.response populateWithData:_requestResp];
|
[request.response populateWithData:_requestResp];
|
||||||
|
|
||||||
// If the fallback error code was detected, issue the fallback request
|
// If the fallback error code was detected, issue the fallback request
|
||||||
@ -106,7 +108,15 @@ static const NSString* HTTPS_PORT = @"47984";
|
|||||||
[self executeRequestSynchronously:request];
|
[self executeRequestSynchronously:request];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_errorOccurred = false;
|
else if (_error && [_error code] == NSURLErrorServerCertificateUntrusted && request.fallbackRequest) {
|
||||||
|
// This will fall back to HTTP on serverinfo queries to allow us to pair again
|
||||||
|
// and get the server cert updated.
|
||||||
|
Log(LOG_D, @"Attempting fallback request after certificate trust failure");
|
||||||
|
request.request = request.fallbackRequest;
|
||||||
|
request.fallbackError = 0;
|
||||||
|
request.fallbackRequest = NULL;
|
||||||
|
[self executeRequestSynchronously:request];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURLRequest*) createRequestFromString:(NSString*) urlString timeout:(int)timeout {
|
- (NSURLRequest*) createRequestFromString:(NSString*) urlString timeout:(int)timeout {
|
||||||
@ -116,9 +126,9 @@ static const NSString* HTTPS_PORT = @"47984";
|
|||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURLRequest*) newPairRequest:(NSData*)salt {
|
- (NSURLRequest*) newPairRequest:(NSData*)salt clientCert:(NSData*)clientCert {
|
||||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&phrase=getservercert&salt=%@&clientcert=%@",
|
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&phrase=getservercert&salt=%@&clientcert=%@",
|
||||||
_baseHTTPSURL, _uniqueId, _deviceName, [self bytesToHex:salt], [self bytesToHex:_cert]];
|
_baseHTTPURL, _uniqueId, _deviceName, [self bytesToHex:salt], [self bytesToHex:clientCert]];
|
||||||
// This call blocks while waiting for the user to input the PIN on the PC
|
// This call blocks while waiting for the user to input the PIN on the PC
|
||||||
return [self createRequestFromString:urlString timeout:EXTRA_LONG_TIMEOUT_SEC];
|
return [self createRequestFromString:urlString timeout:EXTRA_LONG_TIMEOUT_SEC];
|
||||||
}
|
}
|
||||||
@ -130,18 +140,18 @@ static const NSString* HTTPS_PORT = @"47984";
|
|||||||
|
|
||||||
- (NSURLRequest*) newChallengeRequest:(NSData*)challenge {
|
- (NSURLRequest*) newChallengeRequest:(NSData*)challenge {
|
||||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&clientchallenge=%@",
|
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&clientchallenge=%@",
|
||||||
_baseHTTPSURL, _uniqueId, _deviceName, [self bytesToHex:challenge]];
|
_baseHTTPURL, _uniqueId, _deviceName, [self bytesToHex:challenge]];
|
||||||
return [self createRequestFromString:urlString timeout:NORMAL_TIMEOUT_SEC];
|
return [self createRequestFromString:urlString timeout:NORMAL_TIMEOUT_SEC];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURLRequest*) newChallengeRespRequest:(NSData*)challengeResp {
|
- (NSURLRequest*) newChallengeRespRequest:(NSData*)challengeResp {
|
||||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&serverchallengeresp=%@",
|
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&serverchallengeresp=%@",
|
||||||
_baseHTTPSURL, _uniqueId, _deviceName, [self bytesToHex:challengeResp]];
|
_baseHTTPURL, _uniqueId, _deviceName, [self bytesToHex:challengeResp]];
|
||||||
return [self createRequestFromString:urlString timeout:NORMAL_TIMEOUT_SEC];
|
return [self createRequestFromString:urlString timeout:NORMAL_TIMEOUT_SEC];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSURLRequest*) newClientSecretRespRequest:(NSString*)clientPairSecret {
|
- (NSURLRequest*) newClientSecretRespRequest:(NSString*)clientPairSecret {
|
||||||
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&clientpairingsecret=%@", _baseHTTPSURL, _uniqueId, _deviceName, clientPairSecret];
|
NSString* urlString = [NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&clientpairingsecret=%@", _baseHTTPURL, _uniqueId, _deviceName, clientPairSecret];
|
||||||
return [self createRequestFromString:urlString timeout:NORMAL_TIMEOUT_SEC];
|
return [self createRequestFromString:urlString timeout:NORMAL_TIMEOUT_SEC];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,6 +259,26 @@ static const NSString* HTTPS_PORT = @"47984";
|
|||||||
// Allow untrusted server certificates
|
// Allow untrusted server certificates
|
||||||
if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
|
if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
|
||||||
{
|
{
|
||||||
|
if (_serverCert) {
|
||||||
|
SecCertificateRef actualCert = SecTrustGetCertificateAtIndex(challenge.protectionSpace.serverTrust, 0);
|
||||||
|
|
||||||
|
CFDataRef actualCertData;
|
||||||
|
|
||||||
|
actualCertData = SecCertificateCopyData(actualCert);
|
||||||
|
|
||||||
|
if (!CFEqual(actualCertData, (__bridge CFDataRef)_serverCert)) {
|
||||||
|
Log(LOG_E, @"Server certificate mismatch");
|
||||||
|
CFRelease(actualCertData);
|
||||||
|
completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(actualCertData);
|
||||||
|
|
||||||
|
// Fall-through to TLS success
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow TLS handshake to proceed
|
||||||
completionHandler(NSURLSessionAuthChallengeUseCredential,
|
completionHandler(NSURLSessionAuthChallengeUseCredential,
|
||||||
[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust]);
|
[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust]);
|
||||||
}
|
}
|
||||||
|
@ -11,14 +11,14 @@
|
|||||||
@protocol PairCallback <NSObject>
|
@protocol PairCallback <NSObject>
|
||||||
|
|
||||||
- (void) showPIN:(NSString*)PIN;
|
- (void) showPIN:(NSString*)PIN;
|
||||||
- (void) pairSuccessful;
|
- (void) pairSuccessful:(NSData*)serverCert;
|
||||||
- (void) pairFailed:(NSString*)message;
|
- (void) pairFailed:(NSString*)message;
|
||||||
- (void) alreadyPaired;
|
- (void) alreadyPaired;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface PairManager : NSOperation
|
@interface PairManager : NSOperation
|
||||||
- (id) initWithManager:(HttpManager*)httpManager andCert:(NSData*)cert callback:(id<PairCallback>)callback;
|
- (id) initWithManager:(HttpManager*)httpManager clientCert:(NSData*)clientCert callback:(id<PairCallback>)callback;
|
||||||
- (NSString*) generatePIN;
|
- (NSString*) generatePIN;
|
||||||
- (NSData*) saltPIN:(NSString*)PIN;
|
- (NSData*) saltPIN:(NSString*)PIN;
|
||||||
- (void) initiatePair:(int)serverMajorVersion;
|
- (void) initiatePair:(int)serverMajorVersion;
|
||||||
|
@ -17,14 +17,14 @@
|
|||||||
|
|
||||||
@implementation PairManager {
|
@implementation PairManager {
|
||||||
HttpManager* _httpManager;
|
HttpManager* _httpManager;
|
||||||
NSData* _cert;
|
NSData* _clientCert;
|
||||||
id<PairCallback> _callback;
|
id<PairCallback> _callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithManager:(HttpManager*)httpManager andCert:(NSData*)cert callback:(id<PairCallback>)callback {
|
- (id) initWithManager:(HttpManager*)httpManager clientCert:(NSData*)clientCert callback:(id<PairCallback>)callback {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
_httpManager = httpManager;
|
_httpManager = httpManager;
|
||||||
_cert = cert;
|
_clientCert = clientCert;
|
||||||
_callback = callback;
|
_callback = callback;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@
|
|||||||
[_callback showPIN:PIN];
|
[_callback showPIN:PIN];
|
||||||
|
|
||||||
HttpResponse* pairResp = [[HttpResponse alloc] init];
|
HttpResponse* pairResp = [[HttpResponse alloc] init];
|
||||||
[_httpManager executeRequestSynchronously:[HttpRequest requestForResponse:pairResp withUrlRequest:[_httpManager newPairRequest:salt]]];
|
[_httpManager executeRequestSynchronously:[HttpRequest requestForResponse:pairResp withUrlRequest:[_httpManager newPairRequest:salt clientCert:_clientCert]]];
|
||||||
if (![self verifyResponseStatus:pairResp]) {
|
if (![self verifyResponseStatus:pairResp]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -113,7 +113,7 @@
|
|||||||
NSData* serverChallenge = [decServerChallengeResp subdataWithRange:NSMakeRange(hashLength, 16)];
|
NSData* serverChallenge = [decServerChallengeResp subdataWithRange:NSMakeRange(hashLength, 16)];
|
||||||
|
|
||||||
NSData* clientSecret = [Utils randomBytes:16];
|
NSData* clientSecret = [Utils randomBytes:16];
|
||||||
NSData* challengeRespHashInput = [self concatData:[self concatData:serverChallenge with:[CryptoManager getSignatureFromCert:_cert]] with:clientSecret];
|
NSData* challengeRespHashInput = [self concatData:[self concatData:serverChallenge with:[CryptoManager getSignatureFromCert:_clientCert]] with:clientSecret];
|
||||||
NSData* challengeRespHash;
|
NSData* challengeRespHash;
|
||||||
if (serverMajorVersion >= 7) {
|
if (serverMajorVersion >= 7) {
|
||||||
challengeRespHash = [cryptoMan SHA256HashData: challengeRespHashInput];
|
challengeRespHash = [cryptoMan SHA256HashData: challengeRespHashInput];
|
||||||
@ -180,7 +180,8 @@
|
|||||||
[_callback pairFailed:@"Pairing stage #5 failed"];
|
[_callback pairFailed:@"Pairing stage #5 failed"];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
[_callback pairSuccessful];
|
|
||||||
|
[_callback pairSuccessful: [CryptoManager pemToDer:[Utils hexToBytes:plainCert]]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) verifyResponseStatus:(HttpResponse*)resp {
|
- (BOOL) verifyResponseStatus:(HttpResponse*)resp {
|
||||||
|
@ -28,5 +28,6 @@
|
|||||||
@property BOOL enableHdr;
|
@property BOOL enableHdr;
|
||||||
@property BOOL multiController;
|
@property BOOL multiController;
|
||||||
@property BOOL allowHevc;
|
@property BOOL allowHevc;
|
||||||
|
@property NSData* serverCert;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -9,5 +9,5 @@
|
|||||||
#import "StreamConfiguration.h"
|
#import "StreamConfiguration.h"
|
||||||
|
|
||||||
@implementation StreamConfiguration
|
@implementation StreamConfiguration
|
||||||
@synthesize host, appID, width, height, frameRate, bitRate, riKeyId, riKey, gamepadMask, streamingRemotely, appName, optimizeGameSettings, playAudioOnPC, audioChannelMask, audioChannelCount, enableHdr, multiController, allowHevc;
|
@synthesize host, appID, width, height, frameRate, bitRate, riKeyId, riKey, gamepadMask, streamingRemotely, appName, optimizeGameSettings, playAudioOnPC, audioChannelMask, audioChannelCount, enableHdr, multiController, allowHevc, serverCert;
|
||||||
@end
|
@end
|
||||||
|
@ -38,12 +38,10 @@
|
|||||||
- (void)main {
|
- (void)main {
|
||||||
[CryptoManager generateKeyPairUsingSSL];
|
[CryptoManager generateKeyPairUsingSSL];
|
||||||
NSString* uniqueId = [IdManager getUniqueId];
|
NSString* uniqueId = [IdManager getUniqueId];
|
||||||
NSData* cert = [CryptoManager readCertFromFile];
|
|
||||||
|
|
||||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_config.host
|
HttpManager* hMan = [[HttpManager alloc] initWithHost:_config.host
|
||||||
uniqueId:uniqueId
|
uniqueId:uniqueId
|
||||||
deviceName:deviceName
|
serverCert:_config.serverCert];
|
||||||
cert:cert];
|
|
||||||
|
|
||||||
ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init];
|
ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init];
|
||||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResp withUrlRequest:[hMan newServerInfoRequest:false]
|
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResp withUrlRequest:[hMan newServerInfoRequest:false]
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
NSOperationQueue* _opQueue;
|
NSOperationQueue* _opQueue;
|
||||||
TemporaryHost* _selectedHost;
|
TemporaryHost* _selectedHost;
|
||||||
NSString* _uniqueId;
|
NSString* _uniqueId;
|
||||||
NSData* _cert;
|
NSData* _clientCert;
|
||||||
DiscoveryManager* _discMan;
|
DiscoveryManager* _discMan;
|
||||||
AppAssetManager* _appManager;
|
AppAssetManager* _appManager;
|
||||||
StreamConfiguration* _streamConfig;
|
StreamConfiguration* _streamConfig;
|
||||||
@ -98,8 +98,11 @@ static NSMutableSet* hostList;
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)pairSuccessful {
|
- (void)pairSuccessful:(NSData*)serverCert {
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
// Store the cert from pairing with the host
|
||||||
|
self->_selectedHost.serverCert = serverCert;
|
||||||
|
|
||||||
[self->_pairAlert dismissViewControllerAnimated:YES completion:nil];
|
[self->_pairAlert dismissViewControllerAnimated:YES completion:nil];
|
||||||
self->_pairAlert = nil;
|
self->_pairAlert = nil;
|
||||||
|
|
||||||
@ -139,7 +142,7 @@ static NSMutableSet* hostList;
|
|||||||
// Exempt this host from discovery while handling the applist query
|
// Exempt this host from discovery while handling the applist query
|
||||||
[self->_discMan removeHostFromDiscovery:host];
|
[self->_discMan removeHostFromDiscovery:host];
|
||||||
|
|
||||||
AppListResponse* appListResp = [ConnectionHelper getAppListForHostWithHostIP:host.activeAddress deviceName:deviceName cert:self->_cert uniqueID:self->_uniqueId];
|
AppListResponse* appListResp = [ConnectionHelper getAppListForHostWithHostIP:host.activeAddress serverCert:host.serverCert uniqueID:self->_uniqueId];
|
||||||
|
|
||||||
[self->_discMan addHostToDiscovery:host];
|
[self->_discMan addHostToDiscovery:host];
|
||||||
|
|
||||||
@ -307,7 +310,7 @@ static NSMutableSet* hostList;
|
|||||||
|
|
||||||
[self showLoadingFrame: ^{
|
[self showLoadingFrame: ^{
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:host.activeAddress uniqueId:self->_uniqueId deviceName:deviceName cert:self->_cert];
|
HttpManager* hMan = [[HttpManager alloc] initWithHost:host.activeAddress uniqueId:self->_uniqueId serverCert:host.serverCert];
|
||||||
ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init];
|
ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init];
|
||||||
|
|
||||||
// Exempt this host from discovery while handling the serverinfo request
|
// Exempt this host from discovery while handling the serverinfo request
|
||||||
@ -352,7 +355,7 @@ static NSMutableSet* hostList;
|
|||||||
Log(LOG_I, @"Trying to pair");
|
Log(LOG_I, @"Trying to pair");
|
||||||
// Polling the server while pairing causes the server to screw up
|
// Polling the server while pairing causes the server to screw up
|
||||||
[self->_discMan stopDiscoveryBlocking];
|
[self->_discMan stopDiscoveryBlocking];
|
||||||
PairManager* pMan = [[PairManager alloc] initWithManager:hMan andCert:self->_cert callback:self];
|
PairManager* pMan = [[PairManager alloc] initWithManager:hMan clientCert:self->_clientCert callback:self];
|
||||||
[self->_opQueue addOperation:pMan];
|
[self->_opQueue addOperation:pMan];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -457,6 +460,7 @@ static NSMutableSet* hostList;
|
|||||||
_streamConfig.host = app.host.activeAddress;
|
_streamConfig.host = app.host.activeAddress;
|
||||||
_streamConfig.appID = app.id;
|
_streamConfig.appID = app.id;
|
||||||
_streamConfig.appName = app.name;
|
_streamConfig.appName = app.name;
|
||||||
|
_streamConfig.serverCert = app.host.serverCert;
|
||||||
|
|
||||||
DataManager* dataMan = [[DataManager alloc] init];
|
DataManager* dataMan = [[DataManager alloc] init];
|
||||||
TemporarySettings* streamSettings = [dataMan getSettings];
|
TemporarySettings* streamSettings = [dataMan getSettings];
|
||||||
@ -524,7 +528,7 @@ static NSMutableSet* hostList;
|
|||||||
Log(LOG_I, @"Quitting application: %@", currentApp.name);
|
Log(LOG_I, @"Quitting application: %@", currentApp.name);
|
||||||
[self showLoadingFrame: ^{
|
[self showLoadingFrame: ^{
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:app.host.activeAddress uniqueId:self->_uniqueId deviceName:deviceName cert:self->_cert];
|
HttpManager* hMan = [[HttpManager alloc] initWithHost:app.host.activeAddress uniqueId:self->_uniqueId serverCert:app.host.serverCert];
|
||||||
HttpResponse* quitResponse = [[HttpResponse alloc] init];
|
HttpResponse* quitResponse = [[HttpResponse alloc] init];
|
||||||
HttpRequest* quitRequest = [HttpRequest requestForResponse: quitResponse withUrlRequest:[hMan newQuitAppRequest]];
|
HttpRequest* quitRequest = [HttpRequest requestForResponse: quitResponse withUrlRequest:[hMan newQuitAppRequest]];
|
||||||
|
|
||||||
@ -700,7 +704,7 @@ static NSMutableSet* hostList;
|
|||||||
// Set up crypto
|
// Set up crypto
|
||||||
[CryptoManager generateKeyPairUsingSSL];
|
[CryptoManager generateKeyPairUsingSSL];
|
||||||
_uniqueId = [IdManager getUniqueId];
|
_uniqueId = [IdManager getUniqueId];
|
||||||
_cert = [CryptoManager readCertFromFile];
|
_clientCert = [CryptoManager readCertFromFile];
|
||||||
|
|
||||||
_appManager = [[AppAssetManager alloc] initWithCallback:self];
|
_appManager = [[AppAssetManager alloc] initWithCallback:self];
|
||||||
_opQueue = [[NSOperationQueue alloc] init];
|
_opQueue = [[NSOperationQueue alloc] init];
|
||||||
|
@ -165,6 +165,7 @@
|
|||||||
98132E8C20BC9A62007A053F /* Moonlight v1.1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.1.xcdatamodel"; sourceTree = "<group>"; };
|
98132E8C20BC9A62007A053F /* Moonlight v1.1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.1.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
9832D1341BBCD5C50036EF48 /* TemporaryApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TemporaryApp.h; path = Database/TemporaryApp.h; sourceTree = "<group>"; };
|
9832D1341BBCD5C50036EF48 /* TemporaryApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TemporaryApp.h; path = Database/TemporaryApp.h; sourceTree = "<group>"; };
|
||||||
9832D1351BBCD5C50036EF48 /* TemporaryApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TemporaryApp.m; path = Database/TemporaryApp.m; sourceTree = "<group>"; };
|
9832D1351BBCD5C50036EF48 /* TemporaryApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TemporaryApp.m; path = Database/TemporaryApp.m; sourceTree = "<group>"; };
|
||||||
|
98517B1B21CE0A9000481377 /* Moonlight v1.3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.3.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
9865DC3B2132922E0005B9B9 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS11.4.sdk/System/Library/Frameworks/GameController.framework; sourceTree = DEVELOPER_DIR; };
|
9865DC3B2132922E0005B9B9 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS11.4.sdk/System/Library/Frameworks/GameController.framework; sourceTree = DEVELOPER_DIR; };
|
||||||
986CCE6C2133E45300168291 /* Moonlight v1.2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.2.xcdatamodel"; sourceTree = "<group>"; };
|
986CCE6C2133E45300168291 /* Moonlight v1.2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.2.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
98878AE0206A226D00586E90 /* OSPortabilityDefs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSPortabilityDefs.h; sourceTree = "<group>"; };
|
98878AE0206A226D00586E90 /* OSPortabilityDefs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSPortabilityDefs.h; sourceTree = "<group>"; };
|
||||||
@ -1504,6 +1505,7 @@
|
|||||||
FB290D0519B2C406004C83CF /* Limelight.xcdatamodeld */ = {
|
FB290D0519B2C406004C83CF /* Limelight.xcdatamodeld */ = {
|
||||||
isa = XCVersionGroup;
|
isa = XCVersionGroup;
|
||||||
children = (
|
children = (
|
||||||
|
98517B1B21CE0A9000481377 /* Moonlight v1.3.xcdatamodel */,
|
||||||
986CCE6C2133E45300168291 /* Moonlight v1.2.xcdatamodel */,
|
986CCE6C2133E45300168291 /* Moonlight v1.2.xcdatamodel */,
|
||||||
98132E8C20BC9A62007A053F /* Moonlight v1.1.xcdatamodel */,
|
98132E8C20BC9A62007A053F /* Moonlight v1.1.xcdatamodel */,
|
||||||
FB53E1441BE5DCBC00CD6ECE /* Moonlight v1.0-2.xcdatamodel */,
|
FB53E1441BE5DCBC00CD6ECE /* Moonlight v1.0-2.xcdatamodel */,
|
||||||
@ -1512,7 +1514,7 @@
|
|||||||
FB4678F21A51BDCB00377732 /* Limelight 0.3.0.xcdatamodel */,
|
FB4678F21A51BDCB00377732 /* Limelight 0.3.0.xcdatamodel */,
|
||||||
FB290D0619B2C406004C83CF /* Limelight.xcdatamodel */,
|
FB290D0619B2C406004C83CF /* Limelight.xcdatamodel */,
|
||||||
);
|
);
|
||||||
currentVersion = 986CCE6C2133E45300168291 /* Moonlight v1.2.xcdatamodel */;
|
currentVersion = 98517B1B21CE0A9000481377 /* Moonlight v1.3.xcdatamodel */;
|
||||||
path = Limelight.xcdatamodeld;
|
path = Limelight.xcdatamodeld;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
versionGroupType = wrapper.xcdatamodel;
|
versionGroupType = wrapper.xcdatamodel;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user