Merge pull request #145 from Strilanc/audio_stampery

Setting timestamp based on number of samples sent
pull/1/head
Frederic Jacobs 11 years ago
commit 54043cd80d

@ -20,6 +20,7 @@
@interface AudioPacker : NSObject {
@private NSMutableArray* framesToSend;
@private uint16_t nextSequenceNumber;
@private uint32_t nextTimeStamp;
@private Queue* audioFrameToReceiveQueue;
}

@ -9,6 +9,7 @@
AudioPacker* newAudioPackerInstance = [AudioPacker new];
newAudioPackerInstance->audioFrameToReceiveQueue = [Queue new];
newAudioPackerInstance->framesToSend = [NSMutableArray array];
newAudioPackerInstance->nextTimeStamp = [CryptoTools generateSecureRandomUInt32];
newAudioPackerInstance->nextSequenceNumber = [CryptoTools generateSecureRandomUInt16];
// interop fix:
@ -29,10 +30,13 @@
if (framesToSend.count < AUDIO_FRAMES_PER_PACKET) return nil;
uint16_t sequenceNumber = nextSequenceNumber++;
NSData* payload = [framesToSend concatDatas];
uint32_t timeStamp = nextTimeStamp;
NSData* payload = framesToSend.concatDatas;
nextTimeStamp += payload.length;
[framesToSend removeAllObjects];
return [EncodedAudioPacket encodedAudioPacketWithAudioData:payload
andTimeStamp:timeStamp
andSequenceNumber:sequenceNumber];
}

@ -19,19 +19,21 @@
PacketHandlerBlock valueHandler = ^(RtpPacket* rtpPacket) {
require(rtpPacket != nil);
require([rtpPacket isKindOfClass:[RtpPacket class]]);
[handler handlePacket:[EncodedAudioPacket encodedAudioPacketWithAudioData:[rtpPacket payload]
andSequenceNumber:[rtpPacket sequenceNumber]]];
[handler handlePacket:[EncodedAudioPacket encodedAudioPacketWithAudioData:rtpPacket.payload
andTimeStamp:rtpPacket.timeStamp
andSequenceNumber:rtpPacket.sequenceNumber]];
};
[srtpSocket startWithHandler:[PacketHandler packetHandler:valueHandler
withErrorHandler:[handler errorHandler]]
withErrorHandler:handler.errorHandler]
untilCancelled:untilCancelledToken];
}
-(void) send:(EncodedAudioPacket*)audioPacket {
require(audioPacket != nil);
RtpPacket* rtpPacket = [RtpPacket rtpPacketWithDefaultsAndSequenceNumber:[audioPacket sequenceNumber]
andPayload:[audioPacket audioData]];
RtpPacket* rtpPacket = [RtpPacket rtpPacketWithDefaultsAndSequenceNumber:audioPacket.sequenceNumber
andTimeStamp:audioPacket.timeStamp
andPayload:audioPacket.audioData];
[srtpSocket secureAndSendRtpPacket:rtpPacket];
}

@ -12,8 +12,11 @@
@interface EncodedAudioPacket : NSObject
@property (readonly,nonatomic) NSData* audioData;
@property (readonly,nonatomic) uint32_t timeStamp;
@property (readonly,nonatomic) uint16_t sequenceNumber;
+(EncodedAudioPacket*) encodedAudioPacketWithAudioData:(NSData*)audioData andSequenceNumber:(uint16_t)sequenceNumber;
+(EncodedAudioPacket*) encodedAudioPacketWithAudioData:(NSData*)audioData
andTimeStamp:(uint32_t)timeStamp
andSequenceNumber:(uint16_t)sequenceNumber;
@end

