diff --git a/VideoCalls/NCSettingsController.h b/VideoCalls/NCSettingsController.h index 726e6b46..2395af92 100644 --- a/VideoCalls/NCSettingsController.h +++ b/VideoCalls/NCSettingsController.h @@ -16,6 +16,8 @@ extern NSString * const kNCUserKey; extern NSString * const kNCUserDisplayNameKey; extern NSString * const kNCTokenKey; extern NSString * const kNCPushTokenKey; +extern NSString * const kNCPNPublicKey; +extern NSString * const kNCPNPrivateKey; @interface NCSettingsController : NSObject @@ -25,6 +27,8 @@ extern NSString * const kNCPushTokenKey; @property (nonatomic, copy) NSString *ncUserDisplayName; @property (nonatomic, copy) NSString *ncToken; @property (nonatomic, copy) NSString *ncPushToken; +@property (nonatomic, copy) NSData *ncPNPublicKey; +@property (nonatomic, copy) NSData *ncPNPrivateKey; + (instancetype)sharedInstance; - (void)cleanAllStoredValues; diff --git a/VideoCalls/NCSettingsController.m b/VideoCalls/NCSettingsController.m index 61a0dfc3..f129d6e3 100644 --- a/VideoCalls/NCSettingsController.m +++ b/VideoCalls/NCSettingsController.m @@ -8,6 +8,11 @@ #import "NCSettingsController.h" +#import +#import +#import +#import + #import "NCAPIController.h" @implementation NCSettingsController @@ -17,6 +22,8 @@ NSString * const kNCUserKey = @"ncUser"; NSString * const kNCUserDisplayNameKey = @"ncUserDisplayName"; NSString * const kNCTokenKey = @"ncToken"; NSString * const kNCPushTokenKey = @"ncPushToken"; +NSString * const kNCPNPublicKey = @"ncPNPublicKey"; +NSString * const kNCPNPrivateKey = @"ncPNPrivateKey"; + (NCSettingsController *)sharedInstance { @@ -44,6 +51,12 @@ NSString * const kNCPushTokenKey = @"ncPushToken"; _ncUserDisplayName = [UICKeyChainStore stringForKey:kNCUserDisplayNameKey]; _ncToken = [UICKeyChainStore stringForKey:kNCTokenKey]; _ncPushToken = [UICKeyChainStore stringForKey:kNCPushTokenKey]; + _ncPNPublicKey = [UICKeyChainStore dataForKey:kNCPNPublicKey]; + _ncPNPrivateKey = [UICKeyChainStore dataForKey:kNCPNPrivateKey]; + + if (!_ncPNPublicKey) { + [self generatePushNotificationsKeyPair]; + } } - (void)cleanAllStoredValues @@ -53,6 +66,8 @@ NSString * const kNCPushTokenKey = @"ncPushToken"; _ncUserDisplayName = nil; _ncToken = nil; _ncPushToken = nil; + _ncPNPublicKey = nil; + _ncPNPrivateKey = nil; [UICKeyChainStore removeAllItems]; @@ -60,4 +75,75 @@ NSString * const kNCPushTokenKey = @"ncPushToken"; [[NCAPIController sharedInstance] setAuthHeaderWithUser:NULL andToken:NULL]; } +- (BOOL)generatePushNotificationsKeyPair +{ + EVP_PKEY *pkey; + NSError *keyError; + pkey = [self generateRSAKey:&keyError]; + if (keyError) { + return NO; + } + + // Extract publicKey, privateKey + int len; + char *keyBytes; + + // PublicKey + BIO *publicKeyBIO = BIO_new(BIO_s_mem()); + PEM_write_bio_PUBKEY(publicKeyBIO, pkey); + + len = BIO_pending(publicKeyBIO); + keyBytes = malloc(len); + + BIO_read(publicKeyBIO, keyBytes, len); + _ncPNPublicKey = [NSData dataWithBytes:keyBytes length:len]; + [UICKeyChainStore setData:_ncPNPublicKey forKey:kNCPNPublicKey]; + NSLog(@"Push Notifications Key Pair generated: \n%@", [[NSString alloc] initWithData:_ncPNPublicKey encoding:NSUTF8StringEncoding]); + + // PrivateKey + BIO *privateKeyBIO = BIO_new(BIO_s_mem()); + PEM_write_bio_PKCS8PrivateKey(privateKeyBIO, pkey, NULL, NULL, 0, NULL, NULL); + + len = BIO_pending(privateKeyBIO); + keyBytes = malloc(len); + + BIO_read(privateKeyBIO, keyBytes, len); + _ncPNPrivateKey = [NSData dataWithBytes:keyBytes length:len]; + [UICKeyChainStore setData:_ncPNPrivateKey forKey:kNCPNPrivateKey]; + + EVP_PKEY_free(pkey); + + return YES; +} + +- (EVP_PKEY *)generateRSAKey:(NSError **)error +{ + EVP_PKEY *pkey = EVP_PKEY_new(); + if (!pkey) { + return NULL; + } + + BIGNUM *bigNumber = BN_new(); + int exponent = RSA_F4; + RSA *rsa = RSA_new(); + + if (BN_set_word(bigNumber, exponent) < 0) { + goto cleanup; + } + + if (RSA_generate_key_ex(rsa, 2048, bigNumber, NULL) < 0) { + goto cleanup; + } + + if (!EVP_PKEY_set1_RSA(pkey, rsa)) { + goto cleanup; + } + +cleanup: + RSA_free(rsa); + BN_free(bigNumber); + + return pkey; +} + @end