Signal-iOS/SignalServiceKit/tests/Account/SignedPreKeyDeletionTests.m
2021-10-21 09:21:10 -03:00

159 lines
5.4 KiB
Objective-C

//
// Copyright (c) 2021 Open Whisper Systems. All rights reserved.
//
#import "SDSDatabaseStorage+Objc.h"
#import "SSKBaseTestObjC.h"
#import "SSKSignedPreKeyStore.h"
#import "SignedPrekeyRecord.h"
#import "TSPreKeyManager.h"
#import <SignalServiceKit/SignalServiceKit-Swift.h>
@interface TSPreKeyManager (Testing)
+ (void)clearSignedPreKeyRecordsWithKeyId:(NSNumber *)keyId;
@end
#pragma mark -
@interface SignedPreKeyDeletionTests : SSKBaseTestObjC
@end
#pragma mark -
@interface SSKSignedPreKeyStore (Tests)
@end
#pragma mark -
@implementation SSKSignedPreKeyStore (Tests)
- (nullable SignedPreKeyRecord *)loadSignedPreKey:(int)signedPreKeyId
{
__block SignedPreKeyRecord *_Nullable result;
[self.databaseStorage readWithBlock:^(SDSAnyReadTransaction *transaction) {
result = [self loadSignedPreKey:signedPreKeyId transaction:transaction];
}];
return result;
}
@end
#pragma mark -
@implementation SignedPreKeyDeletionTests
- (void)setUp {
[super setUp];
}
- (void)tearDown {
[super tearDown];
}
- (NSUInteger)signedPreKeyCount
{
__block NSUInteger result;
[self.databaseStorage readWithBlock:^(SDSAnyReadTransaction *transaction) {
result = [self.signedPreKeyStore loadSignedPreKeysWithTransaction:transaction].count;
}];
return result;
}
- (void)testSignedPreKeyDeletion {
XCTAssertEqual(0, self.signedPreKeyCount);
int days = 40;
int lastPreKeyId = days;
for (int i = 0; i <= days; i++) { // 41 signed keys are generated, one per day from now until 40 days ago.
int secondsAgo = (i - days) * 24 * 60 * 60;
NSAssert(secondsAgo <= 0, @"Time in past must be negative");
NSDate *generatedAt = [NSDate dateWithTimeIntervalSinceNow:secondsAgo];
SignedPreKeyRecord *record = [[SignedPreKeyRecord alloc] initWithId:i
keyPair:[Curve25519 generateKeyPair]
signature:[NSData new]
generatedAt:generatedAt];
DatabaseStorageWrite(self.databaseStorage, ^(SDSAnyWriteTransaction *transaction) {
[self.signedPreKeyStore storeSignedPreKey:i signedPreKeyRecord:record transaction:transaction];
});
}
// Sanity check
XCTAssertEqual(41, self.signedPreKeyCount);
[TSPreKeyManager clearSignedPreKeyRecordsWithKeyId:@(lastPreKeyId)];
XCTAssert([self.signedPreKeyStore loadSignedPreKey:lastPreKeyId] != nil);
// We'll delete every key created 30 or more days ago.
XCTAssertEqual(30, self.signedPreKeyCount);
}
- (void)testSignedPreKeyDeletionKeepsSomeOldKeys
{
XCTAssertEqual(0, self.signedPreKeyCount);
int lastPreKeyId = 10;
for (int i = 0; i <= 10; i++) {
// All these keys will be considered "old", since they were created more than 30 days ago.
int secondsAgo = (i - 40) * 24 * 60 * 60;
NSAssert(secondsAgo <= 0, @"Time in past must be negative");
NSDate *generatedAt = [NSDate dateWithTimeIntervalSinceNow:secondsAgo];
SignedPreKeyRecord *record = [[SignedPreKeyRecord alloc] initWithId:i
keyPair:[Curve25519 generateKeyPair]
signature:[NSData new]
generatedAt:generatedAt];
// we only retain accepted keys
[record markAsAcceptedByService];
DatabaseStorageWrite(self.databaseStorage, ^(SDSAnyWriteTransaction *transaction) {
[self.signedPreKeyStore storeSignedPreKey:i signedPreKeyRecord:record transaction:transaction];
});
}
// Sanity check
XCTAssertEqual(11, self.signedPreKeyCount);
[TSPreKeyManager clearSignedPreKeyRecordsWithKeyId:@(lastPreKeyId)];
XCTAssert([self.signedPreKeyStore loadSignedPreKey:lastPreKeyId] != nil);
// We need to keep 3 "old" keys, plus the "current" key
XCTAssertEqual(4, self.signedPreKeyCount);
}
- (void)testOlderRecordsNotDeletedIfNoReplacement
{
XCTAssertEqual(0, self.signedPreKeyCount);
int days = 3;
int lastPreKeyId = days;
for (int i = 0; i <= days; i++) { // 4 signed keys are generated, one per day from now until 3 days ago.
int secondsAgo = (i - days) * 24 * 60 * 60;
NSAssert(secondsAgo <= 0, @"Time in past must be negative");
NSDate *generatedAt = [NSDate dateWithTimeIntervalSinceNow:secondsAgo];
SignedPreKeyRecord *record = [[SignedPreKeyRecord alloc] initWithId:i
keyPair:[Curve25519 generateKeyPair]
signature:[NSData new]
generatedAt:generatedAt];
DatabaseStorageWrite(self.databaseStorage, ^(SDSAnyWriteTransaction *transaction) {
[self.signedPreKeyStore storeSignedPreKey:i signedPreKeyRecord:record transaction:transaction];
});
}
// Sanity check
XCTAssertEqual(4, self.signedPreKeyCount);
[TSPreKeyManager clearSignedPreKeyRecordsWithKeyId:@(lastPreKeyId)];
XCTAssert([self.signedPreKeyStore loadSignedPreKey:lastPreKeyId] != nil);
// All records should still be stored.
XCTAssertEqual(4, self.signedPreKeyCount);
}
@end