@ -5,10 +5,13 @@
@synthesize audioData, sequenceNumber;
+(EncodedAudioPacket*) encodedAudioPacketWithAudioData:(NSData*)audioData andSequenceNumber:(uint16_t)sequenceNumber {
+(EncodedAudioPacket*) encodedAudioPacketWithAudioData:(NSData*)audioData
andTimeStamp:(uint32_t)timeStamp
andSequenceNumber:(uint16_t)sequenceNumber {
require(audioData != nil);
EncodedAudioPacket* p = [EncodedAudioPacket new];
p->audioData = audioData;
p->_timeStamp = timeStamp; // Not sure why timeStamp gets a leading underscore but the others don't; probably a reserved name?
p->sequenceNumber = sequenceNumber;
return p;
}

@ -8,6 +8,9 @@
/// Returns a secure random 16-bit unsigned integer.
+(uint16_t)generateSecureRandomUInt16;
/// Returns a secure random 32-bit unsigned integer.
+(uint32_t)generateSecureRandomUInt32;
/// Returns data composed of 'length' cryptographically unpredictable bytes sampled uniformly from [0, 256).
+(NSData*)generateSecureRandomData:(NSUInteger)length;

@ -20,6 +20,10 @@
return [[self generateSecureRandomData:sizeof(uint16_t)] bigEndianUInt16At:0];
}
+(uint32_t)generateSecureRandomUInt32 {
return [[self generateSecureRandomData:sizeof(uint32_t)] bigEndianUInt32At:0];
}
+(NSString*) computeOtpWithPassword:(NSString*)password andCounter:(int64_t)counter {
require(password != nil);

@ -26,7 +26,9 @@
@property (nonatomic,readonly) uint32_t synchronizationSourceIdentifier;
@property (nonatomic,readonly) NSData* payload;
+(RtpPacket*) rtpPacketWithDefaultsAndSequenceNumber:(uint16_t)sequenceNumber andPayload:(NSData*)payload;
+(RtpPacket*) rtpPacketWithDefaultsAndSequenceNumber:(uint16_t)sequenceNumber
andTimeStamp:(uint32_t)timeStamp
andPayload:(NSData *)payload;
+(RtpPacket*) rtpPacketWithVersion:(uint8_t)version
andPadding:(uint8_t)padding

@ -42,7 +42,9 @@ const uint8_t PACKET_VERSION = 2;
@synthesize version;
@synthesize wasAdjustedDueToInteropIssues;
+(RtpPacket*) rtpPacketWithDefaultsAndSequenceNumber:(uint16_t)sequenceNumber andPayload:(NSData *)payload {
+(RtpPacket*) rtpPacketWithDefaultsAndSequenceNumber:(uint16_t)sequenceNumber
andTimeStamp:(uint32_t)timeStamp
andPayload:(NSData *)payload {
require(payload != nil);
return [RtpPacket rtpPacketWithVersion:PACKET_VERSION
andPadding:0
@ -51,7 +53,7 @@ const uint8_t PACKET_VERSION = 2;
andMarkerBit:false
andPayloadtype:0
andSequenceNumber:sequenceNumber
andTimeStamp:0
andTimeStamp:timeStamp
andPayload:payload];
}
+(RtpPacket*) rtpPacketWithVersion:(uint8_t)version
@ -340,7 +342,9 @@ andSynchronizationSourceIdentifier:(uint32_t)synchronizedSourceIdentifier
return extensionHeaderData;
}
-(NSData*) rawPacketDataUsingInteropOptions:(NSArray*)interopOptions {
if (rawPacketData == nil) rawPacketData = [self generateSerializedPacketDataUsingInteropOptions:interopOptions];
if (rawPacketData == nil) {
rawPacketData = [self generateSerializedPacketDataUsingInteropOptions:interopOptions];
}
return rawPacketData;
}
-(bool) isEqualToRtpPacket:(RtpPacket*)other {

@ -10,9 +10,14 @@
-(void) testTrivial {
NSData* d2 = [NSMutableData dataWithLength:6];
testThrows([EncodedAudioPacket encodedAudioPacketWithAudioData:nil andSequenceNumber:0]);
EncodedAudioPacket* p2 = [EncodedAudioPacket encodedAudioPacketWithAudioData:d2 andSequenceNumber:0xFF00];
test([p2 audioData] == d2);
test([p2 sequenceNumber] == 0xFF00);
testThrows([EncodedAudioPacket encodedAudioPacketWithAudioData:nil
andTimeStamp:0
andSequenceNumber:0]);
EncodedAudioPacket* p2 = [EncodedAudioPacket encodedAudioPacketWithAudioData:d2
andTimeStamp:0x23571113
andSequenceNumber:0xFF00];
test(p2.audioData == d2);
test(p2.timeStamp == 0x23571113);
test(p2.sequenceNumber == 0xFF00);
}
@end

@ -15,6 +15,8 @@
#define testLoggedDiscard(q, sequenceNumber, oldReadHeadSequenceNumber, newReadHeadSequenceNumber) testLogged(q, ([NSString stringWithFormat:@"discard %d,%d,%d", sequenceNumber, oldReadHeadSequenceNumber, newReadHeadSequenceNumber]))
#define testLoggedResync(q, oldReadHeadSequenceNumber, newReadHeadSequenceNumber) testLogged(q, ([NSString stringWithFormat:@"resync %d to %d", oldReadHeadSequenceNumber,newReadHeadSequenceNumber]))
#define TICK 320
@interface JitterQueueTest : XCTestCase
@end
@ -24,14 +26,18 @@
JitterQueue* r1 = [JitterQueue jitterQueue];
JitterQueue* r2 = [JitterQueue jitterQueue];
EncodedAudioPacket* q1 = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1] andSequenceNumber:100];
EncodedAudioPacket* q1 = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1]
andTimeStamp:100*TICK
andSequenceNumber:100];
test(r1.count == 0);
test([r1 tryEnqueue:q1]);
test(r1.count == 1);
test([r1 tryDequeue] == q1);
test(r1.count == 0);
EncodedAudioPacket* q2 = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1] andSequenceNumber:0xFF00];
EncodedAudioPacket* q2 = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1]
andTimeStamp:0xFF00*TICK
andSequenceNumber:0xFF00];
test(r2.count == 0);
test([r2 tryEnqueue:q2]);
test(r2.count == 1);
@ -42,7 +48,9 @@
JitterQueue* r = [JitterQueue jitterQueue];
for (uint16_t i = 0; i < 10; i++) {
EncodedAudioPacket* q = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1] andSequenceNumber:i];
EncodedAudioPacket* q = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1]
andTimeStamp:i*TICK
andSequenceNumber:i];
test([r tryEnqueue:q]);
test(r.count == i+1);
}
@ -57,7 +65,9 @@
JitterQueue* r = [JitterQueue jitterQueue];
for (uint16_t i = 0; i < 10; i++) {
EncodedAudioPacket* q = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1] andSequenceNumber:i*2+1];
EncodedAudioPacket* q = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1]
andTimeStamp:(i*2+1)*TICK
andSequenceNumber:i*2+1];
test([r tryEnqueue:q]);
}
@ -73,7 +83,9 @@
for (uint16_t i = 0; i < 20; i++) {
for (uint16_t j = 0; j < 2; j++) {
EncodedAudioPacket* q = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1] andSequenceNumber:i*2+j];
EncodedAudioPacket* q = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1]
andTimeStamp:(i*2+j)*TICK
andSequenceNumber:i*2+j];
test([r tryEnqueue:q]);
}
@ -84,11 +96,15 @@
-(void) testJitterQueueRejectsDuplicateSequenceNumbers {
JitterQueue* r = [JitterQueue jitterQueue];
EncodedAudioPacket* p = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1] andSequenceNumber:0];
EncodedAudioPacket* p = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1]
andTimeStamp:0
andSequenceNumber:0];
test([r tryEnqueue:p]);
for (uint16_t i = 0; i < 10; i++) {
EncodedAudioPacket* q = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1] andSequenceNumber:0];
EncodedAudioPacket* q = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1]
andTimeStamp:0
andSequenceNumber:0];
test(![r tryEnqueue:q]);
}
@ -98,11 +114,15 @@
-(void) testJitterQueueRejectsOldSequenceNumbers {
JitterQueue* r = [JitterQueue jitterQueue];
EncodedAudioPacket* p = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1] andSequenceNumber:50];
EncodedAudioPacket* p = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1]
andTimeStamp:50*TICK
andSequenceNumber:50];
test([r tryEnqueue:p]);
for (uint16_t i = 1; i < 10; i++) {
EncodedAudioPacket* q = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1] andSequenceNumber:50 - i];
EncodedAudioPacket* q = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1]
andTimeStamp:(50-i)*TICK
andSequenceNumber:50 - i];
test(![r tryEnqueue:q]);
}
@ -112,11 +132,15 @@
-(void) testJitterQueueRejectsFarOffSequenceNumbers {
JitterQueue* r = [JitterQueue jitterQueue];
EncodedAudioPacket* p = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1] andSequenceNumber:0];
EncodedAudioPacket* p = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1]
andTimeStamp:0
andSequenceNumber:0];
test([r tryEnqueue:p]);
for (uint16_t i = 0; i < 10; i++) {
EncodedAudioPacket* q = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1] andSequenceNumber:0x7000+i];
EncodedAudioPacket* q = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1]
andTimeStamp:(0x7000+i)*TICK
andSequenceNumber:0x7000+i];
test(![r tryEnqueue:q]);
}
@ -126,11 +150,15 @@
-(void) testJitterQueueResyncsSequenceNumber {
JitterQueue* r = [JitterQueue jitterQueue];
EncodedAudioPacket* p = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1] andSequenceNumber:1];
EncodedAudioPacket* p = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1]
andTimeStamp:1*TICK
andSequenceNumber:1];
test([r tryEnqueue:p]);
test([r tryDequeue] == p);
EncodedAudioPacket* q = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1] andSequenceNumber:0];
EncodedAudioPacket* q = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1]
andTimeStamp:0
andSequenceNumber:0];
test(![r tryEnqueue:q]);
// cause desync to be detected
@ -142,11 +170,25 @@
test([r tryEnqueue:q]);
test([r tryDequeue] == q);
}
-(void) testLoopAround {
-(void) testLoopAround_sequenceNumber {
JitterQueue* r = [JitterQueue jitterQueue];
for (uint32_t i = 0; i < 1 << 17; i++) {
EncodedAudioPacket* q = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1]
andTimeStamp:i*TICK
andSequenceNumber:(uint16_t)(i & 0xFFFF)];
test([r tryEnqueue:q]);
test([r tryDequeue] == q);
}
test([r tryDequeue] == nil);
}
-(void) testLoopAround_timeStamp {
JitterQueue* r = [JitterQueue jitterQueue];
for (int i = 0; i < 1 << 17; i++) {
EncodedAudioPacket* q = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1] andSequenceNumber:(uint16_t)(i & 0xFFFF)];
for (uint32_t i = 0; i < 1 << 17; i++) {
EncodedAudioPacket* q = [EncodedAudioPacket encodedAudioPacketWithAudioData:[NSData dataWithLength:1]
andTimeStamp:i*TICK + 0xFFFF0000
andSequenceNumber:(uint16_t)(i & 0xFFFF)];
test([r tryEnqueue:q]);
test([r tryDequeue] == q);
}
@ -154,15 +196,21 @@
}
-(void) testJitterQueueAvoidsRacingAhead {
JitterQueue* r = [JitterQueue jitterQueue];
EncodedAudioPacket* p1 = [EncodedAudioPacket encodedAudioPacketWithAudioData:increasingData(1) andSequenceNumber:0];
EncodedAudioPacket* p2 = [EncodedAudioPacket encodedAudioPacketWithAudioData:increasingData(1) andSequenceNumber:1];
EncodedAudioPacket* p1 = [EncodedAudioPacket encodedAudioPacketWithAudioData:increasingData(1)
andTimeStamp:0
andSequenceNumber:0];
EncodedAudioPacket* p2 = [EncodedAudioPacket encodedAudioPacketWithAudioData:increasingData(1)
andTimeStamp:1*TICK
andSequenceNumber:1];
test([r tryEnqueue:p1]);
test([r tryDequeue] == p1);
test([r tryDequeue] == nil);
test([r tryEnqueue:[EncodedAudioPacket encodedAudioPacketWithAudioData:increasingData(1) andSequenceNumber:10]]);
test([r tryEnqueue:[EncodedAudioPacket encodedAudioPacketWithAudioData:increasingData(1)
andTimeStamp:10*TICK
andSequenceNumber:10]]);
test([r tryDequeue] == nil);
test([r tryEnqueue:p2]);
@ -173,11 +221,17 @@
-(void) testJitterQueueMeasurement {
JitterQueue* q = [JitterQueue jitterQueue];
[q tryEnqueue:[EncodedAudioPacket encodedAudioPacketWithAudioData:increasingData(20) andSequenceNumber:1]];
[q tryEnqueue:[EncodedAudioPacket encodedAudioPacketWithAudioData:increasingData(20)
andTimeStamp:1*TICK
andSequenceNumber:1]];
test([q currentBufferDepth] == 0);
[q tryEnqueue:[EncodedAudioPacket encodedAudioPacketWithAudioData:increasingData(20) andSequenceNumber:2]];
[q tryEnqueue:[EncodedAudioPacket encodedAudioPacketWithAudioData:increasingData(20)
andTimeStamp:2*TICK
andSequenceNumber:2]];
test([q currentBufferDepth] == 1);
[q tryEnqueue:[EncodedAudioPacket encodedAudioPacketWithAudioData:increasingData(20) andSequenceNumber:4]];
[q tryEnqueue:[EncodedAudioPacket encodedAudioPacketWithAudioData:increasingData(20)
andTimeStamp:4*TICK
andSequenceNumber:4]];
test([q currentBufferDepth] == 3);
[q tryDequeue];
test([q currentBufferDepth] == 2);
@ -187,14 +241,18 @@
test([q currentBufferDepth] == 0);
[q tryDequeue];
test([q currentBufferDepth] == -1);
[q tryEnqueue:[EncodedAudioPacket encodedAudioPacketWithAudioData:increasingData(20) andSequenceNumber:8]];
[q tryEnqueue:[EncodedAudioPacket encodedAudioPacketWithAudioData:increasingData(20)
andTimeStamp:8*TICK
andSequenceNumber:8]];
test([q currentBufferDepth] == 3);
// resyncs to 0
for (int i = 0; i < 500; i++) {
[q tryDequeue];
}
[q tryEnqueue:[EncodedAudioPacket encodedAudioPacketWithAudioData:increasingData(20) andSequenceNumber:9000]];
[q tryEnqueue:[EncodedAudioPacket encodedAudioPacketWithAudioData:increasingData(20)
andTimeStamp:9000*TICK
andSequenceNumber:9000]];
test([q currentBufferDepth] == 0);
}
@end

@ -20,7 +20,7 @@
andMarkerBit:false
andPayloadtype:0
andSequenceNumber:5
andTimeStamp:0
andTimeStamp:0x23571113
andPayload:increasingData(5)];
// values were retained
@ -32,23 +32,27 @@
test(r.isMarkerBitSet == false);
test([r payloadType] == 0);
test([r sequenceNumber] == 5);
test([r timeStamp] == 0);
test([r timeStamp] == 0x23571113);
test([[r payload] isEqualToData:increasingData(5)]);
// equivalent to simplified constructor
test([r isEqualToRtpPacket:[RtpPacket rtpPacketWithDefaultsAndSequenceNumber:5 andPayload:increasingData(5)]]);
test([r isEqualToRtpPacket:[RtpPacket rtpPacketWithDefaultsAndSequenceNumber:5
andTimeStamp:0x23571113
andPayload:increasingData(5)]]);
// packed correctly
NSData* expectedData = [@[
@0x80,@0,@0,@5,
@0,@0,@0,@0,
@0x23,@0x57,@0x11,@0x13,
@0,@0,@0,@0,
@0,@1,@2,@3,@4] toUint8Data];
test([[r rawPacketDataUsingInteropOptions:@[]] isEqualToData:expectedData]);
// reparsing packed data gives same packet
test([r isEqualToRtpPacket:[RtpPacket rtpPacketParsedFromPacketData:expectedData]]);
test(![r isEqualToRtpPacket:[RtpPacket rtpPacketWithDefaultsAndSequenceNumber:0 andPayload:[NSData data]]]);
test(![r isEqualToRtpPacket:[RtpPacket rtpPacketWithDefaultsAndSequenceNumber:0
andTimeStamp:0
andPayload:[NSData data]]]);
}
-(void) testRawData {
RtpPacket* r = [RtpPacket rtpPacketWithVersion:2
@ -84,7 +88,9 @@
test([[r rawPacketDataUsingInteropOptions:@[]] isEqualToData:expectedData]);
test([r isEqualToRtpPacket:[RtpPacket rtpPacketParsedFromPacketData:expectedData]]);
test(![r isEqualToRtpPacket:[RtpPacket rtpPacketWithDefaultsAndSequenceNumber:90 andPayload:[NSData data]]]);
test(![r isEqualToRtpPacket:[RtpPacket rtpPacketWithDefaultsAndSequenceNumber:90
andTimeStamp:0
andPayload:[NSData data]]]);
}
-(void) testExtendedData {
RtpPacket* r = [RtpPacket rtpPacketWithVersion:2
@ -123,7 +129,9 @@
@0,@1,@2,@3,@4] toUint8Data];
test([[r rawPacketDataUsingInteropOptions:@[]] isEqualToData:expectedData]);
test([r isEqualToRtpPacket:[RtpPacket rtpPacketParsedFromPacketData:expectedData]]);
test(![r isEqualToRtpPacket:[RtpPacket rtpPacketWithDefaultsAndSequenceNumber:0 andPayload:[NSData data]]]);
test(![r isEqualToRtpPacket:[RtpPacket rtpPacketWithDefaultsAndSequenceNumber:0
andTimeStamp:0
andPayload:[NSData data]]]);
}
@end

