* Replaced MYKeyPair with MYPrivateKey.
* Changed config files.
5 // Created by Jens Alfke on 4/1/09.
6 // Copyright 2009 Jens Alfke. All rights reserved.
9 #import "MYPublicKey.h"
10 #import "MYPrivateKey.h"
11 #import "MYKeychain.h"
13 #import "MYCrypto_Private.h"
19 #pragma mark KEYCHAIN:
22 TestCase(MYKeychain) {
23 MYKeychain *kc = [MYKeychain defaultKeychain];
24 Log(@"Default keychain = %@", kc);
26 #if !MYCRYPTO_USE_IPHONE_API
30 kc = [MYKeychain allKeychains];
31 Log(@"All-keychains = %@", kc);
33 #if !MYCRYPTO_USE_IPHONE_API
34 CAssertEq(kc.path,nil);
39 TestCase(EnumerateKeys) {
40 RequireTestCase(MYKeychain);
41 NSEnumerator *e = [[MYKeychain allKeychains] enumeratePublicKeys];
42 Log(@"Public Key Enumerator = %@", e);
44 for (MYPublicKey *key in e) {
45 Log(@"Found %@ -- name=%@", key, key.name);
48 e = [[MYKeychain allKeychains] enumeratePrivateKeys];
49 Log(@"Key-Pair Enumerator = %@", e);
51 for (MYPrivateKey *key in e) {
52 Log(@"Found %@ -- name=%@", key, key.name);
55 e = [[MYKeychain allKeychains] enumerateSymmetricKeys];
56 Log(@"Symmetric Key Enumerator = %@", e);
58 for (MYSymmetricKey *key in e) {
59 Log(@"Found %@ -- name=%@", key, key.name);
64 TestCase(EnumerateCerts) {
65 RequireTestCase(MYKeychain);
66 NSEnumerator *e = [[MYKeychain allKeychains] enumerateCertificates];
67 Log(@"Enumerator = %@", e);
69 for (MYCertificate *cert in e) {
70 //Log(@"Found %@ -- name=%@, email=%@", cert, cert.commonName, cert.emailAddresses);
76 #pragma mark SYMMETRIC KEYS:
79 static void testSymmetricKey( CCAlgorithm algorithm, unsigned sizeInBits ) {
80 NSAutoreleasePool *pool = [NSAutoreleasePool new];
81 Log(@"--- Testing %3u-bit #%i", sizeInBits, (int)algorithm);
83 MYSymmetricKey *key = [MYSymmetricKey generateSymmetricKeyOfSize: sizeInBits
84 algorithm: algorithm];
85 Log(@"Created %@", key);
87 CAssertEq(key.algorithm, algorithm);
88 CAssertEq(key.keySizeInBits, sizeInBits);
90 CAssert(key.cssmKey != NULL);
93 NSData *keyData = key.keyData;
94 Log(@"Key data = %@", keyData);
95 CAssertEq(keyData.length, sizeInBits/8);
97 // Encrypt a small amount of text:
98 NSData *cleartext = [@"This is a test. This is only a test." dataUsingEncoding: NSUTF8StringEncoding];
99 NSData *encrypted = [key encryptData: cleartext];
100 Log(@"Encrypted = %u bytes: %@", encrypted.length, encrypted);
101 CAssert(encrypted.length >= cleartext.length);
102 NSData *decrypted = [key decryptData: encrypted];
103 CAssertEqual(decrypted, cleartext);
105 // Encrypt large binary data:
106 cleartext = [NSData dataWithContentsOfFile: @"/Library/Desktop Pictures/Nature/Zen Garden.jpg"];
108 encrypted = [key encryptData: cleartext];
109 Log(@"Encrypted = %u bytes", encrypted.length);
110 CAssert(encrypted.length >= cleartext.length);
111 decrypted = [key decryptData: encrypted];
112 CAssertEqual(decrypted, cleartext);
114 #if !TARGET_OS_IPHONE
115 // Try reconstituting the key from its data:
116 NSData *exported = [key exportKeyInFormat: kSecFormatWrappedPKCS8 withPEM: NO];
117 Log(@"Exported key: %@", exported);
118 // CAssert(exported);
119 //FIX: Exporting symmetric keys isn't working. Temporarily making this optional.
122 MYSymmetricKey *key2 = [[MYSymmetricKey alloc] initWithKeyData: exported algorithm: algorithm];
123 Log(@"Reconstituted as %@", key2);
124 CAssertEqual(key2,key);
125 decrypted = [key2 decryptData: encrypted];
126 CAssertEqual(decrypted, cleartext);
128 Warn(@"Unable to export key in PKCS8");
134 TestCase(MYSymmetricKey) {
136 static const CCAlgorithm kTestAlgorithms[kNTests] = {
137 kCCAlgorithmAES128, kCCAlgorithmAES128, kCCAlgorithmAES128,
138 kCCAlgorithmDES, kCCAlgorithm3DES,
139 kCCAlgorithmCAST, kCCAlgorithmCAST, kCCAlgorithmCAST,
140 kCCAlgorithmRC4, kCCAlgorithmRC4, kCCAlgorithmRC4};
142 static const unsigned kTestBitSizes[kNTests] = {
148 for (int i=0; i<kNTests; i++)
149 testSymmetricKey(kTestAlgorithms[i], kTestBitSizes[i]);
154 #pragma mark KEY-PAIRS:
157 TestCase(MYPrivateKey) {
158 RequireTestCase(MYKeychain);
160 Log(@"Generating key pair...");
161 MYPrivateKey *pair = [[MYKeychain defaultKeychain] generateRSAKeyPairOfSize: 512];
162 Log(@"...created { %@ , %@ }.", pair, pair.publicKey);
164 CAssert(pair.keyRef);
165 MYPublicKey *publicKey = pair.publicKey;
166 CAssert(publicKey.keyRef);
169 NSData *pubKeyData = publicKey.keyData;
170 Log(@"Public key = %@ (%u bytes)",pubKeyData,pubKeyData.length);
173 MYSHA1Digest *pubKeyDigest = publicKey.publicKeyDigest;
174 Log(@"Public key digest = %@",pubKeyDigest);
175 CAssertEqual(pair.publicKeyDigest, pubKeyDigest);
177 Log(@"SHA1 of pub key = %@", pubKeyData.my_SHA1Digest.asData);
179 NSData *data = [@"This is a test. This is only a test!" dataUsingEncoding: NSUTF8StringEncoding];
180 NSData *sig = [pair signData: data];
181 Log(@"Signature = %@ (%u bytes)",sig,sig.length);
183 CAssert( [publicKey verifySignature: sig ofData: data] );
185 [pair setName: @"Test KeyPair Label"];
186 CAssertEqual(pair.name, @"Test KeyPair Label");
187 CAssertEqual(publicKey.name, @"Test KeyPair Label");
188 #if !TARGET_OS_IPHONE
189 [pair setComment: @"This key-pair was generated automatically by a test case."];
190 CAssertEqual(pair.comment, @"This key-pair was generated automatically by a test case.");
191 CAssertEqual(publicKey.comment, @"This key-pair was generated automatically by a test case.");
193 [pair setAlias: @"TestCase@mooseyard.com"];
194 CAssertEqual(pair.alias, @"TestCase@mooseyard.com");
195 CAssertEqual(publicKey.alias, @"TestCase@mooseyard.com");
197 // Test creating a standalone public key:
198 MYPublicKey *pub = [[MYPublicKey alloc] initWithKeyRef: publicKey.keyRef];
199 CAssert( [pub verifySignature: sig ofData: data] );
200 Log(@"Verified signature.");
202 // Test creating a public key from data:
203 Log(@"Reconstituting public key from data...");
204 pub = [[MYPublicKey alloc] initWithKeyData: pubKeyData];
206 CAssertEqual(pub.keyData, pubKeyData);
207 CAssertEqual(pub.publicKeyDigest, pubKeyDigest);
208 CAssert( [pub verifySignature: sig ofData: data] );
209 Log(@"Verified signature from reconstituted key.");
211 // Now let's encrypt...
212 NSData *crypted = [pub encryptData: data];
213 Log(@"Encrypted = %@ (%u bytes)",crypted,crypted.length);
216 CAssertEqual([pair decryptData: crypted], data);
217 Log(@"Verified decryption.");
219 CAssert([pair removeFromKeychain]);
220 Log(@"Removed key-pair.");
225 if ([pair removeFromKeychain])
226 Log(@"Removed key-pair from keychain.");
228 Warn(@"Unable to remove test key-pair from keychain");
236 #pragma mark KEYPAIR EXPORT:
239 static void testKeyPairExportWithPrompt(BOOL withPrompt) {
240 MYKeychain *keychain = [MYKeychain allKeychains];
241 Log(@"Generating key pair...");
242 MYPrivateKey *pair = [keychain generateRSAKeyPairOfSize: 512];
244 CAssert(pair.keyRef);
245 CAssert(pair.publicKey.keyRef);
246 Log(@"...created pair.");
249 NSData *pubKeyData = pair.publicKey.keyData;
250 CAssert(pubKeyData.length >= 512/8);
251 [pair setName: @"Test KeyPair Label"];
252 CAssertEqual(pair.name, @"Test KeyPair Label");
253 #if !TARGET_OS_IPHONE
254 [pair setComment: @"This key-pair was generated automatically by a test case."];
255 CAssertEqual(pair.comment, @"This key-pair was generated automatically by a test case.");
257 [pair setAlias: @"TestCase@mooseyard.com"];
258 CAssertEqual(pair.alias, @"TestCase@mooseyard.com");
260 #if !TARGET_OS_IPHONE
261 Log(@"Exporting key-pair...");
262 NSString *passphrase = @"passphrase";
265 privKeyData = [pair exportKey];
267 privKeyData = [pair _exportKeyInFormat: kSecFormatWrappedOpenSSL
269 passphrase: passphrase];
270 Log(@"Exported data = %@ (%u bytes)", privKeyData,privKeyData.length);
271 CAssert(privKeyData);
272 [privKeyData writeToFile: @"ExportedPrivKey" atomically: YES];
276 Log(@"Looking up public key of pair in keychain...");
277 MYSHA1Digest *digest = pair.publicKeyDigest;
278 MYPublicKey *foundKey = [keychain publicKeyWithDigest: digest];
279 CAssertEqual(foundKey, pair.publicKey);
280 CAssert([keychain.enumeratePublicKeys.allObjects containsObject: pair.publicKey]);
281 MYPrivateKey *foundPair = [keychain privateKeyWithDigest: digest];
282 CAssertEqual(foundPair, pair);
283 CAssert([keychain.enumeratePrivateKeys.allObjects containsObject: pair]);
285 Log(@"Removing key-pair from keychain...");
286 CAssert([pair removeFromKeychain]);
288 CAssert([keychain publicKeyWithDigest: digest] == nil);
290 #if !TARGET_OS_IPHONE
291 Log(@"Importing key-pair...");
293 pair = [keychain importPublicKey: pubKeyData
294 privateKey: privKeyData];
296 pair = [[[MYPrivateKey alloc] _initWithKeyData: privKeyData
297 publicKeyData: pubKeyData
298 forKeychain: keychain.keychainRefOrDefault
299 passphrase: passphrase]
303 CAssertEqual(pair.publicKey.keyData, pubKeyData);
307 if ([pair removeFromKeychain])
308 Log(@"Removed key-pair from keychain.");
310 Warn(@"Unable to remove test key-pair from keychain");
315 TestCase(KeyPairExport) {
316 RequireTestCase(MYKeychain);
317 RequireTestCase(MYPrivateKey);
318 testKeyPairExportWithPrompt(NO);
321 TestCase(KeyPairExportWithUI) {
322 RequireTestCase(KeyPairExport);
323 testKeyPairExportWithPrompt(YES);