]> git.saurik.com Git - apple/security.git/blob - OSX/shared_regressions/si-44-seckey-rsa.m
Security-57740.1.18.tar.gz
[apple/security.git] / OSX / shared_regressions / si-44-seckey-rsa.m
1 /*
2 * Copyright (c) 2016 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 #import <Foundation/Foundation.h>
26
27 #include "shared_regressions.h"
28
29 static NSData *decryptAndUnpad(SecKeyRef privateKey, SecKeyAlgorithm algorithm, NSData *ciphertext, NSError **error) {
30 NSData *plaintext = CFBridgingRelease(SecKeyCreateDecryptedData(privateKey, algorithm, (CFDataRef)ciphertext, (void *)error));
31 if (plaintext != nil && [(__bridge id)algorithm isEqual:(id)kSecKeyAlgorithmRSAEncryptionRaw]) {
32 NSRange range = NSMakeRange(0, plaintext.length);
33 while (((const UInt8 *)plaintext.bytes)[range.location] == 0x00 && range.location < plaintext.length) {
34 range.length--;
35 range.location++;
36 }
37 plaintext = [plaintext subdataWithRange:range];
38 }
39 return plaintext;
40 }
41
42 static void test_encrypt_run(SecKeyRef privateKey, SecKeyRef publicKey, SecKeyRef iosPrivateKey, SecKeyRef iosPublicKey, SecKeyAlgorithm algorithm) {
43 NSData *original = [NSData dataWithBytes:"encrypt" length:7], *plaintext;
44 NSError *error;
45
46 error = nil;
47 NSData *ciphertext = CFBridgingRelease(SecKeyCreateEncryptedData(publicKey, algorithm, (CFDataRef)original, (void *)&error));
48 ok(ciphertext != nil, "RSA encrypt (native) succeeded (error: %@, key %@)", error, publicKey);
49
50 error = nil;
51 NSData *iosCiphertext = CFBridgingRelease(SecKeyCreateEncryptedData(iosPublicKey, algorithm, (CFDataRef)original, (void *)&error));
52 ok(iosCiphertext != nil, "RSA encrypt (native) succeeded (error: %@, key %@)", error, iosPublicKey);
53
54 error = nil;
55 plaintext = decryptAndUnpad(privateKey, algorithm, ciphertext, &error);
56 ok(plaintext != nil, "RSA decrypt (native) succeeded (error: %@, key %@)", error, privateKey);
57 ok([plaintext isEqual:original], "(native -> native) plaintext equals original (%@ : %@)", original, plaintext);
58
59 error = nil;
60 plaintext = decryptAndUnpad(privateKey, algorithm, iosCiphertext, &error);
61 ok(plaintext != nil, "RSA decrypt (native) succeeded (error: %@, key %@)", error, privateKey);
62 ok([plaintext isEqual:original], "(ios -> native) plaintext equals original (%@ : %@)", original, plaintext);
63
64 error = nil;
65 plaintext = decryptAndUnpad(iosPrivateKey, algorithm, ciphertext, &error);
66 ok(plaintext != nil, "RSA decrypt (ios) succeeded (error: %@, key %@)", error, privateKey);
67 ok([plaintext isEqual:original], "(native -> ios) plaintext equals original (%@ : %@)", original, plaintext);
68
69 error = nil;
70 plaintext = decryptAndUnpad(iosPrivateKey, algorithm, iosCiphertext, &error);
71 ok(plaintext != nil, "RSA decrypt (ios) succeeded (error: %@, key %@)", error, privateKey);
72 ok([plaintext isEqual:original], "(ios -> ios) plaintext equals original (%@ : %@)", original, plaintext);
73 }
74 static const int TestCountEncryptRun = 10;
75
76 static void test_encrypt_keypair_run(int keySizeInBits, NSArray *algorithms, NSArray *failAlgorithms) {
77 NSError *error;
78 NSDictionary *params = @{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeRSA, (id)kSecAttrKeySizeInBits: @(keySizeInBits)};
79
80 error = nil;
81 id privateKey = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)params, (void *)&error));
82 ok(privateKey != nil, "generate private key (error %@)", error);
83
84 id publicKey = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)privateKey));
85 ok(publicKey != nil, "get public key");
86
87 NSData *data = CFBridgingRelease(SecKeyCopyExternalRepresentation((SecKeyRef)privateKey, NULL));
88 NSDictionary *attrs = CFBridgingRelease(SecKeyCopyAttributes((SecKeyRef)privateKey));
89 error = nil;
90 id iosPrivateKey = CFBridgingRelease(SecKeyCreateWithData((CFDataRef)data, (CFDictionaryRef)attrs, (void *)&error));
91 ok(iosPrivateKey != nil, "get private key created from data");
92
93 data = CFBridgingRelease(SecKeyCopyExternalRepresentation((SecKeyRef)publicKey, NULL));
94 attrs = CFBridgingRelease(SecKeyCopyAttributes((SecKeyRef)publicKey));
95 error = nil;
96 id iosPublicKey = CFBridgingRelease(SecKeyCreateWithData((CFDataRef)data, (CFDictionaryRef)attrs, (void *)&error));
97 ok(iosPublicKey != nil, "get public key created from data");
98
99 for (id algorithm in algorithms) {
100 test_encrypt_run((__bridge SecKeyRef)privateKey, (__bridge SecKeyRef)publicKey,
101 (__bridge SecKeyRef)iosPrivateKey, (__bridge SecKeyRef)iosPublicKey,
102 (__bridge SecKeyAlgorithm)algorithm);
103 }
104
105 for (id algorithm in failAlgorithms) {
106 error = nil;
107 NSData *data = CFBridgingRelease(SecKeyCreateEncryptedData((SecKeyRef)publicKey, (SecKeyAlgorithm)algorithm, (CFDataRef)[NSData data], (void *)&error));
108 ok(data == nil && error.code == errSecParam, "incorrect algorithm refused");
109 }
110 }
111 static const int TestCountEncryptKeypairRun = 4;
112
113 static void test_encryption() {
114 test_encrypt_keypair_run(1024,
115 @[
116 (id)kSecKeyAlgorithmRSAEncryptionRaw,
117 (id)kSecKeyAlgorithmRSAEncryptionPKCS1,
118 (id)kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
119 (id)kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
120 (id)kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
121 (id)kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
122 ],
123 @[
124 (id)kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
125 ]);
126
127 test_encrypt_keypair_run(2048,
128 @[
129 (id)kSecKeyAlgorithmRSAEncryptionRaw,
130 (id)kSecKeyAlgorithmRSAEncryptionPKCS1,
131 (id)kSecKeyAlgorithmRSAEncryptionOAEPSHA1,
132 (id)kSecKeyAlgorithmRSAEncryptionOAEPSHA224,
133 (id)kSecKeyAlgorithmRSAEncryptionOAEPSHA256,
134 (id)kSecKeyAlgorithmRSAEncryptionOAEPSHA384,
135 (id)kSecKeyAlgorithmRSAEncryptionOAEPSHA512,
136 ],
137 @[
138 ]);
139 }
140 static const int TestCountEncryption =
141 TestCountEncryptKeypairRun + (TestCountEncryptRun * 6) + (1 * 1) +
142 TestCountEncryptKeypairRun + (TestCountEncryptRun * 7) + (1 * 0);
143
144 static const int TestCount = TestCountEncryption;
145 int si_44_seckey_rsa(int argc, char *const *argv) {
146 plan_tests(TestCount);
147
148 @autoreleasepool {
149 test_encryption();
150 }
151
152 return 0;
153 }