mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
aes-gcm via openssl
// FREEBIE
This commit is contained in:
parent
d6d403ce69
commit
72fbb02028
1
Podfile
1
Podfile
|
@ -8,6 +8,7 @@ target 'Signal' do
|
|||
pod 'JSQMessagesViewController', git: 'https://github.com/WhisperSystems/JSQMessagesViewController.git', branch: 'signal-master'
|
||||
#pod 'JSQMessagesViewController', path: '../JSQMessagesViewController'
|
||||
pod 'PureLayout'
|
||||
pod 'OpenSSL', git: 'https://github.com/charlesmchen/OpenSSL-Pod', branch: '1.0.2l'
|
||||
pod 'Reachability'
|
||||
pod 'SignalServiceKit', path: '.'
|
||||
pod 'SocketRocket', :git => 'https://github.com/facebook/SocketRocket.git'
|
||||
|
|
20
Podfile.lock
20
Podfile.lock
|
@ -37,17 +37,19 @@ PODS:
|
|||
- Mantle (2.1.0):
|
||||
- Mantle/extobjc (= 2.1.0)
|
||||
- Mantle/extobjc (2.1.0)
|
||||
- OpenSSL (1.0.212)
|
||||
- ProtocolBuffers (1.9.11)
|
||||
- PureLayout (3.0.2)
|
||||
- Reachability (3.2)
|
||||
- SAMKeychain (1.5.2)
|
||||
- SignalServiceKit (0.9.0):
|
||||
- '25519'
|
||||
- 25519
|
||||
- AFNetworking
|
||||
- AxolotlKit
|
||||
- CocoaLumberjack
|
||||
- libPhoneNumber-iOS
|
||||
- Mantle
|
||||
- OpenSSL
|
||||
- Reachability
|
||||
- SAMKeychain
|
||||
- SocketRocket
|
||||
|
@ -113,6 +115,7 @@ DEPENDENCIES:
|
|||
- ATAppUpdater
|
||||
- AxolotlKit (from `https://github.com/WhisperSystems/SignalProtocolKit.git`)
|
||||
- JSQMessagesViewController (from `https://github.com/WhisperSystems/JSQMessagesViewController.git`, branch `signal-master`)
|
||||
- OpenSSL (from `https://github.com/charlesmchen/OpenSSL-Pod`, branch `1.0.2l`)
|
||||
- PureLayout
|
||||
- Reachability
|
||||
- SignalServiceKit (from `.`)
|
||||
|
@ -124,6 +127,9 @@ EXTERNAL SOURCES:
|
|||
JSQMessagesViewController:
|
||||
:branch: signal-master
|
||||
:git: https://github.com/WhisperSystems/JSQMessagesViewController.git
|
||||
OpenSSL:
|
||||
:branch: 1.0.2l
|
||||
:git: https://github.com/charlesmchen/OpenSSL-Pod
|
||||
SignalServiceKit:
|
||||
:path: .
|
||||
SocketRocket:
|
||||
|
@ -136,12 +142,15 @@ CHECKOUT OPTIONS:
|
|||
JSQMessagesViewController:
|
||||
:commit: 8c10f920bb566fe1051f92abd360a2e3d5530e00
|
||||
:git: https://github.com/WhisperSystems/JSQMessagesViewController.git
|
||||
OpenSSL:
|
||||
:commit: 07d058fd05b794bae017e1d196b0338003b8c29e
|
||||
:git: https://github.com/charlesmchen/OpenSSL-Pod
|
||||
SocketRocket:
|
||||
:commit: 877ac7438be3ad0b45ef5ca3969574e4b97112bf
|
||||
:git: https://github.com/facebook/SocketRocket.git
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
'25519': dc4bad7e2dbcbf1efa121068a705a44cd98c80fc
|
||||
25519: dc4bad7e2dbcbf1efa121068a705a44cd98c80fc
|
||||
AFNetworking: 5e0e199f73d8626b11e79750991f5d173d1f8b67
|
||||
ATAppUpdater: a9f7027060959d47e58733d3b48f6b9a28cb8de1
|
||||
AxolotlKit: ba0ab24b879d34559a68e1270b079cc9bd7b3417
|
||||
|
@ -151,17 +160,18 @@ SPEC CHECKSUMS:
|
|||
JSQSystemSoundPlayer: c5850e77a4363ffd374cd851154b9af93264ed8d
|
||||
libPhoneNumber-iOS: f721ae4d5854bce60934f9fb9b0b28e8e68913cb
|
||||
Mantle: 2fa750afa478cd625a94230fbf1c13462f29395b
|
||||
OpenSSL: 60dae0b3f35e3ba31642260f4695c37d6a4c0fef
|
||||
ProtocolBuffers: d509225eb2ea43d9582a59e94348fcf86e2abd65
|
||||
PureLayout: 4d550abe49a94f24c2808b9b95db9131685fe4cd
|
||||
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
|
||||
SAMKeychain: 1865333198217411f35327e8da61b43de79b635b
|
||||
SignalServiceKit: db63e60f9a9f851e9ae48214bee230be92bb7e57
|
||||
SignalServiceKit: bfac5572f3a1ff8a853ead9b5413274a075f3cb4
|
||||
SocketRocket: dbb1554b8fc288ef8ef370d6285aeca7361be31e
|
||||
SQLCipher: 43d12c0eb9c57fb438749618fc3ce0065509a559
|
||||
TwistedOakCollapsingFutures: f359b90f203e9ab13dfb92c9ff41842a7fe1cd0c
|
||||
UnionFind: c33be5adb12983981d6e827ea94fc7f9e370f52d
|
||||
YapDatabase: cd911121580ff16675f65ad742a9eb0ab4d9e266
|
||||
|
||||
PODFILE CHECKSUM: 13b48854ce4b92e887ffb55d72029fe49b45a789
|
||||
PODFILE CHECKSUM: 6ed599004f6559be1963002dd4dd6a1360e642d4
|
||||
|
||||
COCOAPODS: 1.2.1
|
||||
COCOAPODS: 1.3.1
|
||||
|
|
|
@ -2015,13 +2015,16 @@
|
|||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Signal-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
3465F381B1856CC06933B3A8 /* [CP] Copy Pods Resources */ = {
|
||||
|
@ -2030,9 +2033,21 @@
|
|||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${SRCROOT}/Pods/Target Support Files/Pods-Signal/Pods-Signal-resources.sh",
|
||||
"${PODS_ROOT}/JSQMessagesViewController/JSQMessagesViewController/Assets/JSQMessagesAssets.bundle",
|
||||
"${PODS_ROOT}/JSQMessagesViewController/JSQMessagesViewController/Controllers/JSQMessagesViewController.xib",
|
||||
"${PODS_ROOT}/JSQMessagesViewController/JSQMessagesViewController/Views/JSQMessagesCollectionViewCellIncoming.xib",
|
||||
"${PODS_ROOT}/JSQMessagesViewController/JSQMessagesViewController/Views/JSQMessagesCollectionViewCellOutgoing.xib",
|
||||
"${PODS_ROOT}/JSQMessagesViewController/JSQMessagesViewController/Views/JSQMessagesLoadEarlierHeaderView.xib",
|
||||
"${PODS_ROOT}/JSQMessagesViewController/JSQMessagesViewController/Views/JSQMessagesToolbarContentView.xib",
|
||||
"${PODS_ROOT}/JSQMessagesViewController/JSQMessagesViewController/Views/JSQMessagesTypingIndicatorFooterView.xib",
|
||||
"${PODS_ROOT}/SAMKeychain/Support/SAMKeychain.bundle",
|
||||
"${PODS_ROOT}/../SignalServiceKit/src/Security/PinningCertificate/textsecure.cer",
|
||||
"${PODS_ROOT}/../SignalServiceKit/src/Security/PinningCertificate/GIAG2.crt",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
|
@ -2108,13 +2123,16 @@
|
|||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-SignalTests-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
B4E9B04E862FB64FC9A8F79B /* [CP] Embed Pods Frameworks */ = {
|
||||
|
@ -2524,11 +2542,7 @@
|
|||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
"GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
"SSK_BUILDING_FOR_TESTS=1",
|
||||
);
|
||||
"GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = "DEBUG=1 $(inherited) SSK_BUILDING_FOR_TESTS=1";
|
||||
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
|
||||
GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
|
|
|
@ -12,7 +12,7 @@ extern NSString *const kNSNotificationName_OtherUsersProfileDidChange;
|
|||
extern const NSUInteger kOWSProfileManager_MaxAvatarDiameter;
|
||||
|
||||
@class TSThread;
|
||||
@class OWSAES128Key;
|
||||
@class OWSAES256Key;
|
||||
|
||||
// This class can be safely accessed and used from any thread.
|
||||
@interface OWSProfileManager : NSObject <ProfileManagerProtocol>
|
||||
|
@ -26,7 +26,7 @@ extern const NSUInteger kOWSProfileManager_MaxAvatarDiameter;
|
|||
#pragma mark - Local Profile
|
||||
|
||||
// These two methods should only be called from the main thread.
|
||||
- (OWSAES128Key *)localProfileKey;
|
||||
- (OWSAES256Key *)localProfileKey;
|
||||
- (BOOL)hasLocalProfile;
|
||||
- (nullable NSString *)localProfileName;
|
||||
- (nullable UIImage *)localProfileAvatarImage;
|
||||
|
@ -59,7 +59,7 @@ extern const NSUInteger kOWSProfileManager_MaxAvatarDiameter;
|
|||
|
||||
#pragma mark - Other User's Profiles
|
||||
|
||||
- (nullable OWSAES128Key *)profileKeyForRecipientId:(NSString *)recipientId;
|
||||
- (nullable OWSAES256Key *)profileKeyForRecipientId:(NSString *)recipientId;
|
||||
|
||||
- (nullable NSString *)profileNameForRecipientId:(NSString *)recipientId;
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@interface UserProfile : TSYapDatabaseObject
|
||||
|
||||
@property (atomic, readonly) NSString *recipientId;
|
||||
@property (atomic, nullable) OWSAES128Key *profileKey;
|
||||
@property (atomic, nullable) OWSAES256Key *profileKey;
|
||||
@property (nonatomic, nullable) NSString *profileName;
|
||||
@property (nonatomic, nullable) NSString *avatarUrlPath;
|
||||
// This filename is relative to OWSProfileManager.profileAvatarsDirPath.
|
||||
|
@ -176,7 +176,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
|
|||
OWSAssert(self.localUserProfile);
|
||||
if (!self.localUserProfile.profileKey) {
|
||||
DDLogInfo(@"%@ Generating local profile key", self.tag);
|
||||
self.localUserProfile.profileKey = [OWSAES128Key generateRandomKey];
|
||||
self.localUserProfile.profileKey = [OWSAES256Key generateRandomKey];
|
||||
// Make sure to save on the local db connection for consistency.
|
||||
//
|
||||
// NOTE: we do an async read/write here to avoid blocking during app launch path.
|
||||
|
@ -184,7 +184,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
|
|||
[self.localUserProfile saveWithTransaction:transaction];
|
||||
}];
|
||||
}
|
||||
OWSAssert(self.localUserProfile.profileKey.keyData.length == kAES128_KeyByteLength);
|
||||
OWSAssert(self.localUserProfile.profileKey.keyData.length == kAES256_KeyByteLength);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -259,11 +259,11 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
|
|||
|
||||
#pragma mark - Local Profile
|
||||
|
||||
- (OWSAES128Key *)localProfileKey
|
||||
- (OWSAES256Key *)localProfileKey
|
||||
{
|
||||
@synchronized(self)
|
||||
{
|
||||
OWSAssert(self.localUserProfile.profileKey.keyData.length == kAES128_KeyByteLength);
|
||||
OWSAssert(self.localUserProfile.profileKey.keyData.length == kAES256_KeyByteLength);
|
||||
|
||||
return self.localUserProfile.profileKey;
|
||||
}
|
||||
|
@ -787,7 +787,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
|
|||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
@synchronized(self)
|
||||
{
|
||||
OWSAES128Key *_Nullable profileKey = [OWSAES128Key keyWithData:profileKeyData];
|
||||
OWSAES256Key *_Nullable profileKey = [OWSAES256Key keyWithData:profileKeyData];
|
||||
if (profileKey == nil) {
|
||||
OWSFail(@"Failed to make profile key for key data");
|
||||
return;
|
||||
|
@ -814,7 +814,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
|
|||
});
|
||||
}
|
||||
|
||||
- (nullable OWSAES128Key *)profileKeyForRecipientId:(NSString *)recipientId
|
||||
- (nullable OWSAES256Key *)profileKeyForRecipientId:(NSString *)recipientId
|
||||
{
|
||||
OWSAssert(recipientId.length > 0);
|
||||
|
||||
|
@ -893,7 +893,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
|
|||
return;
|
||||
}
|
||||
|
||||
OWSAES128Key *profileKeyAtStart = userProfile.profileKey;
|
||||
OWSAES256Key *profileKeyAtStart = userProfile.profileKey;
|
||||
|
||||
NSString *fileName = [[NSUUID UUID].UUIDString stringByAppendingPathExtension:@"jpg"];
|
||||
NSString *filePath = [self.profileAvatarsDirPath stringByAppendingPathComponent:fileName];
|
||||
|
@ -1074,9 +1074,9 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
|
|||
|
||||
#pragma mark - Profile Encryption
|
||||
|
||||
- (nullable NSData *)encryptProfileData:(nullable NSData *)encryptedData profileKey:(OWSAES128Key *)profileKey
|
||||
- (nullable NSData *)encryptProfileData:(nullable NSData *)encryptedData profileKey:(OWSAES256Key *)profileKey
|
||||
{
|
||||
OWSAssert(profileKey.keyData.length == kAES128_KeyByteLength);
|
||||
OWSAssert(profileKey.keyData.length == kAES256_KeyByteLength);
|
||||
|
||||
if (!encryptedData) {
|
||||
return nil;
|
||||
|
@ -1085,9 +1085,9 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
|
|||
return [Cryptography encryptAESGCMWithData:encryptedData key:profileKey];
|
||||
}
|
||||
|
||||
- (nullable NSData *)decryptProfileData:(nullable NSData *)encryptedData profileKey:(OWSAES128Key *)profileKey
|
||||
- (nullable NSData *)decryptProfileData:(nullable NSData *)encryptedData profileKey:(OWSAES256Key *)profileKey
|
||||
{
|
||||
OWSAssert(profileKey.keyData.length == kAES128_KeyByteLength);
|
||||
OWSAssert(profileKey.keyData.length == kAES256_KeyByteLength);
|
||||
|
||||
if (!encryptedData) {
|
||||
return nil;
|
||||
|
@ -1096,9 +1096,9 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
|
|||
return [Cryptography decryptAESGCMWithData:encryptedData key:profileKey];
|
||||
}
|
||||
|
||||
- (nullable NSString *)decryptProfileNameData:(nullable NSData *)encryptedData profileKey:(OWSAES128Key *)profileKey
|
||||
- (nullable NSString *)decryptProfileNameData:(nullable NSData *)encryptedData profileKey:(OWSAES256Key *)profileKey
|
||||
{
|
||||
OWSAssert(profileKey.keyData.length == kAES128_KeyByteLength);
|
||||
OWSAssert(profileKey.keyData.length == kAES256_KeyByteLength);
|
||||
|
||||
NSData *_Nullable decryptedData = [self decryptProfileData:encryptedData profileKey:profileKey];
|
||||
if (decryptedData.length < 1) {
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#import "PrivacySettingsTableViewController.h"
|
||||
#import "PropertyListPreferences.h"
|
||||
#import "PushManager.h"
|
||||
#import "Release.h"
|
||||
#import "SignalsViewController.h"
|
||||
#import "TSMessageAdapter.h"
|
||||
#import "UIColor+OWS.h"
|
||||
|
|
|
@ -40,6 +40,7 @@ An Objective-C library for communicating with the Signal messaging service.
|
|||
s.dependency 'YapDatabase/SQLCipher', '~> 2.9.3'
|
||||
s.dependency 'SocketRocket'
|
||||
s.dependency 'libPhoneNumber-iOS'
|
||||
s.dependency 'OpenSSL'
|
||||
s.dependency 'SAMKeychain'
|
||||
s.dependency 'TwistedOakCollapsingFutures'
|
||||
s.dependency 'Reachability'
|
||||
|
|
|
@ -5,6 +5,7 @@ target 'TSKitiOSTestApp' do
|
|||
pod 'SocketRocket', git: 'https://github.com/facebook/SocketRocket.git'
|
||||
pod 'AxolotlKit', git: 'https://github.com/WhisperSystems/SignalProtocolKit.git'
|
||||
pod 'SignalServiceKit', :path => '../../../SignalServiceKit.podspec'
|
||||
pod 'OpenSSL', git: 'https://github.com/charlesmchen/OpenSSL-Pod', branch: '1.0.2l'
|
||||
|
||||
target 'TSKitiOSTestAppTests' do
|
||||
inherit! :search_paths
|
||||
|
|
|
@ -33,6 +33,7 @@ PODS:
|
|||
- Mantle (2.1.0):
|
||||
- Mantle/extobjc (= 2.1.0)
|
||||
- Mantle/extobjc (2.1.0)
|
||||
- OpenSSL (1.0.212)
|
||||
- ProtocolBuffers (1.9.11)
|
||||
- Reachability (3.2)
|
||||
- SAMKeychain (1.5.2)
|
||||
|
@ -43,6 +44,7 @@ PODS:
|
|||
- CocoaLumberjack
|
||||
- libPhoneNumber-iOS
|
||||
- Mantle
|
||||
- OpenSSL
|
||||
- Reachability
|
||||
- SAMKeychain
|
||||
- SocketRocket
|
||||
|
@ -106,12 +108,16 @@ PODS:
|
|||
|
||||
DEPENDENCIES:
|
||||
- AxolotlKit (from `https://github.com/WhisperSystems/SignalProtocolKit.git`)
|
||||
- OpenSSL (from `https://github.com/charlesmchen/OpenSSL-Pod`, branch `1.0.2l`)
|
||||
- SignalServiceKit (from `../../../SignalServiceKit.podspec`)
|
||||
- SocketRocket (from `https://github.com/facebook/SocketRocket.git`)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
AxolotlKit:
|
||||
:git: https://github.com/WhisperSystems/SignalProtocolKit.git
|
||||
OpenSSL:
|
||||
:branch: 1.0.2l
|
||||
:git: https://github.com/charlesmchen/OpenSSL-Pod
|
||||
SignalServiceKit:
|
||||
:path: ../../../SignalServiceKit.podspec
|
||||
SocketRocket:
|
||||
|
@ -121,6 +127,9 @@ CHECKOUT OPTIONS:
|
|||
AxolotlKit:
|
||||
:commit: 28afe5c1dbcfdea73d147e464c53d191d1e3ea50
|
||||
:git: https://github.com/WhisperSystems/SignalProtocolKit.git
|
||||
OpenSSL:
|
||||
:commit: 07d058fd05b794bae017e1d196b0338003b8c29e
|
||||
:git: https://github.com/charlesmchen/OpenSSL-Pod
|
||||
SocketRocket:
|
||||
:commit: 877ac7438be3ad0b45ef5ca3969574e4b97112bf
|
||||
:git: https://github.com/facebook/SocketRocket.git
|
||||
|
@ -133,16 +142,17 @@ SPEC CHECKSUMS:
|
|||
HKDFKit: c058305d6f64b84f28c50bd7aa89574625bcb62a
|
||||
libPhoneNumber-iOS: f721ae4d5854bce60934f9fb9b0b28e8e68913cb
|
||||
Mantle: 2fa750afa478cd625a94230fbf1c13462f29395b
|
||||
OpenSSL: 60dae0b3f35e3ba31642260f4695c37d6a4c0fef
|
||||
ProtocolBuffers: d509225eb2ea43d9582a59e94348fcf86e2abd65
|
||||
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
|
||||
SAMKeychain: 1865333198217411f35327e8da61b43de79b635b
|
||||
SignalServiceKit: db63e60f9a9f851e9ae48214bee230be92bb7e57
|
||||
SignalServiceKit: bfac5572f3a1ff8a853ead9b5413274a075f3cb4
|
||||
SocketRocket: dbb1554b8fc288ef8ef370d6285aeca7361be31e
|
||||
SQLCipher: 43d12c0eb9c57fb438749618fc3ce0065509a559
|
||||
TwistedOakCollapsingFutures: f359b90f203e9ab13dfb92c9ff41842a7fe1cd0c
|
||||
UnionFind: c33be5adb12983981d6e827ea94fc7f9e370f52d
|
||||
YapDatabase: cd911121580ff16675f65ad742a9eb0ab4d9e266
|
||||
|
||||
PODFILE CHECKSUM: 5bfff8cb73ff80b5e5c383fda4dca6aeff2fa8d3
|
||||
PODFILE CHECKSUM: 1d91553ff6ddb91426b1bcb43d0433c2c3cbe272
|
||||
|
||||
COCOAPODS: 1.2.1
|
||||
|
|
|
@ -459,9 +459,12 @@
|
|||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-TSKitiOSTestApp-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
|
@ -519,9 +522,14 @@
|
|||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${SRCROOT}/Pods/Target Support Files/Pods-TSKitiOSTestApp/Pods-TSKitiOSTestApp-resources.sh",
|
||||
"${PODS_ROOT}/SAMKeychain/Support/SAMKeychain.bundle",
|
||||
"${PODS_ROOT}/../../../src/Security/PinningCertificate/textsecure.cer",
|
||||
"${PODS_ROOT}/../../../src/Security/PinningCertificate/GIAG2.crt",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
|
@ -534,9 +542,12 @@
|
|||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-TSKitiOSTestAppTests-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "FF3F51F81980908EDE1836B76AA3A1EC"
|
||||
BlueprintIdentifier = "AABBF31CEB020B42CD1A6FE25E97E11E"
|
||||
BuildableName = "libSignalServiceKit.a"
|
||||
BlueprintName = "SignalServiceKit"
|
||||
ReferencedContainer = "container:Pods/Pods.xcodeproj">
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
//
|
||||
|
||||
@class TSThread;
|
||||
@class OWSAES128Key;
|
||||
@class OWSAES256Key;
|
||||
|
||||
@protocol ProfileManagerProtocol <NSObject>
|
||||
|
||||
- (OWSAES128Key *)localProfileKey;
|
||||
- (OWSAES256Key *)localProfileKey;
|
||||
|
||||
- (void)setProfileKeyData:(NSData *)profileKeyData forRecipientId:(NSString *)recipientId;
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
return NO;
|
||||
}
|
||||
|
||||
- (OWSAES128Key *)localProfileKey
|
||||
- (OWSAES256Key *)localProfileKey
|
||||
{
|
||||
id<ProfileManagerProtocol> profileManager = [TextSecureKitEnv sharedEnv].profileManager;
|
||||
return profileManager.localProfileKey;
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
extern const NSUInteger kAES128_KeyByteLength;
|
||||
extern const NSUInteger kAES256_KeyByteLength;
|
||||
|
||||
/// Key appropriate for use in AES128 crypto
|
||||
@interface OWSAES128Key: NSObject <NSSecureCoding>
|
||||
@interface OWSAES256Key : NSObject <NSSecureCoding>
|
||||
|
||||
/// Generates new secure random key
|
||||
- (instancetype)init;
|
||||
|
@ -60,8 +60,8 @@ typedef NS_ENUM(NSInteger, TSMACType) {
|
|||
outKey:(NSData *_Nonnull *_Nullable)outKey
|
||||
outDigest:(NSData *_Nonnull *_Nullable)outDigest;
|
||||
|
||||
+ (nullable NSData *)encryptAESGCMWithData:(NSData *)plainTextData key:(OWSAES128Key *)key;
|
||||
+ (nullable NSData *)decryptAESGCMWithData:(NSData *)encryptedData key:(OWSAES128Key *)key;
|
||||
+ (nullable NSData *)encryptAESGCMWithData:(NSData *)plaintextData key:(OWSAES256Key *)key;
|
||||
+ (nullable NSData *)decryptAESGCMWithData:(NSData *)encryptedData key:(OWSAES256Key *)key;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -2,17 +2,12 @@
|
|||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <CommonCrypto/CommonCryptor.h>
|
||||
#import <CommonCrypto/CommonHMAC.h>
|
||||
|
||||
// CommonCryptorSPI.h is a local copy of a private APple header fetched: Fri Aug 11 18:33:25 EDT 2017
|
||||
// from https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60074/include/CommonCryptorSPI.h
|
||||
// We use it to provide the not-yet-public AES128-GCM cryptor
|
||||
#import "CommonCryptorSPI.h"
|
||||
|
||||
#import "Cryptography.h"
|
||||
#import "NSData+Base64.h"
|
||||
#import "NSData+OWSConstantTimeCompare.h"
|
||||
#import <CommonCrypto/CommonCryptor.h>
|
||||
#import <CommonCrypto/CommonHMAC.h>
|
||||
#import <openssl/evp.h>
|
||||
|
||||
#define HMAC256_KEY_LENGTH 32
|
||||
#define HMAC256_OUTPUT_LENGTH 32
|
||||
|
@ -21,19 +16,23 @@
|
|||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
||||
// Returned by many OpenSSL functions - indicating success
|
||||
const int kOpenSSLSuccess = 1;
|
||||
|
||||
// length of initialization nonce
|
||||
static const NSUInteger kAESGCM128_IVLength = 12;
|
||||
static const NSUInteger kAESGCM256_IVLength = 12;
|
||||
|
||||
// length of authentication tag for AES128-GCM
|
||||
static const NSUInteger kAESGCM128_TagLength = 16;
|
||||
// length of authentication tag for AES256-GCM
|
||||
static const NSUInteger kAESGCM256_TagLength = 16;
|
||||
|
||||
const NSUInteger kAES128_KeyByteLength = 16;
|
||||
const NSUInteger kAES256_KeyByteLength = 32;
|
||||
|
||||
@implementation OWSAES128Key
|
||||
@implementation OWSAES256Key
|
||||
|
||||
+ (nullable instancetype)keyWithData:(NSData *)data
|
||||
{
|
||||
if (data.length != kAES128_KeyByteLength) {
|
||||
if (data.length != kAES256_KeyByteLength) {
|
||||
OWSFail(@"Invalid key length for AES128: %lu", (unsigned long)data.length);
|
||||
return nil;
|
||||
}
|
||||
|
@ -48,7 +47,7 @@ const NSUInteger kAES128_KeyByteLength = 16;
|
|||
|
||||
- (instancetype)init
|
||||
{
|
||||
return [self initWithData:[Cryptography generateRandomBytes:kAES128_KeyByteLength]];
|
||||
return [self initWithData:[Cryptography generateRandomBytes:kAES256_KeyByteLength]];
|
||||
}
|
||||
|
||||
- (instancetype)initWithData:(NSData *)data
|
||||
|
@ -78,8 +77,8 @@ const NSUInteger kAES128_KeyByteLength = 16;
|
|||
}
|
||||
|
||||
NSData *keyData = [aDecoder decodeObjectOfClass:[NSData class] forKey:@"keyData"];
|
||||
if (keyData.length != kAES128_KeyByteLength) {
|
||||
OWSFail(@"Invalid key length for AES128: %lu", (unsigned long)keyData.length);
|
||||
if (keyData.length != kAES256_KeyByteLength) {
|
||||
OWSFail(@"Invalid key length: %lu", (unsigned long)keyData.length);
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
@ -386,137 +385,164 @@ const NSUInteger kAES128_KeyByteLength = 16;
|
|||
return [encryptedAttachmentData copy];
|
||||
}
|
||||
|
||||
+ (nullable NSData *)encryptAESGCMWithData:(NSData *)plainTextData key:(OWSAES128Key *)key
|
||||
+ (nullable NSData *)encryptAESGCMWithData:(NSData *)plaintext key:(OWSAES256Key *)key
|
||||
{
|
||||
NSData *initializationVector = [Cryptography generateRandomBytes:kAESGCM128_IVLength];
|
||||
uint8_t *cipherTextBytes = malloc(plainTextData.length);
|
||||
if (cipherTextBytes == NULL) {
|
||||
OWSFail(@"%@ Failed to allocate encryptedBytes", self.tag);
|
||||
return nil;
|
||||
}
|
||||
|
||||
uint8_t *authTagBytes = malloc(kAESGCM128_TagLength);
|
||||
if (authTagBytes == NULL) {
|
||||
free(cipherTextBytes);
|
||||
OWSFail(@"%@ Failed to allocate authTagBytes", self.tag);
|
||||
return nil;
|
||||
}
|
||||
|
||||
// NOTE: Since `tagLength` is an input parameter, it seems weird that the signature for tagLength is a `size_t*` rather than just a `size_t`.
|
||||
//
|
||||
// I found a vague reference in the Safari repository implying that this may be a bug:
|
||||
// source: https://www.mail-archive.com/webkit-changes@lists.webkit.org/msg114561.html
|
||||
//
|
||||
// Comment was:
|
||||
// tagLength is actual an input <rdar://problem/30660074>
|
||||
size_t tagLength = kAESGCM128_TagLength;
|
||||
NSData *initializationVector = [Cryptography generateRandomBytes:kAESGCM256_IVLength];
|
||||
NSMutableData *ciphertext = [NSMutableData dataWithLength:plaintext.length];
|
||||
NSMutableData *authTag = [NSMutableData dataWithLength:kAESGCM256_TagLength];
|
||||
|
||||
CCCryptorStatus status
|
||||
= CCCryptorGCM(kCCEncrypt, // CCOperation op, /* kCCEncrypt, kCCDecrypt */
|
||||
kCCAlgorithmAES128, // CCAlgorithm alg,
|
||||
key.keyData.bytes, // const void *key, /* raw key material */
|
||||
key.keyData.length, // size_t keyLength,
|
||||
initializationVector.bytes, // const void *iv,
|
||||
initializationVector.length, // size_t ivLen,
|
||||
NULL, // const void *aData,
|
||||
0, // size_t aDataLen,
|
||||
plainTextData.bytes, // const void *dataIn,
|
||||
plainTextData.length, // size_t dataInLength,
|
||||
cipherTextBytes, // void *dataOut,
|
||||
authTagBytes, // const void *tag,
|
||||
&tagLength // size_t *tagLength)
|
||||
);
|
||||
|
||||
if (status != kCCSuccess) {
|
||||
OWSFail(@"CCCryptorGCM encrypt failed with status: %d", status);
|
||||
free(cipherTextBytes);
|
||||
free(authTagBytes);
|
||||
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
||||
if (!ctx) {
|
||||
OWSFail(@"%@ failed to build context while encrypting", self.tag);
|
||||
return nil;
|
||||
}
|
||||
|
||||
// build up return value: initializationVector || cipherText || authTag
|
||||
|
||||
// Initialise the encryption operation.
|
||||
if (EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL) != kOpenSSLSuccess) {
|
||||
OWSFail(@"%@ failed to init encryption", self.tag);
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Set IV length if default 12 bytes (96 bits) is not appropriate
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, (int)initializationVector.length, NULL) != kOpenSSLSuccess) {
|
||||
OWSFail(@"%@ failed to set IV length", self.tag);
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Initialise key and IV
|
||||
if (EVP_EncryptInit_ex(ctx, NULL, NULL, key.keyData.bytes, initializationVector.bytes) != kOpenSSLSuccess) {
|
||||
OWSFail(@"%@ failed to set key and iv while encrypting", self.tag);
|
||||
return nil;
|
||||
}
|
||||
|
||||
int bytesEncrypted = 0;
|
||||
// Provide the message to be encrypted, and obtain the encrypted output.
|
||||
// EVP_EncryptUpdate can be called multiple times if necessary
|
||||
if (EVP_EncryptUpdate(ctx, ciphertext.mutableBytes, &bytesEncrypted, plaintext.bytes, (int)plaintext.length)
|
||||
!= kOpenSSLSuccess) {
|
||||
OWSFail(@"%@ encryptUpdate failed", self.tag);
|
||||
return nil;
|
||||
}
|
||||
if (bytesEncrypted != plaintext.length) {
|
||||
OWSFail(@"%@ bytesEncrypted != plainTextData.length", self.tag);
|
||||
return nil;
|
||||
}
|
||||
|
||||
int finalizedBytes = 0;
|
||||
// Finalize the encryption. Normally ciphertext bytes may be written at
|
||||
// this stage, but this does not occur in GCM mode
|
||||
if (EVP_EncryptFinal_ex(ctx, ciphertext.mutableBytes + bytesEncrypted, &finalizedBytes) != kOpenSSLSuccess) {
|
||||
OWSFail(@"%@ failed to finalize encryption", self.tag);
|
||||
return nil;
|
||||
}
|
||||
if (finalizedBytes != 0) {
|
||||
OWSFail(@"%@ Unexpected finalized bytes written", self.tag);
|
||||
return nil;
|
||||
}
|
||||
|
||||
/* Get the tag */
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, kAESGCM256_TagLength, authTag.mutableBytes) != kOpenSSLSuccess) {
|
||||
OWSFail(@"%@ failed to write tag", self.tag);
|
||||
return nil;
|
||||
}
|
||||
|
||||
/* Clean up */
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
// build up return value: initializationVector || ciphertext || authTag
|
||||
NSMutableData *encryptedData = [initializationVector mutableCopy];
|
||||
[encryptedData appendBytes:cipherTextBytes length:plainTextData.length];
|
||||
[encryptedData appendBytes:authTagBytes length:tagLength];
|
||||
[encryptedData appendData:ciphertext];
|
||||
[encryptedData appendData:authTag];
|
||||
|
||||
free(cipherTextBytes);
|
||||
free(authTagBytes);
|
||||
|
||||
return [encryptedData copy];
|
||||
}
|
||||
|
||||
+ (nullable NSData *)decryptAESGCMWithData:(NSData *)encryptedData key:(OWSAES128Key *)key
|
||||
+ (nullable NSData *)decryptAESGCMWithData:(NSData *)encryptedData key:(OWSAES256Key *)key
|
||||
{
|
||||
OWSAssert(encryptedData.length > kAESGCM128_IVLength + kAESGCM128_TagLength);
|
||||
NSUInteger cipherTextLength = encryptedData.length - kAESGCM128_IVLength - kAESGCM128_TagLength;
|
||||
|
||||
// encryptedData layout: initializationVector || cipherText || authTag
|
||||
NSData *initializationVector = [encryptedData subdataWithRange:NSMakeRange(0, kAESGCM128_IVLength)];
|
||||
NSData *cipherText = [encryptedData subdataWithRange:NSMakeRange(kAESGCM128_IVLength, cipherTextLength)];
|
||||
OWSAssert(encryptedData.length > kAESGCM256_IVLength + kAESGCM256_TagLength);
|
||||
NSUInteger cipherTextLength = encryptedData.length - kAESGCM256_IVLength - kAESGCM256_TagLength;
|
||||
|
||||
// encryptedData layout: initializationVector || ciphertext || authTag
|
||||
NSData *initializationVector = [encryptedData subdataWithRange:NSMakeRange(0, kAESGCM256_IVLength)];
|
||||
NSData *ciphertext = [encryptedData subdataWithRange:NSMakeRange(kAESGCM256_IVLength, cipherTextLength)];
|
||||
NSData *authTag =
|
||||
[encryptedData subdataWithRange:NSMakeRange(kAESGCM128_IVLength + cipherTextLength, kAESGCM128_TagLength)];
|
||||
[encryptedData subdataWithRange:NSMakeRange(kAESGCM256_IVLength + cipherTextLength, kAESGCM256_TagLength)];
|
||||
|
||||
return
|
||||
[self decryptAESGCMWithInitializationVector:initializationVector cipherText:cipherText authTag:authTag key:key];
|
||||
[self decryptAESGCMWithInitializationVector:initializationVector ciphertext:ciphertext authTag:authTag key:key];
|
||||
}
|
||||
|
||||
+ (nullable NSData *)decryptAESGCMWithInitializationVector:(NSData *)initializationVector
|
||||
cipherText:(NSData *)cipherText
|
||||
ciphertext:(NSData *)ciphertext
|
||||
authTag:(NSData *)authTagFromEncrypt
|
||||
key:(OWSAES128Key *)key
|
||||
key:(OWSAES256Key *)key
|
||||
{
|
||||
void *plainTextBytes = malloc(cipherText.length);
|
||||
if (plainTextBytes == NULL) {
|
||||
OWSFail(@"Failed to malloc plainTextBytes");
|
||||
NSMutableData *plaintext = [NSMutableData dataWithLength:ciphertext.length];
|
||||
|
||||
// Create and initialise the context
|
||||
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
||||
|
||||
if (!ctx) {
|
||||
OWSFail(@"%@ failed to build context while decrypting", self.tag);
|
||||
return nil;
|
||||
}
|
||||
|
||||
void *decryptAuthTagBytes = malloc(kAESGCM128_TagLength);
|
||||
if (decryptAuthTagBytes == NULL) {
|
||||
OWSFail(@"Failed to malloc decryptAuthTagBytes");
|
||||
free(plainTextBytes);
|
||||
// Initialise the decryption operation.
|
||||
if (EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL) != kOpenSSLSuccess) {
|
||||
OWSFail(@"%@ failed to init decryption", self.tag);
|
||||
return nil;
|
||||
}
|
||||
|
||||
// NOTE: Since `tagLength` is an input parameter, it seems weird that the signature for tagLength is a `size_t*` rather than just a `size_t`.
|
||||
//
|
||||
// I found a vague reference in the Safari repository implying that this may be a bug:
|
||||
// source: https://www.mail-archive.com/webkit-changes@lists.webkit.org/msg114561.html
|
||||
//
|
||||
// Comment was:
|
||||
// tagLength is actual an input <rdar://problem/30660074>
|
||||
size_t tagLength = kAESGCM128_TagLength;
|
||||
|
||||
CCCryptorStatus status
|
||||
= CCCryptorGCM(kCCDecrypt, // CCOperation op, /* kCCEncrypt, kCCDecrypt */
|
||||
kCCAlgorithmAES128, // CCAlgorithm alg,
|
||||
key.keyData.bytes, // const void *key, /* raw key material */
|
||||
key.keyData.length, // size_t keyLength,
|
||||
initializationVector.bytes, // const void *iv,
|
||||
initializationVector.length, // size_t ivLen,
|
||||
NULL, // const void *aData,
|
||||
0, // size_t aDataLen,
|
||||
cipherText.bytes, // const void *dataIn,
|
||||
cipherText.length, // size_t dataInLength,
|
||||
plainTextBytes, // void *dataOut,
|
||||
decryptAuthTagBytes, // const void *tag,
|
||||
&tagLength // size_t *tagLength
|
||||
);
|
||||
|
||||
NSData *decryptAuthTag = [NSData dataWithBytesNoCopy:decryptAuthTagBytes length:tagLength freeWhenDone:YES];
|
||||
if (![decryptAuthTag ows_constantTimeIsEqualToData:authTagFromEncrypt]) {
|
||||
OWSFail(@"Auth tags don't match given tag: %@ computed tag: %@", authTagFromEncrypt, decryptAuthTag);
|
||||
free(plainTextBytes);
|
||||
// Set IV length. Not necessary if this is 12 bytes (96 bits)
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, kAESGCM256_IVLength, NULL) != kOpenSSLSuccess) {
|
||||
OWSFail(@"%@ failed to set key and iv while decrypting", self.tag);
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (status != kCCSuccess) {
|
||||
OWSFail(@"CCCryptorGCM decrypt failed with status: %d", status);
|
||||
free(plainTextBytes);
|
||||
// Initialise key and IV
|
||||
if (EVP_DecryptInit_ex(ctx, NULL, NULL, key.keyData.bytes, initializationVector.bytes) != kOpenSSLSuccess) {
|
||||
OWSFail(@"%@ failed to init decryption", self.tag);
|
||||
return nil;
|
||||
}
|
||||
|
||||
return [NSData dataWithBytesNoCopy:plainTextBytes length:cipherText.length freeWhenDone:YES];
|
||||
// Provide the message to be decrypted, and obtain the plaintext output.
|
||||
// EVP_DecryptUpdate can be called multiple times if necessary
|
||||
int decryptedBytes = 0;
|
||||
if (EVP_DecryptUpdate(ctx, plaintext.mutableBytes, &decryptedBytes, ciphertext.bytes, (int)ciphertext.length)
|
||||
!= kOpenSSLSuccess) {
|
||||
OWSFail(@"%@ decryptUpdate failed", self.tag);
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (decryptedBytes != ciphertext.length) {
|
||||
OWSFail(@"%@ Failed to decrypt entire ciphertext", self.tag);
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Set expected tag value. Works in OpenSSL 1.0.1d and later
|
||||
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, (int)authTagFromEncrypt.length, authTagFromEncrypt.bytes)
|
||||
!= kOpenSSLSuccess) {
|
||||
OWSFail(@"%@ Failed to set auth tag in decrypt.", self.tag);
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Finalise the decryption. A positive return value indicates success,
|
||||
// anything else is a failure - the plaintext is not trustworthy.
|
||||
int finalBytes = 0;
|
||||
int decryptStatus = EVP_DecryptFinal_ex(ctx, plaintext.bytes + decryptedBytes, &finalBytes);
|
||||
|
||||
// AESGCM doesn't write any final bytes
|
||||
OWSAssert(finalBytes == 0);
|
||||
|
||||
// Clean up
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
if (decryptStatus > 0) {
|
||||
return [plaintext copy];
|
||||
} else {
|
||||
OWSFail(@"%@ Decrypt verificaiton failed", self.tag);
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Logging
|
||||
|
|
|
@ -10,10 +10,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
@interface OWSFakeProfileManager ()
|
||||
|
||||
@property (nonatomic, readonly) NSMutableDictionary<NSString *, OWSAES128Key *> *profileKeys;
|
||||
@property (nonatomic, readonly) NSMutableDictionary<NSString *, OWSAES256Key *> *profileKeys;
|
||||
@property (nonatomic, readonly) NSMutableSet<NSString *> *recipientWhitelist;
|
||||
@property (nonatomic, readonly) NSMutableSet<NSString *> *threadWhitelist;
|
||||
@property (nonatomic, readonly) OWSAES128Key *localProfileKey;
|
||||
@property (nonatomic, readonly) OWSAES256Key *localProfileKey;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -36,17 +36,17 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
}
|
||||
|
||||
|
||||
- (OWSAES128Key *)localProfileKey
|
||||
- (OWSAES256Key *)localProfileKey
|
||||
{
|
||||
if (_localProfileKey == nil) {
|
||||
_localProfileKey = [OWSAES128Key generateRandomKey];
|
||||
_localProfileKey = [OWSAES256Key generateRandomKey];
|
||||
}
|
||||
return _localProfileKey;
|
||||
}
|
||||
|
||||
- (void)setProfileKeyData:(NSData *)profileKey forRecipientId:(NSString *)recipientId
|
||||
{
|
||||
OWSAES128Key *key = [OWSAES128Key keyWithData:profileKey];
|
||||
OWSAES256Key *key = [OWSAES256Key keyWithData:profileKey];
|
||||
NSAssert(key, @"Unable to build key. Invalid key data?");
|
||||
self.profileKeys[recipientId] = key;
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
@interface Cryptography (TestingPrivateMethods)
|
||||
|
||||
+ (nullable NSData *)decryptAESGCMWithInitializationVector:(NSData *)initializationVector
|
||||
cipherText:(NSData *)cipherText
|
||||
ciphertext:(NSData *)ciphertext
|
||||
authTag:(NSData *)authTagFromEncrypt
|
||||
key:(OWSAES128Key *)key;
|
||||
key:(OWSAES256Key *)key;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -134,8 +134,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
NSData *plainTextData = [@"Super🔥secret🔥test🔥data🏁🏁" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
// Sanity Check
|
||||
XCTAssertEqual(39, plainTextData.length);
|
||||
|
||||
OWSAES128Key *key = [OWSAES128Key new];
|
||||
|
||||
OWSAES256Key *key = [OWSAES256Key new];
|
||||
NSData *_Nullable encryptedData = [Cryptography encryptAESGCMWithData:plainTextData key:key];
|
||||
|
||||
const NSUInteger ivLength = 12;
|
||||
|
@ -156,7 +156,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
// Sanity Check
|
||||
XCTAssertEqual(39, plainTextData.length);
|
||||
|
||||
OWSAES128Key *key = [OWSAES128Key new];
|
||||
OWSAES256Key *key = [OWSAES256Key new];
|
||||
NSData *_Nullable encryptedData = [Cryptography encryptAESGCMWithData:plainTextData key:key];
|
||||
|
||||
const NSUInteger ivLength = 12;
|
||||
|
@ -174,7 +174,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
NSData *authTag = [encryptedData subdataWithRange:NSMakeRange(ivLength + cipherTextLength, tagLength)];
|
||||
|
||||
NSData *_Nullable decryptedData = [Cryptography decryptAESGCMWithInitializationVector:initializationVector
|
||||
cipherText:cipherText
|
||||
ciphertext:cipherText
|
||||
authTag:authTag
|
||||
key:key];
|
||||
|
||||
|
@ -194,7 +194,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[bogusAuthTag replaceBytesInRange:NSMakeRange(0, 1) withBytes:&flippedByte];
|
||||
|
||||
decryptedData = [Cryptography decryptAESGCMWithInitializationVector:initializationVector
|
||||
cipherText:cipherText
|
||||
ciphertext:cipherText
|
||||
authTag:bogusAuthTag
|
||||
key:key];
|
||||
|
||||
|
|
Loading…
Reference in a new issue