@ -21,7 +21,9 @@
SrtpStream* ss = [SrtpStream srtpStreamWithCipherKey:key andMacKey:macKey andCipherIvSalt:salt];
for (uint64_t sequenceNumber = 0; sequenceNumber < 0x70000; sequenceNumber += 0x7000) {
RtpPacket* r = [RtpPacket rtpPacketWithDefaultsAndSequenceNumber:(uint16_t)(sequenceNumber & 0xFFFF) andPayload:generatePseudoRandomData(12)];
RtpPacket* r = [RtpPacket rtpPacketWithDefaultsAndSequenceNumber:(uint16_t)(sequenceNumber & 0xFFFF)
andTimeStamp:(uint32_t)(sequenceNumber * 320)
andPayload:generatePseudoRandomData(12)];
RtpPacket* s = [ss encryptAndAuthenticateNormalRtpPacket:r];
RtpPacket* r2 = [ss verifyAuthenticationAndDecryptSecuredRtpPacket:s];
test(![r isEqualToRtpPacket:s]);
@ -36,12 +38,20 @@
SrtpStream* ss = [SrtpStream srtpStreamWithCipherKey:key andMacKey:macKey andCipherIvSalt:salt];
// fuzzing
testThrows([ss verifyAuthenticationAndDecryptSecuredRtpPacket:[RtpPacket rtpPacketWithDefaultsAndSequenceNumber:0 andPayload:generatePseudoRandomData(0)]]);
testThrows([ss verifyAuthenticationAndDecryptSecuredRtpPacket:[RtpPacket rtpPacketWithDefaultsAndSequenceNumber:0 andPayload:generatePseudoRandomData(12)]]);
testThrows([ss verifyAuthenticationAndDecryptSecuredRtpPacket:[RtpPacket rtpPacketWithDefaultsAndSequenceNumber:0 andPayload:generatePseudoRandomData(100)]]);
testThrows([ss verifyAuthenticationAndDecryptSecuredRtpPacket:[RtpPacket rtpPacketWithDefaultsAndSequenceNumber:0
andTimeStamp:0
andPayload:generatePseudoRandomData(0)]]);
testThrows([ss verifyAuthenticationAndDecryptSecuredRtpPacket:[RtpPacket rtpPacketWithDefaultsAndSequenceNumber:0
andTimeStamp:0
andPayload:generatePseudoRandomData(12)]]);
testThrows([ss verifyAuthenticationAndDecryptSecuredRtpPacket:[RtpPacket rtpPacketWithDefaultsAndSequenceNumber:0
andTimeStamp:0
andPayload:generatePseudoRandomData(100)]]);
// authenticated then bit flip
RtpPacket* r = [RtpPacket rtpPacketWithDefaultsAndSequenceNumber:5 andPayload:generatePseudoRandomData(40)];
RtpPacket* r = [RtpPacket rtpPacketWithDefaultsAndSequenceNumber:5
andTimeStamp:320*5
andPayload:generatePseudoRandomData(40)];
RtpPacket* s = [ss encryptAndAuthenticateNormalRtpPacket:r];
NSMutableData* m = [[s payload] mutableCopy];
[m setUint8At:0 to:[m uint8At:0]^1];
@ -57,11 +67,15 @@
SrtpStream* s2 = [SrtpStream srtpStreamWithCipherKey:key andMacKey:macKey andCipherIvSalt:salt];
for (NSUInteger i = 0; i < 0x20000; i+= 0x100) {
RtpPacket* m = [RtpPacket rtpPacketWithDefaultsAndSequenceNumber:(uint16_t)(i & 0xFFFF) andPayload:generatePseudoRandomData(40)];
RtpPacket* m = [RtpPacket rtpPacketWithDefaultsAndSequenceNumber:(uint16_t)(i & 0xFFFF)
andTimeStamp:(uint32_t)(i*320 + 5)
andPayload:generatePseudoRandomData(40)];
testThrows([s1 verifyAuthenticationAndDecryptSecuredRtpPacket:m]);
}
RtpPacket* r = [RtpPacket rtpPacketWithDefaultsAndSequenceNumber:5 andPayload:generatePseudoRandomData(40)];
RtpPacket* r = [RtpPacket rtpPacketWithDefaultsAndSequenceNumber:5
andTimeStamp:5*320 + 5
andPayload:generatePseudoRandomData(40)];
RtpPacket* s = [s2 encryptAndAuthenticateNormalRtpPacket:r];
RtpPacket* r2 = [s1 verifyAuthenticationAndDecryptSecuredRtpPacket:s];
test([r isEqualToRtpPacket:r2]);

@ -88,10 +88,11 @@ bool pm(HandshakePacket* p1, HandshakePacket* p2) {
[socket startWithHandler:[PacketHandler packetHandler:^(id packet) { test(false); }
withErrorHandler:^(id error, id relatedInfo, bool causedTermination) { test(!causedTermination); }]
untilCancelled:[cc1 untilCancelledToken]];
[socket secureAndSendRtpPacket:[RtpPacket rtpPacketWithDefaultsAndSequenceNumber:1 andPayload:[NSData data]]];
[socket secureAndSendRtpPacket:[RtpPacket rtpPacketWithDefaultsAndSequenceNumber:1
andTimeStamp:320
andPayload:[NSData data]]];
}
testChurnUntil(!f1.isIncomplete, 5.0);
test(f1.hasResult);

@ -75,6 +75,17 @@
test (!same);
}
-(void) testGenerateSecureRandomUInt32_varies {
NSMutableSet* s = [NSMutableSet new];
for (uint i = 0; i < 10; i++) {
[s addObject:@([CryptoTools generateSecureRandomUInt32])];
}
// Note: expected false negative rate is approximately once per hundred million runs
test(s.count == 10);
}
-(void) testKnownAesCipherFeedback {
NSData* iv = [@"000102030405060708090a0b0c0d0e0f" decodedAsHexString];
NSData* plain =[@"6bc1bee22e409f96e93d7e117393172a" decodedAsHexString];

Loading…
Cancel
Save