NCPushNotificationEncryption.m 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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/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. }
  51. return self;
  52. }
  53. - (BOOL)generatePushNotificationsKeyPair:(NSString *)account
  54. {
  55. EVP_PKEY *pkey;
  56. NSError *keyError;
  57. pkey = [[NCEndToEndEncryption sharedManager] generateRSAKey:&keyError];
  58. if (keyError) {
  59. return NO;
  60. }
  61. // Extract publicKey, privateKey
  62. int len;
  63. char *keyBytes;
  64. // PublicKey
  65. BIO *publicKeyBIO = BIO_new(BIO_s_mem());
  66. PEM_write_bio_PUBKEY(publicKeyBIO, pkey);
  67. len = BIO_pending(publicKeyBIO);
  68. keyBytes = malloc(len);
  69. BIO_read(publicKeyBIO, keyBytes, len);
  70. NSData *ncPNPublicKey = [NSData dataWithBytes:keyBytes length:len];
  71. [CCUtility setPushNotificationPublicKey:account data:ncPNPublicKey];
  72. NSLog(@"Push Notifications Key Pair generated: \n%@", [[NSString alloc] initWithData:ncPNPublicKey encoding:NSUTF8StringEncoding]);
  73. // PrivateKey
  74. BIO *privateKeyBIO = BIO_new(BIO_s_mem());
  75. PEM_write_bio_PKCS8PrivateKey(privateKeyBIO, pkey, NULL, NULL, 0, NULL, NULL);
  76. len = BIO_pending(privateKeyBIO);
  77. keyBytes = malloc(len);
  78. BIO_read(privateKeyBIO, keyBytes, len);
  79. NSData *ncPNPrivateKey = [NSData dataWithBytes:keyBytes length:len];
  80. [CCUtility setPushNotificationPrivateKey:account data:ncPNPrivateKey];
  81. EVP_PKEY_free(pkey);
  82. return YES;
  83. }
  84. - (NSString *)decryptPushNotification:(NSString *)message withDevicePrivateKey:(NSData *)privateKey
  85. {
  86. NSString *privateKeyString = [[NSString alloc] initWithData:privateKey encoding:NSUTF8StringEncoding];
  87. NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:message options:0];
  88. char *privKey = (char *)[privateKeyString UTF8String];
  89. // Get Device Private Key from PEM
  90. BIO *bio = BIO_new(BIO_s_mem());
  91. BIO_write(bio, privKey, (int)strlen(privKey));
  92. EVP_PKEY* pkey = 0;
  93. PEM_read_bio_PrivateKey(bio, &pkey, 0, 0);
  94. RSA* rsa = EVP_PKEY_get1_RSA(pkey);
  95. // Decrypt the message
  96. unsigned char *decrypted = (unsigned char *) malloc(4096);
  97. int decrypted_length = RSA_private_decrypt((int)[decodedData length], [decodedData bytes], decrypted, rsa, RSA_PKCS1_PADDING);
  98. if(decrypted_length == -1) {
  99. char buffer[500];
  100. ERR_error_string(ERR_get_error(), buffer);
  101. NSLog(@"%@",[NSString stringWithUTF8String:buffer]);
  102. return nil;
  103. }
  104. NSString *decryptString = [[NSString alloc] initWithBytes:decrypted length:decrypted_length encoding:NSUTF8StringEncoding];
  105. if (decrypted)
  106. free(decrypted);
  107. free(bio);
  108. free(rsa);
  109. return decryptString;
  110. }
  111. @end