Checking error codes and cleaning up when errors occur in EvpKeyAgreement

- Added a test to actually exercise the DH agreement path
//FREEBIE
pull/1/head
Craig Gidney 10 years ago committed by Frederic Jacobs
parent 4dd8df8049
commit e9f8881bd4

@ -1017,7 +1017,6 @@
A157071D17F0CD6D007C2BD6 /* ShortAuthenticationStringGeneratorTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShortAuthenticationStringGeneratorTest.m; sourceTree = "<group>"; }; A157071D17F0CD6D007C2BD6 /* ShortAuthenticationStringGeneratorTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShortAuthenticationStringGeneratorTest.m; sourceTree = "<group>"; };
A157071F17F0CD6D007C2BD6 /* PregeneratedKeyAgreementParticipantProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PregeneratedKeyAgreementParticipantProtocol.h; sourceTree = "<group>"; }; A157071F17F0CD6D007C2BD6 /* PregeneratedKeyAgreementParticipantProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PregeneratedKeyAgreementParticipantProtocol.h; sourceTree = "<group>"; };
A157072017F0CD6D007C2BD6 /* PregeneratedKeyAgreementParticipantProtocol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PregeneratedKeyAgreementParticipantProtocol.m; sourceTree = "<group>"; }; A157072017F0CD6D007C2BD6 /* PregeneratedKeyAgreementParticipantProtocol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PregeneratedKeyAgreementParticipantProtocol.m; sourceTree = "<group>"; };
A157072117F0CD6D007C2BD6 /* ZrtpTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZrtpTest.h; sourceTree = "<group>"; };
A157072217F0CD6D007C2BD6 /* ZrtpTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZrtpTest.m; sourceTree = "<group>"; }; A157072217F0CD6D007C2BD6 /* ZrtpTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZrtpTest.m; sourceTree = "<group>"; };
A157072517F0CD6D007C2BD6 /* LowLatencyConnectorTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LowLatencyConnectorTest.m; sourceTree = "<group>"; }; A157072517F0CD6D007C2BD6 /* LowLatencyConnectorTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LowLatencyConnectorTest.m; sourceTree = "<group>"; };
A157072817F0CD6D007C2BD6 /* NetworkStreamTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NetworkStreamTest.m; sourceTree = "<group>"; }; A157072817F0CD6D007C2BD6 /* NetworkStreamTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NetworkStreamTest.m; sourceTree = "<group>"; };
@ -2271,7 +2270,6 @@
A157071B17F0CD6D007C2BD6 /* MasterSecretTest.m */, A157071B17F0CD6D007C2BD6 /* MasterSecretTest.m */,
A157071D17F0CD6D007C2BD6 /* ShortAuthenticationStringGeneratorTest.m */, A157071D17F0CD6D007C2BD6 /* ShortAuthenticationStringGeneratorTest.m */,
A157071E17F0CD6D007C2BD6 /* utilities */, A157071E17F0CD6D007C2BD6 /* utilities */,
A157072117F0CD6D007C2BD6 /* ZrtpTest.h */,
A157072217F0CD6D007C2BD6 /* ZrtpTest.m */, A157072217F0CD6D007C2BD6 /* ZrtpTest.m */,
E16E5BF818AAF02100B7C403 /* EC25AgreerTest.m */, E16E5BF818AAF02100B7C403 /* EC25AgreerTest.m */,
); );

