NCPushNotificationEncryption.m 4.3 KB

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