initial pairing works

This commit is contained in:
Diego Waxemberg
2014-10-19 04:19:54 -04:00
parent 6225af1e76
commit 8ae0e4a547
7 changed files with 156 additions and 48 deletions
+6 -5
View File
@@ -8,10 +8,11 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@interface CryptoManager : NSObject <NSURLConnectionDelegate> @interface CryptoManager : NSObject
- (void) generateKeyPairUsingSSl;
- (NSString*) getUniqueID;
- (NSData*) readCertFromFile;
+ (void) generateKeyPairUsingSSl;
+ (NSString*) getUniqueID;
+ (NSData*) readCertFromFile;
+ (NSData*) readKeyFromFile;
+ (NSData*) readP12FromFile;
@end @end
+26 -15
View File
@@ -12,33 +12,44 @@
@implementation CryptoManager @implementation CryptoManager
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { // TODO: these three methods are almost identical, fix the copy-pasta
+ (NSData*) readCertFromFile {
}
- (NSData*) readCertFromFile {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *certFile = [documentsDirectory stringByAppendingPathComponent:@"client.crt"]; NSString *certFile = [documentsDirectory stringByAppendingPathComponent:@"client.crt"];
return [NSData dataWithContentsOfFile:certFile]; return [NSData dataWithContentsOfFile:certFile];
} }
- (void) generateKeyPairUsingSSl { + (NSData*) readP12FromFile {
NSLog(@"Generating Certificate: ");
CertKeyPair certKeyPair = generateCertKeyPair();
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *certFile = [documentsDirectory stringByAppendingPathComponent:@"client.crt"]; NSString *p12File = [documentsDirectory stringByAppendingPathComponent:@"client.p12"];
NSString *keyPairFile = [documentsDirectory stringByAppendingPathComponent:@"client.key"]; return [NSData dataWithContentsOfFile:p12File];
}
NSLog(@"Writing cert and key to: \n%@\n%@", certFile, keyPairFile); + (NSData*) readKeyFromFile {
saveCertKeyPair([certFile UTF8String], [keyPairFile UTF8String], certKeyPair); 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();
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); freeCertKeyPair(certKeyPair);
} }
- (NSString*) getUniqueID { + (NSString*) getUniqueID {
// generate a UUID // generate a UUID
NSUUID* uuid = [ASIdentifierManager sharedManager].advertisingIdentifier; NSUUID* uuid = [ASIdentifierManager sharedManager].advertisingIdentifier;
NSString* idString = [NSString stringWithString:[uuid UUIDString]]; NSString* idString = [NSString stringWithString:[uuid UUIDString]];
+3 -3
View File
@@ -8,9 +8,9 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@interface HttpManager : NSObject @interface HttpManager : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate>
- (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId deviceName:(NSString*) deviceName; - (id) initWithHost:(NSString*) host uniqueId:(NSString*) uniqueId deviceName:(NSString*) deviceName cert:(NSData*) cert;
- (NSString*) generatePIN; - (NSString*) generatePIN;
- (NSData*) saltPIN:(NSString*)PIN; - (NSData*) saltPIN:(NSString*)PIN;
- (NSURL*) newPairRequestWithSalt:(NSData*)salt andCert:(NSData*)cert; - (NSURL*) newPairRequest;
@end @end
+84 -7
View File
@@ -7,32 +7,36 @@
// //
#import "HttpManager.h" #import "HttpManager.h"
#import "CryptoManager.h"
@implementation HttpManager { @implementation HttpManager {
NSString* _baseURL; NSString* _baseURL;
NSString* _host; NSString* _host;
NSString* _uniqueId; NSString* _uniqueId;
NSString* _deviceName; NSString* _deviceName;
NSData* _salt;
NSData* _cert;
} }
static const NSString* PORT = @"47984"; 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]; self = [super init];
_host = host; _host = host;
_uniqueId = uniqueId; _uniqueId = uniqueId;
_deviceName = deviceName; _deviceName = deviceName;
_cert = cert;
_baseURL = [[NSString stringWithFormat:@"https://%@:%@", host, PORT] _baseURL = [[NSString stringWithFormat:@"https://%@:%@", host, PORT]
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return self; return self;
} }
- (NSURL*) newPairRequestWithSalt:(NSData*)salt andCert:(NSData*)cert { - (NSURL*) newPairRequest {
NSLog(@"host: %@ \nport: %@ \nuniqueID: %@ \ndeviceName: %@ \nsalt: %@ \ncert: %@", _host, PORT, _uniqueId, _deviceName, salt, 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]; 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]; NSURL* url = [[NSURL alloc] initWithString:urlString];
NSLog(@"pair url: %@", url); //NSLog(@"pair url: %@", url);
return url; return url;
} }
@@ -58,8 +62,8 @@ static const NSString* PORT = @"47984";
[saltedPIN appendData:[self randomBytes:16]]; [saltedPIN appendData:[self randomBytes:16]];
[saltedPIN appendBytes:[PIN UTF8String] length:4]; [saltedPIN appendBytes:[PIN UTF8String] length:4];
NSLog(@"Salted PIN: %@", [saltedPIN description]); //NSLog(@"Salted PIN: %@", [saltedPIN description]);
_salt = saltedPIN;
return saltedPIN; return saltedPIN;
} }
@@ -71,4 +75,77 @@ static const NSString* PORT = @"47984";
return randomData; 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 @end
+11 -11
View File
@@ -14,7 +14,7 @@
#import "HttpManager.h" #import "HttpManager.h"
@implementation MainFrameViewController @implementation MainFrameViewController
NSString* hostAddr; NSString* hostAddr = @"cement-truck.case.edu";
MDNSManager* mDNSManager; MDNSManager* mDNSManager;
+ (const char*)getHostAddr + (const char*)getHostAddr
@@ -87,20 +87,20 @@ MDNSManager* mDNSManager;
self.hostPickerVals = [[NSArray alloc] init]; self.hostPickerVals = [[NSArray alloc] init];
mDNSManager = [[MDNSManager alloc] initWithCallback:self]; mDNSManager = [[MDNSManager alloc] initWithCallback:self];
[mDNSManager searchForHosts]; //[mDNSManager searchForHosts];
CryptoManager* cryptMan = [[CryptoManager alloc] init];
NSString* uniqueId = [cryptMan getUniqueID]; [CryptoManager generateKeyPairUsingSSl];
[cryptMan generateKeyPairUsingSSl]; NSString* uniqueId = [CryptoManager getUniqueID];
NSData* cert = [cryptMan readCertFromFile]; NSData* cert = [CryptoManager readCertFromFile];
HttpManager* hMan = [[HttpManager alloc] initWithHost:hostAddr uniqueId:uniqueId deviceName:@"roth"];
HttpManager* hMan = [[HttpManager alloc] initWithHost:hostAddr uniqueId:uniqueId deviceName:@"roth" cert:cert];
NSString* PIN = [hMan generatePIN]; NSString* PIN = [hMan generatePIN];
NSData* saltedPIN = [hMan saltPIN:PIN]; NSData* saltedPIN = [hMan saltPIN:PIN];
NSLog(@"PIN: %@, saltedPIN: %@", PIN, saltedPIN); NSLog(@"PIN: %@, saltedPIN: %@", PIN, saltedPIN);
NSURL* pairUrl = [hMan newPairRequestWithSalt:saltedPIN andCert:cert]; NSURL* pairUrl = [hMan newPairRequest];
NSURLRequest* pairRequest = [[NSURLRequest alloc] initWithURL:pairUrl]; NSURLRequest* pairRequest = [[NSURLRequest alloc] initWithURL:pairUrl];
NSLog(@"making pair request: %@", [pairRequest description]); // NSLog(@"making pair request: %@", [pairRequest description]);
NSData* pairData = [NSURLConnection sendSynchronousRequest:pairRequest returningResponse:nil error:nil]; [NSURLConnection connectionWithRequest:pairRequest delegate:hMan];
NSLog(@"Pair response: %@", [pairData description]);
} }
- (void)updateHosts:(NSArray *)hosts { - (void)updateHosts:(NSArray *)hosts {
+21 -5
View File
@@ -6,6 +6,7 @@
#include <openssl/pem.h> #include <openssl/pem.h>
#include <openssl/conf.h> #include <openssl/conf.h>
#include <openssl/pkcs12.h>
#ifndef OPENSSL_NO_ENGINE #ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h> #include <openssl/engine.h>
@@ -13,7 +14,7 @@
static const int NUM_BITS = 2048; static const int NUM_BITS = 2048;
static const int SERIAL = 0; 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 mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int years);
int add_ext(X509 *cert, int nid, char *value); int add_ext(X509 *cert, int nid, char *value);
@@ -22,12 +23,21 @@ struct CertKeyPair generateCertKeyPair() {
BIO *bio_err; BIO *bio_err;
X509 *x509 = NULL; X509 *x509 = NULL;
EVP_PKEY *pkey = NULL; EVP_PKEY *pkey = NULL;
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); PKCS12 *p12 = NULL;
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
SSLeay_add_all_algorithms();
ERR_load_crypto_strings();
mkcert(&x509, &pkey, NUM_BITS, SERIAL, NUM_YEARS); 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 // Debug Print statements
//RSA_print_fp(stdout, pkey->pkey.rsa, 0); //RSA_print_fp(stdout, pkey->pkey.rsa, 0);
//X509_print_fp(stdout, x509); //X509_print_fp(stdout, x509);
@@ -43,21 +53,26 @@ struct CertKeyPair generateCertKeyPair() {
CRYPTO_mem_leaks(bio_err); CRYPTO_mem_leaks(bio_err);
BIO_free(bio_err); BIO_free(bio_err);
return (CertKeyPair){x509, pkey}; return (CertKeyPair){x509, pkey, p12};
} }
void freeCertKeyPair(struct CertKeyPair certKeyPair) { void freeCertKeyPair(struct CertKeyPair certKeyPair) {
X509_free(certKeyPair.x509); X509_free(certKeyPair.x509);
EVP_PKEY_free(certKeyPair.pkey); 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* certFilePtr = fopen(certFile, "w");
FILE* keyPairFilePtr = fopen(keyPairFile, "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_PrivateKey(keyPairFilePtr, certKeyPair.pkey, NULL, NULL, 0, NULL, NULL);
PEM_write_X509(certFilePtr, certKeyPair.x509); PEM_write_X509(certFilePtr, certKeyPair.x509);
i2d_PKCS12_fp(p12FilePtr, certKeyPair.p12);
fclose(p12FilePtr);
fclose(certFilePtr); fclose(certFilePtr);
fclose(keyPairFilePtr); fclose(keyPairFilePtr);
} }
@@ -91,7 +106,7 @@ int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int years) {
goto err; goto err;
} }
X509_set_version(x, 3); X509_set_version(x, 2);
ASN1_INTEGER_set(X509_get_serialNumber(x), serial); ASN1_INTEGER_set(X509_get_serialNumber(x), serial);
X509_gmtime_adj(X509_get_notBefore(x), 0); X509_gmtime_adj(X509_get_notBefore(x), 0);
X509_gmtime_adj(X509_get_notAfter(x), (long)60*60*24*365*years); 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; *x509p = x;
*pkeyp = pk; *pkeyp = pk;
return(1); return(1);
err: err:
return(0); return(0);
+4 -1
View File
@@ -10,13 +10,16 @@
#define Limelight_mkcert_h #define Limelight_mkcert_h
#include <openssl/x509v3.h> #include <openssl/x509v3.h>
#include <openssl/pkcs12.h>
typedef struct CertKeyPair { typedef struct CertKeyPair {
X509 *x509; X509 *x509;
EVP_PKEY *pkey; EVP_PKEY *pkey;
PKCS12 *p12;
} CertKeyPair; } CertKeyPair;
struct CertKeyPair generateCertKeyPair(); struct CertKeyPair generateCertKeyPair();
void freeCertKeyPair(CertKeyPair); 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 #endif