UnitTest/RSAOperationsTests.m
/* |
Copyright (C) 2016 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
Tests for the RSA operations. |
*/ |
#import "RSAOperationsTestsBase.h" |
#import "QCCRSASHASignature.h" |
#import "QCCRSASmallCryptor.h" |
#import "ToolCommon.h" |
#import "QHex.h" |
NS_ASSUME_NONNULL_BEGIN |
@interface RSAOperationsTests : RSAOperationsTestsBase |
@end |
@interface RSAOperationsTests () |
@end |
NS_ASSUME_NONNULL_END |
@implementation RSAOperationsTests |
- (void)setUp { |
[super setUp]; |
[ToolCommon sharedInstance].debugRunOpOnMainThread = YES; |
} |
static const QCCRSASHASignatureAlgorithm kAlgorithms[5] = { QCCRSASHASignatureAlgorithmSHA1, QCCRSASHASignatureAlgorithmSHA2_224, QCCRSASHASignatureAlgorithmSHA2_256, QCCRSASHASignatureAlgorithmSHA2_384, QCCRSASHASignatureAlgorithmSHA2_512 }; |
static NSString * kSignatures[5] = { |
@"test.cer-sha1", |
@"test.cer-sha2-224", |
@"test.cer-sha2-256", |
@"test.cer-sha2-384", |
@"test.cer-sha2-512", |
}; |
- (NSInteger)verifyCountForFile:(NSString *)fileName { |
NSInteger result; |
NSData * fileData; |
fileData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:fileName withExtension:@"cer"]]; |
assert(fileData != nil); |
result = 0; |
for (size_t i = 0; i < 5; i++) { |
NSData * signatureData; |
QCCRSASHAVerify * op; |
signatureData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:kSignatures[i] withExtension:@"sig"]]; |
assert(signatureData != nil); |
op = [[QCCRSASHAVerify alloc] initWithAlgorithm:kAlgorithms[i] inputData:fileData publicKey:self.publicKey signatureData:signatureData]; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
assert(op.error == nil); |
if (op.verified) { |
result += 1; |
} |
} |
return result; |
} |
- (void)testRSASHAVerify { |
if ( ! self.hasUnifiedCrypto ) { return; } |
XCTAssertEqual([self verifyCountForFile:@"test"], (NSInteger) 5); |
XCTAssertEqual([self verifyCountForFile:@"test-corrupted"], (NSInteger) 0); |
} |
- (void)testRSASHASign { |
if ( ! self.hasUnifiedCrypto ) { return; } |
NSData * fileData; |
fileData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"test" withExtension:@"cer"]]; |
assert(fileData != nil); |
for (size_t i = 0; i < 5; i++) { |
QCCRSASHASign * op; |
NSData * expectedSignatureData; |
expectedSignatureData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:kSignatures[i] withExtension:@"sig"]]; |
assert(expectedSignatureData != nil); |
op = [[QCCRSASHASign alloc] initWithAlgorithm:kAlgorithms[i] inputData:fileData privateKey:self.privateKey]; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNil(op.error); |
XCTAssertEqualObjects(op.signatureData, expectedSignatureData); |
} |
} |
// When you encrypt with padding you can't test a fixed encryption because the padding |
// adds some randomness so that no two encryptions are the same. Thus, we can only test |
// the round trip case (-testRSASmallCryptor) and the decrypt case (-testRSADecryptPKCS1 |
// and -testRSADecryptOAEP). |
- (void)testRSASmallCryptor { |
if ( ! self.hasUnifiedCrypto ) { return; } |
NSData * fileData; |
QCCRSASmallCryptor * op; |
fileData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"plaintext-32" withExtension:@"dat"]]; |
assert(fileData != nil); |
op = [[QCCRSASmallCryptor alloc] initToEncryptSmallInputData:fileData key:self.publicKey]; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNil(op.error); |
if (op.smallOutputData != nil) { |
op = [[QCCRSASmallCryptor alloc] initToDecryptSmallInputData:op.smallOutputData key:self.privateKey]; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNil(op.error); |
XCTAssertEqualObjects(fileData, op.smallOutputData); |
} |
} |
- (void)testRSADecryptPKCS1 { |
if ( ! self.hasUnifiedCrypto ) { return; } |
NSData * fileData; |
QCCRSASmallCryptor * op; |
NSData * cyphertext32Data; |
fileData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"plaintext-32" withExtension:@"dat"]]; |
assert(fileData != nil); |
// This is the "plaintext-32.dat" data encrypted with the public key using the |
// following OpenSSL command: |
// |
// $ openssl rsautl -encrypt -pkcs -pubin -inkey TestData/public.pem -in TestData/plaintext-32.dat |
cyphertext32Data = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"cyphertext-rsa-pkcs1-32" withExtension:@"dat"]]; |
assert(cyphertext32Data != nil); |
op = [[QCCRSASmallCryptor alloc] initToDecryptSmallInputData:cyphertext32Data key:self.privateKey]; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNil(op.error); |
XCTAssertEqualObjects(fileData, op.smallOutputData); |
} |
- (void)testRSADecryptOAEP { |
if ( ! self.hasUnifiedCrypto ) { return; } |
NSData * fileData; |
QCCRSASmallCryptor * op; |
NSData * cyphertext32Data; |
fileData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"plaintext-32" withExtension:@"dat"]]; |
assert(fileData != nil); |
// This is the "plaintext-32.dat" data encrypted with the public key using the |
// following OpenSSL command: |
// |
// $ openssl rsautl -encrypt -oaep -pubin -inkey TestData/public.pem -in TestData/plaintext-32.dat |
cyphertext32Data = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"cyphertext-rsa-oaep-32" withExtension:@"dat"]]; |
assert(cyphertext32Data != nil); |
op = [[QCCRSASmallCryptor alloc] initToDecryptSmallInputData:cyphertext32Data key:self.privateKey]; |
op.padding = QCCRSASmallCryptorPaddingOAEP; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNil(op.error); |
XCTAssertEqualObjects(fileData, op.smallOutputData); |
} |
- (void)testRSAVerifyError { |
if ( ! self.hasUnifiedCrypto ) { return; } |
NSData * fileData; |
NSData * signatureData; |
QCCRSASHAVerify * op; |
// passing private key to verify |
fileData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"test" withExtension:@"cer"]]; |
assert(fileData != nil); |
signatureData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"test.cer-sha1" withExtension:@"sig"]]; |
assert(signatureData != nil); |
op = [[QCCRSASHAVerify alloc] initWithAlgorithm:QCCRSASHASignatureAlgorithmSHA1 inputData:fileData publicKey:self.privateKey signatureData:signatureData]; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
// We skip the error check because some OS releases make it impossible to determine |
// where there was a very failure or a parameter error. What matters here is that |
// op.verified is false. |
// |
// XCTAssertNotNil(op.error); |
// XCTAssertEqualObjects(op.error.domain, NSOSStatusErrorDomain); |
// XCTAssertEqual(op.error.code, (NSInteger) errSecUnimplemented); |
XCTAssertFalse(op.verified); // this would be true if we'd passed in self.publicKey |
} |
- (void)testRSASignError { |
if ( ! self.hasUnifiedCrypto ) { return; } |
NSData * fileData; |
NSData * expectedSignatureData; |
QCCRSASHASign * op; |
// passing public key to sign |
fileData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"test" withExtension:@"cer"]]; |
assert(fileData != nil); |
expectedSignatureData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"test.cer-sha1" withExtension:@"sig"]]; |
assert(expectedSignatureData != nil); |
op = [[QCCRSASHASign alloc] initWithAlgorithm:QCCRSASHASignatureAlgorithmSHA1 inputData:fileData privateKey:self.publicKey]; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNotNil(op.error); |
XCTAssertNotNil(op.error.domain); |
XCTAssertTrue(op.error.code != 0); // We don't check the specific error here because different OS releases given you different values. |
XCTAssertNil(op.signatureData); |
} |
- (void)testRSACryptorErrorWrongKeys { |
if ( ! self.hasUnifiedCrypto ) { return; } |
NSData * plaintextData; |
NSData * cyphertextData; |
QCCRSASmallCryptor * op; |
// encrypt with the private key |
plaintextData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"plaintext-32" withExtension:@"dat"]]; |
assert(plaintextData != nil); |
op = [[QCCRSASmallCryptor alloc] initToEncryptSmallInputData:plaintextData key:self.privateKey]; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNotNil(op.error); |
XCTAssertEqualObjects(op.error.domain, NSOSStatusErrorDomain); |
XCTAssertTrue(op.error.code != 0); // We don't check the specific error here because different OS releases given you different values. |
XCTAssertNil(op.smallOutputData); |
// decrypt with the public key |
cyphertextData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"cyphertext-rsa-pkcs1-32" withExtension:@"dat"]]; |
assert(cyphertextData != nil); |
op = [[QCCRSASmallCryptor alloc] initToDecryptSmallInputData:cyphertextData key:self.publicKey]; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNotNil(op.error); |
XCTAssertEqualObjects(op.error.domain, NSOSStatusErrorDomain); |
XCTAssertTrue(op.error.code != 0); // We don't check the specific error here because different OS releases given you different values. |
XCTAssertNil(op.smallOutputData); |
} |
- (void)testRSACryptorErrorTooBig { |
if ( ! self.hasUnifiedCrypto ) { return; } |
NSData * plaintextData; |
QCCRSASmallCryptor * op; |
// PKCS#1 |
plaintextData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"plaintext-332" withExtension:@"dat"]]; |
assert(plaintextData != nil); |
op = [[QCCRSASmallCryptor alloc] initToEncryptSmallInputData:plaintextData key:self.publicKey]; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNotNil(op.error); |
XCTAssertEqualObjects(op.error.domain, NSOSStatusErrorDomain); |
XCTAssertEqual(op.error.code, (NSInteger) errSecParam); |
XCTAssertNil(op.smallOutputData); |
plaintextData = [plaintextData subdataWithRange:NSMakeRange(0, 256)]; |
op = [[QCCRSASmallCryptor alloc] initToEncryptSmallInputData:plaintextData key:self.publicKey]; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNotNil(op.error); |
XCTAssertEqualObjects(op.error.domain, NSOSStatusErrorDomain); |
XCTAssertEqual(op.error.code, (NSInteger) errSecParam); |
XCTAssertNil(op.smallOutputData); |
plaintextData = [plaintextData subdataWithRange:NSMakeRange(0, 246)]; |
op = [[QCCRSASmallCryptor alloc] initToEncryptSmallInputData:plaintextData key:self.publicKey]; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNotNil(op.error); |
XCTAssertEqualObjects(op.error.domain, NSOSStatusErrorDomain); |
XCTAssertEqual(op.error.code, (NSInteger) errSecParam); |
XCTAssertNil(op.smallOutputData); |
plaintextData = [plaintextData subdataWithRange:NSMakeRange(0, 245)]; |
op = [[QCCRSASmallCryptor alloc] initToEncryptSmallInputData:plaintextData key:self.publicKey]; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNil(op.error); |
// OAEP |
plaintextData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"plaintext-332" withExtension:@"dat"]]; |
assert(plaintextData != nil); |
op = [[QCCRSASmallCryptor alloc] initToEncryptSmallInputData:plaintextData key:self.publicKey]; |
op.padding = QCCRSASmallCryptorPaddingOAEP; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNotNil(op.error); |
XCTAssertEqualObjects(op.error.domain, NSOSStatusErrorDomain); |
XCTAssertEqual(op.error.code, (NSInteger) errSecParam); |
XCTAssertNil(op.smallOutputData); |
plaintextData = [plaintextData subdataWithRange:NSMakeRange(0, 256)]; |
op = [[QCCRSASmallCryptor alloc] initToEncryptSmallInputData:plaintextData key:self.publicKey]; |
op.padding = QCCRSASmallCryptorPaddingOAEP; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNotNil(op.error); |
XCTAssertEqualObjects(op.error.domain, NSOSStatusErrorDomain); |
XCTAssertEqual(op.error.code, (NSInteger) errSecParam); |
XCTAssertNil(op.smallOutputData); |
plaintextData = [plaintextData subdataWithRange:NSMakeRange(0, 215)]; |
op = [[QCCRSASmallCryptor alloc] initToEncryptSmallInputData:plaintextData key:self.publicKey]; |
op.padding = QCCRSASmallCryptorPaddingOAEP; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNotNil(op.error); |
XCTAssertEqualObjects(op.error.domain, NSOSStatusErrorDomain); |
XCTAssertEqual(op.error.code, (NSInteger) errSecParam); |
XCTAssertNil(op.smallOutputData); |
plaintextData = [plaintextData subdataWithRange:NSMakeRange(0, 214)]; |
op = [[QCCRSASmallCryptor alloc] initToEncryptSmallInputData:plaintextData key:self.publicKey]; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNil(op.error); |
} |
- (void)testRSACryptorErrorWrongLength { |
if ( ! self.hasUnifiedCrypto ) { return; } |
NSData * cyphertextData; |
QCCRSASmallCryptor * op; |
// PKCS#1 |
cyphertextData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"cyphertext-rsa-pkcs1-32" withExtension:@"dat"]]; |
assert(cyphertextData != nil); |
cyphertextData = [cyphertextData subdataWithRange:NSMakeRange(0, 255)]; |
op = [[QCCRSASmallCryptor alloc] initToDecryptSmallInputData:cyphertextData key:self.privateKey]; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNotNil(op.error); |
XCTAssertEqualObjects(op.error.domain, NSOSStatusErrorDomain); |
XCTAssertEqual(op.error.code, (NSInteger) errSecParam); |
XCTAssertNil(op.smallOutputData); |
// OAEP |
cyphertextData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"cyphertext-rsa-oaep-32" withExtension:@"dat"]]; |
assert(cyphertextData != nil); |
cyphertextData = [cyphertextData subdataWithRange:NSMakeRange(0, 255)]; |
op = [[QCCRSASmallCryptor alloc] initToDecryptSmallInputData:cyphertextData key:self.privateKey]; |
op.padding = QCCRSASmallCryptorPaddingOAEP; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNotNil(op.error); |
XCTAssertEqualObjects(op.error.domain, NSOSStatusErrorDomain); |
XCTAssertEqual(op.error.code, (NSInteger) errSecParam); |
XCTAssertNil(op.smallOutputData); |
} |
- (void)testRSAThrows { |
if ( ! self.hasUnifiedCrypto ) { return; } |
#pragma clang diagnostic push |
#pragma clang diagnostic ignored "-Wnonnull" |
XCTAssertThrows((void) [[QCCRSASHAVerify alloc] initWithAlgorithm:QCCRSASHASignatureAlgorithmSHA1 inputData:nil publicKey:self.publicKey signatureData:[NSData data]]); |
XCTAssertThrows((void) [[QCCRSASHAVerify alloc] initWithAlgorithm:QCCRSASHASignatureAlgorithmSHA1 inputData:[NSData data] publicKey:NULL signatureData:[NSData data]]); |
XCTAssertThrows((void) [[QCCRSASHAVerify alloc] initWithAlgorithm:QCCRSASHASignatureAlgorithmSHA1 inputData:[NSData data] publicKey:self.publicKey signatureData:nil]); |
XCTAssertThrows((void) [[QCCRSASHASign alloc] initWithAlgorithm:QCCRSASHASignatureAlgorithmSHA1 inputData:nil privateKey:self.privateKey]); |
XCTAssertThrows((void) [[QCCRSASHASign alloc] initWithAlgorithm:QCCRSASHASignatureAlgorithmSHA1 inputData:[NSData data] privateKey:NULL]); |
XCTAssertThrows((void) [[QCCRSASmallCryptor alloc] initToDecryptSmallInputData:nil key:self.publicKey]); |
XCTAssertThrows((void) [[QCCRSASmallCryptor alloc] initToDecryptSmallInputData:[NSData data] key:NULL]); |
XCTAssertThrows((void) [[QCCRSASmallCryptor alloc] initToEncryptSmallInputData:nil key:self.privateKey]); |
XCTAssertThrows((void) [[QCCRSASmallCryptor alloc] initToEncryptSmallInputData:[NSData data] key:NULL]); |
#pragma clang diagnostic pop |
} |
@end |
Copyright © 2016 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2016-11-17