jens@26
|
1 |
//
|
jens@26
|
2 |
// MYCertificateTest.m
|
jens@26
|
3 |
// MYCrypto-iPhone
|
jens@26
|
4 |
//
|
jens@26
|
5 |
// Created by Jens Alfke on 6/15/09.
|
jens@26
|
6 |
// Copyright 2009 Jens Alfke. All rights reserved.
|
jens@26
|
7 |
//
|
jens@26
|
8 |
|
jens@26
|
9 |
#import "MYCertificateInfo.h"
|
jens@26
|
10 |
#import "MYCrypto.h"
|
jens@26
|
11 |
#import "MYCrypto_Private.h"
|
jens@26
|
12 |
|
jens@26
|
13 |
|
jens@26
|
14 |
#if DEBUG
|
jens@26
|
15 |
|
jens@26
|
16 |
|
jens@26
|
17 |
static MYCertificateInfo* testCertData(NSData *certData, BOOL selfSigned) {
|
jens@26
|
18 |
//Log(@"Cert Data =\n%@", certData);
|
jens@26
|
19 |
CAssert(certData!=nil);
|
jens@26
|
20 |
NSError *error = nil;
|
jens@26
|
21 |
MYCertificateInfo *pcert = [[MYCertificateInfo alloc] initWithCertificateData: certData
|
jens@26
|
22 |
error: &error];
|
jens@26
|
23 |
CAssertNil(error);
|
jens@26
|
24 |
CAssert(pcert != nil);
|
jens@26
|
25 |
|
jens@26
|
26 |
CAssertEq(pcert.isRoot, selfSigned);
|
jens@26
|
27 |
|
jens@26
|
28 |
MYCertificateName *subject = pcert.subject;
|
jens@26
|
29 |
Log(@"Common Name = %@", subject.commonName);
|
jens@26
|
30 |
Log(@"Given Name = %@", subject.givenName);
|
jens@26
|
31 |
Log(@"Surname = %@", subject.surname);
|
jens@26
|
32 |
Log(@"Desc = %@", subject.nameDescription);
|
jens@26
|
33 |
Log(@"Email = %@", subject.emailAddress);
|
jens@26
|
34 |
CAssert(subject.commonName);
|
jens@26
|
35 |
|
jens@26
|
36 |
MYPublicKey *pcertKey = pcert.subjectPublicKey;
|
jens@26
|
37 |
Log(@"Subject Public Key = %@", pcertKey);
|
jens@26
|
38 |
CAssert(pcertKey);
|
jens@26
|
39 |
|
jens@26
|
40 |
// Now go through MYCertificate:
|
jens@26
|
41 |
Log(@"Creating a MYCertificate from the data...");
|
jens@26
|
42 |
MYCertificate *cert = [[MYCertificate alloc] initWithCertificateData: certData];
|
jens@26
|
43 |
Log(@"MYCertificate = %@", cert);
|
jens@26
|
44 |
CAssert(cert);
|
jens@26
|
45 |
CAssertEqual(cert.info, pcert);
|
jens@26
|
46 |
Log(@"Trust = %@", MYTrustResultDescribe([cert evaluateTrust]));
|
jens@26
|
47 |
|
jens@26
|
48 |
MYPublicKey *certKey = cert.publicKey;
|
jens@26
|
49 |
Log(@"MYCertificate public key = ", certKey);
|
jens@26
|
50 |
CAssertEqual(certKey.keyData, pcert.subjectPublicKey.keyData);
|
jens@26
|
51 |
[cert release];
|
jens@26
|
52 |
/*TEMP
|
jens@26
|
53 |
Log(@"Adding to keychain...");
|
jens@26
|
54 |
cert = [[MYKeychain defaultKeychain] importCertificate: certData];
|
jens@26
|
55 |
Log(@"Imported as %@", cert);
|
jens@26
|
56 |
//CAssert(cert);
|
jens@26
|
57 |
if (cert) {
|
jens@26
|
58 |
Log(@"Removing from keychain...");
|
jens@26
|
59 |
CAssert([cert removeFromKeychain]);
|
jens@26
|
60 |
}
|
jens@26
|
61 |
*/
|
jens@26
|
62 |
return pcert;
|
jens@26
|
63 |
}
|
jens@26
|
64 |
|
jens@26
|
65 |
static NSData* readTestFile(NSString *filename) {
|
jens@26
|
66 |
#if TARGET_OS_IPHONE
|
jens@26
|
67 |
filename = [[NSBundle mainBundle] pathForResource: filename ofType: @"cer"];
|
jens@26
|
68 |
#else
|
jens@26
|
69 |
filename = [[@"../../Tests/" stringByAppendingPathComponent: filename]
|
jens@26
|
70 |
stringByAppendingPathExtension: @"cer"];
|
jens@26
|
71 |
#endif
|
jens@26
|
72 |
Log(@"--- Testing certificate file %@", filename);
|
jens@26
|
73 |
NSData *data = [NSData dataWithContentsOfFile: filename];
|
jens@26
|
74 |
CAssert(data, @"Couldn't read file %@", filename);
|
jens@26
|
75 |
return data;
|
jens@26
|
76 |
}
|
jens@26
|
77 |
|
jens@26
|
78 |
static MYCertificateInfo* testCert(NSString *filename, BOOL selfSigned) {
|
jens@26
|
79 |
return testCertData(readTestFile(filename), selfSigned);
|
jens@26
|
80 |
}
|
jens@26
|
81 |
|
jens@26
|
82 |
|
jens@26
|
83 |
TestCase(ParsedCert) {
|
jens@26
|
84 |
testCert(@"selfsigned", YES);
|
jens@26
|
85 |
testCert(@"iphonedev", NO);
|
jens@26
|
86 |
|
jens@26
|
87 |
// Now test a self-signed cert with a bad signature:
|
jens@26
|
88 |
MYCertificate *cert = [[MYCertificate alloc] initWithCertificateData: readTestFile(@"selfsigned_altered")];
|
jens@26
|
89 |
Log(@"MYCertificate = %@", cert);
|
jens@26
|
90 |
CAssertNil(cert);
|
jens@26
|
91 |
}
|
jens@26
|
92 |
|
jens@26
|
93 |
|
jens@26
|
94 |
#import "MYCrypto_Private.h"
|
jens@26
|
95 |
|
jens@26
|
96 |
TestCase(CreateCert) {
|
jens@26
|
97 |
MYPrivateKey *privateKey = [[MYKeychain defaultKeychain] generateRSAKeyPairOfSize: 512];
|
jens@26
|
98 |
CAssert(privateKey);
|
jens@26
|
99 |
Log(@"---- Generated key-pair with %@, %@", privateKey.publicKey, privateKey);
|
jens@26
|
100 |
MYIdentity *identity = nil;
|
jens@26
|
101 |
@try{
|
jens@26
|
102 |
MYCertificateRequest *pcert = [[MYCertificateRequest alloc] initWithPublicKey: privateKey.publicKey];
|
jens@26
|
103 |
MYCertificateName *subject = pcert.subject;
|
jens@26
|
104 |
subject.commonName = @"testcase";
|
jens@26
|
105 |
subject.givenName = @"Test";
|
jens@26
|
106 |
subject.surname = @"Case";
|
jens@26
|
107 |
subject.nameDescription = @"Just a test certificate created by MYCrypto";
|
jens@26
|
108 |
subject.emailAddress = @"testcase@example.com";
|
jens@26
|
109 |
|
jens@26
|
110 |
subject = pcert.subject;
|
jens@26
|
111 |
CAssertEqual(subject.commonName, @"testcase");
|
jens@26
|
112 |
CAssertEqual(subject.givenName, @"Test");
|
jens@26
|
113 |
CAssertEqual(subject.surname, @"Case");
|
jens@26
|
114 |
CAssertEqual(subject.nameDescription, @"Just a test certificate created by MYCrypto");
|
jens@26
|
115 |
CAssertEqual(subject.emailAddress, @"testcase@example.com");
|
jens@26
|
116 |
|
jens@26
|
117 |
CAssertEqual(pcert.subjectPublicKey.keyData, privateKey.publicKey.keyData);
|
jens@26
|
118 |
|
jens@26
|
119 |
Log(@"---- Signing...");
|
jens@26
|
120 |
NSError *error;
|
jens@26
|
121 |
NSData *certData = [pcert selfSignWithPrivateKey: privateKey error: &error];
|
jens@26
|
122 |
Log(@"Generated cert = \n%@", certData);
|
jens@26
|
123 |
CAssert(certData);
|
jens@26
|
124 |
CAssertNil(error);
|
jens@26
|
125 |
CAssert(certData);
|
jens@26
|
126 |
MYCertificateInfo *pcert2 = testCertData(certData, YES);
|
jens@26
|
127 |
|
jens@26
|
128 |
Log(@"---- Verifying Info...");
|
jens@26
|
129 |
MYCertificateName *subject2 = pcert2.subject;
|
jens@26
|
130 |
CAssertEqual(subject2,subject);
|
jens@26
|
131 |
CAssertEqual(subject2.commonName, @"testcase");
|
jens@26
|
132 |
CAssertEqual(subject2.givenName, @"Test");
|
jens@26
|
133 |
CAssertEqual(subject2.surname, @"Case");
|
jens@26
|
134 |
CAssertEqual(subject2.nameDescription, @"Just a test certificate created by MYCrypto");
|
jens@26
|
135 |
CAssertEqual(subject2.emailAddress, @"testcase@example.com");
|
jens@26
|
136 |
|
jens@26
|
137 |
Log(@"---- Creating MYCertificate object...");
|
jens@26
|
138 |
MYCertificate *cert = [[MYCertificate alloc] initWithCertificateData: certData];
|
jens@26
|
139 |
Log(@"Loaded %@", cert);
|
jens@26
|
140 |
CAssert(cert);
|
jens@26
|
141 |
MYPublicKey *certKey = cert.publicKey;
|
jens@26
|
142 |
Log(@"Its public key has name %@", certKey.name);//TEMP
|
jens@26
|
143 |
Log(@"Its public key = %@", certKey);
|
jens@26
|
144 |
CAssertEqual(certKey.keyData, privateKey.publicKey.keyData);
|
jens@26
|
145 |
Log(@"X.509 trust = %@", MYTrustResultDescribe([cert evaluateTrust]));
|
jens@26
|
146 |
Log(@"SSL trust = %@", MYTrustResultDescribe([cert evaluateTrustWithPolicy: [MYCertificate SSLPolicy]]));
|
jens@26
|
147 |
|
jens@26
|
148 |
Log(@"---- Adding cert to keychain...");
|
jens@26
|
149 |
MYCertificate *addedCert = [[MYKeychain defaultKeychain] importCertificate: certData];
|
jens@26
|
150 |
Log(@"Imported as %@", addedCert);
|
jens@26
|
151 |
//CAssert(addedCert);
|
jens@26
|
152 |
if (addedCert)
|
jens@26
|
153 |
CAssert([addedCert removeFromKeychain]);
|
jens@26
|
154 |
|
jens@26
|
155 |
Log(@"---- Creating Identity...");
|
jens@26
|
156 |
identity = [pcert createSelfSignedIdentityWithPrivateKey: privateKey error: &error];
|
jens@26
|
157 |
Log(@"Identity = %@", identity);
|
jens@26
|
158 |
CAssert(identity);
|
jens@26
|
159 |
CAssertNil(error);
|
jens@26
|
160 |
CAssertEqual(identity.keychain, [MYKeychain defaultKeychain]);
|
jens@26
|
161 |
CAssertEqual(identity.privateKey.publicKeyDigest, privateKey.publicKeyDigest);
|
jens@26
|
162 |
CAssert([identity isEqualToCertificate: cert]);
|
jens@26
|
163 |
|
jens@26
|
164 |
[pcert release];
|
jens@26
|
165 |
|
jens@26
|
166 |
} @finally {
|
jens@26
|
167 |
// [privateKey removeFromKeychain];
|
jens@26
|
168 |
// [identity removeFromKeychain];
|
jens@26
|
169 |
// Currently I'm leaving them in, so the EnumerateXXX tests can chew on them later.
|
jens@26
|
170 |
}
|
jens@26
|
171 |
}
|
jens@26
|
172 |
|
jens@26
|
173 |
#endif
|
jens@26
|
174 |
|
jens@26
|
175 |
|
jens@26
|
176 |
/*
|
jens@26
|
177 |
Copyright (c) 2009, Jens Alfke <jens@mooseyard.com>. All rights reserved.
|
jens@26
|
178 |
|
jens@26
|
179 |
Redistribution and use in source and binary forms, with or without modification, are permitted
|
jens@26
|
180 |
provided that the following conditions are met:
|
jens@26
|
181 |
|
jens@26
|
182 |
* Redistributions of source code must retain the above copyright notice, this list of conditions
|
jens@26
|
183 |
and the following disclaimer.
|
jens@26
|
184 |
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions
|
jens@26
|
185 |
and the following disclaimer in the documentation and/or other materials provided with the
|
jens@26
|
186 |
distribution.
|
jens@26
|
187 |
|
jens@26
|
188 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
jens@26
|
189 |
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
jens@26
|
190 |
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
|
jens@26
|
191 |
BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
jens@26
|
192 |
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
jens@26
|
193 |
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
jens@26
|
194 |
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
jens@26
|
195 |
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
jens@26
|
196 |
*/
|