Regression test for provisioning cipher

// FREEBIE
pull/1/head
Michael Kirk 8 years ago
parent 59f2c4674c
commit 1f7b6f61c6

@ -38,7 +38,7 @@ PODS:
- Reachability (3.2)
- SAMKeychain (1.5.2)
- SignalServiceKit (0.9.0):
- 25519
- '25519'
- AFNetworking
- AxolotlKit
- CocoaLumberjack
@ -134,7 +134,7 @@ CHECKOUT OPTIONS:
:git: https://github.com/facebook/SocketRocket.git
SPEC CHECKSUMS:
25519: dc4bad7e2dbcbf1efa121068a705a44cd98c80fc
'25519': dc4bad7e2dbcbf1efa121068a705a44cd98c80fc
AFNetworking: 5e0e199f73d8626b11e79750991f5d173d1f8b67
AxolotlKit: a9530d6835baae0f204b1f6b9dd79b7901176f0d
CocoaLumberjack: aa9dcab71bdf9eaf2a63bbd9ddc87863efe45457
@ -154,4 +154,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 8eff8ab93f8a0a1024e17b16fee43f3a93656c2c
COCOAPODS: 1.3.1
COCOAPODS: 1.2.1

@ -11,6 +11,7 @@
34D99C891F2250FF00D284D6 /* OWSAnalyticsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D99C881F2250FF00D284D6 /* OWSAnalyticsTests.m */; };
45046FE01D95A6130015EFF2 /* TSMessagesManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 45046FDF1D95A6130015EFF2 /* TSMessagesManagerTest.m */; };
450E3C9A1D96DD2600BF4EB6 /* OWSDisappearingMessagesJobTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 450E3C991D96DD2600BF4EB6 /* OWSDisappearingMessagesJobTest.m */; };
451686AE1F527A9C00AC3D4B /* OWSProvisioningCipherTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 451686AD1F527A9C00AC3D4B /* OWSProvisioningCipherTest.m */; };
4516E3E81DD153CC00DC4206 /* TSGroupThreadTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 4516E3E71DD153CC00DC4206 /* TSGroupThreadTest.m */; };
4516E3EA1DD1542300DC4206 /* TSContactThreadTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 4516E3E91DD1542300DC4206 /* TSContactThreadTest.m */; };
452137231E8D6D2F0048FD10 /* OWSFakeMessageSender.m in Sources */ = {isa = PBXBuildFile; fileRef = 452137221E8D6D2F0048FD10 /* OWSFakeMessageSender.m */; };
@ -70,6 +71,7 @@
36DA6C703F99948D553F4E3F /* Pods-TSKitiOSTestAppTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TSKitiOSTestAppTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-TSKitiOSTestAppTests/Pods-TSKitiOSTestAppTests.debug.xcconfig"; sourceTree = "<group>"; };
45046FDF1D95A6130015EFF2 /* TSMessagesManagerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TSMessagesManagerTest.m; path = ../../../tests/Messages/TSMessagesManagerTest.m; sourceTree = "<group>"; };
450E3C991D96DD2600BF4EB6 /* OWSDisappearingMessagesJobTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWSDisappearingMessagesJobTest.m; path = ../../../tests/Messages/OWSDisappearingMessagesJobTest.m; sourceTree = "<group>"; };
451686AD1F527A9C00AC3D4B /* OWSProvisioningCipherTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWSProvisioningCipherTest.m; path = ../../../tests/Devices/OWSProvisioningCipherTest.m; sourceTree = "<group>"; };
4516E3E71DD153CC00DC4206 /* TSGroupThreadTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TSGroupThreadTest.m; path = ../../../tests/Contacts/TSGroupThreadTest.m; sourceTree = "<group>"; };
4516E3E91DD1542300DC4206 /* TSContactThreadTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TSContactThreadTest.m; path = ../../../tests/Contacts/TSContactThreadTest.m; sourceTree = "<group>"; };
452137211E8D6D2F0048FD10 /* OWSFakeMessageSender.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWSFakeMessageSender.h; path = ../../../tests/TestSupport/Fakes/OWSFakeMessageSender.h; sourceTree = "<group>"; };
@ -263,6 +265,7 @@
children = (
45D7243E1D67899F00E0CA54 /* OWSDeviceProvisionerTest.m */,
45B840201D988DA100F9E938 /* OWSReadReceiptTest.m */,
451686AD1F527A9C00AC3D4B /* OWSProvisioningCipherTest.m */,
);
name = Devices;
sourceTree = "<group>";
@ -468,7 +471,7 @@
);
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# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\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";
showEnvVarsInLog = 0;
};
276B029791E679B0E87877B7 /* [CP] Copy Pods Resources */ = {
@ -551,7 +554,7 @@
);
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# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\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";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
@ -590,6 +593,7 @@
45AE48491E072711004D96C2 /* OWSUnitTestEnvironment.m in Sources */,
459850C11D22C6F2006FFEDB /* PhoneNumberTest.m in Sources */,
45DC30C71F3B69B7008C4378 /* OWSFakeProfileManager.m in Sources */,
451686AE1F527A9C00AC3D4B /* OWSProvisioningCipherTest.m in Sources */,
45458B7A1CC342B600A02153 /* TSStorageSignedPreKeyStore.m in Sources */,
453E1FDB1DA83EFB00DDD7B7 /* OWSFakeContactsUpdater.m in Sources */,
452137231E8D6D2F0048FD10 /* OWSFakeMessageSender.m in Sources */,

