NCPushNotificationEncryption.m 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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 <OpenSSL/OpenSSL.h>
  27. #import <CommonCrypto/CommonDigest.h>
  28. #import "NCEndToEndEncryption.h"
  29. #import "CCUtility.h"
  30. @implementation NCPushNotificationEncryption
  31. + (NCPushNotificationEncryption *)sharedInstance
  32. {
  33. static dispatch_once_t once;
  34. static NCPushNotificationEncryption *sharedInstance;
  35. dispatch_once(&once, ^{
  36. sharedInstance = [[self alloc] init];
  37. });
  38. return sharedInstance;
  39. }
  40. - (id)init
  41. {
  42. self = [super init];
  43. if (self) {
  44. }
  45. return self;
  46. }
  47. - (BOOL)generatePushNotificationsKeyPair:(NSString *)account
  48. {
  49. int len;
  50. char *keyBytes;
  51. EVP_PKEY *pkey = EVP_PKEY_new();
  52. BIGNUM *bigNumber = BN_new();
  53. int exponent = RSA_F4;
  54. RSA *rsa = RSA_new();
  55. BN_set_word(bigNumber, exponent);
  56. RSA_generate_key_ex(rsa, 2048, bigNumber, NULL);
  57. EVP_PKEY_set1_RSA(pkey, rsa);
  58. // PublicKey
  59. BIO *publicKeyBIO = BIO_new(BIO_s_mem());
  60. PEM_write_bio_PUBKEY(publicKeyBIO, pkey);
  61. len = BIO_pending(publicKeyBIO);
  62. keyBytes = malloc(len);
  63. BIO_read(publicKeyBIO, keyBytes, len);
  64. NSData *ncPNPublicKey = [NSData dataWithBytes:keyBytes length:len];
  65. [CCUtility setPushNotificationPublicKey:account data:ncPNPublicKey];
  66. NSLog(@"Push Notifications Key Pair generated: \n%@", [[NSString alloc] initWithData:ncPNPublicKey encoding:NSUTF8StringEncoding]);
  67. // PrivateKey
  68. BIO *privateKeyBIO = BIO_new(BIO_s_mem());
  69. PEM_write_bio_PKCS8PrivateKey(privateKeyBIO, pkey, NULL, NULL, 0, NULL, NULL);
  70. len = BIO_pending(privateKeyBIO);
  71. keyBytes = malloc(len);
  72. BIO_read(privateKeyBIO, keyBytes, len);
  73. NSData *ncPNPrivateKey = [NSData dataWithBytes:keyBytes length:len];
  74. [CCUtility setPushNotificationPrivateKey:account data:ncPNPrivateKey];
  75. RSA_free(rsa);
  76. BN_free(bigNumber);
  77. EVP_PKEY_free(pkey);
  78. return YES;
  79. }
  80. - (NSString *)decryptPushNotification:(NSString *)message withDevicePrivateKey:(NSData *)privateKey
  81. {
  82. NSString *privateKeyString = [[NSString alloc] initWithData:privateKey encoding:NSUTF8StringEncoding];
  83. NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:message options:0];
  84. char *privKey = (char *)[privateKeyString UTF8String];
  85. // Get Device Private Key from PEM
  86. BIO *bio = BIO_new(BIO_s_mem());
  87. BIO_write(bio, privKey, (int)strlen(privKey));
  88. EVP_PKEY* pkey = 0;
  89. PEM_read_bio_PrivateKey(bio, &pkey, 0, 0);
  90. RSA* rsa = EVP_PKEY_get1_RSA(pkey);
  91. // Decrypt the message
  92. unsigned char *decrypted = (unsigned char *) malloc(4096);
  93. int decrypted_length = RSA_private_decrypt((int)[decodedData length], [decodedData bytes], decrypted, rsa, RSA_PKCS1_PADDING);
  94. if(decrypted_length == -1) {
  95. char buffer[500];
  96. ERR_error_string(ERR_get_error(), buffer);
  97. NSLog(@"%@",[NSString stringWithUTF8String:buffer]);
  98. return nil;
  99. }
  100. NSString *decryptString = [[NSString alloc] initWithBytes:decrypted length:decrypted_length encoding:NSUTF8StringEncoding];
  101. if (decrypted)
  102. free(decrypted);
  103. free(bio);
  104. free(rsa);
  105. return decryptString;
  106. }
  107. @end