@ -17,6 +17,7 @@
#define ENVIRONMENT_TESTING_OPTION_LOSE_CONF_ACK_ON_PURPOSE @"LoseConfAck" #define ENVIRONMENT_TESTING_OPTION_LOSE_CONF_ACK_ON_PURPOSE @"LoseConfAck"
#define ENVIRONMENT_TESTING_OPTION_ALLOW_NETWORK_STREAM_TO_NON_SECURE_END_POINTS @"AllowTcpWithoutTls" #define ENVIRONMENT_TESTING_OPTION_ALLOW_NETWORK_STREAM_TO_NON_SECURE_END_POINTS @"AllowTcpWithoutTls"
#define ENVIRONMENT_LEGACY_OPTION_RTP_PADDING_BIT_IMPLIES_EXTENSION_BIT_AND_TWELVE_EXTRA_ZERO_BYTES_IN_HEADER @"LegacyAndroidInterop_1" #define ENVIRONMENT_LEGACY_OPTION_RTP_PADDING_BIT_IMPLIES_EXTENSION_BIT_AND_TWELVE_EXTRA_ZERO_BYTES_IN_HEADER @"LegacyAndroidInterop_1"
#define TESTING_OPTION_USE_DH_FOR_HANDSHAKE @"DhKeyAgreementOnly"
@class RecentCallManager; @class RecentCallManager;
@class ContactsManager; @class ContactsManager;

