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

View File

@@ -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

View File

@@ -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]];

View File

@@ -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

View File

@@ -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

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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