@ -1,4 +1,6 @@
// Copyright © 2016 Open Whisper Systems. All rights reserved.
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSProvisioningCipher.h"
#import <25519/Curve25519.h>
@ -11,21 +13,33 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) NSData *theirPublicKey;
@property (nonatomic, readonly) ECKeyPair *ourKeyPair;
@property (nonatomic, readonly) NSData *initializationVector;
@end
@implementation OWSProvisioningCipher
- (instancetype)initWithTheirPublicKey:(NSData *)theirPublicKey
{
return [self initWithTheirPublicKey:theirPublicKey
ourKeyPair:[Curve25519 generateKeyPair]
initializationVector:[Cryptography generateRandomBytes:kCCBlockSizeAES128]];
}
- (instancetype)initWithTheirPublicKey:(NSData *)theirPublicKey
ourKeyPair:(ECKeyPair *)ourKeyPair
initializationVector:(NSData *)initializationVector
{
self = [super init];
if (!self) {
return self;
}
_theirPublicKey = theirPublicKey;
_ourKeyPair = [Curve25519 generateKeyPair];
_ourKeyPair = ourKeyPair;
_initializationVector = initializationVector;
return self;
}
@ -61,7 +75,9 @@ NS_ASSUME_NONNULL_BEGIN
- (NSData *)encrypt:(NSData *)dataToEncrypt withKey:(NSData *)cipherKey
{
NSData *iv = [Cryptography generateRandomBytes:kCCBlockSizeAES128];
NSData *iv = self.initializationVector;
OWSAssert(iv.length == kCCBlockSizeAES128);
// allow space for message + padding any incomplete block
size_t bufferSize = dataToEncrypt.length + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);

