Fix credential storage on tvOS

This commit is contained in:
Cameron Gutman
2018-08-27 00:34:34 -07:00
parent 44550baaa9
commit 450960eaaf
7 changed files with 77 additions and 59 deletions
+1 -1
View File
@@ -8,7 +8,7 @@
@interface CryptoManager : NSObject @interface CryptoManager : NSObject
+ (void) generateKeyPairUsingSSl; + (void) generateKeyPairUsingSSL;
+ (NSData*) readCertFromFile; + (NSData*) readCertFromFile;
+ (NSData*) readKeyFromFile; + (NSData*) readKeyFromFile;
+ (NSData*) readP12FromFile; + (NSData*) readP12FromFile;
+73 -39
View File
@@ -159,47 +159,53 @@ static NSData* p12 = nil;
return signedData; return signedData;
} }
// TODO: these three methods are almost identical, fix the copy-pasta + (NSData*) readCryptoObject:(NSString*)item {
#if TARGET_OS_TV
return [[NSUserDefaults standardUserDefaults] dataForKey:item];
#else
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *file = [documentsDirectory stringByAppendingPathComponent:item];
return [NSData dataWithContentsOfFile:file];
#endif
}
+ (void) writeCryptoObject:(NSString*)item data:(NSData*)data {
#if TARGET_OS_TV
[[NSUserDefaults standardUserDefaults] setObject:data forKey:item];
#else
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *file = [documentsDirectory stringByAppendingPathComponent:item];
[data writeToFile:file atomically:NO];
#endif
}
+ (NSData*) readCertFromFile { + (NSData*) readCertFromFile {
if (cert == nil) { if (cert == nil) {
NSArray *paths = [CryptoManager getPaths]; cert = [CryptoManager readCryptoObject:@"client.crt"];
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *certFile = [documentsDirectory stringByAppendingPathComponent:@"client.crt"];
cert = [NSData dataWithContentsOfFile:certFile];
} }
return cert; return cert;
} }
+ (NSData*) readP12FromFile { + (NSData*) readP12FromFile {
if (p12 == nil) { if (p12 == nil) {
NSArray *paths = [CryptoManager getPaths]; p12 = [CryptoManager readCryptoObject:@"client.p12"];
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *p12File = [documentsDirectory stringByAppendingPathComponent:@"client.p12"];
p12 = [NSData dataWithContentsOfFile:p12File];
} }
return p12; return p12;
} }
+ (NSData*) readKeyFromFile { + (NSData*) readKeyFromFile {
if (key == nil) { if (key == nil) {
NSArray *paths = [CryptoManager getPaths]; key = [CryptoManager readCryptoObject:@"client.key"];
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *keyFile = [documentsDirectory stringByAppendingPathComponent:@"client.key"];
key = [NSData dataWithContentsOfFile:keyFile];
} }
return key; return key;
} }
+ (bool) keyPairExists { + (bool) keyPairExists {
NSArray *paths = [CryptoManager getPaths]; bool keyFileExists = [CryptoManager readCryptoObject:@"client.key"] != nil;
NSString *documentsDirectory = [paths objectAtIndex:0]; bool p12FileExists = [CryptoManager readCryptoObject:@"client.p12"] != nil;
NSString *keyFile = [documentsDirectory stringByAppendingPathComponent:@"client.key"]; bool certFileExists = [CryptoManager readCryptoObject:@"client.crt"] != nil;
NSString *p12File = [documentsDirectory stringByAppendingPathComponent:@"client.p12"];
NSString *certFile = [documentsDirectory stringByAppendingPathComponent:@"client.crt"];
bool keyFileExists = [[NSFileManager defaultManager] fileExistsAtPath:keyFile];
bool p12FileExists = [[NSFileManager defaultManager] fileExistsAtPath:p12File];
bool certFileExists = [[NSFileManager defaultManager] fileExistsAtPath:certFile];
return keyFileExists && p12FileExists && certFileExists; return keyFileExists && p12FileExists && certFileExists;
} }
@@ -218,34 +224,62 @@ static NSData* p12 = nil;
return [NSData dataWithBytes:x509->signature->data length:x509->signature->length]; return [NSData dataWithBytes:x509->signature->data length:x509->signature->length];
} }
+ (void) generateKeyPairUsingSSl { + (NSData*)getKeyFromCertKeyPair:(CertKeyPair*)certKeyPair {
BIO* bio = BIO_new(BIO_s_mem());
PEM_write_bio_PrivateKey(bio, certKeyPair->pkey, NULL, NULL, 0, NULL, NULL);
BUF_MEM* mem;
BIO_get_mem_ptr(bio, &mem);
NSData* data = [NSData dataWithBytes:mem->data length:mem->length];
BIO_free(bio);
return data;
}
+ (NSData*)getP12FromCertKeyPair:(CertKeyPair*)certKeyPair {
BIO* bio = BIO_new(BIO_s_mem());
i2d_PKCS12_bio(bio, certKeyPair->p12);
BUF_MEM* mem;
BIO_get_mem_ptr(bio, &mem);
NSData* data = [NSData dataWithBytes:mem->data length:mem->length];
BIO_free(bio);
return data;
}
+ (NSData*)getCertFromCertKeyPair:(CertKeyPair*)certKeyPair {
BIO* bio = BIO_new(BIO_s_mem());
PEM_write_bio_X509(bio, certKeyPair->x509);
BUF_MEM* mem;
BIO_get_mem_ptr(bio, &mem);
NSData* data = [NSData dataWithBytes:mem->data length:mem->length];
BIO_free(bio);
return data;
}
+ (void) generateKeyPairUsingSSL {
static dispatch_once_t pred; static dispatch_once_t pred;
dispatch_once(&pred, ^{ dispatch_once(&pred, ^{
if (![CryptoManager keyPairExists]) { if (![CryptoManager keyPairExists]) {
Log(LOG_I, @"Generating Certificate... "); Log(LOG_I, @"Generating Certificate... ");
CertKeyPair certKeyPair = generateCertKeyPair(); CertKeyPair certKeyPair = generateCertKeyPair();
NSArray* paths = [CryptoManager getPaths]; NSData* certData = [CryptoManager getCertFromCertKeyPair:&certKeyPair];
NSString* documentsDirectory = [paths objectAtIndex:0]; NSData* p12Data = [CryptoManager getP12FromCertKeyPair:&certKeyPair];
NSString* certFile = [documentsDirectory stringByAppendingPathComponent:@"client.crt"]; NSData* keyData = [CryptoManager getKeyFromCertKeyPair:&certKeyPair];
NSString* keyPairFile = [documentsDirectory stringByAppendingPathComponent:@"client.key"];
NSString* p12File = [documentsDirectory stringByAppendingPathComponent:@"client.p12"];
//Log(LOG_D, @"Writing cert and key to: \n%@\n%@", certFile, keyPairFile);
saveCertKeyPair([certFile UTF8String], [p12File UTF8String], [keyPairFile UTF8String], certKeyPair);
freeCertKeyPair(certKeyPair); freeCertKeyPair(certKeyPair);
[CryptoManager writeCryptoObject:@"client.crt" data:certData];
[CryptoManager writeCryptoObject:@"client.p12" data:p12Data];
[CryptoManager writeCryptoObject:@"client.key" data:keyData];
Log(LOG_I, @"Certificate created"); Log(LOG_I, @"Certificate created");
} }
}); });
} }
+ (NSArray*) getPaths {
#if TARGET_OS_TV
return NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
#else
return NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
#endif
}
@end @end
-15
View File
@@ -62,21 +62,6 @@ void freeCertKeyPair(struct CertKeyPair certKeyPair) {
PKCS12_free(certKeyPair.p12); PKCS12_free(certKeyPair.p12);
} }
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);
}
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) {
X509 *x; X509 *x;
EVP_PKEY *pk; EVP_PKEY *pk;
-1
View File
@@ -20,6 +20,5 @@ typedef struct CertKeyPair {
struct CertKeyPair generateCertKeyPair(void); struct CertKeyPair generateCertKeyPair(void);
void freeCertKeyPair(CertKeyPair); void freeCertKeyPair(CertKeyPair);
void saveCertKeyPair(const char* certFile, const char* p12File, const char* keyPairFile, CertKeyPair certKeyPair);
#endif #endif
+1 -1
View File
@@ -41,7 +41,7 @@
_opQueue = [[NSOperationQueue alloc] init]; _opQueue = [[NSOperationQueue alloc] init];
_mdnsMan = [[MDNSManager alloc] initWithCallback:self]; _mdnsMan = [[MDNSManager alloc] initWithCallback:self];
[CryptoManager generateKeyPairUsingSSl]; [CryptoManager generateKeyPairUsingSSL];
_uniqueId = [IdManager getUniqueId]; _uniqueId = [IdManager getUniqueId];
_cert = [CryptoManager readCertFromFile]; _cert = [CryptoManager readCertFromFile];
return self; return self;
+1 -1
View File
@@ -36,7 +36,7 @@
} }
- (void)main { - (void)main {
[CryptoManager generateKeyPairUsingSSl]; [CryptoManager generateKeyPairUsingSSL];
NSString* uniqueId = [IdManager getUniqueId]; NSString* uniqueId = [IdManager getUniqueId];
NSData* cert = [CryptoManager readCertFromFile]; NSData* cert = [CryptoManager readCertFromFile];
@@ -704,7 +704,7 @@ static NSMutableSet* hostList;
currentPosition = FrontViewPositionLeft; currentPosition = FrontViewPositionLeft;
// Set up crypto // Set up crypto
[CryptoManager generateKeyPairUsingSSl]; [CryptoManager generateKeyPairUsingSSL];
_uniqueId = [IdManager getUniqueId]; _uniqueId = [IdManager getUniqueId];
_cert = [CryptoManager readCertFromFile]; _cert = [CryptoManager readCertFromFile];