123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- //
- // NCPushNotificationEncryption.m
- // Nextcloud
- //
- // Created by Marino Faggiana on 25/07/18.
- // Copyright © 2018 Marino Faggiana. All rights reserved.
- //
- // Author Marino Faggiana <marino.faggiana@nextcloud.com>
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
- //
- // This code derived from : Nextcloud Talk - NCSettingsController Created by Ivan Sein on 26.06.17. Copyright © 2017 struktur AG. All rights reserved.
- //
- #import "NCPushNotificationEncryption.h"
- #import "NCBridgeSwift.h"
- #import <OpenSSL/OpenSSL.h>
- #import <CommonCrypto/CommonDigest.h>
- #import "NCEndToEndEncryption.h"
- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
- @implementation NCPushNotificationEncryption
- //Singleton
- + (instancetype)shared {
- static dispatch_once_t once;
- static NCPushNotificationEncryption *shared;
- dispatch_once(&once, ^{
- shared = [self new];
- });
- return shared;
- }
- - (BOOL)generatePushNotificationsKeyPair:(NSString *)account
- {
- EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
- if (!ctx) {
- return FALSE;
- }
- // Generate an new RSA KEY
- if (EVP_PKEY_keygen_init(ctx) <= 0) {
- EVP_PKEY_CTX_free(ctx);
- return FALSE;
- }
- if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0) {
- EVP_PKEY_CTX_free(ctx);
- return FALSE;
- }
- EVP_PKEY *pkey = NULL;
- if (EVP_PKEY_keygen(ctx, &pkey) <= 0) {
- EVP_PKEY_CTX_free(ctx);
- return FALSE;
- }
- // PublicKey
- BIO *publicKeyBIO = BIO_new(BIO_s_mem());
- PEM_write_bio_PUBKEY(publicKeyBIO, pkey);
-
- int len = BIO_pending(publicKeyBIO);
- char *keyBytes = malloc(len);
- BIO_read(publicKeyBIO, keyBytes, len);
- NSData *publicKey = [NSData dataWithBytes:keyBytes length:len];
- [[[NCKeychain alloc] init] setPushNotificationPublicKeyWithAccount:account data:publicKey];
- NSLog(@"Push Notifications public Key generated: \n%@", [[NSString alloc] initWithData:publicKey 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);
- NSData *privateKey = [NSData dataWithBytes:keyBytes length:len];
- [[[NCKeychain alloc] init] setPushNotificationPrivateKeyWithAccount:account data:privateKey];
- NSLog(@"Push Notifications private Key generated: \n%@", [[NSString alloc] initWithData:privateKey encoding:NSUTF8StringEncoding]);
- EVP_PKEY_free(pkey);
- EVP_PKEY_CTX_free(ctx);
- BIO_free(publicKeyBIO);
- BIO_free(privateKeyBIO);
- return YES;
- }
- - (NSString *)decryptPushNotification:(NSString *)message withDevicePrivateKey:(NSData *)privateKey
- {
- if (message == nil || privateKey == nil) { return nil; }
-
- NSString *privateKeyString = [[NSString alloc] initWithData:privateKey encoding:NSUTF8StringEncoding];
- NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:message options:0];
- char *privKey = (char *)[privateKeyString UTF8String];
-
- // Get Device Private Key from PEM
- BIO *bio = BIO_new(BIO_s_mem());
- BIO_write(bio, privKey, (int)strlen(privKey));
-
- EVP_PKEY *pkey = 0;
- PEM_read_bio_PrivateKey(bio, &pkey, 0, 0);
- RSA *rsa = EVP_PKEY_get1_RSA(pkey);
- // Decrypt the message
- unsigned char *decrypted = (unsigned char *) malloc(4096);
-
- int decrypted_length = RSA_private_decrypt((int)[decodedData length], [decodedData bytes], decrypted, rsa, RSA_PKCS1_PADDING);
- if(decrypted_length == -1) {
- char buffer[500];
- ERR_error_string(ERR_get_error(), buffer);
- NSLog(@"%@",[NSString stringWithUTF8String:buffer]);
- return nil;
- }
-
- NSString *decryptString = [[NSString alloc] initWithBytes:decrypted length:decrypted_length encoding:NSUTF8StringEncoding];
-
- if (decrypted)
- free(decrypted);
- free(bio);
- free(rsa);
-
- return decryptString;
- }
- - (NSString *)stringWithDeviceToken:(NSData *)deviceToken
- {
- const char *data = [deviceToken bytes];
- NSMutableString *token = [NSMutableString string];
- for (NSUInteger i = 0; i < [deviceToken length]; i++) {
- [token appendFormat:@"%02.2hhX", data[i]];
- }
- return [token copy];
- }
- @end
|