@ -0,0 +1,134 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <XCTest/XCTest.h>
#import <SignalServiceKit/OWSProvisioningCipher.h>
#import <25519/Curve25519.h>
#import <SignalServiceKit/Cryptography.h>
@interface OWSProvisioningCipher(Testing)
// Expose private method for testing.
- (instancetype)initWithTheirPublicKey:(NSData *)theirPublicKey
ourKeyPair:(ECKeyPair *)ourKeyPair
initializationVector:(NSData *)initializationVector;
@end
@interface OWSProvisioningCipherTest : XCTestCase
@end
@implementation OWSProvisioningCipherTest
- (NSData *)knownInitializationVector
{
uint8_t initilizationVectorBytes[] = {
0xec, 0x67, 0x0b, 0xb7,
0x18, 0xe1, 0xe9, 0x0a,
0xcc, 0x5e, 0xcb, 0x37,
0xab, 0x79, 0xe0, 0x09
};
return [NSData dataWithBytes:initilizationVectorBytes length:16];
}
- (NSData *)knownPublicKey
{
uint8_t knownPublicKeyBytes[] = {
0x5e, 0x23, 0xe8, 0x49,
0xb2, 0x23, 0x21, 0xdb,
0x2e, 0x3a, 0x77, 0x74,
0x6f, 0x3b, 0x44, 0x18,
0xcc, 0x6c, 0x81, 0xce,
0xd5, 0xc2, 0x91, 0xaf,
0xed, 0xfb, 0x21, 0x4e,
0x59, 0xcc, 0x19, 0xa4
};
return [NSData dataWithBytes:knownPublicKeyBytes length: 32];
}
- (ECKeyPair *)knownKeyPair
{
uint8_t privateKeyBytes[] = {
0x60, 0xfd, 0xc1, 0xeb,
0x6a, 0x68, 0x3d, 0x2b,
0x51, 0x23, 0x1f, 0xea,
0x1a, 0x5e, 0x80, 0x88,
0x0c, 0x65, 0x2d, 0x3d,
0x47, 0x9e, 0x28, 0xc1,
0x9f, 0x48, 0x2c, 0x66,
0xde, 0x48, 0x5d, 0x57
};
uint8_t publicKeyBytes[] = {
0x02, 0x62, 0x7b, 0x5c,
0x21, 0x15, 0x59, 0x1b,
0x37, 0xd1, 0xfe, 0xeb,
0x15, 0x5d, 0xd2, 0x95,
0x0a, 0xce, 0xe8, 0xb2,
0x1e, 0x8e, 0xc8, 0xd6,
0x53, 0x4f, 0x1a, 0xcd,
0xf2, 0x00, 0x98, 0x32
};
// Righteous hack to build a deterministic ECKeyPair
// The publicKey/privateKey ivars are private but it's possible to `initWithCoder:` given the proper keys.
NSKeyedArchiver *archiver = [NSKeyedArchiver new];
[archiver encodeBytes:publicKeyBytes length:ECCKeyLength forKey:@"TSECKeyPairPublicKey"];
[archiver encodeBytes:privateKeyBytes length:ECCKeyLength forKey:@"TSECKeyPairPrivateKey"];
NSData *serialized = [archiver encodedData];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:serialized];
return [[ECKeyPair alloc] initWithCoder:unarchiver];
}
- (NSData *)knownData
{
uint8_t knownBytes[] = {
0x19, 0x33, 0x78, 0x64,
0x96, 0x56, 0xa7, 0xd0,
0x6e, 0xff, 0x37, 0x1d
};
return [NSData dataWithBytes:knownBytes length:12];
}
- (void)testEncrypt
{
NSData *theirPublicKey = [self knownPublicKey];
ECKeyPair *ourKeyPair = [self knownKeyPair];
NSData *initializationVector = [self knownInitializationVector];
OWSProvisioningCipher *cipher = [[OWSProvisioningCipher alloc] initWithTheirPublicKey:theirPublicKey
ourKeyPair:ourKeyPair
initializationVector:initializationVector];
NSData *message = [self knownData];
NSData *actualOutput = [cipher encrypt:message];
uint8_t expectedBytes[] = {
0x01, 0xec, 0x67, 0x0b,
0xb7, 0x18, 0xe1, 0xe9,
0x0a, 0xcc, 0x5e, 0xcb,
0x37, 0xab, 0x79, 0xe0,
0x09, 0xf7, 0x2b, 0xf7,
0x14, 0x3d, 0x45, 0xd7,
0x45, 0x79, 0x1e, 0x4f,
0x9d, 0x34, 0x8a, 0x2d,
0x43, 0x64, 0xd4, 0x7d,
0x48, 0x9a, 0xdc, 0x5a,
0xc3, 0x72, 0xfa, 0x63,
0x41, 0x7a, 0xa8, 0x45,
0x36, 0xe9, 0xc5, 0xcb,
0xee, 0x9b, 0xc1, 0x1f,
0xec, 0x31, 0x1e, 0xc2,
0x33, 0x2d, 0x95, 0x54,
0xcc
};
NSData *expectedOutput = [NSData dataWithBytes:expectedBytes length:65];
XCTAssertEqualObjects(expectedOutput, actualOutput);
}
@end
Loading…
Cancel
Save