UnitTest/RSAOperationsTestsCompat.m
/* |
Copyright (C) 2016 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
Tests for the RSA compatibility operations. |
*/ |
#import "RSAOperationsTestsBase.h" |
#import "QCCRSASHASignatureCompat.h" |
#import "QCCRSASmallCryptorCompat.h" |
#import "ToolCommon.h" |
#import "QHex.h" |
NS_ASSUME_NONNULL_BEGIN |
@interface RSAOperationsTestsCompat : RSAOperationsTestsBase |
@end |
@interface RSAOperationsTestsCompat () |
@end |
NS_ASSUME_NONNULL_END |
static BOOL sUseCompatibilityCode = NO; |
@implementation RSAOperationsTestsCompat |
- (void)setUp { |
[super setUp]; |
[ToolCommon sharedInstance].debugRunOpOnMainThread = YES; |
} |
static const QCCRSASHASignatureCompatAlgorithm kAlgorithms[5] = { QCCRSASHASignatureCompatAlgorithmSHA1, QCCRSASHASignatureCompatAlgorithmSHA2_224, QCCRSASHASignatureCompatAlgorithmSHA2_256, QCCRSASHASignatureCompatAlgorithmSHA2_384, QCCRSASHASignatureCompatAlgorithmSHA2_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; |
QCCRSASHAVerifyCompat * op; |
signatureData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:kSignatures[i] withExtension:@"sig"]]; |
assert(signatureData != nil); |
op = [[QCCRSASHAVerifyCompat alloc] initWithAlgorithm:kAlgorithms[i] inputData:fileData publicKey:self.publicKey signatureData:signatureData]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
assert(op.error == nil); |
if (op.verified) { |
result += 1; |
} |
} |
return result; |
} |
- (void)testRSASHAVerify { |
XCTAssertEqual([self verifyCountForFile:@"test"], (NSInteger) 5); |
XCTAssertEqual([self verifyCountForFile:@"test-corrupted"], (NSInteger) 0); |
} |
- (void)testRSASHASign { |
NSData * fileData; |
fileData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"test" withExtension:@"cer"]]; |
assert(fileData != nil); |
for (size_t i = 0; i < 5; i++) { |
QCCRSASHASignCompat * op; |
NSData * expectedSignatureData; |
expectedSignatureData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:kSignatures[i] withExtension:@"sig"]]; |
assert(expectedSignatureData != nil); |
op = [[QCCRSASHASignCompat alloc] initWithAlgorithm:kAlgorithms[i] inputData:fileData privateKey:self.privateKey]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
[[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 { |
NSData * fileData; |
QCCRSASmallCryptorCompat * op; |
fileData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"plaintext-32" withExtension:@"dat"]]; |
assert(fileData != nil); |
op = [[QCCRSASmallCryptorCompat alloc] initToEncryptSmallInputData:fileData key:self.publicKey]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNil(op.error); |
if (op.smallOutputData != nil) { |
op = [[QCCRSASmallCryptorCompat alloc] initToDecryptSmallInputData:op.smallOutputData key:self.privateKey]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNil(op.error); |
XCTAssertEqualObjects(fileData, op.smallOutputData); |
} |
} |
- (void)testRSADecryptPKCS1 { |
NSData * fileData; |
QCCRSASmallCryptorCompat * 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 = [[QCCRSASmallCryptorCompat alloc] initToDecryptSmallInputData:cyphertext32Data key:self.privateKey]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNil(op.error); |
XCTAssertEqualObjects(fileData, op.smallOutputData); |
} |
- (void)testRSADecryptOAEP { |
NSData * fileData; |
QCCRSASmallCryptorCompat * 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 = [[QCCRSASmallCryptorCompat alloc] initToDecryptSmallInputData:cyphertext32Data key:self.privateKey]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
op.padding = QCCRSASmallCryptorCompatPaddingOAEP; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNil(op.error); |
XCTAssertEqualObjects(fileData, op.smallOutputData); |
} |
- (void)testRSAVerifyError { |
NSData * fileData; |
NSData * signatureData; |
QCCRSASHAVerifyCompat * 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 = [[QCCRSASHAVerifyCompat alloc] initWithAlgorithm:QCCRSASHASignatureCompatAlgorithmSHA1 inputData:fileData publicKey:self.privateKey signatureData:signatureData]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
[[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, @"Internal CSSM error"); |
// XCTAssertTrue(op.error.code != 0); |
XCTAssertFalse(op.verified); // this would be true if we'd passed in self.publicKey |
} |
- (void)testRSASignError { |
NSData * fileData; |
NSData * expectedSignatureData; |
QCCRSASHASignCompat * op; |
// Note: This test fails on OS X 10.7.x because the signing transform doesn't fail if |
// you pass it a public key; rather it succeeds, but produces gibberish results. |
// 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 = [[QCCRSASHASignCompat alloc] initWithAlgorithm:QCCRSASHASignatureCompatAlgorithmSHA1 inputData:fileData privateKey:self.publicKey]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
[[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 { |
NSData * plaintextData; |
NSData * cyphertextData; |
QCCRSASmallCryptorCompat * op; |
// encrypt with the private key |
plaintextData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"plaintext-32" withExtension:@"dat"]]; |
assert(plaintextData != nil); |
op = [[QCCRSASmallCryptorCompat alloc] initToEncryptSmallInputData:plaintextData key:self.privateKey]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
[[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 = [[QCCRSASmallCryptorCompat alloc] initToDecryptSmallInputData:cyphertextData key:self.publicKey]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
[[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 { |
NSData * plaintextData; |
QCCRSASmallCryptorCompat * op; |
// PKCS#1 |
plaintextData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"plaintext-332" withExtension:@"dat"]]; |
assert(plaintextData != nil); |
op = [[QCCRSASmallCryptorCompat alloc] initToEncryptSmallInputData:plaintextData key:self.publicKey]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
[[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 = [[QCCRSASmallCryptorCompat alloc] initToEncryptSmallInputData:plaintextData key:self.publicKey]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
[[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 = [[QCCRSASmallCryptorCompat alloc] initToEncryptSmallInputData:plaintextData key:self.publicKey]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNotNil(op.error); |
XCTAssertEqualObjects(op.error.domain, NSOSStatusErrorDomain); |
XCTAssertEqual(op.error.code, (NSInteger) errSecParam); |
XCTAssertNil(op.smallOutputData); |
// Note: The following test fails on iOS 5.x because of an off-by-one error in the data |
// length check in the Security framework. To make it work on 5.x you have to change |
// 245 to 244. 245 is definitely the right number, so I've left the test as it should be |
// and commented about the failure here. |
plaintextData = [plaintextData subdataWithRange:NSMakeRange(0, 245)]; |
op = [[QCCRSASmallCryptorCompat alloc] initToEncryptSmallInputData:plaintextData key:self.publicKey]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNil(op.error); |
// OAEP |
plaintextData = [NSData dataWithContentsOfURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"plaintext-332" withExtension:@"dat"]]; |
assert(plaintextData != nil); |
op = [[QCCRSASmallCryptorCompat alloc] initToEncryptSmallInputData:plaintextData key:self.publicKey]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
op.padding = QCCRSASmallCryptorCompatPaddingOAEP; |
[[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 = [[QCCRSASmallCryptorCompat alloc] initToEncryptSmallInputData:plaintextData key:self.publicKey]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
op.padding = QCCRSASmallCryptorCompatPaddingOAEP; |
[[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 = [[QCCRSASmallCryptorCompat alloc] initToEncryptSmallInputData:plaintextData key:self.publicKey]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
op.padding = QCCRSASmallCryptorCompatPaddingOAEP; |
[[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 = [[QCCRSASmallCryptorCompat alloc] initToEncryptSmallInputData:plaintextData key:self.publicKey]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
op.padding = QCCRSASmallCryptorCompatPaddingOAEP; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNil(op.error); |
} |
- (void)testRSACryptorErrorWrongLength { |
NSData * cyphertextData; |
QCCRSASmallCryptorCompat * 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 = [[QCCRSASmallCryptorCompat alloc] initToDecryptSmallInputData:cyphertextData key:self.privateKey]; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
[[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 = [[QCCRSASmallCryptorCompat alloc] initToDecryptSmallInputData:cyphertextData key:self.privateKey]; |
op.padding = QCCRSASmallCryptorCompatPaddingOAEP; |
op.debugUseCompatibilityCode = sUseCompatibilityCode; |
[[ToolCommon sharedInstance] synchronouslyRunOperation:op]; |
XCTAssertNotNil(op.error); |
XCTAssertEqualObjects(op.error.domain, NSOSStatusErrorDomain); |
XCTAssertEqual(op.error.code, (NSInteger) errSecParam); |
XCTAssertNil(op.smallOutputData); |
} |
- (void)testRSAThrows { |
#pragma clang diagnostic push |
#pragma clang diagnostic ignored "-Wnonnull" |
XCTAssertThrows((void) [[QCCRSASHAVerifyCompat alloc] initWithAlgorithm:QCCRSASHASignatureCompatAlgorithmSHA1 inputData:nil publicKey:self.publicKey signatureData:[NSData data]]); |
XCTAssertThrows((void) [[QCCRSASHAVerifyCompat alloc] initWithAlgorithm:QCCRSASHASignatureCompatAlgorithmSHA1 inputData:[NSData data] publicKey:NULL signatureData:[NSData data]]); |
XCTAssertThrows((void) [[QCCRSASHAVerifyCompat alloc] initWithAlgorithm:QCCRSASHASignatureCompatAlgorithmSHA1 inputData:[NSData data] publicKey:self.publicKey signatureData:nil]); |
XCTAssertThrows((void) [[QCCRSASHASignCompat alloc] initWithAlgorithm:QCCRSASHASignatureCompatAlgorithmSHA1 inputData:nil privateKey:self.privateKey]); |
XCTAssertThrows((void) [[QCCRSASHASignCompat alloc] initWithAlgorithm:QCCRSASHASignatureCompatAlgorithmSHA1 inputData:[NSData data] privateKey:NULL]); |
XCTAssertThrows((void) [[QCCRSASmallCryptorCompat alloc] initToDecryptSmallInputData:nil key:self.publicKey]); |
XCTAssertThrows((void) [[QCCRSASmallCryptorCompat alloc] initToDecryptSmallInputData:[NSData data] key:NULL]); |
XCTAssertThrows((void) [[QCCRSASmallCryptorCompat alloc] initToEncryptSmallInputData:nil key:self.privateKey]); |
XCTAssertThrows((void) [[QCCRSASmallCryptorCompat 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