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