NCPushNotificationEncryption.m 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. //
  2. // NCPushNotificationEncryption.m
  3. // Nextcloud
  4. //
  5. // Created by Marino Faggiana on 25/07/18.
  6. // Copyright © 2018 Marino Faggiana. All rights reserved.
  7. //
  8. // Author Marino Faggiana <marino.faggiana@nextcloud.com>
  9. //
  10. // This program is free software: you can redistribute it and/or modify
  11. // it under the terms of the GNU General Public License as published by
  12. // the Free Software Foundation, either version 3 of the License, or
  13. // (at your option) any later version.
  14. //
  15. // This program is distributed in the hope that it will be useful,
  16. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. // GNU General Public License for more details.
  19. //
  20. // You should have received a copy of the GNU General Public License
  21. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. //
  23. // This code derived from : Nextcloud Talk - NCSettingsController Created by Ivan Sein on 26.06.17. Copyright © 2017 struktur AG. All rights reserved.
  24. //
  25. #import "NCPushNotificationEncryption.h"
  26. #import "NCBridgeSwift.h"
  27. #import <OpenSSL/OpenSSL.h>
  28. #import <CommonCrypto/CommonDigest.h>
  29. #import "NCEndToEndEncryption.h"
  30. #import "CCUtility.h"
  31. @implementation NCPushNotificationEncryption
  32. + (NCPushNotificationEncryption *)shared
  33. {
  34. static dispatch_once_t once;
  35. static NCPushNotificationEncryption *shared;
  36. dispatch_once(&once, ^{
  37. shared = [[self alloc] init];
  38. });
  39. return shared;
  40. }
  41. - (id)init
  42. {
  43. self = [super init];
  44. if (self) {
  45. }
  46. return self;
  47. }
  48. - (BOOL)generatePushNotificationsKeyPair:(NSString *)account
  49. {
  50. int len;
  51. char *keyBytes;
  52. EVP_PKEY *pkey = EVP_PKEY_new();
  53. BIGNUM *bigNumber = BN_new();
  54. int exponent = RSA_F4;
  55. RSA *rsa = RSA_new();
  56. BN_set_word(bigNumber, exponent);
  57. RSA_generate_key_ex(rsa, 2048, bigNumber, NULL);
  58. EVP_PKEY_set1_RSA(pkey, rsa);
  59. // PublicKey
  60. BIO *publicKeyBIO = BIO_new(BIO_s_mem());
  61. PEM_write_bio_PUBKEY(publicKeyBIO, pkey);
  62. len = BIO_pending(publicKeyBIO);
  63. keyBytes = malloc(len);
  64. BIO_read(publicKeyBIO, keyBytes, len);
  65. NSData *ncPNPublicKey = [NSData dataWithBytes:keyBytes length:len];
  66. [[[NCKeychain alloc] init] setPushNotificationPublicKeyWithAccount:account data:ncPNPublicKey];
  67. NSLog(@"Push Notifications Key Pair generated: \n%@", [[NSString alloc] initWithData:ncPNPublicKey encoding:NSUTF8StringEncoding]);
  68. // PrivateKey
  69. BIO *privateKeyBIO = BIO_new(BIO_s_mem());
  70. PEM_write_bio_PKCS8PrivateKey(privateKeyBIO, pkey, NULL, NULL, 0, NULL, NULL);
  71. len = BIO_pending(privateKeyBIO);
  72. keyBytes = malloc(len);
  73. BIO_read(privateKeyBIO, keyBytes, len);
  74. NSData *ncPNPrivateKey = [NSData dataWithBytes:keyBytes length:len];
  75. [[[NCKeychain alloc] init] setPushNotificationPrivateKeyWithAccount:account data:ncPNPrivateKey];
  76. RSA_free(rsa);
  77. BN_free(bigNumber);
  78. EVP_PKEY_free(pkey);
  79. return YES;
  80. }
  81. - (NSString *)decryptPushNotification:(NSString *)message withDevicePrivateKey:(NSData *)privateKey
  82. {
  83. if (message == nil || privateKey == nil) { return nil; }
  84. NSString *privateKeyString = [[NSString alloc] initWithData:privateKey encoding:NSUTF8StringEncoding];
  85. NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:message options:0];
  86. char *privKey = (char *)[privateKeyString UTF8String];
  87. // Get Device Private Key from PEM
  88. BIO *bio = BIO_new(BIO_s_mem());
  89. BIO_write(bio, privKey, (int)strlen(privKey));
  90. EVP_PKEY* pkey = 0;
  91. PEM_read_bio_PrivateKey(bio, &pkey, 0, 0);
  92. RSA* rsa = EVP_PKEY_get1_RSA(pkey);
  93. // Decrypt the message
  94. unsigned char *decrypted = (unsigned char *) malloc(4096);
  95. int decrypted_length = RSA_private_decrypt((int)[decodedData length], [decodedData bytes], decrypted, rsa, RSA_PKCS1_PADDING);
  96. if(decrypted_length == -1) {
  97. char buffer[500];
  98. ERR_error_string(ERR_get_error(), buffer);
  99. NSLog(@"%@",[NSString stringWithUTF8String:buffer]);
  100. return nil;
  101. }
  102. NSString *decryptString = [[NSString alloc] initWithBytes:decrypted length:decrypted_length encoding:NSUTF8StringEncoding];
  103. if (decrypted)
  104. free(decrypted);
  105. free(bio);
  106. free(rsa);
  107. return decryptString;
  108. }
  109. @end