@ -67,6 +67,11 @@ static unsigned char DH3K_PRIME[]={
} }
+(Environment*) unitTestEnvironment:(NSArray*)testingAndLegacyOptions { +(Environment*) unitTestEnvironment:(NSArray*)testingAndLegacyOptions {
NSArray* keyAgreementProtocols = self.supportedKeyAgreementProtocols;
if ([testingAndLegacyOptions containsObject:TESTING_OPTION_USE_DH_FOR_HANDSHAKE]) {
keyAgreementProtocols = @[[Release supportedDH3KKeyAgreementProtocol]];
}
return [Environment environmentWithLogging:[DiscardingLog discardingLog] return [Environment environmentWithLogging:[DiscardingLog discardingLog]
andErrorNoter:^(id error, id relatedInfo, bool causedTermination) {} andErrorNoter:^(id error, id relatedInfo, bool causedTermination) {}
andServerPort:31337 andServerPort:31337
@ -75,7 +80,7 @@ static unsigned char DH3K_PRIME[]={
andRelayServerHostNameSuffix:@"whispersystems.org" andRelayServerHostNameSuffix:@"whispersystems.org"
andCertificate:[Certificate certificateFromResourcePath:@"whisperReal" ofType:@"cer"] andCertificate:[Certificate certificateFromResourcePath:@"whisperReal" ofType:@"cer"]
andCurrentRegionCodeForPhoneNumbers:@"US" andCurrentRegionCodeForPhoneNumbers:@"US"
andSupportedKeyAgreementProtocols:[self supportedKeyAgreementProtocols] andSupportedKeyAgreementProtocols:keyAgreementProtocols
andPhoneManager:nil andPhoneManager:nil
andRecentCallManager:nil andRecentCallManager:nil
andTestingAndLegacyOptions:testingAndLegacyOptions andTestingAndLegacyOptions:testingAndLegacyOptions

@ -1,12 +1,11 @@
#import "EvpKeyAgreement.h" #import "EvpKeyAgreement.h"
#import "Constraints.h" #import "Util.h"
#import "NumberUtil.h"
#import <openssl/bn.h> #import <openssl/bn.h>
#import <openssl/dh.h> #import <openssl/dh.h>
#import <openssl/ec.h> #import <openssl/ec.h>
#import <openssl/pem.h> #import <openssl/pem.h>
#define checkEvpSucess(expr, desc) checkSecurityOperation((expr) == 1, desc) #define checkEvpOperationResult(expr) checkSecurityOperation((expr) == 1, @"An elliptic curve operation didn't succeed.")
#define checkEvpNotNull(expr, desc) checkSecurityOperation((expr) != NULL, desc) #define checkEvpNotNull(expr, desc) checkSecurityOperation((expr) != NULL, desc)
#define EC25_COORDINATE_LENGTH 32 #define EC25_COORDINATE_LENGTH 32
@ -64,8 +63,7 @@ enum KeyAgreementType {
ctx = EVP_PKEY_CTX_new_id(keyAgreementType, NULL); ctx = EVP_PKEY_CTX_new_id(keyAgreementType, NULL);
checkEvpNotNull(ctx , @"pctx_new_id"); checkEvpNotNull(ctx , @"pctx_new_id");
int ret = EVP_PKEY_paramgen_init(ctx); checkEvpOperationResult(EVP_PKEY_paramgen_init(ctx));
checkEvpSucess(ret, @"paramgen_init");
return ctx; return ctx;
} }
@ -79,15 +77,15 @@ enum KeyAgreementType {
@try{ @try{
checkEvpNotNull(dh, @"dh_new"); checkEvpNotNull(dh, @"dh_new");
dh->p= [self generateBignumberFor:modulus]; dh->p= [self generateBignumberFor:modulus];
dh->g= [self generateBignumberFor:generator]; dh->g= [self generateBignumberFor:generator];
if ((dh->p == NULL) || (dh->g == NULL)) if ((dh->p == NULL) || (dh->g == NULL))
{ {
[self reportError:@"DH Parameters uninitialized"]; [self reportError:@"DH Parameters uninitialized"];
} }
[self createNewEvpKeyFreePreviousIfNessesary:&params]; [self createNewEvpKeyFreePreviousIfNessesary:&params];
EVP_PKEY_set1_DH(params, dh); EVP_PKEY_set1_DH(params, dh);
@ -100,56 +98,47 @@ enum KeyAgreementType {
-(void) generateEc25Parameters { -(void) generateEc25Parameters {
EVP_PKEY_CTX* pctx = [self createParameterContext]; EVP_PKEY_CTX* pctx = [self createParameterContext];
int ret; checkEvpOperationResult(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NAMED_ELLIPTIC_CURVE));
ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NAMED_ELLIPTIC_CURVE);
checkEvpSucess(ret, @"pctx_ec_init");
ret = EVP_PKEY_paramgen(pctx, &params); checkEvpOperationResult(EVP_PKEY_paramgen(pctx, &params));
checkEvpSucess(ret,@"pctx_paramgen" );
EVP_PKEY_CTX_free(pctx); EVP_PKEY_CTX_free(pctx);
} }
-(void) generateKeyPair { -(void) generateKeyPair {
int ret;
EVP_PKEY_CTX* kctx;
checkEvpNotNull(params, @"parameters uninitialized"); checkEvpNotNull(params, @"parameters uninitialized");
kctx = EVP_PKEY_CTX_new(params, NULL); EVP_PKEY_CTX* kctx = NULL;
checkEvpNotNull(kctx, @"key_ctx"); @try {
kctx = EVP_PKEY_CTX_new(params, NULL);
ret = EVP_PKEY_keygen_init(kctx); checkEvpNotNull(kctx, @"key_ctx");
checkEvpSucess(ret, @"keygen_init");
checkEvpOperationResult(EVP_PKEY_keygen_init(kctx));
ret = EVP_PKEY_keygen(kctx, &pkey);
checkEvpSucess(ret, @"keygen"); checkEvpOperationResult(EVP_PKEY_keygen(kctx, &pkey));
} @finally {
EVP_PKEY_CTX_free(kctx); if (kctx != NULL) EVP_PKEY_CTX_free(kctx);
}
} }
-(NSData*) getSharedSecretForRemotePublicKey:(NSData*) publicKey{ -(NSData*) getSharedSecretForRemotePublicKey:(NSData*)publicKey {
size_t secret_len; EVP_PKEY* peerkey = [self deserializePublicKey:publicKey];
unsigned char* secret; EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(pkey, NULL);
checkEvpNotNull(ctx, @"ctx_new");
EVP_PKEY* peerkey = [self deserializePublicKey:[publicKey bytes] withLength:publicKey.length]; checkEvpOperationResult(EVP_PKEY_derive_init(ctx));
EVP_PKEY_CTX* ctx; checkEvpOperationResult(EVP_PKEY_derive_set_peer(ctx, peerkey));
size_t secret_len;
checkEvpOperationResult(EVP_PKEY_derive(ctx, NULL, &secret_len));
ctx = EVP_PKEY_CTX_new(pkey, NULL); unsigned char* secret = OPENSSL_malloc(secret_len);
checkEvpNotNull(ctx, @"ctx_new"); checkEvpNotNull(secret, @"OPENSSL_malloc");
checkEvpSucess(EVP_PKEY_derive_init(ctx), @"derive_init"); checkEvpOperationResult(EVP_PKEY_derive(ctx, secret, &secret_len));
checkEvpSucess(EVP_PKEY_derive_set_peer(ctx, peerkey), @"set_peer");
checkEvpSucess(EVP_PKEY_derive(ctx, NULL, &secret_len), @"derive_step1");
secret = OPENSSL_malloc(secret_len);
checkEvpNotNull(secret, @"secret_malloc");
checkEvpSucess(EVP_PKEY_derive(ctx, secret, &secret_len), @"derive_step2");
NSData* secretData = [NSData dataWithBytes:secret length:secret_len]; NSData* secretData = [NSData dataWithBytes:secret length:secret_len];
EVP_PKEY_CTX_free(ctx); EVP_PKEY_CTX_free(ctx);
@ -173,80 +162,124 @@ enum KeyAgreementType {
} }
-(NSData*) serializeDhPublicKey:(EVP_PKEY*)evkey { -(NSData*) serializeDhPublicKey:(EVP_PKEY*)evkey {
DH* dh = NULL;
DH* dh; unsigned char* buf = NULL;
unsigned char* buf; @try {
dh = EVP_PKEY_get1_DH(evkey);
dh = EVP_PKEY_get1_DH(evkey); checkEvpNotNull(dh, @"EVP_PKEY_get1_DH");
int bufsize = BN_num_bytes(dh->pub_key); int publicKeySize = BN_num_bytes(dh->pub_key);
buf = OPENSSL_malloc(bufsize); NSMutableData* publicKeyBuffer = [NSMutableData dataWithLength:(NSUInteger)publicKeySize];
checkEvpNotNull(buf, @"dh_pubkey_buffer");
int wroteLength = BN_bn2bin(dh->pub_key, publicKeyBuffer.mutableBytes);
BN_bn2bin(dh->pub_key, buf); checkSecurityOperation(wroteLength == (long long)publicKeyBuffer.length, @"BN_bn2bin");
NSData* pub_key = [NSData dataWithBytes:buf length:(unsigned int)bufsize];
return publicKeyBuffer;
DH_free(dh); } @finally {
OPENSSL_free(buf); if (dh != NULL) DH_free(dh);
if (buf != NULL) OPENSSL_free(buf);
return pub_key; }
} }
-(NSData*) serializeEcPublicKey:(EVP_PKEY*)evkey { -(NSData*) serializeEcPublicKey:(EVP_PKEY*)evkey {
require(evkey != NULL);
EC_KEY* ec_key = EVP_PKEY_get1_EC_KEY(evkey); EC_KEY* ec_key = NULL;
const EC_POINT* ec_pub = EC_KEY_get0_public_key(ec_key); @try {
const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key); ec_key = EVP_PKEY_get1_EC_KEY(evkey);
checkEvpNotNull(ec_key, @"EVP_PKEY_get1_EC_KEY");
NSData* data = [self packEcCoordinatesFromEcPoint:ec_pub withEcGroup:ec_group];
const EC_POINT* ec_pub = EC_KEY_get0_public_key(ec_key);
EC_KEY_free(ec_key); checkEvpNotNull(ec_pub, @"EC_KEY_get0_public_key");
return data; const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key);
checkEvpNotNull(ec_group, @"EC_KEY_get0_group");
return [self packEcCoordinatesFromEcPoint:ec_pub withEcGroup:ec_group];
} @finally {
EC_KEY_free(ec_key);
}
} }
-(EVP_PKEY*) deserializePublicKey:(const unsigned char*) buf withLength:(size_t) bufsize { -(EVP_PKEY*) deserializePublicKey:(NSData*)buf {
switch (keyAgreementType) { switch (keyAgreementType) {
case KeyAgreementType_DH: case KeyAgreementType_DH:
return [self deserializeDhPublicKey:buf withLength:bufsize]; return [self deserializeDhPublicKey:buf];
case KeyAgreementType_ECDH: case KeyAgreementType_ECDH:
return [self deserializeEcPublicKey:buf withLength:bufsize]; return [self deserializeEcPublicKey:buf];
default: default:
[self reportError:@"Undefined KeyType"]; [self reportError:@"Undefined KeyType"];
} }
} }
-(EVP_PKEY*) deserializeDhPublicKey:(const unsigned char*) buf withLength:(size_t) bufsize { -(EVP_PKEY*) deserializeDhPublicKey:(NSData*)buf {
EVP_PKEY* evpk = NULL;
EVP_PKEY* evpk = EVP_PKEY_new(); DH* dh = NULL;
DH* dh = DH_new(); BIGNUM* bn = NULL;
@try {
BIGNUM* bn = BN_new(); evpk = EVP_PKEY_new();
BN_bin2bn(buf, [NumberUtil assertConvertNSUIntegerToInt:bufsize], bn); checkEvpNotNull(evpk, @"EVP_PKEY_new");
dh->pub_key = bn;
dh = DH_new();
EVP_PKEY_assign_DH(evpk, dh); checkEvpNotNull(dh, @"DH_new");
return evpk; bn = BN_bin2bn(buf.bytes, [NumberUtil assertConvertNSUIntegerToInt:buf.length], NULL);
checkEvpNotNull(bn, @"BN_bin2bn");
dh->pub_key = bn;
checkEvpOperationResult(EVP_PKEY_assign_DH(evpk, dh));
// Return without cleaning up the result
EVP_PKEY* result = evpk;
evpk = NULL;
dh = NULL;
bn = NULL;
return result;
} @finally {
if (evpk != NULL) EVP_PKEY_free(evpk);
if (dh != NULL) DH_free(dh);
if (bn != NULL) BN_free(bn);
}
} }
-(EVP_PKEY*) deserializeEcPublicKey:(const unsigned char*) buf withLength:(size_t) bufsize { -(EVP_PKEY*) deserializeEcPublicKey:(NSData*)buf {
EC_KEY* eck = EC_KEY_new_by_curve_name(NAMED_ELLIPTIC_CURVE); EC_KEY* key = NULL;
const EC_GROUP* ecg = EC_KEY_get0_group(eck); EC_POINT* publicKeyPoint = NULL;
EVP_PKEY* publicKey = NULL;
EC_POINT* ecp = EC_POINT_new(ecg); @try {
[self unpackEcCoordinatesFromBuffer:buf ofSize:bufsize toEcPoint:ecp withEcGroup:ecg]; key = EC_KEY_new_by_curve_name(NAMED_ELLIPTIC_CURVE);
checkSecurityOperation(key != NULL, @"EC_KEY_new_by_curve_name");
EVP_PKEY* evpk = EVP_PKEY_new();
EC_KEY_set_public_key(eck, ecp); const EC_GROUP* group = EC_KEY_get0_group(key);
EVP_PKEY_assign_EC_KEY(evpk, eck); checkSecurityOperation(group != NULL, @"EC_KEY_get0_group");
EC_POINT_free(ecp); publicKeyPoint = EC_POINT_new(group);
checkSecurityOperation(publicKeyPoint != NULL, @"EC_POINT_new");
return evpk;
[self unpackEcCoordinatesFromBuffer:buf
toEcPoint:publicKeyPoint
withEcGroup:group];
publicKey = EVP_PKEY_new();
checkSecurityOperation(publicKey != NULL, @"EVP_PKEY_new");
checkEvpOperationResult(EC_KEY_set_public_key(key, publicKeyPoint));
checkEvpOperationResult(EVP_PKEY_assign_EC_KEY(publicKey, key));
// Return without cleaning up the result
EVP_PKEY* result = publicKey;
publicKey = NULL;
key = NULL;
publicKeyPoint = NULL;
return result;
} @finally {
if (key != NULL) EC_KEY_free(key);
if (publicKeyPoint != NULL) EC_POINT_free(publicKeyPoint);
if (publicKey != NULL) EVP_PKEY_free(publicKey);
}
} }
-(NSData*) packEcCoordinatesFromEcPoint:(const EC_POINT*) ec_point withEcGroup:(const EC_GROUP*) ec_group { -(NSData*) packEcCoordinatesFromEcPoint:(const EC_POINT*) ec_point withEcGroup:(const EC_GROUP*) ec_group {
@ -256,16 +289,16 @@ enum KeyAgreementType {
x = BN_new(); x = BN_new();
y = BN_new(); y = BN_new();
checkSecurityOperation(x != NULL && y != NULL, @"BN_new"); checkSecurityOperation(x != NULL && y != NULL, @"BN_new");
checkSecurityOperation(1 == EC_POINT_get_affine_coordinates_GFp(ec_group, ec_point, x, y, NULL), @"EC_POINT_get_affine_coordinates_GFp"); checkEvpOperationResult(EC_POINT_get_affine_coordinates_GFp(ec_group, ec_point, x, y, NULL));
int len_x = BN_num_bytes(x); int len_x = BN_num_bytes(x);
int len_y = BN_num_bytes(y); int len_y = BN_num_bytes(y);
checkSecurityOperation(len_x >= 0 && len_x <= EC25_COORDINATE_LENGTH, @"BN_num_bytes(x)"); checkSecurityOperation(len_x >= 0 && len_x <= EC25_COORDINATE_LENGTH, @"BN_num_bytes(x)");
checkSecurityOperation(len_y >= 0 && len_y <= EC25_COORDINATE_LENGTH, @"BN_num_bytes(y)"); checkSecurityOperation(len_y >= 0 && len_y <= EC25_COORDINATE_LENGTH, @"BN_num_bytes(y)");
int unused_x = EC25_COORDINATE_LENGTH - len_x; int unused_x = EC25_COORDINATE_LENGTH - len_x;
int unused_y = EC25_COORDINATE_LENGTH - len_y; int unused_y = EC25_COORDINATE_LENGTH - len_y;
NSMutableData* data = [NSMutableData dataWithLength:EC25_COORDINATE_LENGTH*2]; NSMutableData* data = [NSMutableData dataWithLength:EC25_COORDINATE_LENGTH*2];
// We offset the writes to keep things constant sized. // We offset the writes to keep things constant sized.
@ -281,23 +314,25 @@ enum KeyAgreementType {
} }
} }
-(void) unpackEcCoordinatesFromBuffer:(const unsigned char*) buffer -(void) unpackEcCoordinatesFromBuffer:(NSData*)buffer
ofSize:(size_t) bufsize toEcPoint:(EC_POINT*)ecp
toEcPoint:(EC_POINT*) ecp withEcGroup:(const EC_GROUP*)ecg {
withEcGroup:(const EC_GROUP*) ecg {
checkOperation(2*EC25_COORDINATE_LENGTH == bufsize);
BIGNUM* x = BN_new();
BIGNUM* y = BN_new();
BN_bin2bn(buffer, EC25_COORDINATE_LENGTH, x); checkOperation(buffer.length == 2*EC25_COORDINATE_LENGTH);
BN_bin2bn(buffer+EC25_COORDINATE_LENGTH, EC25_COORDINATE_LENGTH, y);
EC_POINT_set_affine_coordinates_GFp(ecg, ecp, x, y, NULL); BIGNUM* x = NULL;
BIGNUM* y = NULL;
BN_free(x); @try {
BN_free(y); const unsigned char* bytes = buffer.bytes;
x = BN_bin2bn(bytes, EC25_COORDINATE_LENGTH, NULL);
y = BN_bin2bn(bytes + EC25_COORDINATE_LENGTH, EC25_COORDINATE_LENGTH, NULL);
checkSecurityOperation(x != NULL && y != NULL, @"BN_bin2bn");
checkEvpOperationResult(EC_POINT_set_affine_coordinates_GFp(ecg, ecp, x, y, NULL));
} @finally {
if (x != NULL) BN_free(x);
if (y != NULL) BN_free(y);
}
} }
#pragma mark Helper Functions #pragma mark Helper Functions
@ -324,9 +359,4 @@ enum KeyAgreementType {
[SecurityFailure raise:[NSString stringWithFormat:@"Security related failure: %@ (in %s at line %d)", errorString,__FILE__,__LINE__]]; [SecurityFailure raise:[NSString stringWithFormat:@"Security related failure: %@ (in %s at line %d)", errorString,__FILE__,__LINE__]];
} }
@end @end

@ -1,17 +0,0 @@
#import <XCTest/XCTest.h>
#import "ZrtpManager.h"
#import "HelloPacket.h"
#import "ConfirmPacket.h"
#import "DhPacket.h"
#import "CommitPacket.h"
#import "HandshakePacket.h"
#import "Util.h"
#import "DH3KKeyAgreementProtocol.h"
#import "PregeneratedKeyAgreementParticipantProtocol.h"
#import "MasterSecret.h"
#import "ZrtpResponder.h"
#import "ZrtpInitiator.h"
@interface ZrtpTest : XCTestCase
@end

@ -1,6 +1,8 @@
#import "ZrtpTest.h" #import <XCTest/XCTest.h>
#import "ZrtpHandshakeResult.h"
#import "TestUtil.h" #import "TestUtil.h"
#import "Util.h"
#import "CallController.h"
#import "ZrtpManager.h"
#import "ThreadManager.h" #import "ThreadManager.h"
#import "ZrtpHandshakeResult.h" #import "ZrtpHandshakeResult.h"
#import "DiscardingLog.h" #import "DiscardingLog.h"
@ -19,6 +21,9 @@ bool pm(HandshakePacket* p1, HandshakePacket* p2) {
} }
#define AssertPacketsMatch(p1, p2) STAssertTrue(pm(p1, p2), @"") #define AssertPacketsMatch(p1, p2) STAssertTrue(pm(p1, p2), @"")
@interface ZrtpTest : XCTestCase
@end
@implementation ZrtpTest @implementation ZrtpTest
- (void)setUp{ - (void)setUp{
@ -94,4 +99,32 @@ bool pm(HandshakePacket* p1, HandshakePacket* p2) {
[cc2 terminateWithReason:CallTerminationType_HangupLocal withFailureInfo:nil andRelatedInfo:nil]; [cc2 terminateWithReason:CallTerminationType_HangupLocal withFailureInfo:nil andRelatedInfo:nil];
} }
-(void) testDhHandshake {
[Environment setCurrent:testEnvWith(TESTING_OPTION_USE_DH_FOR_HANDSHAKE)];
IpEndPoint* receiver = [IpEndPoint ipEndPointAtAddress:[IpAddress localhost]
onPort:10000 + (in_port_t)arc4random_uniform(20000)];
UdpSocket* u1 = [UdpSocket udpSocketToFirstSenderOnLocalPort:receiver.port];
CallController* cc1 = [CallController callControllerForCallInitiatedLocally:true
withRemoteNumber:testPhoneNumber1
andOptionallySpecifiedContact:nil];
TOCFuture* f1 = [ZrtpManager asyncPerformHandshakeOver:[RtpSocket rtpSocketOverUdp:u1 interopOptions:@[]]
andCallController:cc1];
UdpSocket* u2 = [UdpSocket udpSocketTo:receiver];
CallController* cc2 = [CallController callControllerForCallInitiatedLocally:false
withRemoteNumber:testPhoneNumber2
andOptionallySpecifiedContact:nil];
TOCFuture* f2 = [ZrtpManager asyncPerformHandshakeOver:[RtpSocket rtpSocketOverUdp:u2 interopOptions:@[]]
andCallController:cc2];
testChurnUntil(!f1.isIncomplete && !f2.isIncomplete, 15.0);
test(f1.hasResult);
test(f2.hasResult);
[cc1 terminateWithReason:CallTerminationType_HangupLocal withFailureInfo:nil andRelatedInfo:nil];
[cc2 terminateWithReason:CallTerminationType_HangupLocal withFailureInfo:nil andRelatedInfo:nil];
}
@end @end

Loading…
Cancel
Save