mirror of
https://github.com/moonlight-stream/moonlight-ios.git
synced 2026-04-08 17:06:09 +00:00
initial pairing works
This commit is contained in:
@@ -8,10 +8,11 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface CryptoManager : NSObject <NSURLConnectionDelegate>
|
||||
|
||||
- (void) generateKeyPairUsingSSl;
|
||||
- (NSString*) getUniqueID;
|
||||
- (NSData*) readCertFromFile;
|
||||
@interface CryptoManager : NSObject
|
||||
|
||||
+ (void) generateKeyPairUsingSSl;
|
||||
+ (NSString*) getUniqueID;
|
||||
+ (NSData*) readCertFromFile;
|
||||
+ (NSData*) readKeyFromFile;
|
||||
+ (NSData*) readP12FromFile;
|
||||
@end
|
||||
|
||||
@@ -12,33 +12,44 @@
|
||||
|
||||
@implementation CryptoManager
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (NSData*) readCertFromFile {
|
||||
// TODO: these three methods are almost identical, fix the copy-pasta
|
||||
+ (NSData*) readCertFromFile {
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
NSString *documentsDirectory = [paths objectAtIndex:0];
|
||||
NSString *certFile = [documentsDirectory stringByAppendingPathComponent:@"client.crt"];
|
||||
return [NSData dataWithContentsOfFile:certFile];
|
||||
}
|
||||
|
||||
- (void) generateKeyPairUsingSSl {
|
||||
NSLog(@"Generating Certificate: ");
|
||||
CertKeyPair certKeyPair = generateCertKeyPair();
|
||||
|
||||
+ (NSData*) readP12FromFile {
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
NSString *documentsDirectory = [paths objectAtIndex:0];
|
||||
NSString *certFile = [documentsDirectory stringByAppendingPathComponent:@"client.crt"];
|
||||
NSString *keyPairFile = [documentsDirectory stringByAppendingPathComponent:@"client.key"];
|
||||
NSString *p12File = [documentsDirectory stringByAppendingPathComponent:@"client.p12"];
|
||||
return [NSData dataWithContentsOfFile:p12File];
|
||||
}
|
||||
|
||||
+ (NSData*) readKeyFromFile {
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
NSString *documentsDirectory = [paths objectAtIndex:0];
|
||||
NSString *keyFile = [documentsDirectory stringByAppendingPathComponent:@"client.key"];
|
||||
return [NSData dataWithContentsOfFile:keyFile];
|
||||
}
|
||||
|
||||
+ (void) generateKeyPairUsingSSl {
|
||||
NSLog(@"Generating Certificate... ");
|
||||
CertKeyPair certKeyPair = generateCertKeyPair();
|
||||
|
||||
NSLog(@"Writing cert and key to: \n%@\n%@", certFile, keyPairFile);
|
||||
saveCertKeyPair([certFile UTF8String], [keyPairFile UTF8String], certKeyPair);
|
||||
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
NSString* documentsDirectory = [paths objectAtIndex:0];
|
||||
NSString* certFile = [documentsDirectory stringByAppendingPathComponent:@"client.crt"];
|
||||
NSString* keyPairFile = [documentsDirectory stringByAppendingPathComponent:@"client.key"];
|
||||
NSString* p12File = [documentsDirectory stringByAppendingPathComponent:@"client.p12"];
|
||||
|
||||
//NSLog(@"Writing cert and key to: \n%@\n%@", certFile, keyPairFile);
|
||||
saveCertKeyPair([certFile UTF8String], [p12File UTF8String], [keyPairFile UTF8String], certKeyPair);
|
||||
freeCertKeyPair(certKeyPair);
|
||||
}
|
||||
|
||||
- (NSString*) getUniqueID {
|
||||
+ (NSString*) getUniqueID {
|
||||
// generate a UUID
|
||||
NSUUID* uuid = [ASIdentifierManager sharedManager].advertisingIdentifier;
|
||||
NSString* idString = [NSString stringWithString:[uuid UUIDString]];
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface HttpManager : NSObject
|
||||
- (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId deviceName:(NSString*) deviceName;
|
||||
@interface HttpManager : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate>
|
||||
- (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId deviceName:(NSString*) deviceName cert:(NSData*) cert;
|
||||
- (NSString*) generatePIN;
|
||||
- (NSData*) saltPIN:(NSString*)PIN;
|
||||
- (NSURL*) newPairRequestWithSalt:(NSData*)salt andCert:(NSData*)cert;
|
||||
- (NSURL*) newPairRequest;
|
||||
@end
|
||||
|
||||
@@ -7,32 +7,36 @@
|
||||
//
|
||||
|
||||
#import "HttpManager.h"
|
||||
#import "CryptoManager.h"
|
||||
|
||||
@implementation HttpManager {
|
||||
NSString* _baseURL;
|
||||
NSString* _host;
|
||||
NSString* _uniqueId;
|
||||
NSString* _deviceName;
|
||||
NSData* _salt;
|
||||
NSData* _cert;
|
||||
}
|
||||
|
||||
static const NSString* PORT = @"47984";
|
||||
|
||||
|
||||
- (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId deviceName:(NSString*) deviceName {
|
||||
- (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId deviceName:(NSString*) deviceName cert:(NSData*) cert {
|
||||
self = [super init];
|
||||
_host = host;
|
||||
_uniqueId = uniqueId;
|
||||
_deviceName = deviceName;
|
||||
_cert = cert;
|
||||
_baseURL = [[NSString stringWithFormat:@"https://%@:%@", host, PORT]
|
||||
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSURL*) newPairRequestWithSalt:(NSData*)salt andCert:(NSData*)cert {
|
||||
NSLog(@"host: %@ \nport: %@ \nuniqueID: %@ \ndeviceName: %@ \nsalt: %@ \ncert: %@", _host, PORT, _uniqueId, _deviceName, salt, cert);
|
||||
NSString* urlString = [[NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&phrase=getservercert&salt=%@&clientcert=%@", _baseURL, _uniqueId, _deviceName, [self bytesToHex:salt], [self bytesToHex:cert]] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
- (NSURL*) newPairRequest {
|
||||
//NSLog(@"host: %@ \nport: %@ \nuniqueID: %@ \ndeviceName: %@ \nsalt: %@ \ncert: %@", _host, PORT, _uniqueId, _deviceName, salt, cert);
|
||||
NSString* urlString = [[NSString stringWithFormat:@"%@/pair?uniqueid=%@&devicename=%@&updateState=1&phrase=getservercert&salt=%@&clientcert=%@", _baseURL, _uniqueId, _deviceName, [self bytesToHex:_salt], [self bytesToHex:_cert]] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
NSURL* url = [[NSURL alloc] initWithString:urlString];
|
||||
NSLog(@"pair url: %@", url);
|
||||
//NSLog(@"pair url: %@", url);
|
||||
return url;
|
||||
}
|
||||
|
||||
@@ -58,8 +62,8 @@ static const NSString* PORT = @"47984";
|
||||
[saltedPIN appendData:[self randomBytes:16]];
|
||||
[saltedPIN appendBytes:[PIN UTF8String] length:4];
|
||||
|
||||
NSLog(@"Salted PIN: %@", [saltedPIN description]);
|
||||
|
||||
//NSLog(@"Salted PIN: %@", [saltedPIN description]);
|
||||
_salt = saltedPIN;
|
||||
return saltedPIN;
|
||||
}
|
||||
|
||||
@@ -71,4 +75,77 @@ static const NSString* PORT = @"47984";
|
||||
return randomData;
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
|
||||
NSLog(@"Received response: %@", response);
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
|
||||
NSLog(@"Received data: %@", data);
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
|
||||
SecIdentityRef identity = [self getClientCertificate]; // Go get a SecIdentityRef
|
||||
CFArrayRef certs = [self getCertificate:identity]; // Get an array of certificates
|
||||
// Convert the CFArrayRef to a NSArray
|
||||
NSArray *myArray = (__bridge NSArray *)certs;
|
||||
|
||||
// Create the NSURLCredential
|
||||
NSURLCredential *newCredential = [NSURLCredential credentialWithIdentity:identity certificates:myArray persistence:NSURLCredentialPersistencePermanent];
|
||||
|
||||
// Send
|
||||
[challenge.sender useCredential:newCredential forAuthenticationChallenge:challenge];
|
||||
}
|
||||
|
||||
// Returns an array containing the certificate
|
||||
- (CFArrayRef)getCertificate:(SecIdentityRef) identity {
|
||||
SecCertificateRef certificate = nil;
|
||||
|
||||
SecIdentityCopyCertificate(identity, &certificate);
|
||||
SecCertificateRef certs[1] = { certificate };
|
||||
|
||||
CFArrayRef array = CFArrayCreate(NULL, (const void **) certs, 1, NULL);
|
||||
|
||||
SecPolicyRef myPolicy = SecPolicyCreateBasicX509();
|
||||
SecTrustRef myTrust;
|
||||
|
||||
OSStatus status = SecTrustCreateWithCertificates(array, myPolicy, &myTrust);
|
||||
if (status == noErr) {
|
||||
NSLog(@"No Err creating certificate");
|
||||
} else {
|
||||
NSLog(@"Possible Err Creating certificate");
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
// Returns the identity
|
||||
- (SecIdentityRef)getClientCertificate {
|
||||
SecIdentityRef identityApp = nil;
|
||||
NSData *PKCS12Data = [CryptoManager readP12FromFile];
|
||||
CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data;
|
||||
|
||||
CFStringRef password = CFSTR("limelight"); // no password
|
||||
const void *keys[] = { kSecImportExportPassphrase };//kSecImportExportPassphrase };
|
||||
const void *values[] = { password };
|
||||
CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
|
||||
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
|
||||
OSStatus securityError = SecPKCS12Import(inPKCS12Data, options, &items);
|
||||
|
||||
if (securityError == errSecSuccess) {
|
||||
NSLog(@"Success opening p12 certificate. Items: %ld", CFArrayGetCount(items));
|
||||
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
|
||||
identityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity);
|
||||
} else {
|
||||
NSLog(@"Error opening Certificate.");
|
||||
}
|
||||
|
||||
CFRelease(options);
|
||||
CFRelease(password);
|
||||
|
||||
return identityApp;
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
|
||||
NSLog(@"connection error: %@", error);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#import "HttpManager.h"
|
||||
|
||||
@implementation MainFrameViewController
|
||||
NSString* hostAddr;
|
||||
NSString* hostAddr = @"cement-truck.case.edu";
|
||||
MDNSManager* mDNSManager;
|
||||
|
||||
+ (const char*)getHostAddr
|
||||
@@ -87,20 +87,20 @@ MDNSManager* mDNSManager;
|
||||
self.hostPickerVals = [[NSArray alloc] init];
|
||||
|
||||
mDNSManager = [[MDNSManager alloc] initWithCallback:self];
|
||||
[mDNSManager searchForHosts];
|
||||
CryptoManager* cryptMan = [[CryptoManager alloc] init];
|
||||
NSString* uniqueId = [cryptMan getUniqueID];
|
||||
[cryptMan generateKeyPairUsingSSl];
|
||||
NSData* cert = [cryptMan readCertFromFile];
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:hostAddr uniqueId:uniqueId deviceName:@"roth"];
|
||||
//[mDNSManager searchForHosts];
|
||||
|
||||
[CryptoManager generateKeyPairUsingSSl];
|
||||
NSString* uniqueId = [CryptoManager getUniqueID];
|
||||
NSData* cert = [CryptoManager readCertFromFile];
|
||||
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:hostAddr uniqueId:uniqueId deviceName:@"roth" cert:cert];
|
||||
NSString* PIN = [hMan generatePIN];
|
||||
NSData* saltedPIN = [hMan saltPIN:PIN];
|
||||
NSLog(@"PIN: %@, saltedPIN: %@", PIN, saltedPIN);
|
||||
NSURL* pairUrl = [hMan newPairRequestWithSalt:saltedPIN andCert:cert];
|
||||
NSURL* pairUrl = [hMan newPairRequest];
|
||||
NSURLRequest* pairRequest = [[NSURLRequest alloc] initWithURL:pairUrl];
|
||||
NSLog(@"making pair request: %@", [pairRequest description]);
|
||||
NSData* pairData = [NSURLConnection sendSynchronousRequest:pairRequest returningResponse:nil error:nil];
|
||||
NSLog(@"Pair response: %@", [pairData description]);
|
||||
// NSLog(@"making pair request: %@", [pairRequest description]);
|
||||
[NSURLConnection connectionWithRequest:pairRequest delegate:hMan];
|
||||
}
|
||||
|
||||
- (void)updateHosts:(NSArray *)hosts {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
#include <openssl/engine.h>
|
||||
@@ -13,7 +14,7 @@
|
||||
|
||||
static const int NUM_BITS = 2048;
|
||||
static const int SERIAL = 0;
|
||||
static const int NUM_YEARS = 20;
|
||||
static const int NUM_YEARS = 10;
|
||||
|
||||
int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int years);
|
||||
int add_ext(X509 *cert, int nid, char *value);
|
||||
@@ -22,12 +23,21 @@ struct CertKeyPair generateCertKeyPair() {
|
||||
BIO *bio_err;
|
||||
X509 *x509 = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
PKCS12 *p12 = NULL;
|
||||
|
||||
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
|
||||
|
||||
bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
|
||||
|
||||
mkcert(&x509, &pkey, NUM_BITS, SERIAL, NUM_YEARS);
|
||||
SSLeay_add_all_algorithms();
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
mkcert(&x509, &pkey, NUM_BITS, SERIAL, NUM_YEARS);
|
||||
|
||||
p12 = PKCS12_create("limelight", "GameStream", pkey, x509, NULL, 0, 0, 0, 0, 0);
|
||||
if (p12 == NULL) {
|
||||
printf("Error generating a valid PKCS12 certificate.\n");
|
||||
}
|
||||
|
||||
// Debug Print statements
|
||||
//RSA_print_fp(stdout, pkey->pkey.rsa, 0);
|
||||
//X509_print_fp(stdout, x509);
|
||||
@@ -43,21 +53,26 @@ struct CertKeyPair generateCertKeyPair() {
|
||||
CRYPTO_mem_leaks(bio_err);
|
||||
BIO_free(bio_err);
|
||||
|
||||
return (CertKeyPair){x509, pkey};
|
||||
return (CertKeyPair){x509, pkey, p12};
|
||||
}
|
||||
|
||||
void freeCertKeyPair(struct CertKeyPair certKeyPair) {
|
||||
X509_free(certKeyPair.x509);
|
||||
EVP_PKEY_free(certKeyPair.pkey);
|
||||
PKCS12_free(certKeyPair.p12);
|
||||
}
|
||||
|
||||
void saveCertKeyPair(const char* certFile, const char* keyPairFile, CertKeyPair certKeyPair) {
|
||||
void saveCertKeyPair(const char* certFile, const char* p12File, const char* keyPairFile, CertKeyPair certKeyPair) {
|
||||
FILE* certFilePtr = fopen(certFile, "w");
|
||||
FILE* keyPairFilePtr = fopen(keyPairFile, "w");
|
||||
FILE* p12FilePtr = fopen(p12File, "wb");
|
||||
|
||||
//TODO: error check
|
||||
PEM_write_PrivateKey(keyPairFilePtr, certKeyPair.pkey, NULL, NULL, 0, NULL, NULL);
|
||||
PEM_write_X509(certFilePtr, certKeyPair.x509);
|
||||
i2d_PKCS12_fp(p12FilePtr, certKeyPair.p12);
|
||||
|
||||
fclose(p12FilePtr);
|
||||
fclose(certFilePtr);
|
||||
fclose(keyPairFilePtr);
|
||||
}
|
||||
@@ -91,7 +106,7 @@ int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int years) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
X509_set_version(x, 3);
|
||||
X509_set_version(x, 2);
|
||||
ASN1_INTEGER_set(X509_get_serialNumber(x), serial);
|
||||
X509_gmtime_adj(X509_get_notBefore(x), 0);
|
||||
X509_gmtime_adj(X509_get_notAfter(x), (long)60*60*24*365*years);
|
||||
@@ -121,6 +136,7 @@ int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int years) {
|
||||
|
||||
*x509p = x;
|
||||
*pkeyp = pk;
|
||||
|
||||
return(1);
|
||||
err:
|
||||
return(0);
|
||||
|
||||
@@ -10,13 +10,16 @@
|
||||
#define Limelight_mkcert_h
|
||||
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
|
||||
typedef struct CertKeyPair {
|
||||
X509 *x509;
|
||||
EVP_PKEY *pkey;
|
||||
PKCS12 *p12;
|
||||
} CertKeyPair;
|
||||
|
||||
struct CertKeyPair generateCertKeyPair();
|
||||
void freeCertKeyPair(CertKeyPair);
|
||||
void saveCertKeyPair(const char* certFile, const char* keyPairFile, CertKeyPair certKeyPair);
|
||||
void saveCertKeyPair(const char* certFile, const char* p12File, const char* keyPairFile, CertKeyPair certKeyPair);
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user