]> git.saurik.com Git - apple/security.git/blob - OSX/regressions/test/testpolicy.m
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / regressions / test / testpolicy.m
1 /*
2 * Copyright (c) 2011-2014 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 #include "testpolicy.h"
26
27 #include <TargetConditionals.h>
28
29 #if TARGET_OS_IPHONE
30
31 #include <Foundation/Foundation.h>
32 #include <CoreFoundation/CoreFoundation.h>
33 #include <utilities/SecCFWrappers.h>
34 #include <Security/SecCertificate.h>
35 #include <Security/SecCertificatePriv.h>
36 #include <Security/SecInternal.h>
37 #include <Security/SecPolicyPriv.h>
38 #include <Security/SecTrust.h>
39 #include <Security/SecTrustPriv.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42
43 #include "testmore.h"
44
45 /*
46 * Copyright (c) 2011-2014 Apple Inc. All Rights Reserved.
47 */
48
49 #include <Foundation/Foundation.h>
50 #include <CoreFoundation/CoreFoundation.h>
51 #include <Security/SecCertificate.h>
52 #include <Security/SecCertificatePriv.h>
53 #include <Security/SecInternal.h>
54 #include <Security/SecPolicyPriv.h>
55 #include <Security/SecTrust.h>
56 #include <Security/SecTrustPriv.h>
57 #include <stdlib.h>
58 #include <unistd.h>
59
60 #include "testmore.h"
61
62 /* Those tests were originally written around that date. */
63 CFGiblisGetSingleton(CFDateRef, GetFrozenTime, frozenTime, ^{
64 *frozenTime = CFDateCreateForGregorianZuluDay(NULL, 2011, 9, 1);
65 });
66
67 static void runOneLeafTest(SecPolicyRef policy,
68 NSArray* anchors,
69 NSArray* intermediates,
70 NSString* path,
71 bool expectedResult,
72 NSObject* expectations,
73 CFDateRef date)
74 {
75 NSString* fileName = [path lastPathComponent];
76 const char *reason = NULL;
77 SecTrustRef trustRef = NULL;
78 CFStringRef failReason = NULL;
79 NSMutableArray* certArray = NULL;
80 SecCertificateRef certRef = NULL;
81
82 if (expectations) {
83 if ([expectations isKindOfClass: [NSString class]]) {
84 reason = [(NSString *)expectations UTF8String];
85 } else if ([expectations isKindOfClass: [NSDictionary class]]) {
86 NSDictionary *dict = (NSDictionary *)expectations;
87 NSObject *value = [dict valueForKey:@"valid"];
88 if (value) {
89 if ([value isKindOfClass: [NSNumber class]]) {
90 expectedResult = [(NSNumber *)value boolValue];
91 } else {
92 NSLog(@"Unexpected valid value %@ in dict for key %@", value, fileName);
93 }
94 }
95 value = [dict valueForKey:@"reason"];
96 if (value) {
97 if ([value isKindOfClass: [NSString class]]) {
98 reason = [(NSString *)value UTF8String];
99 } else {
100 NSLog(@"Unexpected reason value %@ in dict for key %@", value, fileName);
101 }
102 }
103 } else if ([expectations isKindOfClass: [NSNumber class]]) {
104 expectedResult = [(NSNumber *)expectations boolValue];
105 } else {
106 NSLog(@"Unexpected class %@ value %@ for key %@", [expectations class], expectations, fileName);
107 }
108 }
109
110 certRef = SecCertificateCreateWithData(NULL, (CFDataRef)[NSData dataWithContentsOfFile:path]);
111 if (!certRef) {
112 if (reason) {
113 todo(reason);
114 fail("%@ unable to create certificate", fileName);
115 } else {
116 fail("PARSE %@ unable to create certificate", fileName);
117 }
118 goto exit;
119 }
120
121 certArray = [NSMutableArray arrayWithArray:intermediates];
122 [certArray insertObject:(id)certRef atIndex:0]; //The certificate to be verified must be the first in the array.
123
124 OSStatus err;
125 err = SecTrustCreateWithCertificates(certArray, policy, &trustRef);
126 if (err) {
127 ok_status(err, "SecTrustCreateWithCertificates");
128 goto exit;
129 }
130 if ([anchors count])
131 SecTrustSetAnchorCertificates(trustRef, (CFArrayRef)anchors);
132
133 SecTrustSetVerifyDate(trustRef, date ? date : GetFrozenTime());
134
135 SecTrustResultType evalRes = 0;
136 //NSLog(@"Evaluating: %@",certRef);
137 err = SecTrustEvaluate(trustRef, &evalRes);
138 if (err) {
139 ok_status(err, "SecTrustCreateWithCertificates");
140 goto exit;
141 }
142 BOOL isValid = (evalRes == kSecTrustResultProceed || evalRes == kSecTrustResultUnspecified);
143 if (!isValid && expectedResult) {
144 failReason = SecTrustCopyFailureDescription(trustRef);
145 }
146 if (reason) {
147 todo(reason);
148 ok(isValid == expectedResult, "%@%@",
149 fileName,
150 (expectedResult
151 ? (failReason ? failReason : CFSTR(""))
152 : CFSTR(" valid")));
153 } else {
154 ok(isValid == expectedResult, "%s %@%@",
155 expectedResult ? "REGRESSION" : "SECURITY", fileName,
156 failReason ? failReason : CFSTR(""));
157 }
158
159 exit:
160 CFReleaseSafe(failReason);
161 CFReleaseSafe(trustRef);
162 CFReleaseSafe(certRef);
163 }
164
165 // TODO: Export this interface in a better way.
166 static void runCertificateTestFor(SecPolicyRef policy,
167 NSArray* anchors,
168 NSArray* intermediates,
169 NSMutableArray* leafPaths,
170 NSDictionary* expect,
171 CFDateRef date)
172 {
173 /* Sort the tests by name. */
174 [leafPaths sortUsingSelector:@selector(compare:)];
175
176 for (NSString* path in leafPaths) {
177 NSString* fileName = [path lastPathComponent];
178 runOneLeafTest(policy, anchors, intermediates, path, ![fileName hasPrefix:@"Invalid"], [expect objectForKey:fileName], date);
179 }
180 }
181
182 void runCertificateTestForDirectory(SecPolicyRef policy, CFStringRef resourceSubDirectory, CFDateRef date)
183 {
184 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
185 NSMutableArray* allRoots = [NSMutableArray array];
186 NSMutableArray* allCAs = [NSMutableArray array];
187 NSMutableArray* certTests = [NSMutableArray array];
188 NSDictionary* expect = NULL;
189
190 /* Iterate though the nist-certs resources dir. */
191 NSURL* filesDirectory = [[[NSBundle mainBundle] resourceURL] URLByAppendingPathComponent:(NSString*)resourceSubDirectory];
192 for (NSURL* fileURL in [[NSFileManager defaultManager] contentsOfDirectoryAtURL:filesDirectory includingPropertiesForKeys:[NSArray array] options:NSDirectoryEnumerationSkipsSubdirectoryDescendants error:nil]) {
193 NSString* path = [fileURL path];
194 if ([path hasSuffix:@"Cert.crt"]) {
195 SecCertificateRef certRef = SecCertificateCreateWithData(NULL, (CFDataRef)[NSData dataWithContentsOfFile:path]);
196 [allCAs addObject:(id)certRef];
197 } else if ([path hasSuffix:@"RootCertificate.crt"]) {
198 SecCertificateRef certRef = SecCertificateCreateWithData(NULL, (CFDataRef)[NSData dataWithContentsOfFile:path]);
199 [allRoots addObject:(id)certRef];
200 } else if ([path hasSuffix:@".crt"]) {
201 [certTests addObject:path];
202 } else if ([path hasSuffix:@".plist"]) {
203 if (expect) {
204 fail("Multiple .plist files found in %@", filesDirectory);
205 } else {
206 expect = [NSDictionary dictionaryWithContentsOfFile:path];
207 }
208 }
209 }
210
211 runCertificateTestFor(policy, allRoots, allCAs, certTests, expect, date);
212
213 [pool release];
214 }
215
216 #endif /* TARGET_OS_IPHONE */