2 * Copyright (c) 2018 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 <AssertMacros.h>
26 #import <XCTest/XCTest.h>
27 #include <Security/SecCertificate.h>
28 #include <Security/SecCertificatePriv.h>
29 #include <Security/SecCertificateInternal.h>
30 #include <Security/SecFramework.h>
31 #include <utilities/SecCFRelease.h>
32 #include "../TestMacroConversions.h"
34 #include "TrustFrameworkTestCase.h"
36 const NSString *kSecTestParseFailureResources = @"si-18-certificate-parse/ParseFailureCerts";
37 const NSString *kSecTestParseSuccessResources = @"si-18-certificate-parse/ParseSuccessCerts";
38 const NSString *kSecTestKeyFailureResources = @"si-18-certificate-parse/KeyFailureCerts";
39 const NSString *kSecTestTODOFailureResources = @"si-18-certificate-parse/TODOFailureCerts";
40 const NSString *kSecTestExtensionFailureResources = @"si-18-certificate-parse/ExtensionFailureCerts";
42 @interface CertificateParseTests : TrustFrameworkTestCase
46 @implementation CertificateParseTests
48 - (void)testParseFailure {
49 /* A bunch of certificates with different parsing errors */
50 NSArray <NSURL *>* certURLs = [[NSBundle bundleForClass:[self class]]URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestParseFailureResources];
51 XCTAssertTrue([certURLs count] > 0, "Unable to find parse test failure certs in bundle.");
53 if ([certURLs count] > 0) {
54 [certURLs enumerateObjectsUsingBlock:^(NSURL *url, __unused NSUInteger idx, __unused BOOL *stop) {
55 NSData *certData = [NSData dataWithContentsOfURL:url];
56 SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData);
57 is(cert, NULL, "Successfully parsed bad cert: %@", url);
63 - (void)testParseSuccess {
64 /* A bunch of certificates with different parsing variations */
65 NSArray <NSURL *>* certURLs = [[NSBundle bundleForClass:[self class]]URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestParseSuccessResources];
66 XCTAssertTrue([certURLs count] > 0, "Unable to find parse test success certs in bundle.");
68 if ([certURLs count] > 0) {
69 [certURLs enumerateObjectsUsingBlock:^(NSURL *url, __unused NSUInteger idx, __unused BOOL *stop) {
70 NSData *certData = [NSData dataWithContentsOfURL:url];
71 SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData);
72 isnt(cert, NULL, "Failed to parse good cert: %@", url);
73 is(SecCertificateGetUnparseableKnownExtension(cert), kCFNotFound, "Found bad extension in good certs: %@", url);
79 - (void)testKeyFailure {
80 /* Parse failures that require public key extraction */
81 NSArray <NSURL *>* certURLs = [[NSBundle bundleForClass:[self class]]URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestKeyFailureResources];
82 XCTAssertTrue([certURLs count] > 0, "Unable to find parse test key failure certs in bundle.");
84 if ([certURLs count] > 0) {
85 [certURLs enumerateObjectsUsingBlock:^(NSURL *url, __unused NSUInteger idx, __unused BOOL *stop) {
86 NSData *certData = [NSData dataWithContentsOfURL:url];
87 SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData);
88 SecKeyRef pubkey = NULL;
89 require_action(cert, blockOut,
90 fail("Failed to parse cert with SPKI error: %@", url));
91 pubkey = SecCertificateCopyKey(cert);
92 is(pubkey, NULL, "Successfully parsed bad SPKI: %@", url);
96 CFReleaseNull(pubkey);
101 - (void)testTODOFailures {
102 /* A bunch of certificates with different parsing errors that currently succeed. */
103 NSArray <NSURL *>* certURLs = [[NSBundle bundleForClass:[self class]]URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestTODOFailureResources];
104 XCTAssertTrue([certURLs count] > 0, "Unable to find parse test TODO failure certs in bundle.");
106 if ([certURLs count] > 0) {
107 [certURLs enumerateObjectsUsingBlock:^(NSURL *url, __unused NSUInteger idx, __unused BOOL *stop) {
108 NSData *certData = [NSData dataWithContentsOfURL:url];
109 SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData);
110 isnt(cert, NULL, "Successfully parsed bad TODO cert: %@", url);
116 - (void)testUnparseableExtensions {
117 /* A bunch of certificates with different parsing errors in known (but non-critical) extensions */
118 NSArray <NSURL *>* certURLs = [[NSBundle bundleForClass:[self class]]URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestExtensionFailureResources];
119 XCTAssertTrue([certURLs count] > 0, "Unable to find parse test extension failure certs in bundle.");
121 if ([certURLs count] > 0) {
122 [certURLs enumerateObjectsUsingBlock:^(NSURL *url, __unused NSUInteger idx, __unused BOOL *stop) {
123 NSData *certData = [NSData dataWithContentsOfURL:url];
124 SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData);
125 isnt(cert, NULL, "Failed to parse bad cert with unparseable extension: %@", url);
126 isnt(SecCertificateGetUnparseableKnownExtension(cert), kCFNotFound, "Unable to find unparseable extension: %@", url);