2 * Copyright (c) 2011-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 #include "testpolicy.h"
27 #include <TargetConditionals.h>
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>
46 * Copyright (c) 2011-2014 Apple Inc. All Rights Reserved.
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>
62 /* Those tests were originally written around that date. */
63 CFGiblisGetSingleton(CFDateRef, GetFrozenTime, frozenTime, ^{
64 *frozenTime = CFDateCreateForGregorianZuluDay(NULL, 2011, 9, 1);
67 static void runOneLeafTest(SecPolicyRef policy,
69 NSArray* intermediates,
72 NSObject* expectations,
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;
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"];
89 if ([value isKindOfClass: [NSNumber class]]) {
90 expectedResult = [(NSNumber *)value boolValue];
92 NSLog(@"Unexpected valid value %@ in dict for key %@", value, fileName);
95 value = [dict valueForKey:@"reason"];
97 if ([value isKindOfClass: [NSString class]]) {
98 reason = [(NSString *)value UTF8String];
100 NSLog(@"Unexpected reason value %@ in dict for key %@", value, fileName);
103 } else if ([expectations isKindOfClass: [NSNumber class]]) {
104 expectedResult = [(NSNumber *)expectations boolValue];
106 NSLog(@"Unexpected class %@ value %@ for key %@", [expectations class], expectations, fileName);
110 certRef = SecCertificateCreateWithData(NULL, (CFDataRef)[NSData dataWithContentsOfFile:path]);
114 fail("%@ unable to create certificate", fileName);
116 fail("PARSE %@ unable to create certificate", fileName);
121 certArray = [NSMutableArray arrayWithArray:intermediates];
122 [certArray insertObject:(id)certRef atIndex:0]; //The certificate to be verified must be the first in the array.
125 err = SecTrustCreateWithCertificates(certArray, policy, &trustRef);
127 ok_status(err, "SecTrustCreateWithCertificates");
131 SecTrustSetAnchorCertificates(trustRef, (CFArrayRef)anchors);
133 SecTrustSetVerifyDate(trustRef, date ? date : GetFrozenTime());
135 SecTrustResultType evalRes = 0;
136 //NSLog(@"Evaluating: %@",certRef);
137 err = SecTrustEvaluate(trustRef, &evalRes);
139 ok_status(err, "SecTrustCreateWithCertificates");
142 BOOL isValid = (evalRes == kSecTrustResultProceed || evalRes == kSecTrustResultUnspecified);
143 if (!isValid && expectedResult) {
144 failReason = SecTrustCopyFailureDescription(trustRef);
148 ok(isValid == expectedResult, "%@%@",
151 ? (failReason ? failReason : CFSTR(""))
154 ok(isValid == expectedResult, "%s %@%@",
155 expectedResult ? "REGRESSION" : "SECURITY", fileName,
156 failReason ? failReason : CFSTR(""));
160 CFReleaseSafe(failReason);
161 CFReleaseSafe(trustRef);
162 CFReleaseSafe(certRef);
165 // TODO: Export this interface in a better way.
166 static void runCertificateTestFor(SecPolicyRef policy,
168 NSArray* intermediates,
169 NSMutableArray* leafPaths,
170 NSDictionary* expect,
173 /* Sort the tests by name. */
174 [leafPaths sortUsingSelector:@selector(compare:)];
176 for (NSString* path in leafPaths) {
177 NSString* fileName = [path lastPathComponent];
178 runOneLeafTest(policy, anchors, intermediates, path, ![fileName hasPrefix:@"Invalid"], [expect objectForKey:fileName], date);
182 void runCertificateTestForDirectory(SecPolicyRef policy, CFStringRef resourceSubDirectory, CFDateRef date)
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;
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"]) {
204 fail("Multiple .plist files found in %@", filesDirectory);
206 expect = [NSDictionary dictionaryWithContentsOfFile:path];
211 runCertificateTestFor(policy, allRoots, allCAs, certTests, expect, date);
216 #endif /* TARGET_OS_IPHONE */