From: Apple Date: Wed, 15 Aug 2018 19:08:10 +0000 (+0000) Subject: Security-58286.51.6.tar.gz X-Git-Tag: macos-10134^0 X-Git-Url: https://git.saurik.com/apple/security.git/commitdiff_plain/ecaf5866106b8f08bdb7c1b4f489ef4dfd01278a Security-58286.51.6.tar.gz --- diff --git a/Analytics/Clients/SOSAnalytics.h b/Analytics/Clients/SOSAnalytics.h new file mode 100644 index 00000000..53e81312 --- /dev/null +++ b/Analytics/Clients/SOSAnalytics.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if __OBJC2__ +#ifndef SOSAnalytics_h +#define SOSAnalytics_h + +#import +#import "Analytics/SFAnalytics.h" + +extern NSString* const CKDKVSPerformanceCountersSampler; + +@protocol CKDKVSPerformanceCounter +@end +typedef NSString CKDKVSPerformanceCounter; +extern CKDKVSPerformanceCounter* const CKDKVSPerfCounterSynchronize; +extern CKDKVSPerformanceCounter* const CKDKVSPerfCounterSynchronizeWithCompletionHandler; +extern CKDKVSPerformanceCounter* const CKDKVSPerfCounterIncomingMessages; +extern CKDKVSPerformanceCounter* const CKDKVSPerfCounterOutgoingMessages; +extern CKDKVSPerformanceCounter* const CKDKVSPerfCounterTotalWaitTimeSynchronize; +extern CKDKVSPerformanceCounter* const CKDKVSPerfCounterLongestWaitTimeSynchronize; +extern CKDKVSPerformanceCounter* const CKDKVSPerfCounterSynchronizeFailures; + +@interface SOSAnalytics : SFAnalytics + ++ (instancetype)logger; + +@end + +#endif +#endif diff --git a/Analytics/Clients/SOSAnalytics.m b/Analytics/Clients/SOSAnalytics.m new file mode 100644 index 00000000..fb680277 --- /dev/null +++ b/Analytics/Clients/SOSAnalytics.m @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if __OBJC2__ + +#import "SOSAnalytics.h" +#include +#include + +NSString* const CKDKVSPerformanceCountersSampler = @"CKDKVSPerformanceCounterSampler"; + +CKDKVSPerformanceCounter* const CKDKVSPerfCounterSynchronize = (CKDKVSPerformanceCounter*)@"CKDKVS-synchronize"; +CKDKVSPerformanceCounter* const CKDKVSPerfCounterSynchronizeWithCompletionHandler = (CKDKVSPerformanceCounter*)@"CKDKVS-synchronizeWithCompletionHandler"; +CKDKVSPerformanceCounter* const CKDKVSPerfCounterIncomingMessages = (CKDKVSPerformanceCounter*)@"CKDKVS-incomingMessages"; +CKDKVSPerformanceCounter* const CKDKVSPerfCounterOutgoingMessages = (CKDKVSPerformanceCounter*)@"CKDKVS-outgoingMessages"; +CKDKVSPerformanceCounter* const CKDKVSPerfCounterTotalWaitTimeSynchronize = (CKDKVSPerformanceCounter*)@"CKDKVS-totalWaittimeSynchronize"; +CKDKVSPerformanceCounter* const CKDKVSPerfCounterLongestWaitTimeSynchronize = (CKDKVSPerformanceCounter*)@"CKDKVS-longestWaittimeSynchronize"; +CKDKVSPerformanceCounter* const CKDKVSPerfCounterSynchronizeFailures = (CKDKVSPerformanceCounter*)@"CKDKVS-synchronizeFailures"; + +@implementation SOSAnalytics + ++ (NSString*)databasePath +{ + // This block exists because we moved database locations in 11.3 for easier sandboxing, so we're cleaning up. + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + WithPathInKeychainDirectory(CFSTR("sos_analytics.db"), ^(const char *filename) { + remove(filename); + }); + WithPathInKeychainDirectory(CFSTR("sos_analytics.db-wal"), ^(const char *filename) { + remove(filename); + }); + WithPathInKeychainDirectory(CFSTR("sos_analytics.db-shm"), ^(const char *filename) { + remove(filename); + }); + }); + WithPathInKeychainDirectory(CFSTR("Analytics"), ^(const char *path) { +#if TARGET_OS_IPHONE + mode_t permissions = 0775; +#else + mode_t permissions = 0700; +#endif // TARGET_OS_IPHONE + mkpath_np(path, permissions); + chmod(path, permissions); + }); + return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"Analytics/sos_analytics.db") path]; +} + ++ (instancetype)logger +{ + return [super logger]; +} + +@end + +#endif diff --git a/Analytics/SFAnalytics+Internal.h b/Analytics/SFAnalytics+Internal.h new file mode 100644 index 00000000..05aa19a7 --- /dev/null +++ b/Analytics/SFAnalytics+Internal.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef SFAnalytics_Internal_h +#define SFAnalytics_Internal_h + +#if __OBJC2__ + +#import "SFAnalytics.h" + +@interface SFAnalytics (Internal) + +- (void)logMetric:(NSNumber*)metric withName:(NSString*)metricName oncePerReport:(BOOL)once; + +@end + +#endif // objc2 +#endif /* SFAnalytics_Internal_h */ diff --git a/Analytics/SFAnalytics.h b/Analytics/SFAnalytics.h new file mode 100644 index 00000000..66b0fe36 --- /dev/null +++ b/Analytics/SFAnalytics.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if __OBJC2__ +#ifndef SFAnalytics_h +#define SFAnalytics_h + +#import +#import "SFAnalyticsSampler.h" +#import "SFAnalyticsMultiSampler.h" +#import "SFAnalyticsActivityTracker.h" + +// this sampling interval will cause the sampler to run only at data reporting time +extern const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport; + +@interface SFAnalytics : NSObject + ++ (instancetype)logger; + ++ (NSInteger)fuzzyDaysSinceDate:(NSDate*)date; ++ (void)addOSVersionToEvent:(NSMutableDictionary*)event; + +// Log event-based metrics: create an event corresponding to some event in your feature +// and call the appropriate method based on the successfulness of that event +- (void)logSuccessForEventNamed:(NSString*)eventName; +- (void)logHardFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary*)attributes; +- (void)logSoftFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary*)attributes; +// or just log an event if it is not failable +- (void)noteEventNamed:(NSString*)eventName; + +- (void)logResultForEvent:(NSString*)eventName hardFailure:(bool)hardFailure result:(NSError*)eventResultError; + +// Track the state of a named value over time +- (SFAnalyticsSampler*)addMetricSamplerForName:(NSString*)samplerName withTimeInterval:(NSTimeInterval)timeInterval block:(NSNumber* (^)(void))block; +- (SFAnalyticsSampler*)existingMetricSamplerForName:(NSString*)samplerName; +- (void)removeMetricSamplerForName:(NSString*)samplerName; +// Same idea, but log multiple named values in a single block +- (SFAnalyticsMultiSampler*)AddMultiSamplerForName:(NSString*)samplerName withTimeInterval:(NSTimeInterval)timeInterval block:(NSDictionary* (^)(void))block; +- (SFAnalyticsMultiSampler*)existingMultiSamplerForName:(NSString*)samplerName; +- (void)removeMultiSamplerForName:(NSString*)samplerName; + +// Log measurements of arbitrary things +// System metrics measures how much time it takes to complete the action - possibly more in the future. The return value can be ignored if you only need to execute 1 block for your activity +- (SFAnalyticsActivityTracker*)logSystemMetricsForActivityNamed:(NSString*)eventName withAction:(void (^)(void))action; +- (void)logMetric:(NSNumber*)metric withName:(NSString*)metricName; + + + +// -------------------------------- +// Things below are for subclasses + +// Override to create a concrete logger instance +@property (readonly, class) NSString* databasePath; + +// Storing dates +- (void)setDateProperty:(NSDate*)date forKey:(NSString*)key; +- (NSDate*)datePropertyForKey:(NSString*)key; + +// -------------------------------- +// Things below are for unit testing + +- (void)removeState; // removes DB object and any samplers + +@end + +#endif +#endif diff --git a/Analytics/SFAnalytics.m b/Analytics/SFAnalytics.m new file mode 100644 index 00000000..af07dd86 --- /dev/null +++ b/Analytics/SFAnalytics.m @@ -0,0 +1,530 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if __OBJC2__ + +#import "SFAnalytics+Internal.h" +#import "SFAnalyticsDefines.h" +#import "SFAnalyticsActivityTracker+Internal.h" +#import "SFAnalyticsSampler+Internal.h" +#import "SFAnalyticsMultiSampler+Internal.h" +#import "SFAnalyticsSQLiteStore.h" +#import "utilities/debugging.h" +#import +#import + +// SFAnalyticsDefines constants +NSString* const SFAnalyticsTableSuccessCount = @"success_count"; +NSString* const SFAnalyticsTableHardFailures = @"hard_failures"; +NSString* const SFAnalyticsTableSoftFailures = @"soft_failures"; +NSString* const SFAnalyticsTableSamples = @"samples"; +NSString* const SFAnalyticsTableAllEvents = @"all_events"; + +NSString* const SFAnalyticsColumnSuccessCount = @"success_count"; +NSString* const SFAnalyticsColumnHardFailureCount = @"hard_failure_count"; +NSString* const SFAnalyticsColumnSoftFailureCount = @"soft_failure_count"; +NSString* const SFAnalyticsColumnSampleValue = @"value"; +NSString* const SFAnalyticsColumnSampleName = @"name"; + +NSString* const SFAnalyticsEventTime = @"eventTime"; +NSString* const SFAnalyticsEventType = @"eventType"; +NSString* const SFAnalyticsEventClassKey = @"eventClass"; + +NSString* const SFAnalyticsAttributeErrorUnderlyingChain = @"errorChain"; +NSString* const SFAnalyticsAttributeErrorDomain = @"errorDomain"; +NSString* const SFAnalyticsAttributeErrorCode = @"errorCode"; + +NSString* const SFAnalyticsUserDefaultsSuite = @"com.apple.security.analytics"; + +char* const SFAnalyticsFireSamplersNotification = "com.apple.security.sfanalytics.samplers"; + +NSString* const SFAnalyticsTopicKeySync = @"KeySyncTopic"; +NSString* const SFAnaltyicsTopicTrust = @"TrustTopic"; + +NSString* const SFAnalyticsTableSchema = @"CREATE TABLE IF NOT EXISTS hard_failures (\n" + @"id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + @"timestamp REAL," + @"data BLOB\n" + @");\n" + @"CREATE TRIGGER IF NOT EXISTS maintain_ring_buffer_hard_failures AFTER INSERT ON hard_failures\n" + @"BEGIN\n" + @"DELETE FROM hard_failures WHERE id != NEW.id AND id % 1000 = NEW.id % 1000;\n" + @"END;\n" + @"CREATE TABLE IF NOT EXISTS soft_failures (\n" + @"id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + @"timestamp REAL," + @"data BLOB\n" + @");\n" + @"CREATE TRIGGER IF NOT EXISTS maintain_ring_buffer_soft_failures AFTER INSERT ON soft_failures\n" + @"BEGIN\n" + @"DELETE FROM soft_failures WHERE id != NEW.id AND id % 1000 = NEW.id % 1000;\n" + @"END;\n" + @"CREATE TABLE IF NOT EXISTS all_events (\n" + @"id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + @"timestamp REAL," + @"data BLOB\n" + @");\n" + @"CREATE TRIGGER IF NOT EXISTS maintain_ring_buffer_all_events AFTER INSERT ON all_events\n" + @"BEGIN\n" + @"DELETE FROM all_events WHERE id != NEW.id AND id % 10000 = NEW.id % 10000;\n" + @"END;\n" + @"CREATE TABLE IF NOT EXISTS samples (\n" + @"id INTEGER PRIMARY KEY AUTOINCREMENT,\n" + @"timestamp REAL,\n" + @"name STRING,\n" + @"value REAL\n" + @");\n" + @"CREATE TRIGGER IF NOT EXISTS maintain_ring_buffer_samples AFTER INSERT ON samples\n" + @"BEGIN\n" + @"DELETE FROM samples WHERE id != NEW.id AND id % 1000 = NEW.id % 1000;\n" + @"END;\n" + @"CREATE TABLE IF NOT EXISTS success_count (\n" + @"event_type STRING PRIMARY KEY,\n" + @"success_count INTEGER,\n" + @"hard_failure_count INTEGER,\n" + @"soft_failure_count INTEGER\n" + @");\n"; + +NSUInteger const SFAnalyticsMaxEventsToReport = 1000; + +// Local constants +NSString* const SFAnalyticsEventBuild = @"build"; +NSString* const SFAnalyticsEventProduct = @"product"; +const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; + +@interface SFAnalytics () +@property (nonatomic) SFAnalyticsSQLiteStore* database; +@end + +@implementation SFAnalytics { + SFAnalyticsSQLiteStore* _database; + dispatch_queue_t _queue; + NSMutableDictionary* _samplers; + NSMutableDictionary* _multisamplers; + unsigned int _disableLogging:1; +} + ++ (instancetype)logger +{ +#if TARGET_OS_SIMULATOR + return nil; +#else + + if (self == [SFAnalytics class]) { + secerror("attempt to instatiate abstract class SFAnalytics"); + return nil; + } + + SFAnalytics* logger = nil; + @synchronized(self) { + logger = objc_getAssociatedObject(self, "SFAnalyticsInstance"); + if (!logger) { + logger = [[self alloc] init]; + objc_setAssociatedObject(self, "SFAnalyticsInstance", logger, OBJC_ASSOCIATION_RETAIN); + } + } + + [logger database]; // For unit testing so there's always a database. DB shouldn't be nilled in production though + return logger; +#endif +} + ++ (NSString*)databasePath +{ + return nil; +} + ++ (NSInteger)fuzzyDaysSinceDate:(NSDate*)date +{ + // Sentinel: it didn't happen at all + if (!date) { + return -1; + } + + // Sentinel: it happened but we don't know when because the date doesn't make sense + // Magic number represents January 1, 2017. + if ([date compare:[NSDate dateWithTimeIntervalSince1970:1483228800]] == NSOrderedAscending) { + return 1000; + } + + NSInteger secondsPerDay = 60 * 60 * 24; + + NSTimeInterval timeIntervalSinceDate = [[NSDate date] timeIntervalSinceDate:date]; + if (timeIntervalSinceDate < secondsPerDay) { + return 0; + } + else if (timeIntervalSinceDate < (secondsPerDay * 7)) { + return 1; + } + else if (timeIntervalSinceDate < (secondsPerDay * 30)) { + return 7; + } + else if (timeIntervalSinceDate < (secondsPerDay * 365)) { + return 30; + } + else { + return 365; + } +} + +// Instantiate lazily so unit tests can have clean databases each +- (SFAnalyticsSQLiteStore*)database +{ + if (!_database) { + _database = [SFAnalyticsSQLiteStore storeWithPath:self.class.databasePath schema:SFAnalyticsTableSchema]; + } + return _database; +} + +- (void)removeState +{ + [_samplers removeAllObjects]; + [_multisamplers removeAllObjects]; + + __weak __typeof(self) weakSelf = self; + dispatch_sync(_queue, ^{ + __strong __typeof(self) strongSelf = weakSelf; + if (strongSelf) { + [strongSelf.database close]; + strongSelf->_database = nil; + } + }); +} + +- (void)setDateProperty:(NSDate*)date forKey:(NSString*)key +{ + __weak __typeof(self) weakSelf = self; + dispatch_sync(_queue, ^{ + __strong __typeof(self) strongSelf = weakSelf; + if (strongSelf) { + [strongSelf.database setDateProperty:date forKey:key]; + } + }); +} + +- (NSDate*)datePropertyForKey:(NSString*)key +{ + __block NSDate* result = nil; + __weak __typeof(self) weakSelf = self; + dispatch_sync(_queue, ^{ + __strong __typeof(self) strongSelf = weakSelf; + if (strongSelf) { + result = [strongSelf.database datePropertyForKey:key]; + } + }); + return result; +} + ++ (void)addOSVersionToEvent:(NSMutableDictionary*)eventDict { + static dispatch_once_t onceToken; + static NSString *build = NULL; + static NSString *product = NULL; + dispatch_once(&onceToken, ^{ + NSDictionary *version = CFBridgingRelease(_CFCopySystemVersionDictionary()); + if (version == NULL) + return; + build = version[(__bridge NSString *)_kCFSystemVersionBuildVersionKey]; + product = version[(__bridge NSString *)_kCFSystemVersionProductNameKey]; + }); + if (build) { + eventDict[SFAnalyticsEventBuild] = build; + } + if (product) { + eventDict[SFAnalyticsEventProduct] = product; + } +} + +- (instancetype)init +{ + if (self = [super init]) { + _queue = dispatch_queue_create("SFAnalytics data access queue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + _samplers = [NSMutableDictionary new]; + _multisamplers = [NSMutableDictionary new]; + [self database]; // for side effect of instantiating DB object. Used for testing. + } + + return self; +} + +// MARK: Event logging + +- (void)logSuccessForEventNamed:(NSString*)eventName +{ + [self logEventNamed:eventName class:SFAnalyticsEventClassSuccess attributes:nil]; +} + +- (void)logHardFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary*)attributes +{ + [self logEventNamed:eventName class:SFAnalyticsEventClassHardFailure attributes:attributes]; +} + +- (void)logSoftFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary*)attributes +{ + [self logEventNamed:eventName class:SFAnalyticsEventClassSoftFailure attributes:attributes]; +} + +- (void)logResultForEvent:(NSString*)eventName hardFailure:(bool)hardFailure result:(NSError*)eventResultError +{ + if(!eventResultError) { + [self logSuccessForEventNamed:eventName]; + } else { + // Make an Attributes dictionary + NSMutableDictionary* eventAttributes = [NSMutableDictionary dictionary]; + + /* if we have underlying errors, capture the chain below the top-most error */ + NSError *underlyingError = eventResultError.userInfo[NSUnderlyingErrorKey]; + if ([underlyingError isKindOfClass:[NSError class]]) { + NSMutableString *chain = [NSMutableString string]; + int count = 0; + do { + [chain appendFormat:@"%@-%ld:", underlyingError.domain, (long)underlyingError.code]; + underlyingError = underlyingError.userInfo[NSUnderlyingErrorKey]; + } while (count++ < 5 && [underlyingError isKindOfClass:[NSError class]]); + + eventAttributes[SFAnalyticsAttributeErrorUnderlyingChain] = chain; + } + + eventAttributes[SFAnalyticsAttributeErrorDomain] = eventResultError.domain; + eventAttributes[SFAnalyticsAttributeErrorCode] = @(eventResultError.code); + + if(hardFailure) { + [self logHardFailureForEventNamed:eventName withAttributes:eventAttributes]; + } else { + [self logSoftFailureForEventNamed:eventName withAttributes:eventAttributes]; + } + } +} + +- (void)noteEventNamed:(NSString*)eventName +{ + [self logEventNamed:eventName class:SFAnalyticsEventClassNote attributes:nil]; +} + +- (void)logEventNamed:(NSString*)eventName class:(SFAnalyticsEventClass)class attributes:(NSDictionary*)attributes +{ + if (!eventName) { + secerror("SFAnalytics: attempt to log an event with no name"); + return; + } + + __weak __typeof(self) weakSelf = self; + dispatch_sync(_queue, ^{ + __strong __typeof(self) strongSelf = weakSelf; + if (!strongSelf || strongSelf->_disableLogging) { + return; + } + + NSDictionary* eventDict = [self eventDictForEventName:eventName withAttributes:attributes eventClass:class]; + [strongSelf.database addEventDict:eventDict toTable:SFAnalyticsTableAllEvents]; + + if (class == SFAnalyticsEventClassHardFailure) { + [strongSelf.database addEventDict:eventDict toTable:SFAnalyticsTableHardFailures]; + [strongSelf.database incrementHardFailureCountForEventType:eventName]; + } + else if (class == SFAnalyticsEventClassSoftFailure) { + [strongSelf.database addEventDict:eventDict toTable:SFAnalyticsTableSoftFailures]; + [strongSelf.database incrementSoftFailureCountForEventType:eventName]; + } + else if (class == SFAnalyticsEventClassSuccess || class == SFAnalyticsEventClassNote) { + [strongSelf.database incrementSuccessCountForEventType:eventName]; + } + }); +} + +- (NSDictionary*)eventDictForEventName:(NSString*)eventName withAttributes:(NSDictionary*)attributes eventClass:(SFAnalyticsEventClass)eventClass +{ + NSMutableDictionary* eventDict = attributes ? attributes.mutableCopy : [NSMutableDictionary dictionary]; + eventDict[SFAnalyticsEventType] = eventName; + // our backend wants timestamps in milliseconds + eventDict[SFAnalyticsEventTime] = @([[NSDate date] timeIntervalSince1970] * 1000); + eventDict[SFAnalyticsEventClassKey] = @(eventClass); + [SFAnalytics addOSVersionToEvent:eventDict]; + + return eventDict; +} + +// MARK: Sampling + +- (SFAnalyticsSampler*)addMetricSamplerForName:(NSString *)samplerName withTimeInterval:(NSTimeInterval)timeInterval block:(NSNumber *(^)(void))block +{ + if (!samplerName) { + secerror("SFAnalytics: cannot add sampler without name"); + return nil; + } + if (timeInterval < 1.0f && timeInterval != SFAnalyticsSamplerIntervalOncePerReport) { + secerror("SFAnalytics: cannot add sampler with interval %f", timeInterval); + return nil; + } + if (!block) { + secerror("SFAnalytics: cannot add sampler without block"); + return nil; + } + + __block SFAnalyticsSampler* sampler = nil; + + __weak __typeof(self) weakSelf = self; + dispatch_sync(_queue, ^{ + __strong __typeof(self) strongSelf = weakSelf; + if (strongSelf->_samplers[samplerName]) { + secerror("SFAnalytics: sampler \"%@\" already exists", samplerName); + } else { + sampler = [[SFAnalyticsSampler alloc] initWithName:samplerName interval:timeInterval block:block clientClass:[self class]]; + strongSelf->_samplers[samplerName] = sampler; // If sampler did not init because of bad data this 'removes' it from the dict, so a noop + } + }); + + return sampler; +} + +- (SFAnalyticsMultiSampler*)AddMultiSamplerForName:(NSString *)samplerName withTimeInterval:(NSTimeInterval)timeInterval block:(NSDictionary *(^)(void))block +{ + if (!samplerName) { + secerror("SFAnalytics: cannot add sampler without name"); + return nil; + } + if (timeInterval < 1.0f && timeInterval != SFAnalyticsSamplerIntervalOncePerReport) { + secerror("SFAnalytics: cannot add sampler with interval %f", timeInterval); + return nil; + } + if (!block) { + secerror("SFAnalytics: cannot add sampler without block"); + return nil; + } + + __block SFAnalyticsMultiSampler* sampler = nil; + __weak __typeof(self) weakSelf = self; + dispatch_sync(_queue, ^{ + __strong __typeof(self) strongSelf = weakSelf; + if (strongSelf->_multisamplers[samplerName]) { + secerror("SFAnalytics: multisampler \"%@\" already exists", samplerName); + } else { + sampler = [[SFAnalyticsMultiSampler alloc] initWithName:samplerName interval:timeInterval block:block clientClass:[self class]]; + strongSelf->_multisamplers[samplerName] = sampler; + } + + }); + + return sampler; +} + +- (SFAnalyticsSampler*)existingMetricSamplerForName:(NSString *)samplerName +{ + __block SFAnalyticsSampler* sampler = nil; + + __weak __typeof(self) weakSelf = self; + dispatch_sync(_queue, ^{ + __strong __typeof(self) strongSelf = weakSelf; + if (strongSelf) { + sampler = strongSelf->_samplers[samplerName]; + } + }); + return sampler; +} + +- (SFAnalyticsMultiSampler*)existingMultiSamplerForName:(NSString *)samplerName +{ + __block SFAnalyticsMultiSampler* sampler = nil; + + __weak __typeof(self) weakSelf = self; + dispatch_sync(_queue, ^{ + __strong __typeof(self) strongSelf = weakSelf; + if (strongSelf) { + sampler = strongSelf->_multisamplers[samplerName]; + } + }); + return sampler; +} + +- (void)removeMetricSamplerForName:(NSString *)samplerName +{ + if (!samplerName) { + secerror("Attempt to remove sampler without specifying samplerName"); + return; + } + + __weak __typeof(self) weakSelf = self; + dispatch_sync(_queue, ^{ + __strong __typeof(self) strongSelf = weakSelf; + if (strongSelf) { + [strongSelf->_samplers[samplerName] pauseSampling]; // when dealloced it would also stop, but we're not sure when that is so let's stop it right away + [strongSelf->_samplers removeObjectForKey:samplerName]; + } + }); +} + +- (void)removeMultiSamplerForName:(NSString *)samplerName +{ + if (!samplerName) { + secerror("Attempt to remove multisampler without specifying samplerName"); + return; + } + + __weak __typeof(self) weakSelf = self; + dispatch_sync(_queue, ^{ + __strong __typeof(self) strongSelf = weakSelf; + if (strongSelf) { + [strongSelf->_multisamplers[samplerName] pauseSampling]; // when dealloced it would also stop, but we're not sure when that is so let's stop it right away + [strongSelf->_multisamplers removeObjectForKey:samplerName]; + } + }); +} + +- (SFAnalyticsActivityTracker*)logSystemMetricsForActivityNamed:(NSString *)eventName withAction:(void (^)(void))action +{ + if (![eventName isKindOfClass:[NSString class]]) { + secerror("Cannot log system metrics without name"); + return nil; + } + SFAnalyticsActivityTracker* tracker = [[SFAnalyticsActivityTracker alloc] initWithName:eventName clientClass:[self class]]; + if (action) + [tracker performAction:action]; + return tracker; +} + +- (void)logMetric:(NSNumber *)metric withName:(NSString *)metricName +{ + [self logMetric:metric withName:metricName oncePerReport:NO]; +} + +- (void)logMetric:(NSNumber*)metric withName:(NSString*)metricName oncePerReport:(BOOL)once +{ + if (![metric isKindOfClass:[NSNumber class]] || ![metricName isKindOfClass:[NSString class]]) { + secerror("SFAnalytics: Need a valid result and name to log result"); + return; + } + + __weak __typeof(self) weakSelf = self; + dispatch_sync(_queue, ^{ + __strong __typeof(self) strongSelf = weakSelf; + if (strongSelf && !strongSelf->_disableLogging) { + if (once) { + [strongSelf.database removeAllSamplesForName:metricName]; + } + [strongSelf.database addSample:metric forName:metricName]; + } + }); +} + +@end + +#endif // __OBJC2__ diff --git a/Analytics/SFAnalytics.plist b/Analytics/SFAnalytics.plist new file mode 100644 index 00000000..964747db --- /dev/null +++ b/Analytics/SFAnalytics.plist @@ -0,0 +1,26 @@ + + + + + KeySyncTopic + + splunk_allowInsecureCertificate + + splunk_topic + xp_sear_keysync + splunk_bagURL + https://xp.apple.com/config/1/report/xp_sear_keysync + + TrustTopic + + splunk_allowInsecureCertificate + + splunk_topic + xp_sear_trust + splunk_bagURL + https://xp.apple.com/config/1/report/xp_sear_trust + disableClientId + + + + diff --git a/Analytics/SFAnalyticsActivityTracker+Internal.h b/Analytics/SFAnalyticsActivityTracker+Internal.h new file mode 100644 index 00000000..3d24b00c --- /dev/null +++ b/Analytics/SFAnalyticsActivityTracker+Internal.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef SFAnalyticsActivityTracker_Internal_h +#define SFAnalyticsActivityTracker_Internal_h + +#if __OBJC2__ + +#import "SFAnalyticsActivityTracker.h" + +@interface SFAnalyticsActivityTracker(Internal) + +- (instancetype)initWithName:(NSString*)name clientClass:(Class)className; + +@end + +#endif // objc2 + +#endif /* SFAnalyticsActivityTracker_private_h */ diff --git a/Analytics/SFAnalyticsActivityTracker.h b/Analytics/SFAnalyticsActivityTracker.h new file mode 100644 index 00000000..5f5c9360 --- /dev/null +++ b/Analytics/SFAnalyticsActivityTracker.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if __OBJC2__ +#ifndef SFAnalyticsActivityTracker_h +#define SFAnalyticsActivityTracker_h + +#import + +@interface SFAnalyticsActivityTracker : NSObject + +- (instancetype)init NS_UNAVAILABLE; +- (void)performAction:(void (^)(void))action; +- (void)cancel; + +- (void)start; +- (void)stop; + +@end + +#endif +#endif diff --git a/Analytics/SFAnalyticsActivityTracker.m b/Analytics/SFAnalyticsActivityTracker.m new file mode 100644 index 00000000..f2c628a2 --- /dev/null +++ b/Analytics/SFAnalyticsActivityTracker.m @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if __OBJC2__ + +#import "SFAnalyticsActivityTracker.h" +#import "SFAnalyticsActivityTracker+Internal.h" +#import "SFAnalytics.h" +#import +#import "utilities/debugging.h" + +@implementation SFAnalyticsActivityTracker { + dispatch_queue_t _queue; + NSString* _name; + Class _clientClass; + NSNumber* _measurement; + uint64_t _start; + BOOL _canceled; +} + +- (instancetype)initWithName:(NSString*)name clientClass:(Class)className { + if (![name isKindOfClass:[NSString class]] || ![className isSubclassOfClass:[SFAnalytics class]] ) { + secerror("Cannot instantiate SFActivityTracker without name and client class"); + return nil; + } + + if (self = [super init]) { + _queue = dispatch_queue_create("SFAnalyticsActivityTracker queue", DISPATCH_QUEUE_SERIAL); + _name = name; + _clientClass = className; + _measurement = nil; + _canceled = NO; + _start = 0; + } + return self; +} + +- (void)performAction:(void (^)(void))action +{ + _start = mach_absolute_time(); + action(); + [self stop]; +} + +- (void)start +{ + if (_canceled) + return; + NSAssert(_start == 0, @"SFAnalyticsActivityTracker user called start twice"); + _start = mach_absolute_time(); +} + +- (void)stop +{ + uint64_t end = mach_absolute_time(); + static mach_timebase_info_data_t sTimebaseInfo; + if ( sTimebaseInfo.denom == 0 ) { + (void)mach_timebase_info(&sTimebaseInfo); + } + if (_canceled) + return; + + NSAssert(_start != 0, @"SFAnalyticsActivityTracker user called stop w/o calling start"); + + _measurement = @([_measurement doubleValue] + (1.0f * (end - _start) * (1.0f * sTimebaseInfo.numer / sTimebaseInfo.denom))); + _start = 0; +} + +- (void)cancel +{ + _canceled = YES; +} + +- (void)dealloc +{ + if (!_canceled && _measurement != nil) { + [[_clientClass logger] logMetric:_measurement withName:_name]; + } +} + +@end + +#endif diff --git a/Analytics/SFAnalyticsDefines.h b/Analytics/SFAnalyticsDefines.h new file mode 100644 index 00000000..aa6af75c --- /dev/null +++ b/Analytics/SFAnalyticsDefines.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef SFAnalyticsDefines_h +#define SFAnalyticsDefines_h + +#if __OBJC2__ + +extern NSString* const SFAnalyticsTableSuccessCount; +extern NSString* const SFAnalyticsTableHardFailures; +extern NSString* const SFAnalyticsTableSoftFailures; +extern NSString* const SFAnalyticsTableSamples; +extern NSString* const SFAnalyticsTableAllEvents; + +extern NSString* const SFAnalyticsColumnSuccessCount; +extern NSString* const SFAnalyticsColumnHardFailureCount; +extern NSString* const SFAnalyticsColumnSoftFailureCount; +extern NSString* const SFAnalyticsColumnSampleValue; +extern NSString* const SFAnalyticsColumnSampleName; + +extern NSString* const SFAnalyticsEventTime; +extern NSString* const SFAnalyticsEventType; +extern NSString* const SFAnalyticsEventClassKey; + +// Helpers for logging NSErrors +extern NSString* const SFAnalyticsAttributeErrorUnderlyingChain; +extern NSString* const SFAnalyticsAttributeErrorDomain; +extern NSString* const SFAnalyticsAttributeErrorCode; + +extern NSString* const SFAnalyticsUserDefaultsSuite; + +extern char* const SFAnalyticsFireSamplersNotification; + +/* Internal Topic Names */ +extern NSString* const SFAnalyticsTopicKeySync; +extern NSString* const SFAnaltyicsTopicTrust; + +typedef NS_ENUM(NSInteger, SFAnalyticsEventClass) { + SFAnalyticsEventClassSuccess, + SFAnalyticsEventClassHardFailure, + SFAnalyticsEventClassSoftFailure, + SFAnalyticsEventClassNote +}; + +extern NSString* const SFAnalyticsTableSchema; + +// We can only send this many events in total to splunk per upload +extern NSUInteger const SFAnalyticsMaxEventsToReport; + +#endif /* __OBJC2__ */ + +#endif /* SFAnalyticsDefines_h */ diff --git a/Analytics/SFAnalyticsLogger.h b/Analytics/SFAnalyticsLogger.h deleted file mode 100644 index 6dfed9ff..00000000 --- a/Analytics/SFAnalyticsLogger.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -#if __OBJC2__ - -@interface SFAnalyticsLogger : NSObject - -+ (instancetype)logger; - -+ (NSInteger)fuzzyDaysSinceDate:(NSDate*)date; - -- (void)logSuccessForEventNamed:(NSString*)eventName; -- (void)logHardFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary*)attributes; -- (void)logSoftFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary*)attributes; - -- (void)noteEventNamed:(NSString*)eventName; - -// -------------------------------- -// Things below are for subclasses - -// Override to create a concrete logger instance -@property (readonly, class) NSString* databasePath; - -// Storing dates -- (void)setDateProperty:(NSDate*)date forKey:(NSString*)key; -- (NSDate*)datePropertyForKey:(NSString*)key; - -- (NSDictionary*)extraValuesToUploadToServer; -- (NSString*)sysdiagnoseStringForEventRecord:(NSDictionary*)eventRecord; - -// -------------------------------- -// Things below are for utilities to drive and/or test the system - -- (NSString*)getSysdiagnoseDumpWithError:(NSError**)error; -- (NSData*)getLoggingJSON:(bool)pretty error:(NSError**)error; -- (BOOL)forceUploadWithError:(NSError**)error; - -// -------------------------------- -// Things below are for unit testing - -@property (readonly) dispatch_queue_t splunkLoggingQueue; -@property (readonly) NSURL* splunkUploadURL; -@property (readonly) NSString* splunkTopicName; -@property (readonly) NSURL* splunkBagURL; -@property (readonly) BOOL allowsInsecureSplunkCert; -@property BOOL ignoreServerDisablingMessages; - -@end - -#endif diff --git a/Analytics/SFAnalyticsLogger.m b/Analytics/SFAnalyticsLogger.m deleted file mode 100644 index 2bc376f9..00000000 --- a/Analytics/SFAnalyticsLogger.m +++ /dev/null @@ -1,985 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#if __OBJC2__ - -#import "SFAnalyticsLogger.h" -#import "SFSQLite.h" -#import "CKKSViewManager.h" -#import "debugging.h" -#import -#import -#import - -NSString* const SFAnalyticsLoggerTableSuccessCount = @"success_count"; -NSString* const SFAnalyticsLoggerColumnEventType = @"event_type"; -NSString* const SFAnalyticsLoggerColumnSuccessCount = @"success_count"; -NSString* const SFAnalyticsLoggerColumnHardFailureCount = @"hard_failure_count"; -NSString* const SFAnalyticsLoggerColumnSoftFailureCount = @"soft_failure_count"; - -NSString* const SFAnalyticsLoggerTableHardFailures = @"hard_failures"; -NSString* const SFAnalyticsLoggerTableSoftFailures = @"soft_failures"; -NSString* const SFAnalyticsLoggerTableAllEvents = @"all_events"; -NSString* const SFAnalyticsLoggerColumnDate = @"timestamp"; -NSString* const SFAnalyticsLoggerColumnData = @"data"; - -NSString* const SFAnalyticsLoggerUploadDate = @"upload_date"; - -NSString* const SFAnalyticsLoggerSplunkTopic = @"topic"; -NSString* const SFAnalyticsLoggerSplunkEventTime = @"eventTime"; -NSString* const SFAnalyticsLoggerSplunkPostTime = @"postTime"; -NSString* const SFAnalyticsLoggerSplunkEventType = @"eventType"; -NSString* const SFAnalyticsLoggerSplunkEventBuild = @"build"; -NSString* const SFAnalyticsLoggerSplunkEventProduct = @"product"; - -NSString* const SFAnalyticsLoggerMetricsBase = @"metricsBase"; -NSString* const SFAnalyticsLoggerEventClassKey = @"eventClass"; - - -NSString* const SFAnalyticsUserDefaultsSuite = @"com.apple.security.analytics"; - -static NSString* const SFAnalyticsLoggerTableSchema = @"CREATE TABLE IF NOT EXISTS hard_failures (\n" - @"id INTEGER PRIMARY KEY AUTOINCREMENT,\n" - @"timestamp REAL," - @"data BLOB\n" - @");\n" - @"CREATE TRIGGER IF NOT EXISTS maintain_ring_buffer_hard_failures AFTER INSERT ON hard_failures\n" - @"BEGIN\n" - @"DELETE FROM hard_failures WHERE id != NEW.id AND id % 999 = NEW.id % 999;\n" - @"END;\n" - @"CREATE TABLE IF NOT EXISTS soft_failures (\n" - @"id INTEGER PRIMARY KEY AUTOINCREMENT,\n" - @"timestamp REAL," - @"data BLOB\n" - @");\n" - @"CREATE TRIGGER IF NOT EXISTS maintain_ring_buffer_soft_failures AFTER INSERT ON soft_failures\n" - @"BEGIN\n" - @"DELETE FROM soft_failures WHERE id != NEW.id AND id % 999 = NEW.id % 999;\n" - @"END;\n" - @"CREATE TABLE IF NOT EXISTS all_events (\n" - @"id INTEGER PRIMARY KEY AUTOINCREMENT,\n" - @"timestamp REAL," - @"data BLOB\n" - @");\n" - @"CREATE TRIGGER IF NOT EXISTS maintain_ring_buffer_all_events AFTER INSERT ON all_events\n" - @"BEGIN\n" - @"DELETE FROM all_events WHERE id != NEW.id AND id % 10000 = NEW.id % 10000;\n" - @"END;\n" - @"CREATE TABLE IF NOT EXISTS success_count (\n" - @"event_type STRING PRIMARY KEY,\n" - @"success_count INTEGER,\n" - @"hard_failure_count INTEGER,\n" - @"soft_failure_count INTEGER\n" - @");\n"; - -#define SFANALYTICS_SPLUNK_DEV 0 -#define SFANALYTICS_MAX_EVENTS_TO_REPORT 999 - -#define SECONDS_PER_DAY (60 * 60 * 24) - -#if SFANALYTICS_SPLUNK_DEV -#define SECONDS_BETWEEN_UPLOADS_CUSTOMER 10 -#define SECONDS_BETWEEN_UPLOADS_INTERNAL 10 -#else -#define SECONDS_BETWEEN_UPLOADS_CUSTOMER (3 * SECONDS_PER_DAY) -#define SECONDS_BETWEEN_UPLOADS_INTERNAL (SECONDS_PER_DAY) -#endif - -typedef NS_ENUM(NSInteger, SFAnalyticsEventClass) { - SFAnalyticsEventClassSuccess, - SFAnalyticsEventClassHardFailure, - SFAnalyticsEventClassSoftFailure, - SFAnalyticsEventClassNote -}; - -@interface SFAnalyticsLoggerSQLiteStore : SFSQLite - -@property (readonly, strong) NSArray* failureRecords; -@property (readonly, strong) NSArray* allEvents; -@property (readwrite, strong) NSDate* uploadDate; - -+ (instancetype)storeWithPath:(NSString*)path schema:(NSString*)schema; - -- (void)incrementSuccessCountForEventType:(NSString*)eventType; -- (void)incrementHardFailureCountForEventType:(NSString*)eventType; -- (void)incrementSoftFailureCountForEventType:(NSString*)eventType; -- (NSInteger)successCountForEventType:(NSString*)eventType; -- (NSInteger)hardFailureCountForEventType:(NSString*)eventType; -- (NSInteger)softFailureCountForEventType:(NSString*)eventType; -- (void)addEventDict:(NSDictionary*)eventDict toTable:(NSString*)table; -- (void)clearAllData; -- (BOOL)tryToOpenDatabase; - -- (NSDictionary*)summaryCounts; - -@end - -@implementation SFAnalyticsLogger { - SFAnalyticsLoggerSQLiteStore* _database; - NSURL* _splunkUploadURL; - NSString* _splunkTopicName; - NSURL* _splunkBagURL; - dispatch_queue_t _queue; - NSInteger _secondsBetweenUploads; - NSDictionary* _metricsBase; // data the server provides and wants us to send back - NSArray* _blacklistedFields; - NSArray* _blacklistedEvents; - - unsigned int _allowInsecureSplunkCert:1; - unsigned int _disableLogging:1; - unsigned int _disableUploads:1; - unsigned int _ignoreServersMessagesTellingUsToGoAway:1; -} - -@synthesize splunkUploadURL = _splunkUploadURL; -@synthesize splunkBagURL = _splunkBagURL; -@synthesize splunkTopicName = _splunkTopicName; -@synthesize splunkLoggingQueue = _queue; - -+ (instancetype)logger -{ -#if TARGET_OS_SIMULATOR - return nil; -#else - - if (self == [SFAnalyticsLogger class]) { - secerror("attempt to instatiate abstract class SFAnalyticsLogger"); - return nil; - } - - SFAnalyticsLogger* logger = nil; - @synchronized(self) { - logger = objc_getAssociatedObject(self, "SFAnalyticsLoggerInstance"); - if (!logger) { - logger = [[self alloc] init]; - objc_setAssociatedObject(self, "SFAnalyticsLoggerInstance", logger, OBJC_ASSOCIATION_RETAIN); - } - } - return logger; -#endif -} - -+ (NSString*)databasePath -{ - return nil; -} - -+ (NSInteger)fuzzyDaysSinceDate:(NSDate*)date -{ - NSTimeInterval timeIntervalSinceDate = [[NSDate date] timeIntervalSinceDate:date]; - if (timeIntervalSinceDate < SECONDS_PER_DAY) { - return 0; - } - else if (timeIntervalSinceDate < (SECONDS_PER_DAY * 7)) { - return 1; - } - else if (timeIntervalSinceDate < (SECONDS_PER_DAY * 30)) { - return 7; - } - else if (timeIntervalSinceDate < (SECONDS_PER_DAY * 365)) { - return 30; - } - else { - return 365; - } -} - -- (instancetype)init -{ - if (self = [super init]) { - _database = [SFAnalyticsLoggerSQLiteStore storeWithPath:self.class.databasePath schema:SFAnalyticsLoggerTableSchema]; - _queue = dispatch_queue_create("com.apple.security.analytics", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - - if (os_variant_has_internal_diagnostics("Security")) { - _secondsBetweenUploads = SECONDS_BETWEEN_UPLOADS_INTERNAL; - } else { - _secondsBetweenUploads = SECONDS_BETWEEN_UPLOADS_CUSTOMER; - } - - NSDictionary* systemDefaultValues = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle bundleWithPath:@"/System/Library/Frameworks/Security.framework"] pathForResource:@"SFAnalyticsLogging" ofType:@"plist"]]; - _splunkTopicName = systemDefaultValues[@"splunk_topic"]; - _splunkUploadURL = [NSURL URLWithString:systemDefaultValues[@"splunk_uploadURL"]]; - _splunkBagURL = [NSURL URLWithString:systemDefaultValues[@"splunk_bagURL"]]; - _allowInsecureSplunkCert = [[systemDefaultValues valueForKey:@"splunk_allowInsecureCertificate"] boolValue]; - NSString* splunkEndpoint = systemDefaultValues[@"splunk_endpointDomain"]; - - NSUserDefaults* defaults = [[NSUserDefaults alloc] initWithSuiteName:SFAnalyticsUserDefaultsSuite]; - NSString* userDefaultsSplunkTopic = [defaults stringForKey:@"splunk_topic"]; - if (userDefaultsSplunkTopic) { - _splunkTopicName = userDefaultsSplunkTopic; - } - - NSURL* userDefaultsSplunkUploadURL = [NSURL URLWithString:[defaults stringForKey:@"splunk_uploadURL"]]; - if (userDefaultsSplunkUploadURL) { - _splunkUploadURL = userDefaultsSplunkUploadURL; - } - - NSURL* userDefaultsSplunkBagURL = [NSURL URLWithString:[defaults stringForKey:@"splunk_bagURL"]]; - if (userDefaultsSplunkUploadURL) { - _splunkBagURL = userDefaultsSplunkBagURL; - } - - BOOL userDefaultsAllowInsecureSplunkCert = [defaults boolForKey:@"splunk_allowInsecureCertificate"]; - _allowInsecureSplunkCert |= userDefaultsAllowInsecureSplunkCert; - - NSString* userDefaultsSplunkEndpoint = [defaults stringForKey:@"splunk_endpointDomain"]; - if (userDefaultsSplunkEndpoint) { - splunkEndpoint = userDefaultsSplunkEndpoint; - } - -#if SFANALYTICS_SPLUNK_DEV - _ignoreServersMessagesTellingUsToGoAway = YES; - - if (!_splunkUploadURL && splunkEndpoint) { - NSString* urlString = [NSString stringWithFormat:@"https://%@/report/2/%@", splunkEndpoint, _splunkTopicName]; - _splunkUploadURL = [NSURL URLWithString:urlString]; - } -#else - (void)splunkEndpoint; -#endif - } - - return self; -} - -- (void)logSuccessForEventNamed:(NSString*)eventName -{ - [self logEventNamed:eventName class:SFAnalyticsEventClassSuccess attributes:nil]; -} - -- (void)logHardFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary*)attributes -{ - [self logEventNamed:eventName class:SFAnalyticsEventClassHardFailure attributes:attributes]; -} - -- (void)logSoftFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary*)attributes -{ - [self logEventNamed:eventName class:SFAnalyticsEventClassSoftFailure attributes:attributes]; -} - -- (void)noteEventNamed:(NSString*)eventName -{ - [self logEventNamed:eventName class:SFAnalyticsEventClassNote attributes:nil]; -} - -- (void)logEventNamed:(NSString*)eventName class:(SFAnalyticsEventClass)class attributes:(NSDictionary*)attributes -{ - if (!eventName) { - secinfo("SFAnalytics", "attempt to log an event with no name"); - return; - } - - __block NSDate* uploadDate = nil; - __weak __typeof(self) weakSelf = self; - dispatch_sync(_queue, ^{ - __strong __typeof(self) strongSelf = weakSelf; - if (!strongSelf || strongSelf->_disableLogging || [strongSelf->_blacklistedEvents containsObject:eventName]) { - return; - } - - NSDictionary* eventDict = [self eventDictForEventName:eventName withAttributes:attributes eventClass:class]; - [strongSelf->_database addEventDict:eventDict toTable:SFAnalyticsLoggerTableAllEvents]; - - if (class == SFAnalyticsEventClassHardFailure) { - NSDictionary* strippedDict = [self eventDictWithBlacklistedFieldsStrippedFrom:eventDict]; - [strongSelf->_database addEventDict:strippedDict toTable:SFAnalyticsLoggerTableHardFailures]; - [strongSelf->_database incrementHardFailureCountForEventType:eventName]; - } - else if (class == SFAnalyticsEventClassSoftFailure) { - NSDictionary* strippedDict = [self eventDictWithBlacklistedFieldsStrippedFrom:eventDict]; - [strongSelf->_database addEventDict:strippedDict toTable:SFAnalyticsLoggerTableSoftFailures]; - [strongSelf->_database incrementSoftFailureCountForEventType:eventName]; - } - else if (class == SFAnalyticsEventClassSuccess || class == SFAnalyticsEventClassNote) { - [strongSelf->_database incrementSuccessCountForEventType:eventName]; - } - - uploadDate = strongSelf->_database.uploadDate; - }); - - NSDate* nowDate = [NSDate date]; - if (uploadDate) { - if ([nowDate compare:uploadDate] == NSOrderedDescending) { - NSError* error = nil; - BOOL uploadSuccess = [self forceUploadWithError:&error]; - if (uploadSuccess) { - secinfo("SFAnalytics", "uploaded sync health data"); - [self resetUploadDate:YES]; - } - - if (error) { - secerror("SFAnalytics: failed to upload json to analytics server with error: %@", error); - } - } - } - else { - [self resetUploadDate:NO]; - } -} - -- (void)resetUploadDate:(BOOL)clearData -{ - __weak __typeof(self) weakSelf = self; - dispatch_sync(_queue, ^{ - __strong __typeof(self) strongSelf = weakSelf; - if (!strongSelf) { - return; - } - - if (clearData) { - [strongSelf->_database clearAllData]; - } - strongSelf->_database.uploadDate = [NSDate dateWithTimeIntervalSinceNow:strongSelf->_secondsBetweenUploads]; - }); -} - -- (NSDictionary*)eventDictForEventName:(NSString*)eventName withAttributes:(NSDictionary*)attributes eventClass:(SFAnalyticsEventClass)eventClass -{ - NSMutableDictionary* eventDict = attributes ? attributes.mutableCopy : [NSMutableDictionary dictionary]; - eventDict[SFAnalyticsLoggerSplunkTopic] = _splunkTopicName; - eventDict[SFAnalyticsLoggerSplunkEventType] = eventName; - eventDict[SFAnalyticsLoggerSplunkEventTime] = @([[NSDate date] timeIntervalSince1970] * 1000); - eventDict[SFAnalyticsLoggerEventClassKey] = @(eventClass); - - [_metricsBase enumerateKeysAndObjectsUsingBlock:^(NSString* key, id object, BOOL* stop) { - if (!eventDict[key]) { - eventDict[key] = object; - } - }]; - - return eventDict; -} - -- (NSDictionary*)eventDictWithBlacklistedFieldsStrippedFrom:(NSDictionary*)eventDict -{ - NSMutableDictionary* strippedDict = eventDict.mutableCopy; - for (NSString* blacklistedField in _blacklistedFields) { - [strippedDict removeObjectForKey:blacklistedField]; - } - return strippedDict; -} - -- (void)setDateProperty:(NSDate*)date forKey:(NSString*)key -{ - dispatch_sync(_queue, ^{ - [self->_database setDateProperty:date forKey:key]; - }); -} - -- (NSDate*)datePropertyForKey:(NSString*)key -{ - __block NSDate* result = nil; - dispatch_sync(_queue, ^{ - result = [self->_database datePropertyForKey:key]; - }); - return result; -} - -- (NSDictionary*)extraValuesToUploadToServer -{ - return [NSDictionary dictionary]; -} - -// this method is kind of evil for the fact that it has side-effects in pulling other things besides the metricsURL from the server, and as such should NOT be memoized. -// TODO redo this, probably to return a dictionary. -- (NSURL*)splunkUploadURL -{ - dispatch_assert_queue(_queue); - - if (_splunkUploadURL) { - return _splunkUploadURL; - } - - __weak __typeof(self) weakSelf = self; - dispatch_semaphore_t sem = dispatch_semaphore_create(0); - - __block NSError* error = nil; - NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; - - configuration.HTTPAdditionalHeaders = @{ @"User-Agent" : [NSString stringWithFormat:@"securityd/%s", SECURITY_BUILD_VERSION]}; - - NSURLSession* storeBagSession = [NSURLSession sessionWithConfiguration:configuration - delegate:self - delegateQueue:nil]; - - NSURL* requestEndpoint = _splunkBagURL; - __block NSURL* result = nil; - NSURLSessionDataTask* storeBagTask = [storeBagSession dataTaskWithURL:requestEndpoint completionHandler:^(NSData * _Nullable data, - NSURLResponse * _Nullable __unused response, - NSError * _Nullable responseError) { - - __strong __typeof(self) strongSelf = weakSelf; - if (!strongSelf) { - return; - } - - if (data && !responseError) { - NSData *responseData = data; // shut up compiler - NSDictionary* responseDict = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error]; - if([responseDict isKindOfClass:NSDictionary.class] && !error) { - if (!self->_ignoreServersMessagesTellingUsToGoAway) { - strongSelf->_disableLogging = [[responseDict valueForKey:@"disabled"] boolValue]; - if (strongSelf->_disableLogging || [[responseDict valueForKey:@"sendDisabled"] boolValue]) { - // then don't upload anything right now - secerror("not returning a splunk URL because uploads are disabled"); - dispatch_semaphore_signal(sem); - return; - } - - NSUInteger millisecondsBetweenUploads = [[responseDict valueForKey:@"postFrequency"] unsignedIntegerValue] / 1000; - if (millisecondsBetweenUploads > 0) { - strongSelf->_secondsBetweenUploads = millisecondsBetweenUploads; - } - - strongSelf->_blacklistedEvents = responseDict[@"blacklistedEvents"]; - strongSelf->_blacklistedFields = responseDict[@"blacklistedFields"]; - } - - strongSelf->_metricsBase = responseDict[@"metricsBase"]; - - NSString* metricsEndpoint = responseDict[@"metricsUrl"]; - if([metricsEndpoint isKindOfClass:NSString.class]) { - /* Lives our URL */ - NSString* endpoint = [metricsEndpoint stringByAppendingFormat:@"/2/%@", strongSelf->_splunkTopicName]; - secnotice("ckks", "got metrics endpoint: %@", endpoint); - NSURL* endpointURL = [NSURL URLWithString:endpoint]; - if([endpointURL.scheme isEqualToString:@"https"]) { - result = endpointURL; - } - } - } - } - else { - error = responseError; - } - if(error) { - secnotice("ckks", "Unable to fetch splunk endpoint at URL: %@ -- error: %@", requestEndpoint, error.description); - } - else if(!result) { - secnotice("ckks", "Malformed iTunes config payload!"); - } - - dispatch_semaphore_signal(sem); - }]; - - [storeBagTask resume]; - dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); - - return result; -} - -- (BOOL)forceUploadWithError:(NSError**)error -{ - __block BOOL result = NO; - NSData* json = [self getLoggingJSON:false error: error]; - dispatch_sync(_queue, ^{ - if (json && [self _onQueuePostJSON:json error:error]) { - secinfo("ckks", "uploading sync health data: %@", json); - - [self->_database clearAllData]; - self->_database.uploadDate = [NSDate dateWithTimeIntervalSinceNow:self->_secondsBetweenUploads]; - result = YES; - } - else { - result = NO; - } - }); - - return result; -} - -- (BOOL)_onQueuePostJSON:(NSData*)json error:(NSError**)error -{ - dispatch_assert_queue(_queue); - - /* - * Create the NSURLSession - * We use the ephemeral session config because we don't need cookies or cache - */ - NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; - - configuration.HTTPAdditionalHeaders = @{ @"User-Agent" : [NSString stringWithFormat:@"securityd/%s", SECURITY_BUILD_VERSION]}; - - NSURLSession* postSession = [NSURLSession sessionWithConfiguration:configuration - delegate:self - delegateQueue:nil]; - - /* - * Create the request - */ - NSURL* postEndpoint = self.splunkUploadURL; - if (!postEndpoint) { - secerror("failed to get a splunk upload endpoint - not uploading"); - return NO; - } - - NSMutableURLRequest* postRequest = [[NSMutableURLRequest alloc] init]; - postRequest.URL = postEndpoint; - postRequest.HTTPMethod = @"POST"; - postRequest.HTTPBody = json; - - /* - * Create the upload task. - */ - dispatch_semaphore_t sem = dispatch_semaphore_create(0); - __block BOOL uploadSuccess = NO; - NSURLSessionDataTask* uploadTask = [postSession dataTaskWithRequest:postRequest - completionHandler:^(NSData * _Nullable __unused data, NSURLResponse * _Nullable response, NSError * _Nullable requestError) { - if(requestError) { - secerror("Error in uploading the events to splunk: %@", requestError); - } - else if (![response isKindOfClass:NSHTTPURLResponse.class]){ - Class class = response.class; - secerror("Received the wrong kind of response: %@", NSStringFromClass(class)); - } - else { - NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response; - if(httpResponse.statusCode >= 200 && httpResponse.statusCode < 300) { - /* Success */ - uploadSuccess = YES; - secnotice("ckks", "Splunk upload success"); - } - else { - secnotice("ckks", "Splunk upload unexpected status to URL: %@ -- status: %d", postEndpoint, (int)(httpResponse.statusCode)); - } - } - dispatch_semaphore_signal(sem); - }]; - - secnotice("ckks", "Splunk upload start"); - [uploadTask resume]; - dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); - return uploadSuccess; -} - -- (NSString*)stringForEventClass:(SFAnalyticsEventClass)eventClass -{ - if (eventClass == SFAnalyticsEventClassNote) { - return @"EventNote"; - } - else if (eventClass == SFAnalyticsEventClassSuccess) { - return @"EventSuccess"; - } - else if (eventClass == SFAnalyticsEventClassHardFailure) { - return @"EventHardFailure"; - } - else if (eventClass == SFAnalyticsEventClassSoftFailure) { - return @"EventSoftFailure"; - } - else { - return @"EventUnknown"; - } -} - -- (NSString*)sysdiagnoseStringForEventRecord:(NSDictionary*)eventRecord -{ - NSMutableDictionary* mutableEventRecord = eventRecord.mutableCopy; - [mutableEventRecord removeObjectForKey:SFAnalyticsLoggerSplunkTopic]; - - NSDate* eventDate = [NSDate dateWithTimeIntervalSince1970:[[eventRecord valueForKey:SFAnalyticsLoggerSplunkEventTime] doubleValue] / 1000]; - [mutableEventRecord removeObjectForKey:SFAnalyticsLoggerSplunkEventTime]; - - NSString* eventName = eventRecord[SFAnalyticsLoggerSplunkEventType]; - [mutableEventRecord removeObjectForKey:SFAnalyticsLoggerSplunkEventType]; - - SFAnalyticsEventClass eventClass = [[eventRecord valueForKey:SFAnalyticsLoggerEventClassKey] integerValue]; - NSString* eventClassString = [self stringForEventClass:eventClass]; - [mutableEventRecord removeObjectForKey:SFAnalyticsLoggerEventClassKey]; - - NSMutableString* additionalAttributesString = [NSMutableString string]; - if (mutableEventRecord.count > 0) { - [additionalAttributesString appendString:@" - Attributes: {" ]; - __block BOOL firstAttribute = YES; - [mutableEventRecord enumerateKeysAndObjectsUsingBlock:^(NSString* key, id object, BOOL* stop) { - NSString* openingString = firstAttribute ? @"" : @", "; - [additionalAttributesString appendString:[NSString stringWithFormat:@"%@%@ : %@", openingString, key, object]]; - firstAttribute = NO; - }]; - [additionalAttributesString appendString:@" }"]; - } - - return [NSString stringWithFormat:@"%@ %@: %@%@", eventDate, eventClassString, eventName, additionalAttributesString]; -} - -- (NSString*)getSysdiagnoseDumpWithError:(NSError**)error -{ - NSMutableString* sysdiagnose = [[NSMutableString alloc] init]; - NSDictionary* extraValues = self.extraValuesToUploadToServer; - [extraValues enumerateKeysAndObjectsUsingBlock:^(NSString* key, id object, BOOL* stop) { - [sysdiagnose appendFormat:@"Key: %@, Value: %@\n", key, object]; - }]; - - [sysdiagnose appendString:@"\n"]; - - dispatch_sync(_queue, ^{ - NSArray* allEvents = self->_database.allEvents; - for (NSDictionary* eventRecord in allEvents) { - [sysdiagnose appendFormat:@"%@\n", [self sysdiagnoseStringForEventRecord:eventRecord]]; - } - }); - - return sysdiagnose; -} - -+ (void)addOSVersion:(NSMutableDictionary *)event -{ - static dispatch_once_t onceToken; - static NSString *build = NULL; - static NSString *product = NULL; - dispatch_once(&onceToken, ^{ - NSDictionary *version = CFBridgingRelease(_CFCopySystemVersionDictionary()); - if (version == NULL) - return; - build = version[(__bridge NSString *)_kCFSystemVersionBuildVersionKey]; - product = version[(__bridge NSString *)_kCFSystemVersionProductNameKey]; - }); - if (build) - event[SFAnalyticsLoggerSplunkEventBuild] = build; - if (product) - event[SFAnalyticsLoggerSplunkEventProduct] = product; -} - -- (NSData*)getLoggingJSON:(bool)pretty error:(NSError**)error -{ - __block NSData* json = nil; - NSDictionary* extraValues = self.extraValuesToUploadToServer; - dispatch_sync(_queue, ^{ - if (![self->_database tryToOpenDatabase]) { - // we should not even be here because uploadDate was nil. But since we are, let's get out of here. - // Returning nil here will abort the upload (but again, the uploadDate should've done that already) - secerror("can't get logging JSON because database is not openable"); - if (error) { - *error = [NSError errorWithDomain:@"SFAnalyticsLogger" code:-1 userInfo:@{NSLocalizedDescriptionKey : @"could not open db to read and process metrics (device in class D?)"}]; - } - return; - } - - NSArray* failureRecords = self->_database.failureRecords; - - NSDictionary* successCounts = self->_database.summaryCounts; - NSInteger totalSuccessCount = 0; - NSInteger totalHardFailureCount = 0; - NSInteger totalSoftFailureCount = 0; - for (NSDictionary* perEventTypeSuccessCounts in successCounts.objectEnumerator) { - totalSuccessCount += [perEventTypeSuccessCounts[SFAnalyticsLoggerColumnSuccessCount] integerValue]; - totalHardFailureCount += [perEventTypeSuccessCounts[SFAnalyticsLoggerColumnHardFailureCount] integerValue]; - totalSoftFailureCount += [perEventTypeSuccessCounts[SFAnalyticsLoggerColumnSoftFailureCount] integerValue]; - } - - NSDate* now = [NSDate date]; - - NSMutableDictionary* healthSummaryEvent = extraValues ? extraValues.mutableCopy : [[NSMutableDictionary alloc] init]; - healthSummaryEvent[SFAnalyticsLoggerSplunkTopic] = self->_splunkTopicName ?: [NSNull null]; - healthSummaryEvent[SFAnalyticsLoggerSplunkEventTime] = @([now timeIntervalSince1970] * 1000); - healthSummaryEvent[SFAnalyticsLoggerSplunkEventType] = @"ckksHealthSummary"; - healthSummaryEvent[SFAnalyticsLoggerColumnSuccessCount] = @(totalSuccessCount); - healthSummaryEvent[SFAnalyticsLoggerColumnHardFailureCount] = @(totalHardFailureCount); - healthSummaryEvent[SFAnalyticsLoggerColumnSoftFailureCount] = @(totalSoftFailureCount); - [SFAnalyticsLogger addOSVersion:healthSummaryEvent]; - - NSMutableArray* splunkRecords = failureRecords.mutableCopy; - [splunkRecords addObject:healthSummaryEvent]; - - NSDictionary* jsonDict = @{ - SFAnalyticsLoggerSplunkPostTime : @([now timeIntervalSince1970] * 1000), - @"events" : splunkRecords - }; - - json = [NSJSONSerialization dataWithJSONObject:jsonDict - options:(pretty ? NSJSONWritingPrettyPrinted : 0) - error:error]; - }); - - return json; -} - -- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge - completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler { - assert(completionHandler); - (void)session; - secnotice("ckks", "Splunk upload challenge"); - NSURLCredential *cred = nil; - SecTrustResultType result = kSecTrustResultInvalid; - - if ([challenge previousFailureCount] > 0) { - // Previous failures occurred, bail - completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); - - } else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { - /* - * Evaluate trust for the certificate - */ - - SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; - SecTrustEvaluate(serverTrust, &result); - if (_allowInsecureSplunkCert || (result == kSecTrustResultProceed) || (result == kSecTrustResultUnspecified)) { - /* - * All is well, accept the credentials - */ - if(_allowInsecureSplunkCert) { - secnotice("ckks", "Force Accepting Splunk Credential"); - } - cred = [NSURLCredential credentialForTrust:serverTrust]; - completionHandler(NSURLSessionAuthChallengeUseCredential, cred); - - } else { - /* - * An error occurred in evaluating trust, bail - */ - completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); - } - } else { - /* - * Just perform the default handling - */ - completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); - } - -} - -- (BOOL)ignoreServerDisablingMessages -{ - return _ignoreServersMessagesTellingUsToGoAway; -} - -- (void)setIgnoreServerDisablingMessages:(BOOL)ignoreServer -{ - _ignoreServersMessagesTellingUsToGoAway = ignoreServer ? YES : NO; -} - -- (BOOL)allowsInsecureSplunkCert -{ - return _allowInsecureSplunkCert; -} - -- (void)setAllowsInsecureSplunkCert:(BOOL)allowsInsecureSplunkCert -{ - _allowInsecureSplunkCert = allowsInsecureSplunkCert ? YES : NO; -} - -@end - -@implementation SFAnalyticsLoggerSQLiteStore - -+ (instancetype)storeWithPath:(NSString*)path schema:(NSString*)schema -{ - SFAnalyticsLoggerSQLiteStore* store = nil; - @synchronized([SFAnalyticsLoggerSQLiteStore class]) { - static NSMutableDictionary* loggingStores = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - loggingStores = [[NSMutableDictionary alloc] init]; - }); - - NSString* standardizedPath = path.stringByStandardizingPath; - store = loggingStores[standardizedPath]; - if (!store) { - store = [[self alloc] initWithPath:standardizedPath schema:schema]; - loggingStores[standardizedPath] = store; - } - - NSError* error = nil; - if (![store openWithError:&error]) { - secerror("SFAnalyticsLogger: could not open db at init, will try again later. Error: %@", error); - } - - } - - return store; -} - -- (void)dealloc -{ - [self close]; -} - -- (BOOL)tryToOpenDatabase -{ - if (!self.isOpen) { - secwarning("SFAnalyticsLogger: db is closed, attempting to open"); - NSError* error = nil; - if (![self openWithError:&error]) { - secerror("SFAnalyticsLogger: failed to open db with error %@", error); - return NO; - } - } - return YES; -} - -- (NSInteger)successCountForEventType:(NSString*)eventType -{ - if ([self tryToOpenDatabase]) { - return [[[[self select:@[SFAnalyticsLoggerColumnSuccessCount] from:SFAnalyticsLoggerTableSuccessCount where:@"event_type = ?" bindings:@[eventType]] firstObject] valueForKey:SFAnalyticsLoggerColumnSuccessCount] integerValue]; - } - return 0; -} - -- (void)incrementSuccessCountForEventType:(NSString*)eventType -{ - if ([self tryToOpenDatabase]) { - NSInteger successCount = [self successCountForEventType:eventType]; - NSInteger hardFailureCount = [self hardFailureCountForEventType:eventType]; - NSInteger softFailureCount = [self softFailureCountForEventType:eventType]; - [self insertOrReplaceInto:SFAnalyticsLoggerTableSuccessCount values:@{SFAnalyticsLoggerColumnEventType : eventType, SFAnalyticsLoggerColumnSuccessCount : @(successCount + 1), SFAnalyticsLoggerColumnHardFailureCount : @(hardFailureCount), SFAnalyticsLoggerColumnSoftFailureCount : @(softFailureCount)}]; - } -} - -- (NSInteger)hardFailureCountForEventType:(NSString*)eventType -{ - if ([self tryToOpenDatabase]) { - return [[[[self select:@[SFAnalyticsLoggerColumnHardFailureCount] from:SFAnalyticsLoggerTableSuccessCount where:@"event_type = ?" bindings:@[eventType]] firstObject] valueForKey:SFAnalyticsLoggerColumnHardFailureCount] integerValue]; - } - return 0; -} - -- (NSInteger)softFailureCountForEventType:(NSString*)eventType -{ - if ([self tryToOpenDatabase]) { - return [[[[self select:@[SFAnalyticsLoggerColumnSoftFailureCount] from:SFAnalyticsLoggerTableSuccessCount where:@"event_type = ?" bindings:@[eventType]] firstObject] valueForKey:SFAnalyticsLoggerColumnSoftFailureCount] integerValue]; - } - return 0; -} - -- (void)incrementHardFailureCountForEventType:(NSString*)eventType -{ - if ([self tryToOpenDatabase]) { - NSInteger successCount = [self successCountForEventType:eventType]; - NSInteger hardFailureCount = [self hardFailureCountForEventType:eventType]; - NSInteger softFailureCount = [self softFailureCountForEventType:eventType]; - [self insertOrReplaceInto:SFAnalyticsLoggerTableSuccessCount values:@{SFAnalyticsLoggerColumnEventType : eventType, SFAnalyticsLoggerColumnSuccessCount : @(successCount), SFAnalyticsLoggerColumnHardFailureCount : @(hardFailureCount + 1), SFAnalyticsLoggerColumnSoftFailureCount : @(softFailureCount)}]; - } -} - -- (void)incrementSoftFailureCountForEventType:(NSString*)eventType -{ - if ([self tryToOpenDatabase]) { - NSInteger successCount = [self successCountForEventType:eventType]; - NSInteger hardFailureCount = [self hardFailureCountForEventType:eventType]; - NSInteger softFailureCount = [self softFailureCountForEventType:eventType]; - [self insertOrReplaceInto:SFAnalyticsLoggerTableSuccessCount values:@{SFAnalyticsLoggerColumnEventType : eventType, SFAnalyticsLoggerColumnSuccessCount : @(successCount), SFAnalyticsLoggerColumnHardFailureCount : @(hardFailureCount), SFAnalyticsLoggerColumnSoftFailureCount : @(softFailureCount + 1)}]; - } -} - -- (NSDictionary*)summaryCounts -{ - if ([self tryToOpenDatabase]) { - NSMutableDictionary* successCountsDict = [NSMutableDictionary dictionary]; - NSArray* rows = [self selectAllFrom:SFAnalyticsLoggerTableSuccessCount where:nil bindings:nil]; - for (NSDictionary* rowDict in rows) { - NSString* eventName = rowDict[SFAnalyticsLoggerColumnEventType]; - if (!eventName) { - secinfo("SFAnalytics", "ignoring entry in success counts table without an event name"); - continue; - } - - successCountsDict[eventName] = @{SFAnalyticsLoggerTableSuccessCount : rowDict[SFAnalyticsLoggerColumnSuccessCount], SFAnalyticsLoggerColumnHardFailureCount : rowDict[SFAnalyticsLoggerColumnHardFailureCount], SFAnalyticsLoggerColumnSoftFailureCount : rowDict[SFAnalyticsLoggerColumnSoftFailureCount]}; - } - return successCountsDict; - } - return [NSDictionary new]; -} - -- (NSArray*)failureRecords -{ - if ([self tryToOpenDatabase]) { - NSArray* recordBlobs = [self select:@[SFAnalyticsLoggerColumnData] from:SFAnalyticsLoggerTableHardFailures]; - if (recordBlobs.count < SFANALYTICS_MAX_EVENTS_TO_REPORT) { - NSArray* softFailureBlobs = [self select:@[SFAnalyticsLoggerColumnData] from:SFAnalyticsLoggerTableSoftFailures]; - if (softFailureBlobs.count > 0) { - NSUInteger numSoftFailuresToReport = SFANALYTICS_MAX_EVENTS_TO_REPORT - recordBlobs.count; - if (numSoftFailuresToReport > softFailureBlobs.count) - numSoftFailuresToReport = softFailureBlobs.count; - - recordBlobs = [recordBlobs arrayByAddingObjectsFromArray:[softFailureBlobs subarrayWithRange:NSMakeRange(softFailureBlobs.count - numSoftFailuresToReport, numSoftFailuresToReport)]]; - } - } - - NSMutableArray* failureRecords = [[NSMutableArray alloc] init]; - for (NSDictionary* row in recordBlobs) { - NSMutableDictionary* deserializedRecord = [NSPropertyListSerialization propertyListWithData:row[SFAnalyticsLoggerColumnData] options:NSPropertyListMutableContainers format:nil error:nil]; - [SFAnalyticsLogger addOSVersion:deserializedRecord]; - [failureRecords addObject:deserializedRecord]; - } - return failureRecords; - } - return [NSArray new]; -} - -- (NSArray*)allEvents -{ - if ([self tryToOpenDatabase]) { - NSArray* recordBlobs = [self select:@[SFAnalyticsLoggerColumnData] from:SFAnalyticsLoggerTableAllEvents]; - NSMutableArray* records = [[NSMutableArray alloc] init]; - for (NSDictionary* row in recordBlobs) { - NSDictionary* deserializedRecord = [NSPropertyListSerialization propertyListWithData:row[SFAnalyticsLoggerColumnData] options:0 format:nil error:nil]; - [records addObject:deserializedRecord]; - } - return records; - } - return [NSArray new]; -} - -- (void)addEventDict:(NSDictionary*)eventDict toTable:(NSString*)table -{ - if ([self tryToOpenDatabase]) { - NSError* error = nil; - NSData* serializedRecord = [NSPropertyListSerialization dataWithPropertyList:eventDict format:NSPropertyListBinaryFormat_v1_0 options:0 error:&error]; - if(!error && serializedRecord) { - [self insertOrReplaceInto:table values:@{SFAnalyticsLoggerColumnDate : [NSDate date], SFAnalyticsLoggerColumnData : serializedRecord}]; - } - if(error && !serializedRecord) { - secerror("Couldn't serialize failure record: %@", error); - } - } -} - -// the other returning methods give default values in case of closed db, -// but this needs to be nil so the comparison to 'now' fails and we don't upload -- (NSDate*)uploadDate -{ - if ([self tryToOpenDatabase]) { - return [self datePropertyForKey:SFAnalyticsLoggerUploadDate]; - } - return nil; -} - -- (void)setUploadDate:(NSDate*)uploadDate -{ - if ([self tryToOpenDatabase]) { - [self setDateProperty:uploadDate forKey:SFAnalyticsLoggerUploadDate]; - } -} - -- (void)clearAllData -{ - if ([self tryToOpenDatabase]) { - [self deleteFrom:SFAnalyticsLoggerTableSuccessCount where:@"event_type like ?" bindings:@[@"%"]]; - [self deleteFrom:SFAnalyticsLoggerTableHardFailures where:@"id >= 0" bindings:nil]; - [self deleteFrom:SFAnalyticsLoggerTableSoftFailures where:@"id >= 0" bindings:nil]; - [self deleteFrom:SFAnalyticsLoggerTableAllEvents where:@"id >= 0" bindings:nil]; - } -} - -@end - -#endif // __OBJC2__ diff --git a/Analytics/SFAnalyticsLogging.plist b/Analytics/SFAnalyticsLogging.plist deleted file mode 100644 index 060222c3..00000000 --- a/Analytics/SFAnalyticsLogging.plist +++ /dev/null @@ -1,16 +0,0 @@ - - - - - splunk_topic - xp_sear_keysync - splunk_allowInsecureCertificate - - splunk_bagURL - https://xp.apple.com/config/1/report/xp_sear_keysync - SyncManifests - - EnforceManifests - - - diff --git a/Analytics/SFAnalyticsMultiSampler+Internal.h b/Analytics/SFAnalyticsMultiSampler+Internal.h new file mode 100644 index 00000000..cc365744 --- /dev/null +++ b/Analytics/SFAnalyticsMultiSampler+Internal.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef SFAnalyticsMultiSampler_Internal_h +#define SFAnalyticsMultiSampler_Internal_h + +#if __OBJC2__ + +#import "SFAnalyticsMultiSampler.h" + +typedef NSDictionary* MultiSamplerDictionary; + +@interface SFAnalyticsMultiSampler(Internal) +- (instancetype)initWithName:(NSString*)name interval:(NSTimeInterval)interval block:(MultiSamplerDictionary (^)(void))block clientClass:(Class)clientClass; +@end + +#endif // objc2 + +#endif /* SFAnalyticsSampler_private_h */ diff --git a/Analytics/SFAnalyticsMultiSampler.h b/Analytics/SFAnalyticsMultiSampler.h new file mode 100644 index 00000000..93284f06 --- /dev/null +++ b/Analytics/SFAnalyticsMultiSampler.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if __OBJC2__ +#ifndef SFAnalyticsMultiSampler_h +#define SFAnalyticsMultiSampler_h + +#import + +@interface SFAnalyticsMultiSampler : NSObject + +@property (nonatomic) NSTimeInterval samplingInterval; +@property (nonatomic, readonly) NSString* name; + +- (instancetype)init NS_UNAVAILABLE; +- (NSDictionary*)sampleNow; +- (void)pauseSampling; +- (void)resumeSampling; + +@end + +#endif +#endif diff --git a/Analytics/SFAnalyticsMultiSampler.m b/Analytics/SFAnalyticsMultiSampler.m new file mode 100644 index 00000000..638f338f --- /dev/null +++ b/Analytics/SFAnalyticsMultiSampler.m @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if __OBJC2__ + +#import "SFAnalyticsMultiSampler+Internal.h" +#import "SFAnalytics+Internal.h" +#import "SFAnalyticsDefines.h" +#import "utilities/debugging.h" +#include +#include + +@implementation SFAnalyticsMultiSampler { + NSTimeInterval _samplingInterval; + dispatch_source_t _timer; + NSString* _name; + MultiSamplerDictionary (^_block)(void); + int _notificationToken; + Class _clientClass; + BOOL _oncePerReport; + BOOL _activeTimer; +} + +@synthesize name = _name; +@synthesize samplingInterval = _samplingInterval; + +- (instancetype)initWithName:(NSString*)name interval:(NSTimeInterval)interval block:(MultiSamplerDictionary (^)(void))block clientClass:(Class)clientClass +{ + if (self = [super init]) { + if (![clientClass isSubclassOfClass:[SFAnalytics class]]) { + secerror("SFAnalyticsSampler created without valid client class (%@)", clientClass); + return nil; + } + + if (!name || (interval < 1.0f && interval != SFAnalyticsSamplerIntervalOncePerReport) || !block) { + secerror("SFAnalyticsSampler created without proper data"); + return nil; + } + + _clientClass = clientClass; + _block = block; + _name = name; + _samplingInterval = interval; + [self newTimer]; + } + return self; +} + +- (void)newTimer +{ + if (_activeTimer) { + [self pauseSampling]; + } + + _oncePerReport = (_samplingInterval == SFAnalyticsSamplerIntervalOncePerReport); + if (_oncePerReport) { + [self setupOnceTimer]; + } else { + [self setupPeriodicTimer]; + } +} + +- (void)setupOnceTimer +{ + __weak __typeof(self) weakSelf = self; + notify_register_dispatch(SFAnalyticsFireSamplersNotification, &_notificationToken, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(int token) { + __strong __typeof(self) strongSelf = weakSelf; + if (!strongSelf) { + secnotice("SFAnalyticsSampler", "sampler went away before we could run its once-per-report block"); + notify_cancel(token); + return; + } + + MultiSamplerDictionary data = strongSelf->_block(); + [data enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSNumber * _Nonnull obj, BOOL * _Nonnull stop) { + [[strongSelf->_clientClass logger] logMetric:obj withName:key oncePerReport:strongSelf->_oncePerReport]; + }]; + }); + _activeTimer = YES; +} + +- (void)setupPeriodicTimer +{ + _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); + dispatch_source_set_timer(_timer, dispatch_walltime(0, _samplingInterval * NSEC_PER_SEC), _samplingInterval * NSEC_PER_SEC, _samplingInterval * NSEC_PER_SEC / 50.0); // give 2% leeway on timer + + __weak __typeof(self) weakSelf = self; + dispatch_source_set_event_handler(_timer, ^{ + __strong __typeof(self) strongSelf = weakSelf; + if (!strongSelf) { + secnotice("SFAnalyticsSampler", "sampler went away before we could run its once-per-report block"); + return; + } + + MultiSamplerDictionary data = strongSelf->_block(); + [data enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSNumber * _Nonnull obj, BOOL * _Nonnull stop) { + [[strongSelf->_clientClass logger] logMetric:obj withName:key oncePerReport:strongSelf->_oncePerReport]; + }]; + }); + dispatch_resume(_timer); + + _activeTimer = YES; +} + +- (void)setSamplingInterval:(NSTimeInterval)interval +{ + if (interval < 1.0f && !(interval == SFAnalyticsSamplerIntervalOncePerReport)) { + secerror("SFAnalyticsSampler: interval %f is not supported", interval); + return; + } + + _samplingInterval = interval; + [self newTimer]; +} + +- (NSTimeInterval)samplingInterval { + return _samplingInterval; +} + +- (MultiSamplerDictionary)sampleNow +{ + MultiSamplerDictionary data = _block(); + [data enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSNumber * _Nonnull obj, BOOL * _Nonnull stop) { + [[self->_clientClass logger] logMetric:obj withName:key oncePerReport:self->_oncePerReport]; + }]; + return data; +} + +- (void)pauseSampling +{ + if (!_activeTimer) { + return; + } + + if (_oncePerReport) { + notify_cancel(_notificationToken); + _notificationToken = 0; + } else { + dispatch_source_cancel(_timer); + } + _activeTimer = NO; +} + +- (void)resumeSampling +{ + [self newTimer]; +} + +- (void)dealloc +{ + [self pauseSampling]; +} + +@end + +#endif diff --git a/Analytics/SFAnalyticsSQLiteStore.h b/Analytics/SFAnalyticsSQLiteStore.h new file mode 100644 index 00000000..3cecef1e --- /dev/null +++ b/Analytics/SFAnalyticsSQLiteStore.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if __OBJC2__ + +#import "SFSQLite.h" + +@interface SFAnalyticsSQLiteStore : SFSQLite + +@property (readonly, strong) NSArray* hardFailures; +@property (readonly, strong) NSArray* softFailures; +@property (readonly, strong) NSArray* allEvents; +@property (readonly, strong) NSArray* samples; +@property (readwrite, strong) NSDate* uploadDate; + ++ (instancetype)storeWithPath:(NSString*)path schema:(NSString*)schema; + +- (BOOL)tryToOpenDatabase; +- (void)incrementSuccessCountForEventType:(NSString*)eventType; +- (void)incrementHardFailureCountForEventType:(NSString*)eventType; +- (void)incrementSoftFailureCountForEventType:(NSString*)eventType; +- (NSInteger)successCountForEventType:(NSString*)eventType; +- (NSInteger)hardFailureCountForEventType:(NSString*)eventType; +- (NSInteger)softFailureCountForEventType:(NSString*)eventType; +- (void)addEventDict:(NSDictionary*)eventDict toTable:(NSString*)table; +- (void)addSample:(NSNumber*)value forName:(NSString*)name; +- (void)removeAllSamplesForName:(NSString*)name; +- (void)clearAllData; + +- (NSDictionary*)summaryCounts; + +@end + +#endif diff --git a/Analytics/SFAnalyticsSQLiteStore.m b/Analytics/SFAnalyticsSQLiteStore.m new file mode 100644 index 00000000..f779d289 --- /dev/null +++ b/Analytics/SFAnalyticsSQLiteStore.m @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if __OBJC2__ + +#import "SFAnalyticsSQLiteStore.h" +#import "SFAnalyticsDefines.h" +#import "debugging.h" + +NSString* const SFAnalyticsColumnEventType = @"event_type"; +NSString* const SFAnalyticsColumnDate = @"timestamp"; +NSString* const SFAnalyticsColumnData = @"data"; +NSString* const SFAnalyticsUploadDate = @"upload_date"; + +@implementation SFAnalyticsSQLiteStore + ++ (instancetype)storeWithPath:(NSString*)path schema:(NSString*)schema +{ + SFAnalyticsSQLiteStore* store = nil; + @synchronized([SFAnalyticsSQLiteStore class]) { + static NSMutableDictionary* loggingStores = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + loggingStores = [[NSMutableDictionary alloc] init]; + }); + + NSString* standardizedPath = path.stringByStandardizingPath; + store = loggingStores[standardizedPath]; + if (!store) { + store = [[self alloc] initWithPath:standardizedPath schema:schema]; + loggingStores[standardizedPath] = store; + } + NSError* error = nil; + if (![store openWithError:&error] && !(error && error.code == SQLITE_AUTH)) { + secerror("SFAnalytics: could not open db at init, will try again later. Error: %@", error); + } + } + + return store; +} + +- (void)dealloc +{ + [self close]; +} + +- (BOOL)tryToOpenDatabase +{ + if (!self.isOpen) { + NSError* error = nil; + if (![self openWithError:&error]) { + return NO; + } + secnotice("SFAnalytics", "successfully opened analytics db"); + } + return YES; +} + +- (NSInteger)successCountForEventType:(NSString*)eventType +{ + if (![self tryToOpenDatabase]) { + return 0; + } + return [[[[self select:@[SFAnalyticsColumnSuccessCount] from:SFAnalyticsTableSuccessCount where:@"event_type = ?" bindings:@[eventType]] firstObject] valueForKey:SFAnalyticsColumnSuccessCount] integerValue]; +} + +- (void)incrementSuccessCountForEventType:(NSString*)eventType +{ + if (![self tryToOpenDatabase]) { + return; + } + NSInteger successCount = [self successCountForEventType:eventType]; + NSInteger hardFailureCount = [self hardFailureCountForEventType:eventType]; + NSInteger softFailureCount = [self softFailureCountForEventType:eventType]; + [self insertOrReplaceInto:SFAnalyticsTableSuccessCount values:@{SFAnalyticsColumnEventType : eventType, SFAnalyticsColumnSuccessCount : @(successCount + 1), SFAnalyticsColumnHardFailureCount : @(hardFailureCount), SFAnalyticsColumnSoftFailureCount : @(softFailureCount)}]; +} + +- (NSInteger)hardFailureCountForEventType:(NSString*)eventType +{ + if (![self tryToOpenDatabase]) { + return 0; + } + return [[[[self select:@[SFAnalyticsColumnHardFailureCount] from:SFAnalyticsTableSuccessCount where:@"event_type = ?" bindings:@[eventType]] firstObject] valueForKey:SFAnalyticsColumnHardFailureCount] integerValue]; +} + +- (NSInteger)softFailureCountForEventType:(NSString*)eventType +{ + if (![self tryToOpenDatabase]) { + return 0; + } + return [[[[self select:@[SFAnalyticsColumnSoftFailureCount] from:SFAnalyticsTableSuccessCount where:@"event_type = ?" bindings:@[eventType]] firstObject] valueForKey:SFAnalyticsColumnSoftFailureCount] integerValue]; +} + +- (void)incrementHardFailureCountForEventType:(NSString*)eventType +{ + if (![self tryToOpenDatabase]) { + return; + } + NSInteger successCount = [self successCountForEventType:eventType]; + NSInteger hardFailureCount = [self hardFailureCountForEventType:eventType]; + NSInteger softFailureCount = [self softFailureCountForEventType:eventType]; + [self insertOrReplaceInto:SFAnalyticsTableSuccessCount values:@{SFAnalyticsColumnEventType : eventType, SFAnalyticsColumnSuccessCount : @(successCount), SFAnalyticsColumnHardFailureCount : @(hardFailureCount + 1), SFAnalyticsColumnSoftFailureCount : @(softFailureCount)}]; +} + +- (void)incrementSoftFailureCountForEventType:(NSString*)eventType +{ + if (![self tryToOpenDatabase]) { + return; + } + NSInteger successCount = [self successCountForEventType:eventType]; + NSInteger hardFailureCount = [self hardFailureCountForEventType:eventType]; + NSInteger softFailureCount = [self softFailureCountForEventType:eventType]; + [self insertOrReplaceInto:SFAnalyticsTableSuccessCount values:@{SFAnalyticsColumnEventType : eventType, SFAnalyticsColumnSuccessCount : @(successCount), SFAnalyticsColumnHardFailureCount : @(hardFailureCount), SFAnalyticsColumnSoftFailureCount : @(softFailureCount + 1)}]; +} + +- (NSDictionary*)summaryCounts +{ + if (![self tryToOpenDatabase]) { + return [NSDictionary new]; + } + NSMutableDictionary* successCountsDict = [NSMutableDictionary dictionary]; + NSArray* rows = [self selectAllFrom:SFAnalyticsTableSuccessCount where:nil bindings:nil]; + for (NSDictionary* rowDict in rows) { + NSString* eventName = rowDict[SFAnalyticsColumnEventType]; + if (!eventName) { + secinfo("SFAnalytics", "ignoring entry in success counts table without an event name"); + continue; + } + + successCountsDict[eventName] = @{SFAnalyticsTableSuccessCount : rowDict[SFAnalyticsColumnSuccessCount], SFAnalyticsColumnHardFailureCount : rowDict[SFAnalyticsColumnHardFailureCount], SFAnalyticsColumnSoftFailureCount : rowDict[SFAnalyticsColumnSoftFailureCount]}; + } + + return successCountsDict; +} + +- (NSArray*)deserializedRecords:(NSArray*)recordBlobs +{ + if (![self tryToOpenDatabase]) { + return [NSArray new]; + } + NSMutableArray* records = [NSMutableArray new]; + for (NSDictionary* row in recordBlobs) { + NSMutableDictionary* deserializedRecord = [NSPropertyListSerialization propertyListWithData:row[SFAnalyticsColumnData] options:NSPropertyListMutableContainers format:nil error:nil]; + [records addObject:deserializedRecord]; + } + return records; +} + +- (NSArray*)hardFailures +{ + if (![self tryToOpenDatabase]) { + return [NSArray new]; + } + return [self deserializedRecords:[self select:@[SFAnalyticsColumnData] from:SFAnalyticsTableHardFailures]]; +} + +- (NSArray*)softFailures +{ + if (![self tryToOpenDatabase]) { + return [NSArray new]; + } + return [self deserializedRecords:[self select:@[SFAnalyticsColumnData] from:SFAnalyticsTableSoftFailures]]; +} + +- (NSArray*)allEvents +{ + if (![self tryToOpenDatabase]) { + return [NSArray new]; + } + return [self deserializedRecords:[self select:@[SFAnalyticsColumnData] from:SFAnalyticsTableAllEvents]]; +} + +- (NSArray*)samples +{ + if (![self tryToOpenDatabase]) { + return [NSArray new]; + } + return [self select:@[SFAnalyticsColumnSampleName, SFAnalyticsColumnSampleValue] from:SFAnalyticsTableSamples]; +} + +- (void)addEventDict:(NSDictionary*)eventDict toTable:(NSString*)table +{ + if (![self tryToOpenDatabase]) { + return; + } + NSError* error = nil; + NSData* serializedRecord = [NSPropertyListSerialization dataWithPropertyList:eventDict format:NSPropertyListBinaryFormat_v1_0 options:0 error:&error]; + if(!error && serializedRecord) { + [self insertOrReplaceInto:table values:@{SFAnalyticsColumnDate : @([[NSDate date] timeIntervalSince1970]), SFAnalyticsColumnData : serializedRecord}]; + } + if(error && !serializedRecord) { + secerror("Couldn't serialize failure record: %@", error); + } +} + +- (void)addSample:(NSNumber*)value forName:(NSString*)name +{ + if (![self tryToOpenDatabase]) { + return; + } + [self insertOrReplaceInto:SFAnalyticsTableSamples values:@{SFAnalyticsColumnDate : @([[NSDate date] timeIntervalSince1970]), SFAnalyticsColumnSampleName : name, SFAnalyticsColumnSampleValue : value}]; +} + +- (void)removeAllSamplesForName:(NSString*)name +{ + if (![self tryToOpenDatabase]) { + return; + } + [self deleteFrom:SFAnalyticsTableSamples where:[NSString stringWithFormat:@"name == '%@'", name] bindings:nil]; +} + +- (NSDate*)uploadDate +{ + if (![self tryToOpenDatabase]) { + return nil; // In other cases return default object but nil is better here to avoid entering the upload flow + } + return [self datePropertyForKey:SFAnalyticsUploadDate]; +} + +- (void)setUploadDate:(NSDate*)uploadDate +{ + if (![self tryToOpenDatabase]) { + return; + } + [self setDateProperty:uploadDate forKey:SFAnalyticsUploadDate]; +} + +- (void)clearAllData +{ + if (![self tryToOpenDatabase]) { + return; + } + [self deleteFrom:SFAnalyticsTableSuccessCount where:@"event_type like ?" bindings:@[@"%"]]; + [self deleteFrom:SFAnalyticsTableHardFailures where:@"id >= 0" bindings:nil]; + [self deleteFrom:SFAnalyticsTableSoftFailures where:@"id >= 0" bindings:nil]; + [self deleteFrom:SFAnalyticsTableSamples where:@"id >= 0" bindings:nil]; + [self deleteFrom:SFAnalyticsTableAllEvents where:@"id >= 0" bindings:nil]; +} + +@end + +#endif // OBJC2 diff --git a/Analytics/SFAnalyticsSampler+Internal.h b/Analytics/SFAnalyticsSampler+Internal.h new file mode 100644 index 00000000..fdf3d3d1 --- /dev/null +++ b/Analytics/SFAnalyticsSampler+Internal.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef SFAnalyticsSampler_Internal_h +#define SFAnalyticsSampler_Internal_h + +#if __OBJC2__ + +#import "SFAnalyticsSampler.h" + +@interface SFAnalyticsSampler(Internal) +- (instancetype)initWithName:(NSString*)name interval:(NSTimeInterval)interval block:(NSNumber* (^)(void))block clientClass:(Class)clientClass; +@end + +#endif // objc2 + +#endif /* SFAnalyticsSampler_private_h */ diff --git a/Analytics/SFAnalyticsSampler.h b/Analytics/SFAnalyticsSampler.h new file mode 100644 index 00000000..3844d8f4 --- /dev/null +++ b/Analytics/SFAnalyticsSampler.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if __OBJC2__ +#ifndef SFAnalyticsSampler_h +#define SFAnalyticsSampler_h + +#import + +@interface SFAnalyticsSampler : NSObject + +@property (nonatomic) NSTimeInterval samplingInterval; +@property (nonatomic, readonly) NSString* name; + +- (instancetype)init NS_UNAVAILABLE; +- (NSNumber*)sampleNow; +- (void)pauseSampling; +- (void)resumeSampling; + +@end + +#endif +#endif diff --git a/Analytics/SFAnalyticsSampler.m b/Analytics/SFAnalyticsSampler.m new file mode 100644 index 00000000..bd887abf --- /dev/null +++ b/Analytics/SFAnalyticsSampler.m @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if __OBJC2__ + +#import "SFAnalyticsSampler+Internal.h" +#import "SFAnalytics+Internal.h" +#import "SFAnalyticsDefines.h" +#import "utilities/debugging.h" +#include +#include + +@implementation SFAnalyticsSampler { + NSTimeInterval _samplingInterval; + dispatch_source_t _timer; + NSString* _name; + NSNumber* (^_block)(void); + int _notificationToken; + Class _clientClass; + BOOL _oncePerReport; + BOOL _activeTimer; +} + +@synthesize name = _name; +@synthesize samplingInterval = _samplingInterval; + +- (instancetype)initWithName:(NSString*)name interval:(NSTimeInterval)interval block:(NSNumber* (^)(void))block clientClass:(Class)clientClass +{ + if (self = [super init]) { + if (![clientClass isSubclassOfClass:[SFAnalytics class]]) { + secerror("SFAnalyticsSampler created without valid client class (%@)", clientClass); + return nil; + } + + if (!name || (interval < 1.0f && interval != SFAnalyticsSamplerIntervalOncePerReport) || !block) { + secerror("SFAnalyticsSampler created without proper data"); + return nil; + } + + _clientClass = clientClass; + _block = block; + _name = name; + _samplingInterval = interval; + [self newTimer]; + } + return self; +} + +- (void)newTimer +{ + if (_activeTimer) { + [self pauseSampling]; + } + + _oncePerReport = (_samplingInterval == SFAnalyticsSamplerIntervalOncePerReport); + if (_oncePerReport) { + [self setupOnceTimer]; + } else { + [self setupPeriodicTimer]; + } +} + +- (void)setupOnceTimer +{ + __weak __typeof(self) weakSelf = self; + notify_register_dispatch(SFAnalyticsFireSamplersNotification, &_notificationToken, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(int token) { + __strong __typeof(self) strongSelf = weakSelf; + if (!strongSelf) { + secnotice("SFAnalyticsSampler", "sampler went away before we could run its once-per-report block"); + notify_cancel(token); + return; + } + [[strongSelf->_clientClass logger] logMetric:strongSelf->_block() withName:strongSelf->_name oncePerReport:strongSelf->_oncePerReport]; + }); + _activeTimer = YES; +} + +- (void)setupPeriodicTimer +{ + _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); + dispatch_source_set_timer(_timer, dispatch_walltime(0, _samplingInterval * NSEC_PER_SEC), _samplingInterval * NSEC_PER_SEC, _samplingInterval * NSEC_PER_SEC / 50.0); // give 2% leeway on timer + + __weak __typeof(self) weakSelf = self; + dispatch_source_set_event_handler(_timer, ^{ + __strong __typeof(self) strongSelf = weakSelf; + if (!strongSelf) { + // TODO: can we cancel this thing from here? + secnotice("SFAnalyticsSampler", "sampler went away before we could run its once-per-report block"); + return; + } + [[strongSelf->_clientClass logger] logMetric:strongSelf->_block() withName:strongSelf->_name oncePerReport:strongSelf->_oncePerReport]; + }); + dispatch_resume(_timer); + + _activeTimer = YES; +} + +- (void)setSamplingInterval:(NSTimeInterval)interval +{ + if (interval < 1.0f && !(interval == SFAnalyticsSamplerIntervalOncePerReport)) { + secerror("SFAnalyticsSampler: interval %f is not supported", interval); + return; + } + + _samplingInterval = interval; + [self newTimer]; +} + +- (NSTimeInterval)samplingInterval { + return _samplingInterval; +} + +- (NSNumber*)sampleNow +{ + NSNumber* result = _block(); + [[_clientClass logger] logMetric:result withName:_name oncePerReport:_oncePerReport]; + return result; +} + +- (void)pauseSampling +{ + if (!_activeTimer) { + return; + } + + if (_oncePerReport) { + notify_cancel(_notificationToken); + _notificationToken = 0; + } else { + dispatch_source_cancel(_timer); + } + _activeTimer = NO; +} + +- (void)resumeSampling +{ + [self newTimer]; +} + +- (void)dealloc +{ + [self pauseSampling]; +} + +@end + +#endif diff --git a/Analytics/SQLite/SFObjCType.h b/Analytics/SQLite/SFObjCType.h index 61acd4b6..50400597 100644 --- a/Analytics/SQLite/SFObjCType.h +++ b/Analytics/SQLite/SFObjCType.h @@ -21,6 +21,8 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if __OBJC2__ + #import typedef NS_ENUM(NSInteger, SFObjCTypeCode) { @@ -86,3 +88,5 @@ typedef NS_ENUM(NSInteger, SFObjCTypeFlag) { - (void)getBytes:(void *)bytes forObject:(id)object; @end + +#endif diff --git a/Analytics/SQLite/SFObjCType.m b/Analytics/SQLite/SFObjCType.m index 98257f2b..dcc27ff5 100644 --- a/Analytics/SQLite/SFObjCType.m +++ b/Analytics/SQLite/SFObjCType.m @@ -21,8 +21,9 @@ * @APPLE_LICENSE_HEADER_END@ */ -#import "SFObjCType.h" +#if __OBJC2__ +#import "SFObjCType.h" static NSArray *_SFObjCTypesByCode = nil; @@ -167,3 +168,5 @@ static NSArray *_SFObjCTypesByCode = nil; } @end + +#endif diff --git a/Analytics/SQLite/SFSQLite.h b/Analytics/SQLite/SFSQLite.h index cb6a80df..4eda2730 100644 --- a/Analytics/SQLite/SFSQLite.h +++ b/Analytics/SQLite/SFSQLite.h @@ -23,6 +23,8 @@ // Header exposed for unit testing only +#if __OBJC2__ + #import #import @@ -39,7 +41,7 @@ typedef NS_ENUM(NSInteger, SFSQLiteSynchronousMode) { SFSQLiteSynchronousModeFull = 2 }; -@protocol SFSQLiteDelegate +@protocol SFSQLiteDelegate @property (nonatomic, readonly) SInt32 userVersion; - (BOOL)migrateDatabase:(SFSQLite *)db fromVersion:(SInt32)version; @@ -47,6 +49,7 @@ typedef NS_ENUM(NSInteger, SFSQLiteSynchronousMode) { // Wrapper around the SQLite API. Typically subclassed to add table accessor methods. @interface SFSQLite : NSObject { +@private id _delegate; NSString* _path; NSString* _schema; @@ -147,3 +150,5 @@ typedef NS_ENUM(NSInteger, SFSQLiteSynchronousMode) { - (SInt32)dbUserVersion; @end + +#endif diff --git a/Analytics/SQLite/SFSQLite.m b/Analytics/SQLite/SFSQLite.m index f83444e1..b7512c12 100644 --- a/Analytics/SQLite/SFSQLite.m +++ b/Analytics/SQLite/SFSQLite.m @@ -21,11 +21,14 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if __OBJC2__ + #import "SFSQLite.h" #import "SFSQLiteStatement.h" #include #include #import "debugging.h" +#include #define kSFSQLiteBusyTimeout (5*60*1000) @@ -292,13 +295,39 @@ allDone: // https://sqlite.org/pragma.html#pragma_auto_vacuum NSDate *lastVacuumDate = [NSDate dateWithTimeIntervalSinceReferenceDate:[[self propertyForKey:kSFSQLiteLastVacuumKey] floatValue]]; if ([lastVacuumDate timeIntervalSinceNow] < -(kCKSQLVacuumInterval)) { - [self executeSQL:@"VACUUM"]; - - NSString *vacuumDateString = [NSString stringWithFormat:@"%f", [[NSDate date] timeIntervalSinceReferenceDate]]; - [self setProperty:vacuumDateString forKey:kSFSQLiteLastVacuumKey]; + @autoreleasepool { + os_transaction_t transaction = os_transaction_create("SFSQLITE DB Vacuum"); + secnotice("SFSQLITE", "performing periodic vacuum"); + [self executeSQL:@"VACUUM"]; + (void)transaction; // dead store + + NSString *vacuumDateString = [NSString stringWithFormat:@"%f", [[NSDate date] timeIntervalSinceReferenceDate]]; + [self setProperty:vacuumDateString forKey:kSFSQLiteLastVacuumKey]; + } } } +/* + Best-effort attempts to set/correct filesystem permissions. + May fail when we don't own DB which means we must wait for them to update permissions, + or file does not exist yet which is okay because db will exist and the aux files inherit permissions +*/ +- (void)attemptProperDatabasePermissions +{ +#if TARGET_OS_IPHONE + NSFileManager* fm = [NSFileManager defaultManager]; + [fm setAttributes:@{NSFilePosixPermissions : [NSNumber numberWithShort:0666]} + ofItemAtPath:_path + error:nil]; + [fm setAttributes:@{NSFilePosixPermissions : [NSNumber numberWithShort:0666]} + ofItemAtPath:[NSString stringWithFormat:@"%@-wal",_path] + error:nil]; + [fm setAttributes:@{NSFilePosixPermissions : [NSNumber numberWithShort:0666]} + ofItemAtPath:[NSString stringWithFormat:@"%@-shm",_path] + error:nil]; +#endif +} + - (BOOL)openWithError:(NSError **)error { BOOL success = NO; NSError *localError; @@ -325,9 +354,13 @@ allDone: #endif int rc = sqlite3_open_v2([arcSafePath fileSystemRepresentation], &_db, flags, NULL); if (rc != SQLITE_OK) { - localError = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Error opening db at %@, rc=%d(0x%x)", _path, rc, rc]}]; + localError = [NSError errorWithDomain:NSCocoaErrorDomain code:rc userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Error opening db at %@, rc=%d(0x%x)", _path, rc, rc]}]; goto done; } + + // Filesystem foo for multiple daemons from different users + [self attemptProperDatabasePermissions]; + sqlite3_extended_result_codes(_db, 1); rc = sqlite3_busy_timeout(_db, kSFSQLiteBusyTimeout); if (rc != SQLITE_OK) { @@ -419,7 +452,7 @@ done: if (!success && error) { if (!localError) { - localError = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Error opening db at %@, ", _path]}]; + localError = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Error opening db at %@", _path]}]; } *error = localError; } @@ -428,7 +461,7 @@ done: - (void)open { NSError *error; - if (![self openWithError:&error]) { + if (![self openWithError:&error] && !(error && error.code == SQLITE_AUTH)) { secerror("sfsqlite: Error opening db at %@: %@", self.path, error); return; } @@ -515,7 +548,9 @@ done: } int execRet = sqlite3_exec(_db, [SQL UTF8String], NULL, NULL, NULL); if (execRet != SQLITE_OK) { - secerror("sfsqlite: Error executing SQL: \"%@\" (%d)", SQL, execRet); + if (execRet != SQLITE_AUTH && execRet != SQLITE_READONLY) { + secerror("sfsqlite: Error executing SQL: \"%@\" (%d)", SQL, execRet); + } return NO; } @@ -684,7 +719,7 @@ done: NSString *orderByString = [orderBy componentsJoinedByString:@", "]; [SQL appendFormat:@" order by %@", orderByString]; } - if (limit) { + if (limit != nil) { [SQL appendFormat:@" limit %ld", (long)limit.integerValue]; } @@ -721,7 +756,7 @@ done: NSString *orderByString = [orderBy componentsJoinedByString:@", "]; [SQL appendFormat:@" order by %@", orderByString]; } - if (limit) { + if (limit != nil) { [SQL appendFormat:@" limit %ld", (long)limit.integerValue]; } @@ -753,7 +788,7 @@ done: if (whereSQL.length) { [SQL appendFormat:@" where %@", whereSQL]; } - if (limit) { + if (limit != nil) { [SQL appendFormat:@" limit %ld", (long)limit.integerValue]; } @@ -779,7 +814,7 @@ done: if (whereSQL.length) { [SQL appendFormat:@" where %@", whereSQL]; } - if (limit) { + if (limit != nil) { [SQL appendFormat:@" limit %ld", (long)limit.integerValue]; } @@ -884,3 +919,5 @@ done: } @end + +#endif diff --git a/Analytics/SQLite/SFSQLiteStatement.h b/Analytics/SQLite/SFSQLiteStatement.h index 15ddb278..cdace807 100644 --- a/Analytics/SQLite/SFSQLiteStatement.h +++ b/Analytics/SQLite/SFSQLiteStatement.h @@ -21,6 +21,8 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if __OBJC2__ + #import #import @@ -70,3 +72,5 @@ - (NSDictionary *)allObjectsByColumnName; @end + +#endif diff --git a/Analytics/SQLite/SFSQLiteStatement.m b/Analytics/SQLite/SFSQLiteStatement.m index a142bc9f..bbc58697 100644 --- a/Analytics/SQLite/SFSQLiteStatement.m +++ b/Analytics/SQLite/SFSQLiteStatement.m @@ -21,6 +21,9 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if __OBJC2__ + +#import #import "SFSQLite.h" #import "SFSQLiteStatement.h" #import "SFObjCType.h" @@ -199,12 +202,8 @@ } } else { NSAssert(type.isFloatingPointNumber, @"Expected number type to be either integer or floating point"); - if (type.code == SFObjCTypeFloat) { - [self bindInt:[value intValue] atIndex:index]; - } else { - NSAssert(type.code == SFObjCTypeDouble, @"Unexpected floating point number type: %@", type); - [self bindInt64:[value longLongValue] atIndex:index]; - } + NSAssert(type.code == SFObjCTypeDouble || type.code == SFObjCTypeFloat, @"Unexpected floating point number type: %@", type); + [self bindDouble:[value doubleValue] atIndex:index]; } } else if ([value isKindOfClass:[NSData class]]) { [self bindBlob:value atIndex:index]; @@ -219,7 +218,7 @@ } else if ([value isKindOfClass:[NSDate class]]) { [self bindDouble:[(NSDate *)value timeIntervalSinceReferenceDate] atIndex:index]; } else if ([value isKindOfClass:[NSError class]]) { - [self bindBlob:[self retainedTemporaryBoundObject:[NSKeyedArchiver archivedDataWithRootObject:value]] atIndex:index]; + [self bindBlob:[self retainedTemporaryBoundObject:[NSKeyedArchiver archivedDataWithRootObject:value requiringSecureCoding:YES error:nil]] atIndex:index]; } else if ([value isKindOfClass:[NSURL class]]) { [self bindText:[self retainedTemporaryBoundObject:[value absoluteString]] atIndex:index]; } else { @@ -340,3 +339,5 @@ } @end + +#endif diff --git a/CSSMOID.exp-in b/CSSMOID.exp-in index 9704e53c..531b3558 100644 --- a/CSSMOID.exp-in +++ b/CSSMOID.exp-in @@ -8,6 +8,125 @@ _CSSMOID_ECDSA_WithSHA1 _CSSMOID_ECDSA_WithSHA256 _CSSMOID_ECDSA_WithSHA384 _CSSMOID_PKCS5_HMAC_SHA1 + +_CSSMOID_ANSI_DH_EPHEM +_CSSMOID_ANSI_DH_EPHEM_SHA1 +_CSSMOID_ANSI_DH_HYBRID1 +_CSSMOID_ANSI_DH_HYBRID1_SHA1 +_CSSMOID_ANSI_DH_HYBRID2 +_CSSMOID_ANSI_DH_HYBRID2_SHA1 +_CSSMOID_ANSI_DH_HYBRID_ONEFLOW +_CSSMOID_ANSI_DH_ONE_FLOW +_CSSMOID_ANSI_DH_ONE_FLOW_SHA1 +_CSSMOID_ANSI_DH_PUB_NUMBER +_CSSMOID_ANSI_DH_STATIC +_CSSMOID_ANSI_DH_STATIC_SHA1 +_CSSMOID_ANSI_MQV1 +_CSSMOID_ANSI_MQV1_SHA1 +_CSSMOID_ANSI_MQV2 +_CSSMOID_ANSI_MQV2_SHA1 +_CSSMOID_APPLE_ASC +_CSSMOID_APPLE_ECDSA +_CSSMOID_APPLE_FEE +_CSSMOID_APPLE_FEED +_CSSMOID_APPLE_FEEDEXP +_CSSMOID_APPLE_FEE_MD5 +_CSSMOID_APPLE_FEE_SHA1 +_CSSMOID_APPLE_ISIGN +_CSSMOID_APPLE_TP_APPLEID_SHARING +_CSSMOID_APPLE_TP_CODE_SIGN +_CSSMOID_APPLE_TP_CODE_SIGNING +_CSSMOID_APPLE_TP_CSR_GEN +_CSSMOID_APPLE_TP_EAP +_CSSMOID_APPLE_TP_ESCROW_SERVICE +_CSSMOID_APPLE_TP_ICHAT +_CSSMOID_APPLE_TP_IP_SEC +_CSSMOID_APPLE_TP_LOCAL_CERT_GEN +_CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT +_CSSMOID_APPLE_TP_MOBILE_STORE +_CSSMOID_APPLE_TP_PACKAGE_SIGNING +_CSSMOID_APPLE_TP_PASSBOOK_SIGNING +_CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE +_CSSMOID_APPLE_TP_PKINIT_CLIENT +_CSSMOID_APPLE_TP_PKINIT_SERVER +_CSSMOID_APPLE_TP_PROFILE_SIGNING +_CSSMOID_APPLE_TP_PROVISIONING_PROFILE_SIGNING +_CSSMOID_APPLE_TP_QA_PROFILE_SIGNING +_CSSMOID_APPLE_TP_RESOURCE_SIGN +_CSSMOID_APPLE_TP_REVOCATION +_CSSMOID_APPLE_TP_REVOCATION_CRL +_CSSMOID_APPLE_TP_REVOCATION_OCSP +_CSSMOID_APPLE_TP_SMIME +_CSSMOID_APPLE_TP_SSL +_CSSMOID_APPLE_TP_SW_UPDATE_SIGNING +_CSSMOID_APPLE_TP_TEST_MOBILE_STORE +_CSSMOID_APPLE_TP_TIMESTAMPING +_CSSMOID_APPLE_X509_BASIC +_CSSMOID_DES_CBC +_CSSMOID_DH +_CSSMOID_DOTMAC_CERT +_CSSMOID_DOTMAC_CERT_REQ +_CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_FETCH +_CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_LIST +_CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_REMOVE +_CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_STORE +_CSSMOID_DOTMAC_CERT_REQ_EMAIL_ENCRYPT +_CSSMOID_DOTMAC_CERT_REQ_EMAIL_SIGN +_CSSMOID_DOTMAC_CERT_REQ_IDENTITY +_CSSMOID_DOTMAC_CERT_REQ_SHARED_SERVICES +_CSSMOID_DOTMAC_CERT_REQ_VALUE_ASYNC +_CSSMOID_DOTMAC_CERT_REQ_VALUE_HOSTNAME +_CSSMOID_DOTMAC_CERT_REQ_VALUE_IS_PENDING +_CSSMOID_DOTMAC_CERT_REQ_VALUE_PASSWORD +_CSSMOID_DOTMAC_CERT_REQ_VALUE_RENEW +_CSSMOID_DOTMAC_CERT_REQ_VALUE_USERNAME +_CSSMOID_DSA +_CSSMOID_DSA_CMS +_CSSMOID_DSA_JDK +_CSSMOID_ECDSA_WithSHA224 +_CSSMOID_ECDSA_WithSHA512 +_CSSMOID_ECDSA_WithSpecified +_CSSMOID_MD2 +_CSSMOID_MD2WithRSA +_CSSMOID_MD4 +_CSSMOID_MD4WithRSA +_CSSMOID_MD5 +_CSSMOID_OAEP_ID_PSPECIFIED +_CSSMOID_OAEP_MGF1 +_CSSMOID_PKCS12_pbeWithSHAAnd128BitRC2CBC +_CSSMOID_PKCS12_pbeWithSHAAnd128BitRC4 +_CSSMOID_PKCS12_pbeWithSHAAnd2Key3DESCBC +_CSSMOID_PKCS12_pbeWithSHAAnd3Key3DESCBC +_CSSMOID_PKCS12_pbeWithSHAAnd40BitRC4 +_CSSMOID_PKCS12_pbewithSHAAnd40BitRC2CBC +_CSSMOID_PKCS3 +_CSSMOID_PKCS5_DES_EDE3_CBC +_CSSMOID_PKCS5_DIGEST_ALG +_CSSMOID_PKCS5_ENCRYPT_ALG +_CSSMOID_PKCS5_PBES2 +_CSSMOID_PKCS5_PBKDF2 +_CSSMOID_PKCS5_PBMAC1 +_CSSMOID_PKCS5_RC2_CBC +_CSSMOID_PKCS5_RC5_CBC +_CSSMOID_PKCS5_pbeWithMD2AndDES +_CSSMOID_PKCS5_pbeWithMD2AndRC2 +_CSSMOID_PKCS5_pbeWithMD5AndDES +_CSSMOID_PKCS5_pbeWithMD5AndRC2 +_CSSMOID_PKCS5_pbeWithSHA1AndDES +_CSSMOID_PKCS5_pbeWithSHA1AndRC2 +_CSSMOID_RSA +_CSSMOID_RSAWithOAEP +_CSSMOID_SHA1WithDSA +_CSSMOID_SHA1WithDSA_CMS +_CSSMOID_SHA1WithDSA_JDK +_CSSMOID_SHA1WithRSA_OIW +_CSSMOID_SHA224 +_CSSMOID_SHA224WithRSA +_CSSMOID_SHA256 +_CSSMOID_SHA384 +_CSSMOID_SHA512 +_CSSMOID_SHA512WithRSA +_CSSMOID_ecPublicKey #endif #if TARGET_OS_OSX @@ -109,6 +228,7 @@ _CSSMOID_EmailProtection _CSSMOID_EnhancedSearchGuide _CSSMOID_ExtendedCertificateAttributes _CSSMOID_ExtendedKeyUsage +_CSSMOID_InhibitAnyPolicy _CSSMOID_AuthorityInfoAccess _CSSMOID_BiometricInfo _CSSMOID_QC_Statements @@ -243,6 +363,7 @@ _CSSMOID_SHA256WithRSA _CSSMOID_SHA384WithRSA _CSSMOID_SHA512WithRSA _CSSMOID_SHA1WithRSA_OIW +_CSSMOID_DES_CBC _CSSMOID_RSAWithOAEP _CSSMOID_OAEP_MGF1 _CSSMOID_OAEP_ID_PSPECIFIED @@ -273,6 +394,7 @@ _CSSMOID_UnstructuredName _CSSMOID_UseExemptions _CSSMOID_UserCertificate _CSSMOID_UserID +_CSSMOID_DomainComponent _CSSMOID_UserPassword _CSSMOID_X509V1CRLIssuerNameCStruct _CSSMOID_X509V1CRLIssuerNameLDAP @@ -398,7 +520,12 @@ _CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE _CSSMOID_APPLE_EXTENSION_APPLEID_INTERMEDIATE _CSSMOID_APPLE_EXTENSION_APPLEID_SHARING _CSSMOID_APPLE_EXTENSION_SYSINT2_INTERMEDIATE +_CSSMOID_APPLE_EXTENSION_DEVELOPER_AUTHENTICATION +_CSSMOID_APPLE_EXTENSION_PROVISIONING_PROFILE_SIGNING +_CSSMOID_APPLE_EXTENSION_SERVER_AUTHENTICATION _CSSMOID_APPLE_EXTENSION_ESCROW_SERVICE +_CSSMOID_APPLE_TP_PCS_ESCROW_SERVICE +_CSSMOID_APPLE_TP_PROVISIONING_PROFILE_SIGNING _CSSMOID_PKIX_OCSP _CSSMOID_PKIX_OCSP_ARCHIVE_CUTOFF _CSSMOID_PKIX_OCSP_BASIC diff --git a/CircleJoinRequested/Applicant.m b/CircleJoinRequested/Applicant.m index 84ada23b..5cce5177 100644 --- a/CircleJoinRequested/Applicant.m +++ b/CircleJoinRequested/Applicant.m @@ -36,8 +36,8 @@ -(void)dealloc { - if (self.rawPeerInfo) { - CFRelease(self.rawPeerInfo); + if (self->_rawPeerInfo) { + CFRelease(self->_rawPeerInfo); } } diff --git a/CircleJoinRequested/CircleJoinRequested.m b/CircleJoinRequested/CircleJoinRequested.m index 19f2a4b6..4f6ed2e2 100644 --- a/CircleJoinRequested/CircleJoinRequested.m +++ b/CircleJoinRequested/CircleJoinRequested.m @@ -82,7 +82,7 @@ bool processApplicantsAfterUnlock = false; bool _unlockedSinceBoot = false; bool _hasPostedFollowupAndStillInError = false; bool _isAccountICDP = false; - +bool _executeProcessEventsOnce = false; NSString *castleKeychainUrl = @"prefs:root=APPLE_ACCOUNT&path=ICLOUD_SERVICE/com.apple.Dataclass.KeychainSync/ADVANCED"; NSString *rejoinICDPUrl = @"prefs:root=APPLE_ACCOUNT&aaaction=CDP&command=rejoin"; @@ -808,14 +808,17 @@ static bool processEvents() } }); state.lastCircleStatus = circleStatus; + _executeProcessEventsOnce = true; return false; } else if(circleStatus == kSOSCCInCircle){ secnotice("cjr", "follow up should be resolved"); + _executeProcessEventsOnce = true; _hasPostedFollowupAndStillInError = false; } else{ secnotice("cjr", "followup not resolved"); + _executeProcessEventsOnce = true; return false; } } @@ -1059,7 +1062,7 @@ int main (int argc, const char * argv[]) { }); int falseInARow = 0; - while (falseInARow < 2) { + while (falseInARow < 2 && !_executeProcessEventsOnce) { if (processEvents()) { secnotice("cjr", "Processed events!!!"); falseInARow = 0; diff --git a/KVSKeychainSyncingProxy/CKDKVSProxy.h b/KVSKeychainSyncingProxy/CKDKVSProxy.h index 23dc1994..a955f796 100644 --- a/KVSKeychainSyncingProxy/CKDKVSProxy.h +++ b/KVSKeychainSyncingProxy/CKDKVSProxy.h @@ -76,6 +76,9 @@ typedef void (^FreshnessResponseBlock)(bool success, NSError *err); @property (retain, nonatomic) NSMutableSet* shadowPendingSyncBackupPeerIDs; @property (atomic) bool ensurePeerRegistration; +@property (atomic) bool ensurePeerRegistrationEnqueuedButNotStarted; + +// Another version of ensurePeerRegistration due to legacy code structure @property (atomic) bool shadowEnsurePeerRegistration; @property (atomic) bool inCallout; diff --git a/KVSKeychainSyncingProxy/CKDKVSProxy.m b/KVSKeychainSyncingProxy/CKDKVSProxy.m index 9b74ef60..a9e8a776 100644 --- a/KVSKeychainSyncingProxy/CKDKVSProxy.m +++ b/KVSKeychainSyncingProxy/CKDKVSProxy.m @@ -617,9 +617,8 @@ const CFStringRef kSOSKVSOfficialDSIDKey = CFSTR("^OfficialDSID"); self->_ensurePeerRegistration = ((self->_ensurePeerRegistration && !handledEnsurePeerRegistration) || self->_shadowEnsurePeerRegistration); self->_shadowEnsurePeerRegistration = NO; - - if(self->_ensurePeerRegistration && ![self.lockMonitor locked]) - [self doEnsurePeerRegistration]; + + [self handlePendingEnsurePeerRegistrationRequests:true]; bool hadShadowPeerIDs = ![self->_shadowPendingSyncPeerIDs isEmpty] || ![self->_shadowPendingSyncBackupPeerIDs isEmpty]; @@ -666,8 +665,12 @@ const CFStringRef kSOSKVSOfficialDSIDKey = CFSTR("^OfficialDSID"); // Handle shadow pended stuff // We only kick off another sync if we got new stuff during handling - if (hadShadowPeerIDs && ![self.lockMonitor locked]) - [self newPeersToSyncWith]; + if (hadShadowPeerIDs && ![self.lockMonitor locked]) { + secnotice("event", "%@ syncWithPeersPending: %d inCallout: %d isLocked: %d", self, [self hasPendingSyncIDs], self->_inCallout, [self.lockMonitor locked]); + if ([self hasPendingSyncIDs] && !self->_inCallout && ![self.lockMonitor locked]){ + [self doSyncWithPendingPeers]; + } + } /* We don't want to call processKeyChangedEvent if we failed to handle pending keys and the device didn't unlock nor receive @@ -713,11 +716,28 @@ const CFStringRef kSOSKVSOfficialDSIDKey = CFSTR("^OfficialDSID"); }]; } +- (void)handlePendingEnsurePeerRegistrationRequests:(bool)onlyIfUnlocked +{ + // doEnsurePeerRegistration's callback will be run on _calloutQueue, so we should check the 'are we running yet' flags on that queue + dispatch_async(_calloutQueue, ^{ + if(self.ensurePeerRegistration && (!onlyIfUnlocked || ![self.lockMonitor locked])) { + if(self.ensurePeerRegistrationEnqueuedButNotStarted) { + secnotice("EnsurePeerRegistration", "%@ ensurePeerRegistration block already enqueued, not starting a new one", self); + return; + } + + [self doEnsurePeerRegistration]; + } + }); +} + - (void) doEnsurePeerRegistration { NSObject* accountDelegate = [self account]; + self.ensurePeerRegistrationEnqueuedButNotStarted = true; [self calloutWith:^(NSSet *pending, NSSet* pendingSyncIDs, NSSet* pendingBackupSyncIDs, bool ensurePeerRegistration, dispatch_queue_t queue, void(^done)(NSSet *handledKeys, NSSet *handledSyncs, bool handledEnsurePeerRegistration, NSError* error)) { NSError* error = nil; + self.ensurePeerRegistrationEnqueuedButNotStarted = false; bool handledEnsurePeerRegistration = [accountDelegate ensurePeerRegistration:&error]; secnotice("EnsurePeerRegistration", "%@ ensurePeerRegistration called, %@ (%@)", self, handledEnsurePeerRegistration ? @"success" : @"failure", error); if (!handledEnsurePeerRegistration) { @@ -766,17 +786,6 @@ const CFStringRef kSOSKVSOfficialDSIDKey = CFSTR("^OfficialDSID"); }]; } -- (void)newPeersToSyncWith -{ - secnotice("event", "%@ syncWithPeersPending: %d inCallout: %d isLocked: %d", self, [self hasPendingSyncIDs], _inCallout, [self.lockMonitor locked]); - if(_ensurePeerRegistration){ - [self doEnsurePeerRegistration]; - } - if ([self hasPendingSyncIDs] && !_inCallout && ![self.lockMonitor locked]){ - [self doSyncWithPendingPeers]; - } -} - - (bool)hasPendingNonShadowSyncIDs { return ![_pendingSyncPeerIDs isEmpty] || ![_pendingSyncBackupPeerIDs isEmpty]; } @@ -815,9 +824,8 @@ const CFStringRef kSOSKVSOfficialDSIDKey = CFSTR("^OfficialDSID"); [self persistState]; - if(_ensurePeerRegistration){ - [self doEnsurePeerRegistration]; - } + [self handlePendingEnsurePeerRegistrationRequests:true]; + if ([self hasPendingSyncIDs] && !_inCallout && ![self.lockMonitor locked]){ [self doSyncWithPendingPeers]; } @@ -843,9 +851,7 @@ const CFStringRef kSOSKVSOfficialDSIDKey = CFSTR("^OfficialDSID"); _shadowEnsurePeerRegistration = YES; } else { _ensurePeerRegistration = YES; - if (![self.lockMonitor locked]){ - [self doEnsurePeerRegistration]; - } + [self handlePendingEnsurePeerRegistrationRequests:true]; [self persistState]; } @@ -864,9 +870,7 @@ const CFStringRef kSOSKVSOfficialDSIDKey = CFSTR("^OfficialDSID"); dispatch_assert_queue(_ckdkvsproxy_queue); secnotice("event", "%@ Unlocked", self); - if (_ensurePeerRegistration) { - [self doEnsurePeerRegistration]; - } + [self handlePendingEnsurePeerRegistrationRequests:false]; // First send changed keys to securityd so it can proccess updates [self processPendingKeysForCurrentLockState]; diff --git a/KVSKeychainSyncingProxy/CKDKVSStore.m b/KVSKeychainSyncingProxy/CKDKVSStore.m index 89bdd329..03386203 100644 --- a/KVSKeychainSyncingProxy/CKDKVSStore.m +++ b/KVSKeychainSyncingProxy/CKDKVSStore.m @@ -17,6 +17,8 @@ #import "SyncedDefaults/SYDConstants.h" #include +#import "Analytics/Clients/SOSAnalytics.h" + struct CKDKVSCounters { uint64_t synchronize; uint64_t synchronizeWithCompletionHandler; @@ -32,7 +34,7 @@ struct CKDKVSCounters { @interface CKDKVSStore () @property (readwrite, weak) UbiqitousKVSProxy* proxy; @property (readwrite) NSUbiquitousKeyValueStore* cloudStore; -@property (assign,readwrite) struct CKDKVSCounters *perfCounters; +@property (assign,readwrite) struct CKDKVSCounters* perfCounters; @property dispatch_queue_t perfQueue; @end @@ -55,6 +57,7 @@ struct CKDKVSCounters { self.perfQueue = dispatch_queue_create("CKDKVSStorePerfQueue", NULL); self.perfCounters = calloc(1, sizeof(struct CKDKVSCounters)); + [self setupSamplers]; return self; } @@ -232,17 +235,41 @@ struct CKDKVSCounters { { dispatch_async(self.perfQueue, ^{ callback(@{ - @"CKDKVS-synchronize" : @(self.perfCounters->synchronize), - @"CKDKVS-synchronizeWithCompletionHandler" : @(self.perfCounters->synchronizeWithCompletionHandler), - @"CKDKVS-incomingMessages" : @(self.perfCounters->incomingMessages), - @"CKDKVS-outgoingMessages" : @(self.perfCounters->outgoingMessages), - @"CKDKVS-totalWaittimeSynchronize" : @(self.perfCounters->totalWaittimeSynchronize), - @"CKDKVS-longestWaittimeSynchronize" : @(self.perfCounters->longestWaittimeSynchronize), - @"CKDKVS-synchronizeFailures" : @(self.perfCounters->synchronizeFailures), + CKDKVSPerfCounterSynchronize : @(self.perfCounters->synchronize), + CKDKVSPerfCounterSynchronizeWithCompletionHandler : @(self.perfCounters->synchronizeWithCompletionHandler), + CKDKVSPerfCounterIncomingMessages : @(self.perfCounters->incomingMessages), + CKDKVSPerfCounterOutgoingMessages : @(self.perfCounters->outgoingMessages), + CKDKVSPerfCounterTotalWaitTimeSynchronize : @(self.perfCounters->totalWaittimeSynchronize), + CKDKVSPerfCounterLongestWaitTimeSynchronize : @(self.perfCounters->longestWaittimeSynchronize), + CKDKVSPerfCounterSynchronizeFailures : @(self.perfCounters->synchronizeFailures), }); }); } +#if __OBJC2__ +- (void)setupSamplers +{ + [[SOSAnalytics logger] AddMultiSamplerForName:CKDKVSPerformanceCountersSampler + withTimeInterval:SFAnalyticsSamplerIntervalOncePerReport + block:^NSDictionary *{ + __block NSDictionary* data; + [self perfCounters:^(NSDictionary *counters) { + data = counters; + }]; + + dispatch_sync(self.perfQueue, ^{ + memset(self.perfCounters, 0, sizeof(struct CKDKVSCounters)); + }); + return data; + }]; +} +#else +- (void)setupSamplers +{ + // SFA is only for 64 bit cool kids +} +#endif + - (void)addOneToOutGoing { dispatch_async(self.perfQueue, ^{ diff --git a/KVSKeychainSyncingProxy/CKDLockMonitor.h b/KVSKeychainSyncingProxy/CKDLockMonitor.h index 83ab5c29..36cf8e90 100644 --- a/KVSKeychainSyncingProxy/CKDLockMonitor.h +++ b/KVSKeychainSyncingProxy/CKDLockMonitor.h @@ -5,14 +5,14 @@ #import "CKDLockMonitor.h" -@protocol CKDLockListener +@protocol CKDLockListener - (void) unlocked; - (void) locked; @end -@protocol CKDLockMonitor +@protocol CKDLockMonitor @property (readonly) BOOL unlockedSinceBoot; @property (readonly) BOOL locked; diff --git a/KVSKeychainSyncingProxy/CKDStore.h b/KVSKeychainSyncingProxy/CKDStore.h index 46b8a031..ec68f709 100644 --- a/KVSKeychainSyncingProxy/CKDStore.h +++ b/KVSKeychainSyncingProxy/CKDStore.h @@ -8,7 +8,7 @@ @class UbiqitousKVSProxy; -@protocol CKDStore +@protocol CKDStore - (void)connectToProxy: (UbiqitousKVSProxy*) proxy; diff --git a/KVSKeychainSyncingProxy/XPCNotificationDispatcher.h b/KVSKeychainSyncingProxy/XPCNotificationDispatcher.h index 3fc9c4c4..6b1b6243 100644 --- a/KVSKeychainSyncingProxy/XPCNotificationDispatcher.h +++ b/KVSKeychainSyncingProxy/XPCNotificationDispatcher.h @@ -6,7 +6,7 @@ #import -@protocol XPCNotificationListener +@protocol XPCNotificationListener - (void) handleNotification: (const char *) name; @end diff --git a/KVSKeychainSyncingProxy/cloudkeychainproxy.m b/KVSKeychainSyncingProxy/cloudkeychainproxy.m index 29ea3024..ece3bb25 100644 --- a/KVSKeychainSyncingProxy/cloudkeychainproxy.m +++ b/KVSKeychainSyncingProxy/cloudkeychainproxy.m @@ -330,7 +330,6 @@ void finalize_connection(void *not_used) static bool operation_put_dictionary(xpc_object_t event) { // PUT a set of objects into the KVS store. Return false if error - describeXPCObject("operation_put_dictionary event: ", event); xpc_object_t xvalue = xpc_dictionary_get_value(event, kMessageKeyValue); if (!xvalue) { return false; @@ -349,9 +348,7 @@ static bool operation_put_dictionary(xpc_object_t event) static bool operation_get_v2(xpc_connection_t peer, xpc_object_t event) { - // GET a set of objects from the KVS store. Return false if error - describeXPCObject("operation_get_v2 event: ", event); - + // GET a set of objects from the KVS store. Return false if error xpc_object_t replyMessage = xpc_dictionary_create_reply(event); if (!replyMessage) { @@ -393,7 +390,6 @@ static bool operation_get_v2(xpc_connection_t peer, xpc_object_t event) secdebug(PROXYXPCSCOPE, "get: key: %@, object: %@", key, object); xpc_object_t xobject = object ? _CFXPCCreateXPCObjectFromCFObject((__bridge CFTypeRef)object) : xpc_null_create(); xpc_dictionary_set_value(returnedValues, [key UTF8String], xobject); - describeXPCObject("operation_get_v2: value from kvs: ", xobject); }]; } else // get all values from kvs @@ -425,8 +421,6 @@ static void cloudkeychainproxy_event_handler(xpc_connection_t peer) xpc_connection_set_target_queue(peer, [SharedProxy() ckdkvsproxy_queue]); xpc_connection_set_event_handler(peer, ^(xpc_object_t event) { - describeXPCObject("peer: ", peer); // Only describes under debug - // We could handle other peer events (e.g.) disconnects, // but we don't keep per-client state so there is no need. if (xpc_get_type(event) == XPC_TYPE_DICTIONARY) { diff --git a/KeychainCircle/KCJoiningAcceptSession.m b/KeychainCircle/KCJoiningAcceptSession.m index ec8b8b90..3c216c0b 100644 --- a/KeychainCircle/KCJoiningAcceptSession.m +++ b/KeychainCircle/KCJoiningAcceptSession.m @@ -210,15 +210,26 @@ typedef enum { } NSData* joinData = [self.circleDelegate circleJoinDataFor:ref error:error]; + if(ref) { + CFRelease(ref); + ref = NULL; + } + if (joinData == nil) return nil; if(self->_piggy_version == kPiggyV1){ - //grab iCloud Identity, TLK, BackupV0 thing + //grab iCloud Identities, TLKs secnotice("acceptor", "piggy version is 1"); - NSData* initialSyncData = [self.circleDelegate circleGetInitialSyncViews:error]; + NSError *localV1Error = nil; + NSData* initialSyncData = [self.circleDelegate circleGetInitialSyncViews:&localV1Error]; + if(localV1Error){ + secnotice("piggy", "PB v1 threw an error: %@", localV1Error); + } + NSMutableData* growPacket = [[NSMutableData alloc] initWithData:joinData]; [growPacket appendData:initialSyncData]; joinData = growPacket; + } NSData* encryptedOutgoing = [self.session encrypt:joinData error:error]; diff --git a/KeychainCircle/KCJoiningRequestSession.m b/KeychainCircle/KCJoiningRequestSession.m index 731a11c8..e3be618e 100644 --- a/KeychainCircle/KCJoiningRequestSession.m +++ b/KeychainCircle/KCJoiningRequestSession.m @@ -308,6 +308,10 @@ static const uint64_t KCProtocolVersion = kPiggyV1; if (us == NULL) return nil; CFErrorRef cfError = NULL; NSData* piEncoded = (__bridge_transfer NSData*) SOSPeerInfoCopyEncodedData(us, NULL, &cfError); + if(us) { + CFRelease(us); + us = NULL; + } if (piEncoded == nil) { if (error != nil) { diff --git a/KeychainCircle/KCJoiningSession.h b/KeychainCircle/KCJoiningSession.h index 5c251ed5..2eb96b16 100644 --- a/KeychainCircle/KCJoiningSession.h +++ b/KeychainCircle/KCJoiningSession.h @@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN -@protocol KCJoiningRequestCircleDelegate +@protocol KCJoiningRequestCircleDelegate /*! Get this devices peer info (As Application) @@ -34,7 +34,7 @@ NS_ASSUME_NONNULL_BEGIN @end -@protocol KCJoiningRequestSecretDelegate +@protocol KCJoiningRequestSecretDelegate /*! Get the shared secret for this session. Not called during creation or initialMessage: to allow the initial message to be sent before @@ -108,7 +108,7 @@ NS_ASSUME_NONNULL_BEGIN @end -@protocol KCJoiningAcceptCircleDelegate +@protocol KCJoiningAcceptCircleDelegate /*! Handle the request's peer info and get the blob they can use to get in circle @param peer @@ -137,7 +137,7 @@ typedef enum { kKCRetryWithNewChallenge } KCRetryOrNot; -@protocol KCJoiningAcceptSecretDelegate +@protocol KCJoiningAcceptSecretDelegate /*! Get the shared secret for this session @result diff --git a/KeychainCircle/PairingChannel.m b/KeychainCircle/PairingChannel.m index 7d353e57..b1160b75 100644 --- a/KeychainCircle/PairingChannel.m +++ b/KeychainCircle/PairingChannel.m @@ -11,6 +11,7 @@ #import #import #import +#import #import #if TARGET_OS_EMBEDDED @@ -402,16 +403,9 @@ const compression_algorithm pairingCompression = COMPRESSION_LZFSE; if (self.connection) return true; - xpc_endpoint_t endpoint = _SecSecuritydCopySOSStatusEndpoint(NULL); - if (endpoint == NULL) - return false; - NSXPCInterface *interface = [NSXPCInterface interfaceWithProtocol:@protocol(SOSControlProtocol)]; - NSXPCListenerEndpoint *listenerEndpoint = [[NSXPCListenerEndpoint alloc] init]; - - [listenerEndpoint _setEndpoint:endpoint]; - self.connection = [[NSXPCConnection alloc] initWithListenerEndpoint:listenerEndpoint]; + self.connection = [[NSXPCConnection alloc] initWithMachServiceName:@(kSecuritydSOSServiceName) options:0]; if (self.connection == NULL) return false; diff --git a/KeychainCircle/Tests/KCAESGCMTest.m b/KeychainCircle/Tests/KCAESGCMTest.m index 708a53a7..602e5afb 100644 --- a/KeychainCircle/Tests/KCAESGCMTest.m +++ b/KeychainCircle/Tests/KCAESGCMTest.m @@ -8,6 +8,7 @@ #import #import +#import @interface KCAESGCMTest : XCTestCase @@ -66,13 +67,10 @@ } - (KCAESGCMDuplexSession*) archiveDearchive: (KCAESGCMDuplexSession*) original { - NSMutableData *data = [NSMutableData data]; - NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; [archiver encodeObject:original forKey:@"Top"]; - [archiver finishEncoding]; - NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; - unarchiver.requiresSecureCoding = YES; + NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:archiver.encodedData error:nil]; // Customize the unarchiver. KCAESGCMDuplexSession *result = [unarchiver decodeObjectForKey:@"Top"]; diff --git a/KeychainCircle/Tests/KCJoiningSessionTest.m b/KeychainCircle/Tests/KCJoiningSessionTest.m index 7a437f07..6d1d06db 100644 --- a/KeychainCircle/Tests/KCJoiningSessionTest.m +++ b/KeychainCircle/Tests/KCJoiningSessionTest.m @@ -82,6 +82,12 @@ static SecKeyRef GenerateFullECKey(int keySize, NSError** error) { @implementation KCJoiningRequestTestDelegate +- (void)dealloc { + if(_peerInfo) { + CFRelease(_peerInfo); + } +} + + (id) requestDelegateWithSecret:(NSString*) secret { return [[KCJoiningRequestTestDelegate alloc] initWithSecret:secret incorrectSecret:@"" @@ -106,10 +112,14 @@ static SecKeyRef GenerateFullECKey(int keySize, NSError** error) { SecKeyRef octagonSigningKey = GenerateFullECKey(384, NULL); SecKeyRef octagonEncryptionKey = GenerateFullECKey(384, NULL); - self.peerInfo = SOSPeerInfoCreate(NULL, (__bridge CFDictionaryRef) @{(__bridge NSString*)kPIUserDefinedDeviceNameKey:@"Fakey"}, NULL, signingKey, octagonSigningKey, octagonEncryptionKey, NULL); + SOSPeerInfoRef newPeerInfo = SOSPeerInfoCreate(NULL, (__bridge CFDictionaryRef) @{(__bridge NSString*)kPIUserDefinedDeviceNameKey:@"Fakey"}, NULL, signingKey, octagonSigningKey, octagonEncryptionKey, NULL); - if (self.peerInfo == NULL) + if (newPeerInfo == NULL) { return nil; + } + self.peerInfo = newPeerInfo; + CFRelease(newPeerInfo); + newPeerInfo = NULL; self.sharedSecret = secret; self.incorrectSecret = incorrectSecret; @@ -135,7 +145,11 @@ static SecKeyRef GenerateFullECKey(int keySize, NSError** error) { } - (SOSPeerInfoRef) copyPeerInfoError: (NSError**) error { - return self.peerInfo; + if(!self.peerInfo) { + return NULL; + } + + return (SOSPeerInfoRef) CFRetain(self.peerInfo); } - (bool) processCircleJoinData: (NSData*) circleJoinData version:(PiggyBackProtocolVersion)version error: (NSError**)error { diff --git a/KeychainCircle/Tests/KCPairingTest.m b/KeychainCircle/Tests/KCPairingTest.m index 7e106ada..19694e48 100644 --- a/KeychainCircle/Tests/KCPairingTest.m +++ b/KeychainCircle/Tests/KCPairingTest.m @@ -289,6 +289,10 @@ abort(); signature = SOSCircleCopyNextGenSignatureWithPeerAdded(prunedCircle, applicant, _deviceKey, &error); + if(applicant) { + CFRelease(applicant); + applicant = NULL; + } NSData *pbblob = CFBridgingRelease(SOSPiggyBackBlobCopyEncodedData(gencount, _deviceKey, signature, &error)); @@ -343,8 +347,6 @@ // intentionally left blank // these are used by the security/2 tool and are only declared here to make the compiler happy about conforming the protocol we shoved the methods into } - - @end @implementation KCPairingTest diff --git a/KeychainSyncAccountNotification/KeychainSyncAccountNotification.m b/KeychainSyncAccountNotification/KeychainSyncAccountNotification.m index 2aeb9955..09cbfb96 100644 --- a/KeychainSyncAccountNotification/KeychainSyncAccountNotification.m +++ b/KeychainSyncAccountNotification/KeychainSyncAccountNotification.m @@ -13,9 +13,37 @@ #endif #import #import - +#if OCTAGON +#import +#include +#endif #import "utilities/debugging.h" +#if OCTAGON + +static bool SecOTIsEnabled(void) +{ + bool userDefaultsShouldBottledPeer = true; + CFBooleanRef enabled = (CFBooleanRef)CFPreferencesCopyValue(CFSTR("EnableOTRestore"), + CFSTR("com.apple.security"), + kCFPreferencesAnyUser, kCFPreferencesAnyHost); + if(enabled && CFGetTypeID(enabled) == CFBooleanGetTypeID()){ + if(enabled == kCFBooleanFalse){ + secnotice("octagon", "Octagon Restore Disabled"); + userDefaultsShouldBottledPeer = false; + } + if(enabled == kCFBooleanTrue){ + secnotice("octagon", "Octagon Restore Enabled"); + userDefaultsShouldBottledPeer = true; + } + } + + CFReleaseNull(enabled); + return userDefaultsShouldBottledPeer; +} + +#endif + @implementation KeychainSyncAccountNotification - (bool)accountIsPrimary:(ACAccount *)account @@ -31,6 +59,39 @@ NSString* oldAccountIdentifier = oldAccount.identifier; NSString* accountIdentifier = account.identifier; + if((changeType == kACAccountChangeTypeAdded) && + [account.accountType.identifier isEqualToString: ACAccountTypeIdentifierAppleAccount] && + [self accountIsPrimary:account]) { +#if OCTAGON + if(SecOTIsEnabled()){ + __block NSError* error = nil; + NSString *dsid = account.accountProperties[@"personID"]; + OTControl* otcontrol = [OTControl controlObject:&error]; + + if (nil == otcontrol) { + secerror("octagon: Failed to get OTControl: %@", error.localizedDescription); + } else { + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [otcontrol signIn:dsid reply:^(BOOL result, NSError * _Nullable signedInError) { + if(!result || signedInError){ + secerror("octagon: error signing in: %s", [[signedInError description] UTF8String]); + } + else{ + secnotice("octagon", "signed into octagon trust"); + } + dispatch_semaphore_signal(sema); + + }]; + if (0 != dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60 * 5))) { + secerror("octagon: Timed out signing in"); + } + } + }else{ + secerror("Octagon not enabled!"); + } +#endif + } if ((changeType == kACAccountChangeTypeDeleted) && [oldAccount.accountType.identifier isEqualToString:ACAccountTypeIdentifierAppleAccount]) { if(oldAccountIdentifier != NULL && oldAccount.username !=NULL) { if ([self accountIsPrimary:oldAccount]) { @@ -41,6 +102,34 @@ if (!SOSCCLoggedOutOfAccount(&removalError)) { secerror("Account %@ could not leave the SOS circle: %@", oldAccountIdentifier, removalError); } +#if OCTAGON + if(SecOTIsEnabled()){ + __block NSError* error = nil; + OTControl* otcontrol = [OTControl controlObject:&error]; + + if (nil == otcontrol) { + secerror("octagon: Failed to get OTControl: %@", error.localizedDescription); + } else { + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [otcontrol signOut:^(BOOL result, NSError * _Nullable signedOutError) { + if(!result || signedOutError){ + secerror("octagon: error signing out: %s", [[signedOutError description] UTF8String]); + } + else{ + secnotice("octagon", "signed out of octagon trust"); + } + dispatch_semaphore_signal(sema); + }]; + if (0 != dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60 * 5))) { + secerror("octagon: Timed out signing out"); + } + } + } + else{ + secerror("Octagon not enabled!"); + } +#endif } else { secinfo("accounts", "NOT performing SOS circle credential removal for secondary account %@: %@", accountIdentifier, account.username); } diff --git a/KeychainSyncingOverIDSProxy/IDSProxy.h b/KeychainSyncingOverIDSProxy/IDSProxy.h index 9985fe04..ec09a8fe 100644 --- a/KeychainSyncingOverIDSProxy/IDSProxy.h +++ b/KeychainSyncingOverIDSProxy/IDSProxy.h @@ -56,10 +56,7 @@ typedef enum { // Only touch these three dictionaries from the dataQueue or you will crash, eventually. @property (retain, nonatomic) NSMutableDictionary *messagesInFlight; @property (retain, nonatomic) NSMutableDictionary *unhandledMessageBuffer; -@property (retain, nonatomic) NSMutableDictionary *monitor; - -@property (retain, nonatomic) NSArray* listOfDevices; - +@property (retain, nonatomic) NSMutableDictionary *monitor; @property (atomic) dispatch_source_t penaltyTimer; @property (atomic) bool penaltyTimerScheduled; @property (retain, atomic) NSDictionary *queuedMessages; @@ -68,6 +65,10 @@ typedef enum { @property (atomic) NSInteger outgoingMessages; @property (atomic) NSInteger incomingMessages; + + + + @property (atomic) bool isIDSInitDone; @property (atomic) bool shadowDoInitializeIDSService; @property (atomic) bool isSecDRunningAsRoot; @@ -88,6 +89,7 @@ typedef enum { @property (atomic) bool handleAllPendingMessages; @property (atomic) bool shadowHandleAllPendingMessages; @property (atomic) bool sendRestoredMessages; +@property (atomic) bool allowKVSFallBack; + (KeychainSyncingOverIDSProxy *) idsProxy; @@ -109,7 +111,11 @@ typedef enum { - (NSDictionary*) collectStats; - (void) scheduleRetryRequestTimer; - (BOOL) haveMessagesInFlight; +-(void) printMessage:(NSDictionary*) message state:(NSString*)state; + @end NSString* createErrorString(NSString* format, ...) NS_FORMAT_FUNCTION(1, 2); + + diff --git a/KeychainSyncingOverIDSProxy/IDSProxy.m b/KeychainSyncingOverIDSProxy/IDSProxy.m index c6cbe5bb..0f09c6e9 100644 --- a/KeychainSyncingOverIDSProxy/IDSProxy.m +++ b/KeychainSyncingOverIDSProxy/IDSProxy.m @@ -56,6 +56,8 @@ static NSString *kExportUnhandledMessages = @"UnhandledMessages"; static NSString *kMessagesInFlight = @"MessagesInFlight"; static const char *kStreamName = "com.apple.notifyd.matching"; static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; +static NSString *const kIDSNumberOfFragments = @"NumberOfIDSMessageFragments"; +static NSString *const kIDSFragmentIndex = @"kFragmentIndex"; static NSString *const kOutgoingMessages = @"IDS Outgoing Messages"; static NSString *const kIncomingMessages = @"IDS Incoming Messages"; @@ -169,7 +171,7 @@ CFIndex SECD_RUN_AS_ROOT_ERROR = 1041; NSString *peerID = (NSString*)[idsMessage objectForKey:(__bridge NSString*)kIDSMessageRecipientPeerID]; NSString *ID = (NSString*)[idsMessage objectForKey:(__bridge NSString*)kIDSMessageRecipientDeviceID]; - + NSString *senderDeviceID = (NSString*)[idsMessage objectForKey:(__bridge NSString*)kIDSMessageSenderDeviceID]; dispatch_sync(self.dataQueue, ^{ [self.messagesInFlight removeObjectForKey:key]; }); @@ -177,10 +179,11 @@ CFIndex SECD_RUN_AS_ROOT_ERROR = 1041; if (!peerID || !ID) { return; } - secnotice("IDS Transport", "sending this message: %@", idsMessage); - if([self sendIDSMessage:idsMessage name:ID peer:peerID]){ + [self printMessage:idsMessage state:@"sending persisted message"]; + + if([self sendIDSMessage:idsMessage name:ID peer:peerID senderDeviceID:senderDeviceID]){ NSString *useAckModel = [idsMessage objectForKey:kIDSMessageUseACKModel]; - if([useAckModel compare:@"YES"] == NSOrderedSame){ + if([useAckModel compare:@"YES"] == NSOrderedSame && [KeychainSyncingOverIDSProxy idsProxy].allowKVSFallBack){ secnotice("IDS Transport", "setting timer!"); [self setMessageTimer:uniqueMessageID deviceID:ID message:idsMessage]; } @@ -204,11 +207,11 @@ CFIndex SECD_RUN_AS_ROOT_ERROR = 1041; deviceIDFromAuthToken = [[NSMutableDictionary alloc] init]; _peerNextSendCache = [[NSMutableDictionary alloc] init]; _counterValues = [[NSMutableDictionary alloc] init]; - _listOfDevices = [[NSMutableArray alloc] init]; _outgoingMessages = 0; _incomingMessages = 0; _isSecDRunningAsRoot = false; _doesSecDHavePeer = true; + _allowKVSFallBack = true; secdebug(IDSPROXYSCOPE, "%@ done", self); [self doIDSInitialization]; @@ -388,15 +391,6 @@ CFIndex SECD_RUN_AS_ROOT_ERROR = 1041; self->_isIDSInitDone = true; if(self->_isSecDRunningAsRoot == false) [self doSetIDSDeviceID]; - - NSArray *ListOfIDSDevices = [self->_service devices]; - self.listOfDevices = ListOfIDSDevices; - - for(NSUInteger i = 0; i < [ self.listOfDevices count ]; i++){ - IDSDevice *device = self.listOfDevices[i]; - NSString *authToken = IDSCopyIDForDevice(device); - [self.deviceIDFromAuthToken setObject:device.uniqueID forKey:authToken]; - } } }); } @@ -554,5 +548,16 @@ NSString* createErrorString(NSString* format, ...) return _counterValues; } +-(void) printMessage:(NSDictionary*) message state:(NSString*)state +{ + secnotice("IDS Transport", "message state: %@", state); + secnotice("IDS Transport", "msg id: %@", message[(__bridge NSString*)kIDSMessageUniqueID]); + secnotice("IDS Transport", "receiver ids device id: %@", message[(__bridge NSString*)kIDSMessageRecipientDeviceID]); + secnotice("IDS Transport", "sender device id: %@", message[(__bridge NSString*)kIDSMessageSenderDeviceID]); + secnotice("IDS Transport", "receiver peer id: %@", message[(__bridge NSString*)kIDSMessageRecipientPeerID]); + secnotice("IDS Transport", "fragment index: %@", (NSNumber*)message[kIDSFragmentIndex]); + secnotice("IDS Transport", "total number of fragments: %@", (NSNumber*)message[kIDSNumberOfFragments]); + secnotice("IDS Transport", "%@ data: %@", state, message[(__bridge NSString*)kIDSMessageToSendKey]); +} @end diff --git a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.h b/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.h index 297e4e47..1a2f70a0 100644 --- a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.h +++ b/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.h @@ -29,7 +29,7 @@ -(BOOL) checkForFragmentation:(NSDictionary*)message id:(NSString*)fromID data:(NSData*)messageData; -(NSMutableDictionary*) combineMessage:(NSString*)deviceID peerID:(NSString*)peerID uuid:(NSString*)uuid; - (void)service:(IDSService *)service account:(IDSAccount *)account incomingMessage:(NSDictionary *)message fromID:(NSString *)fromID context:(IDSMessageContext *)context; -- (void)sendMessageToSecurity:(NSMutableDictionary*)messageAndFromID fromID:(NSString*)fromID; +-(void)sendMessageToSecurity:(NSMutableDictionary*)messageAndFromID fromID:(NSString*)fromID shouldSendAck:(NSString *)useAck peerID:(NSString*)peerID messageID:(NSString*)messageID deviceID:(NSString*)deviceID; - (void) handleAllPendingMessage; @end diff --git a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.m b/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.m index 05d2f626..d3e0317a 100644 --- a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.m +++ b/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+ReceiveMessage.m @@ -49,14 +49,15 @@ #import "KeychainSyncingOverIDSProxy+SendMessage.h" #import "IDSProxy.h" + static NSString *const kIDSNumberOfFragments = @"NumberOfIDSMessageFragments"; static NSString *const kIDSFragmentIndex = @"kFragmentIndex"; static NSString *const kIDSMessageRecipientID = @"RecipientPeerID"; static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; +static NSString *const kIDSMessageSendersDeviceID = @"SendersDeviceID"; @implementation KeychainSyncingOverIDSProxy (ReceiveMessage) - -(int) countNumberOfValidObjects:(NSMutableArray*)fragmentsForDeviceID { __block int count = 0; @@ -71,19 +72,19 @@ static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; -(BOOL) checkForFragmentation:(NSDictionary*)message id:(NSString*)fromID data:(NSData*)messageData { BOOL handOffMessage = false; - + if([message valueForKey:kIDSNumberOfFragments] != nil){ NSNumber *idsNumberOfFragments = [message objectForKey:kIDSNumberOfFragments]; NSNumber *index = [message objectForKey:kIDSFragmentIndex]; NSString *uuidString = [message objectForKey:(__bridge NSString*)kIDSMessageUniqueID]; - + if([KeychainSyncingOverIDSProxy idsProxy].allFragmentedMessages == nil) [KeychainSyncingOverIDSProxy idsProxy].allFragmentedMessages = [NSMutableDictionary dictionary]; - + NSMutableDictionary *uniqueMessages = [[KeychainSyncingOverIDSProxy idsProxy].allFragmentedMessages objectForKey: fromID]; if(uniqueMessages == nil) uniqueMessages = [NSMutableDictionary dictionary]; - + NSMutableArray *fragmentsForDeviceID = [uniqueMessages objectForKey: uuidString]; if(fragmentsForDeviceID == nil){ fragmentsForDeviceID = [ [NSMutableArray alloc] initWithCapacity: [idsNumberOfFragments longValue]]; @@ -91,22 +92,22 @@ static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; [fragmentsForDeviceID addObject:[NSNull null]]; } } - + [fragmentsForDeviceID replaceObjectAtIndex: [index intValue] withObject:messageData ]; [uniqueMessages setObject: fragmentsForDeviceID forKey:uuidString]; [[KeychainSyncingOverIDSProxy idsProxy].allFragmentedMessages setObject:uniqueMessages forKey: fromID]; - + if([self countNumberOfValidObjects:fragmentsForDeviceID] == [idsNumberOfFragments longValue]) handOffMessage = true; else handOffMessage = false; - + } else //no fragmentation in the message, ready to hand off to securityd handOffMessage = true; - + return handOffMessage; - + } -(NSMutableDictionary*) combineMessage:(NSString*)ID peerID:(NSString*)peerID uuid:(NSString*)uuid @@ -114,7 +115,7 @@ static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; NSString *dataKey = [ NSString stringWithUTF8String: kMessageKeyIDSDataMessage ]; NSString *deviceIDKey = [ NSString stringWithUTF8String: kMessageKeyDeviceID ]; NSString *peerIDKey = [ NSString stringWithUTF8String: kMessageKeyPeerID ]; - + NSMutableDictionary *arrayOfFragmentedMessagesByUUID = [[KeychainSyncingOverIDSProxy idsProxy].allFragmentedMessages objectForKey:ID]; NSMutableArray *messagesForUUID = [arrayOfFragmentedMessagesByUUID objectForKey:uuid]; NSMutableData* completeMessage = [NSMutableData data]; @@ -127,7 +128,7 @@ static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; //we've combined the message, now remove it from the fragmented messages dictionary [arrayOfFragmentedMessagesByUUID removeObjectForKey:uuid]; - return [NSMutableDictionary dictionaryWithObjectsAndKeys: completeMessage, dataKey, deviceID, deviceIDKey, peerID, peerIDKey, nil]; + return [NSMutableDictionary dictionaryWithObjectsAndKeys: completeMessage, dataKey, ID, deviceIDKey, peerID, peerIDKey, nil]; } -(void) handleTestMessage:(NSString*)operation id:(NSString*)ID messageID:(NSString*)uniqueID senderPeerID:(NSString*)senderPeerID @@ -168,7 +169,7 @@ static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; NSDictionary* messsageDictionary = @{(__bridge NSString*)kIDSOperationType:operationString, (__bridge NSString*)kIDSMessageToSendKey:messageString}; // We can always hold on to a message and our remote peers would bother everyone - [self sendIDSMessage:messsageDictionary name:ID peer:@"me"]; + [self sendIDSMessage:messsageDictionary name:ID peer:@"me" senderDeviceID:NULL]; free(messageCharS); @@ -207,7 +208,7 @@ static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; } } -- (void)sendACK:(NSString*)ID peerID:(NSString*)sendersPeerID uniqueID:(NSString*)uniqueID +- (void)sendACK:(NSString*)ID peerID:(NSString*)sendersPeerID uniqueID:(NSString*)uniqueID senderDeviceID:(NSString*)senderDeviceID { char* messageCharS; NSString* messageString = @"ACK"; @@ -217,7 +218,7 @@ static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; NSDictionary* messageDictionary = @{(__bridge NSString*)kIDSOperationType:operationString, (__bridge NSString*)kIDSMessageToSendKey:messageString, (__bridge NSString*)kIDSMessageUniqueID:uniqueID}; - [self sendIDSMessage:messageDictionary name:ID peer:sendersPeerID]; + [self sendIDSMessage:messageDictionary name:ID peer:sendersPeerID senderDeviceID:senderDeviceID]; free(messageCharS); @@ -249,23 +250,26 @@ static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; NSString* operationTypeAsString = nil; NSMutableDictionary *messageDictionary = nil; NSString *useAck = nil; - NSString *ID = nil; + NSString *senderDeviceID = nil; NSArray *devices = [self->_service devices]; for(NSUInteger i = 0; i < [ devices count ]; i++){ IDSDevice *device = devices[i]; if( [(IDSCopyIDForDevice(device)) containsString: fromID] == YES){ - ID = device.uniqueID; + senderDeviceID = device.uniqueID; break; } } - secnotice("IDS Transport", "Received message from: %@: %@ ", ID, message); + [[KeychainSyncingOverIDSProxy idsProxy] printMessage:message state:[NSString stringWithFormat:@"received message from: %@", senderDeviceID]]; NSString *sendersPeerID = [message objectForKey: sendersPeerIDKey]; if(sendersPeerID == nil) sendersPeerID = [NSString string]; - - - require_action_quiet(ID, fail, hadError = true; errorMessage = CFSTR("require the sender's device ID")); + + if(!senderDeviceID){ + senderDeviceID = message[kIDSMessageSendersDeviceID]; + secnotice("IDS Transport", "Their device ID!: %@", senderDeviceID); + } + require_action_quiet(senderDeviceID, fail, hadError = true; errorMessage = CFSTR("require the sender's device ID")); operationTypeAsString = [message objectForKey: (__bridge NSString*)kIDSOperationType]; messageDictionary = [message objectForKey: (__bridge NSString*)kIDSMessageToSendKey]; @@ -276,12 +280,12 @@ static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; if(useAck != nil && [useAck compare:@"YES"] == NSOrderedSame) require_quiet(messageID != nil, fail); - secnotice("IDS Transport","from peer %@, operation type as string: %@, as integer: %d", ID, operationTypeAsString, [operationTypeAsString intValue]); + secnotice("IDS Transport","from peer %@, operation: %@", senderDeviceID, operationTypeAsString); operationType = [operationTypeAsString intValue]; if(operationType != kIDSKeychainSyncIDSFragmentation) { - [self handleTestMessage:operationTypeAsString id:ID messageID:messageID senderPeerID:sendersPeerID]; + [self handleTestMessage:operationTypeAsString id:senderDeviceID messageID:messageID senderPeerID:sendersPeerID]; } else{ @@ -289,20 +293,19 @@ static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; myPeerID = (NSString*)key; messageData = (NSData*)obj; }]; - - if(useAck != nil && [useAck compare:@"YES"] == NSOrderedSame) - [self sendACK:ID peerID:myPeerID uniqueID:messageID]; - - BOOL readyToHandOffToSecD = [self checkForFragmentation:message id:ID data:messageData]; + + BOOL readyToHandOffToSecD = [self checkForFragmentation:message id:senderDeviceID data:messageData]; NSMutableDictionary *messageAndFromID = nil; if(readyToHandOffToSecD && ([message objectForKey:kIDSFragmentIndex])!= nil){ + secnotice("IDS Transport", "combing message"); NSString* uuid = [message objectForKey:(__bridge NSString*)kIDSMessageUniqueID]; - messageAndFromID = [self combineMessage:ID peerID:myPeerID uuid:uuid]; + messageAndFromID = [self combineMessage:senderDeviceID peerID:myPeerID uuid:uuid]; + //update next sequence number } else if(readyToHandOffToSecD){ - messageAndFromID = [NSMutableDictionary dictionaryWithObjectsAndKeys: messageData, dataKey, ID, deviceIDKey, myPeerID, peerIDKey, nil]; + messageAndFromID = [NSMutableDictionary dictionaryWithObjectsAndKeys: messageData, dataKey, senderDeviceID, deviceIDKey, myPeerID, peerIDKey, nil]; } else return; @@ -316,8 +319,10 @@ static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; [self.unhandledMessageBuffer setObject: messageAndFromID forKey: fromID]; }); } - else - [self sendMessageToSecurity:messageAndFromID fromID:fromID]; + else{ + [self sendMessageToSecurity:messageAndFromID fromID:fromID shouldSendAck:useAck peerID:myPeerID messageID:messageID deviceID:senderDeviceID]; + + } } fail: @@ -347,7 +352,7 @@ static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; dispatch_sync(self.dataQueue, ^{ [self.unhandledMessageBuffer removeObjectForKey: fromID]; }); - [self sendMessageToSecurity:messageAndFromID fromID:fromID]; + [self sendMessageToSecurity:messageAndFromID fromID:fromID shouldSendAck:nil peerID:nil messageID:nil deviceID:nil]; }]; } @@ -365,7 +370,7 @@ static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; return true; } --(void)sendMessageToSecurity:(NSMutableDictionary*)messageAndFromID fromID:(NSString*)fromID +-(void)sendMessageToSecurity:(NSMutableDictionary*)messageAndFromID fromID:(NSString*)fromID shouldSendAck:(NSString *)useAck peerID:(NSString*)peerID messageID:(NSString*)messageID deviceID:(NSString*)senderDeviceID { __block CFErrorRef cf_error = NULL; __block HandleIDSMessageReason success = kHandleIDSMessageSuccess; @@ -428,6 +433,9 @@ static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; } else{ secnotice("IDS Transport","IDSProxy handled this message %@, from: %@", messageAndFromID, fromID); + + if(useAck != nil && [useAck compare:@"YES"] == NSOrderedSame) + [self sendACK:senderDeviceID peerID:peerID uniqueID:messageID senderDeviceID:senderDeviceID]; return (NSMutableDictionary*)messageAndFromID; } diff --git a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.h b/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.h index 0de3f5b3..22a7da7e 100644 --- a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.h +++ b/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.h @@ -25,8 +25,8 @@ #import "IDSProxy.h" @interface KeychainSyncingOverIDSProxy (SendMessage) --(BOOL) sendFragmentedIDSMessages:(NSDictionary*)data name:(NSString*) deviceName peer:(NSString*) ourPeerID error:(NSError**) error; --(BOOL) sendIDSMessage:(NSDictionary*)data name:(NSString*) deviceName peer:(NSString*) peerID; +-(BOOL) sendFragmentedIDSMessages:(NSDictionary*)data name:(NSString*) deviceName peer:(NSString*) ourPeerID senderDeviceID:(NSString*)senderDeviceID error:(NSError**) error; +-(BOOL) sendIDSMessage:(NSDictionary*)data name:(NSString*) deviceName peer:(NSString*) peerID senderDeviceID:(NSString*)senderDeviceID; -(void) ackTimerFired:(NSString*)identifier deviceID:(NSString*)deviceID; -(void) setMessageTimer:(NSString*)identifier deviceID:(NSString*)deviceID message:(NSDictionary*)message; - (void)pingTimerFired:(NSString*)deviceID peerID:(NSString*)peerID identifier:(NSString*)identifier; diff --git a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.m b/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.m index 168f2518..dd382a3b 100644 --- a/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.m +++ b/KeychainSyncingOverIDSProxy/KeychainSyncingOverIDSProxy+SendMessage.m @@ -54,19 +54,19 @@ static NSString *const IDSSendMessageOptionForceEncryptionOffKey = @"IDSSendMess static NSString *const kIDSNumberOfFragments = @"NumberOfIDSMessageFragments"; static NSString *const kIDSFragmentIndex = @"kFragmentIndex"; static NSString *const kIDSMessageUseACKModel = @"UsesAckModel"; -static NSString *const kIDSDeviceID = @"deviceID"; +static NSString *const kIDSMessageSendersDeviceID = @"SendersDeviceID"; +static NSString *const kIDSDeviceID = @"deviceID"; static const int64_t kRetryTimerLeeway = (NSEC_PER_MSEC * 250); // 250ms leeway for handling unhandled messages. -static const int64_t timeout = 3ull; +static const int64_t timeout = 5ull; static const int64_t KVS_BACKOFF = 5; static const NSUInteger kMaxIDSMessagePayloadSize = 64000; - @implementation KeychainSyncingOverIDSProxy (SendMessage) - --(bool) chunkAndSendKeychainPayload:(NSData*)keychainData deviceID:(NSString*)deviceName ourPeerID:(NSString*)ourPeerID theirPeerID:(NSString*) theirPeerID operation:(NSString*)operationTypeAsString uuid:(NSString*)uuidString error:(NSError**) error +-(bool) chunkAndSendKeychainPayload:(NSData*)keychainData deviceID:(NSString*)deviceName ourPeerID:(NSString*)ourPeerID theirPeerID:(NSString*) theirPeerID operation:(NSString*)operationTypeAsString uuid:(NSString*)uuidString senderDeviceID:(NSString*)senderDeviceID + error:(NSError**) error { __block BOOL result = true; @@ -97,7 +97,7 @@ static const NSUInteger kMaxIDSMessagePayloadSize = 64000; [fragmentDictionary setObject:[NSNumber numberWithInt:fragmentIndex] forKey:kIDSFragmentIndex]; - result = [self sendIDSMessage:fragmentDictionary name:deviceName peer:ourPeerID]; + result = [self sendIDSMessage:fragmentDictionary name:deviceName peer:ourPeerID senderDeviceID:senderDeviceID]; if(!result) secerror("Could not send fragmented message"); @@ -117,10 +117,10 @@ static const NSUInteger kMaxIDSMessagePayloadSize = 64000; bool success = SOSCCRequestSyncWithPeerOverKVS(((__bridge CFStringRef)theirPeerID), (__bridge CFDataRef)message, &cf_error); if(success){ - secnotice("IDSPing", "sent peerID: %@ to securityd to sync over KVS", theirPeerID); + secnotice("IDS Transport", "rerouting message %@", message); } else{ - secerror("Could not hand peerID: %@ to securityd, error: %@", theirPeerID, cf_error); + secerror("could not route message to %@, error: %@", theirPeerID, cf_error); } CFReleaseNull(cf_error); @@ -163,7 +163,7 @@ static const NSUInteger kMaxIDSMessagePayloadSize = 64000; success = SOSCCRequestSyncWithPeerOverKVSUsingIDOnly(((__bridge CFStringRef)IDSid), &cf_error); if(success){ - secnotice("IDSPing", "sent peerID: %@ to securityd to sync over KVS", IDSid); + secnotice("IDS Transport", "rerouting message for %@", peerID); } else{ secerror("Could not hand peerID: %@ to securityd, error: %@", IDSid, cf_error); @@ -184,7 +184,7 @@ static const NSUInteger kMaxIDSMessagePayloadSize = 64000; bool result = false; secnotice("IDS Transport", "sending to id: %@", IDSid); - result = [self sendIDSMessage:messageDictionary name:IDSid peer:peerID]; + result = [self sendIDSMessage:messageDictionary name:IDSid peer:peerID senderDeviceID:[NSString string]]; if(!result){ secerror("Could not send message over IDS"); @@ -193,7 +193,7 @@ static const NSUInteger kMaxIDSMessagePayloadSize = 64000; bool success = SOSCCRequestSyncWithPeerOverKVSUsingIDOnly(((__bridge CFStringRef)IDSid), &kvsError); if(success){ - secnotice("IDSPing", "sent peerID: %@ to securityd to sync over KVS", IDSid); + secnotice("IDS Transport", "sent peerID: %@ to securityd to sync over KVS", IDSid); } else{ secerror("Could not hand peerID: %@ to securityd, error: %@", IDSid, kvsError); @@ -263,7 +263,7 @@ static const NSUInteger kMaxIDSMessagePayloadSize = 64000; return isPingMessage; } --(BOOL) sendFragmentedIDSMessages:(NSDictionary*)data name:(NSString*) deviceName peer:(NSString*) ourPeerID error:(NSError**) error +-(BOOL) sendFragmentedIDSMessages:(NSDictionary*)data name:(NSString*) deviceName peer:(NSString*) ourPeerID senderDeviceID:(NSString*)senderDeviceID error:(NSError**) error { BOOL result = false; BOOL isPingMessage = false; @@ -278,14 +278,13 @@ static const NSUInteger kMaxIDSMessagePayloadSize = 64000; //check the peer cache for the next time to send timestamp //if the timestamp is set in the future, reroute the message to KVS //otherwise send the message over IDS - if(![self shouldProxySendMessage:deviceName]) - { + if(![self shouldProxySendMessage:deviceName] && [KeychainSyncingOverIDSProxy idsProxy].allowKVSFallBack) + { if(isPingMessage){ secnotice("IDS Transport", "peer negative cache check: peer cannot send yet. not sending ping message"); return true; } else{ - secnotice("IDS Transport", "peer negative cache check: peer cannot send yet. rerouting message to be sent over KVS: %@", messageDictionary); [self sendMessageToKVS:messageDictionary]; return true; } @@ -294,7 +293,8 @@ static const NSUInteger kMaxIDSMessagePayloadSize = 64000; if(isPingMessage){ //foward the ping message, no processing result = [self sendIDSMessage:data name:deviceName - peer:ourPeerID]; + peer:ourPeerID + senderDeviceID:senderDeviceID]; if(!result){ secerror("Could not send ping message"); } @@ -325,21 +325,24 @@ static const NSUInteger kMaxIDSMessagePayloadSize = 64000; theirPeerID:theirPeerID operation:operationTypeAsString uuid:localMessageIdentifier + senderDeviceID:senderDeviceID error:&localError]; } else{ NSMutableDictionary* dataCopy = [NSMutableDictionary dictionaryWithDictionary:data]; [dataCopy setObject:localMessageIdentifier forKey:(__bridge NSString*)kIDSMessageUniqueID]; + result = [self sendIDSMessage:dataCopy name:deviceName - peer:ourPeerID]; + peer:ourPeerID + senderDeviceID:senderDeviceID]; } - if(result && useAckModel){ + if(result && useAckModel && [KeychainSyncingOverIDSProxy idsProxy].allowKVSFallBack){ secnotice("IDS Transport", "setting ack timer"); [self setMessageTimer:localMessageIdentifier deviceID:deviceName message:data]; } - + secnotice("IDS Transport","returning result: %d, error: %@", result, error ? *error : nil); return result; } @@ -367,9 +370,10 @@ static const NSUInteger kMaxIDSMessagePayloadSize = 64000; if(!message){ return; } - NSDictionary *encapsulatedKeychainMessage = [message objectForKey:(__bridge NSString*)kIDSMessageToSendKey]; + NSDictionary *mesageInFlight = [message objectForKey:(__bridge NSString*)kIDSMessageToSendKey]; + + [[KeychainSyncingOverIDSProxy idsProxy] printMessage:mesageInFlight state:@"timeout occured, rerouting to KVS"]; - secnotice("IDS Transport", "Encapsulated message: %@", encapsulatedKeychainMessage); //cleanup timers dispatch_async(self.pingQueue, ^{ dispatch_source_t timer = [[KeychainSyncingOverIDSProxy idsProxy].pingTimers objectForKey:identifier]; //remove timer @@ -378,7 +382,7 @@ static const NSUInteger kMaxIDSMessagePayloadSize = 64000; [[KeychainSyncingOverIDSProxy idsProxy].pingTimers removeObjectForKey:identifier]; }); - [self sendMessageToKVS:encapsulatedKeychainMessage]; + [self sendMessageToKVS:mesageInFlight]; //setting next time to send [self updateNextTimeToSendFor5Minutes:ID]; @@ -397,7 +401,6 @@ static const NSUInteger kMaxIDSMessagePayloadSize = 64000; dispatch_resume(timer); //restructure message in flight - //set the timer for message id dispatch_async(self.pingQueue, ^{ @@ -426,9 +429,7 @@ static const NSUInteger kMaxIDSMessagePayloadSize = 64000; secnotice("IDS Transport", "no message for identifier: %@", messageIdentifier); return; } - secnotice("IDS Transport", "sending over KVS: %@", messageToSendToKVS); - - + [[KeychainSyncingOverIDSProxy idsProxy] printMessage:messageToSendToKVS state:@"IDS rejected send, message rerouted to KVS"]; //cleanup timer for message dispatch_async(self.pingQueue, ^{ @@ -439,16 +440,15 @@ static const NSUInteger kMaxIDSMessagePayloadSize = 64000; }); } - NSDictionary *encapsulatedKeychainMessage = [messageToSendToKVS objectForKey:(__bridge NSString*)kIDSMessageToSendKey]; - - if([encapsulatedKeychainMessage isKindOfClass:[NSDictionary class]]){ - secnotice("IDS Transport", "Encapsulated message: %@", encapsulatedKeychainMessage); - [self sendMessageToKVS:encapsulatedKeychainMessage]; + NSDictionary *messageInFlight = [messageToSendToKVS objectForKey:(__bridge NSString*)kIDSMessageToSendKey]; + if([messageInFlight isKindOfClass:[NSDictionary class]]){ + [[KeychainSyncingOverIDSProxy idsProxy] printMessage:messageInFlight state:@"IDS rejected send, message rerouted to KVS"]; + [self sendMessageToKVS:messageInFlight]; } } --(BOOL) sendIDSMessage:(NSDictionary*)data name:(NSString*) deviceName peer:(NSString*) peerID +-(BOOL) sendIDSMessage:(NSDictionary*)data name:(NSString*) deviceName peer:(NSString*) peerID senderDeviceID:(NSString*)senderDeviceID { if(!self->_service){ @@ -456,38 +456,48 @@ static const NSUInteger kMaxIDSMessagePayloadSize = 64000; return NO; } + NSMutableDictionary *dataCopy = [NSMutableDictionary dictionaryWithDictionary: data]; + + __block NSString* senderDeviceIDCopy = nil; + if(senderDeviceID){ + senderDeviceIDCopy = [[NSString alloc]initWithString:senderDeviceID]; + } + else{ + secnotice("IDS Transport", "device id doesn't exist for peer:%@", peerID); + senderDeviceIDCopy = [NSString string]; + } + dispatch_async(self.calloutQueue, ^{ IDSMessagePriority priority = IDSMessagePriorityHigh; BOOL encryptionOff = YES; NSString *sendersPeerIDKey = [ NSString stringWithUTF8String: kMessageKeySendersPeerID]; - secnotice("backoff","!!writing these keys to IDS!!: %@", data); - NSDictionary *options = @{IDSSendMessageOptionForceEncryptionOffKey : [NSNumber numberWithBool:encryptionOff] }; - NSMutableDictionary *dataCopy = [NSMutableDictionary dictionaryWithDictionary: data]; - //set our peer id and a unique id for this message [dataCopy setObject:peerID forKey:sendersPeerIDKey]; - secnotice("IDS Transport", "%@ sending message %@ to: %@", peerID, data, deviceName); + [dataCopy setObject:senderDeviceIDCopy forKey:kIDSMessageSendersDeviceID]; + secnotice("IDS Transport","Our device Name: %@", senderDeviceID); + [[KeychainSyncingOverIDSProxy idsProxy] printMessage:dataCopy state:@"sending"]; NSDictionary *info; NSInteger errorCode = 0; - NSInteger numberOfDevices = 0; + NSUInteger numberOfDevices = 0; NSString *errMessage = nil; NSMutableSet *destinations = nil; NSError *localError = nil; NSString *identifier = nil; IDSDevice *device = nil; - numberOfDevices = [self.listOfDevices count]; + NSArray* listOfDevices = [self->_service devices]; + numberOfDevices = [listOfDevices count]; require_action_quiet(numberOfDevices > 0, fail, errorCode = kSecIDSErrorNotRegistered; errMessage=createErrorString(@"Could not send message to peer: %@: IDS devices are not registered yet", deviceName)); secnotice("IDS Transport","List of devices: %@", [self->_service devices]); destinations = [NSMutableSet set]; - for(NSUInteger i = 0; i < [ self.listOfDevices count ]; i++){ - device = self.listOfDevices[i]; + for(NSUInteger i = 0; i < numberOfDevices; i++){ + device = listOfDevices[i]; if( [ deviceName compare:device.uniqueID ] == 0){ [destinations addObject: IDSCopyIDForDevice(device)]; } @@ -499,7 +509,7 @@ static const NSUInteger kMaxIDSMessagePayloadSize = 64000; [KeychainSyncingOverIDSProxy idsProxy].outgoingMessages++; require_action_quiet(localError == nil && result, fail, errorCode = kSecIDSErrorFailedToSend; errMessage = createErrorString(@"Had an error sending IDS message to peer: %@", deviceName)); - secnotice("IDS Transport","successfully sent to peer:%@, message: %@", deviceName, dataCopy); + [[KeychainSyncingOverIDSProxy idsProxy] printMessage:dataCopy state:@"sent!"]; fail: if(errMessage != nil){ diff --git a/KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.m b/KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.m index 810d4b8f..b045d443 100644 --- a/KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.m +++ b/KeychainSyncingOverIDSProxy/keychainsyncingoveridsproxy.m @@ -131,21 +131,26 @@ static void idskeychainsyncingproxy_peer_dictionary_handler(const xpc_connection xpc_object_t xidsMessageData = xpc_dictionary_get_value(event, kMessageKeyValue); xpc_object_t xDeviceName = xpc_dictionary_get_value(event, kMessageKeyDeviceName); xpc_object_t xPeerID = xpc_dictionary_get_value(event, kMessageKeyPeerID); + xpc_object_t xSenderDeviceID = xpc_dictionary_get_value(event, kMessageKeyDeviceID); BOOL object = false; NSString *deviceName = (__bridge_transfer NSString*)(_CFXPCCreateCFObjectFromXPCObject(xDeviceName)); NSString *peerID = (__bridge_transfer NSString*)(_CFXPCCreateCFObjectFromXPCObject(xPeerID)); NSDictionary *messageDictionary = (__bridge_transfer NSDictionary*)(_CFXPCCreateCFObjectFromXPCObject(xidsMessageData)); + NSString *senderDeviceID = (__bridge_transfer NSString*)(_CFXPCCreateCFObjectFromXPCObject(xSenderDeviceID)); + NSError *error = NULL; bool isNameString = (CFGetTypeID((__bridge CFTypeRef)(deviceName)) == CFStringGetTypeID()); bool isPeerIDString = (CFGetTypeID((__bridge CFTypeRef)(peerID)) == CFStringGetTypeID()); bool isMessageDictionary = (CFGetTypeID((__bridge CFTypeRef)(messageDictionary)) == CFDictionaryGetTypeID()); + bool isDeviceIDString = (CFGetTypeID((__bridge CFTypeRef)(senderDeviceID)) == CFStringGetTypeID()); require_quiet(isNameString, xit); require_quiet(isPeerIDString, xit); + require_quiet(isDeviceIDString, xit); require_quiet(isMessageDictionary, xit); - object = [[KeychainSyncingOverIDSProxy idsProxy] sendFragmentedIDSMessages:messageDictionary name:deviceName peer:peerID error:&error]; + object = [[KeychainSyncingOverIDSProxy idsProxy] sendFragmentedIDSMessages:messageDictionary name:deviceName peer:peerID senderDeviceID:senderDeviceID error:&error]; xpc_object_t replyMessage = xpc_dictionary_create_reply(event); xpc_dictionary_set_bool(replyMessage, kMessageKeyValue, object); @@ -162,30 +167,36 @@ static void idskeychainsyncingproxy_peer_dictionary_handler(const xpc_connection xpc_object_t xidsMessageData = xpc_dictionary_get_value(event, kMessageKeyValue); xpc_object_t xDeviceName = xpc_dictionary_get_value(event, kMessageKeyDeviceName); xpc_object_t xPeerID = xpc_dictionary_get_value(event, kMessageKeyPeerID); + xpc_object_t xSenderDeviceID = xpc_dictionary_get_value(event, kMessageKeyDeviceID); + BOOL object = false; NSString *deviceName = (__bridge_transfer NSString*)(_CFXPCCreateCFObjectFromXPCObject(xDeviceName)); NSString *peerID = (__bridge_transfer NSString*)(_CFXPCCreateCFObjectFromXPCObject(xPeerID)); NSDictionary *messageDictionary = (__bridge_transfer NSDictionary*)(_CFXPCCreateCFObjectFromXPCObject(xidsMessageData)); + NSString *senderDeviceID = (__bridge_transfer NSString*)(_CFXPCCreateCFObjectFromXPCObject(xSenderDeviceID)); + CFErrorRef error = NULL; bool isNameString = (CFGetTypeID((__bridge CFTypeRef)(deviceName)) == CFStringGetTypeID()); bool isPeerIDString = (CFGetTypeID((__bridge CFTypeRef)(peerID)) == CFStringGetTypeID()); bool isMessageDictionary = (CFGetTypeID((__bridge CFTypeRef)(messageDictionary)) == CFDictionaryGetTypeID()); - + bool isDeviceIDString = (CFGetTypeID((__bridge CFTypeRef)(senderDeviceID)) == CFStringGetTypeID()); + require_quiet(isNameString, xit); require_quiet(isPeerIDString, xit); require_quiet(isMessageDictionary, xit); - + require_quiet(isDeviceIDString, xit); + NSString *localMessageIdentifier = [[NSUUID UUID] UUIDString]; NSMutableDictionary* messageDictionaryCopy = [NSMutableDictionary dictionaryWithDictionary:messageDictionary]; [messageDictionaryCopy setObject:localMessageIdentifier forKey:(__bridge NSString*)(kIDSMessageUniqueID)]; - if([[KeychainSyncingOverIDSProxy idsProxy] sendIDSMessage:messageDictionaryCopy name:deviceName peer:peerID]) + if([[KeychainSyncingOverIDSProxy idsProxy] sendIDSMessage:messageDictionaryCopy name:deviceName peer:peerID senderDeviceID:senderDeviceID]) { object = true; NSString *useAckModel = [messageDictionaryCopy objectForKey:(__bridge NSString*)(kIDSMessageUsesAckModel)]; - if(object && [useAckModel compare:@"YES"] == NSOrderedSame){ + if(object && [useAckModel compare:@"YES"] == NSOrderedSame && [KeychainSyncingOverIDSProxy idsProxy].allowKVSFallBack){ secnotice("IDS Transport", "setting timer!"); [[KeychainSyncingOverIDSProxy idsProxy] setMessageTimer:localMessageIdentifier deviceID:deviceName message:messageDictionaryCopy]; } @@ -221,7 +232,6 @@ xit: static void idskeychainsyncingproxy_peer_event_handler(xpc_connection_t peer, xpc_object_t event) { - describeXPCObject("peer: ", peer); xpc_type_t type = xpc_get_type(event); if (type == XPC_TYPE_ERROR) { if (event == XPC_ERROR_CONNECTION_INVALID) { @@ -235,8 +245,6 @@ static void idskeychainsyncingproxy_peer_event_handler(xpc_connection_t peer, xp } } else { assert(type == XPC_TYPE_DICTIONARY); - // Handle the message. - // describeXPCObject("dictionary:", event); dispatch_async(dispatch_get_main_queue(), ^{ idskeychainsyncingproxy_peer_dictionary_handler(peer, event); }); @@ -265,6 +273,20 @@ static void idskeychainsyncingproxy_event_handler(xpc_connection_t peer) xpc_connection_resume(peer); } +static bool kvsFallbackFromDefaultsWrite(void) +{ + bool kvsFallbackEnabled = true; + + //defaults write ~/Library/Preferences/com.apple.security allowKVSFallback -bool + CFBooleanRef value = (CFBooleanRef)CFPreferencesCopyValue(CFSTR("allowKVSFallback"), CFSTR("com.apple.security"), kCFPreferencesAnyUser, kCFPreferencesCurrentHost); + if ( value ) + { + kvsFallbackEnabled = CFBooleanGetValue(value); + CFReleaseNull(value); + } + return kvsFallbackEnabled; +} + int idsproxymain(int argc, const char *argv[]) { secdebug(PROXYXPCSCOPE, "Starting IDSProxy"); @@ -289,6 +311,8 @@ int idsproxymain(int argc, const char *argv[]) [KeychainSyncingOverIDSProxy idsProxy].sendRestoredMessages = false; } + [KeychainSyncingOverIDSProxy idsProxy].allowKVSFallBack = kvsFallbackFromDefaultsWrite(); + // It looks to me like there is insufficient locking to allow a request to come in on the XPC connection while doing the initial all items. // Therefore I'm leaving the XPC connection suspended until that has time to process. xpc_connection_resume(listener); diff --git a/OSX/SecurityTestsOSX/SecurityTests-Entitlements.plist b/OSX/SecurityTestsOSX/SecurityTests-Entitlements.plist index 44259696..39da8b2f 100644 --- a/OSX/SecurityTestsOSX/SecurityTests-Entitlements.plist +++ b/OSX/SecurityTestsOSX/SecurityTests-Entitlements.plist @@ -26,6 +26,8 @@ com.apple.security.regressions com.apple.private.uninstall.deletion + com.apple.private.security.delete.all + keychain-access-groups com.apple.security.regressions @@ -36,17 +38,5 @@ 123456.test.group2 com.apple.bluetooth - com.apple.private.ubiquity-kvstore-access - - com.apple.securityd - - com.apple.developer.ubiquity-kvstore-identifier - com.apple.security.cloudkeychainproxy3 - com.apple.developer.ubiquity-container-identifiers - - com.apple.security.cloudkeychainproxy3 - com.apple.security.cloudkeychain - CloudKeychainProxy.xpc - diff --git a/OSX/authd/authorization.plist b/OSX/authd/authorization.plist index f4f68f3b..179b0d5d 100644 --- a/OSX/authd/authorization.plist +++ b/OSX/authd/authorization.plist @@ -1286,22 +1286,20 @@ See remaining rules for examples. system.services.directory.configure - allow-root - - authenticate-user - class - user + rule + k-of-n + 1 + rule + + is-root + entitled + authenticate-admin-nonshared + comment For making Directory Services changes. - group - admin - session-owner - - shared - version - 2 + 3 system.services.networkextension.filtering diff --git a/OSX/authd/engine.c b/OSX/authd/engine.c index 7991cff5..2a3de5c0 100644 --- a/OSX/authd/engine.c +++ b/OSX/authd/engine.c @@ -434,6 +434,9 @@ _extract_password_from_la(engine_t engine) if (passdata) { if (CFDataGetBytePtr(passdata)) { auth_items_set_data(engine->context, kAuthorizationEnvironmentPassword, CFDataGetBytePtr(passdata), CFDataGetLength(passdata)); + } else { + const char *empty_pass = "\0"; // authd code is unable to process empty strings so passing empty string as terminator only + auth_items_set_data(engine->context, kAuthorizationEnvironmentPassword, empty_pass, 1); } CFRelease(passdata); } @@ -879,7 +882,7 @@ _evaluate_class_rule(engine_t engine, rule_t rule, bool *save_pwd) uint32_t total = (uint32_t)rule_get_delegates_count(rule); __block uint32_t success_count = 0; __block uint32_t count = 0; - os_log_debug(AUTHD_LOG, "engine: ** rule %{public}s has %zi delegates kofn = %lli",rule_get_name(rule), total, kofn); + os_log_debug(AUTHD_LOG, "engine: ** rule %{public}s has %u delegates kofn = %lli",rule_get_name(rule), total, kofn); rule_delegates_iterator(rule, ^bool(rule_t delegate) { count++; @@ -1388,11 +1391,11 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en save_password = true; } const char *user = auth_items_get_string(environment, kAuthorizationEnvironmentUsername); - require(user, done); + require_action(user, done, os_log_debug(AUTHD_LOG, "engine: Missing username"); status = errAuthorizationDenied); auth_items_set_string(engine->context, kAuthorizationEnvironmentUsername, user); struct passwd *pwd = getpwnam(user); - require(pwd, done); + require_action(pwd, done, os_log_debug(AUTHD_LOG, "engine: Invalid username %s", user); status = errAuthorizationDenied); auth_items_set_uint(engine->context, "sheet-uid", pwd->pw_uid); // move sheet-specific items from hints to context @@ -1810,10 +1813,11 @@ CFTypeRef engine_copy_context(engine_t engine, auth_items_t source) bool engine_acquire_sheet_data(engine_t engine) { - uid_t uid = auth_items_get_int(engine->context, "sheet-uid"); - if (!uid) + if (!auth_items_exist(engine->context, "sheet-uid")) return false; + uid_t uid = auth_items_get_uint(engine->context, "sheet-uid"); + CFReleaseSafe(engine->la_context); engine->la_context = engine_copy_context(engine, engine->hints); if (engine->la_context) { diff --git a/OSX/config/lib.xcconfig b/OSX/config/lib.xcconfig index fdb54902..0a9bbcb5 100644 --- a/OSX/config/lib.xcconfig +++ b/OSX/config/lib.xcconfig @@ -5,7 +5,7 @@ EXECUTABLE_PREFIX = CODE_SIGN_IDENTITY = -HEADER_SEARCH_PATHS = $(PROJECT_DIR)/../ $(PROJECT_DIR)/../include $(BUILT_PRODUCTS_DIR)/derived_src $(BUILT_PRODUCTS_DIR) $(PROJECT_DIR)/lib $(PROJECT_DIR)/../utilities $(inherited) +HEADER_SEARCH_PATHS = $(PROJECT_DIR)/../ $(PROJECT_DIR)/../include $(BUILT_PRODUCTS_DIR)/derived_src $(BUILT_PRODUCTS_DIR) $(PROJECT_DIR)/lib $(PROJECT_DIR)/../utilities $(PROJECT_DIR)/../../header_symlinks/macOS $(PROJECT_DIR)/../../header_symlinks/ $(inherited) SKIP_INSTALL = YES diff --git a/OSX/config/security_framework_macos.xcconfig b/OSX/config/security_framework_macos.xcconfig index 2e878c70..2dff3356 100644 --- a/OSX/config/security_framework_macos.xcconfig +++ b/OSX/config/security_framework_macos.xcconfig @@ -24,3 +24,11 @@ APPLY_RULES_IN_COPY_FILES = NO // Not entirely sure what this is for, but, okay. INSTALLHDRS_SCRIPT_PHASE = YES + +// Adding things here is against the spirit of TAPI. If something is in the framework, it should be in the framework headers. +// Don't add things. +OTHER_TAPI_FLAGS_TRUST = -extra-private-header $(PROJECT_DIR)/OSX/trustd/macOS/SecTrustOSXEntryPoints.h -extra-private-header $(PROJECT_DIR)/OSX/sec/Security/SecCertificateInternal.h +OTHER_TAPI_FLAGS_USR_LIB_HEADERS = -extra-private-header $(PROJECT_DIR)/OSX/utilities/src/debugging.h +OTHER_TAPI_FLAGS_HACKS = -exclude-public-header $(BUILT_PRODUCTS_DIR)/Security.framework/Versions/A/Headers/AuthorizationPlugin.h -extra-public-header $(PROJECT_DIR)/OSX/macos_tapi_hacks.h -D SECURITY_PROJECT_TAPI_HACKS=1 + +OTHER_TAPI_FLAGS = $(inherited) $(OTHER_TAPI_FLAGS_SECURITY_FRAMEWORK) -I$(PROJECT_DIR)/header_symlinks/ $(OTHER_TAPI_FLAGS_TRUST) $(OTHER_TAPI_FLAGS_USR_LIB_HEADERS) $(OTHER_TAPI_FLAGS_HACKS) diff --git a/OSX/config/security_macos.xcconfig b/OSX/config/security_macos.xcconfig index 0a2b9ed2..a7acee1d 100644 --- a/OSX/config/security_macos.xcconfig +++ b/OSX/config/security_macos.xcconfig @@ -14,9 +14,6 @@ DEPLOYMENT_POSTPROCESSING = NO GCC_C_LANGUAGE_STANDARD = gnu99 SUPPORTED_PLATFORMS = macOS -// Don't use the inherited cflags; they set SEC_IOS_ON_OSX -GCC_PREPROCESSOR_DEFINITIONS = SECURITY_BUILD_VERSION=\"$(SECURITY_BUILD_VERSION)\" - GCC_TREAT_WARNINGS_AS_ERRORS = YES GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO GCC_SYMBOLS_PRIVATE_EXTERN = NO diff --git a/OSX/lib/generateErrStrings.pl b/OSX/lib/generateErrStrings.pl index 509bb088..1aa92e2b 100644 --- a/OSX/lib/generateErrStrings.pl +++ b/OSX/lib/generateErrStrings.pl @@ -72,7 +72,7 @@ # CSSM_CSSM_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT + 0x10, # CSSMERR_CSSM_SCOPE_NOT_SUPPORTED = CSSM_CSSM_BASE_CSSM_ERROR + 1, # -# Style A has the comment after the comment. Style has the comment before the value, +# Style A has the comment after the value. Style has the comment before the value, # and Style C has no comment. In cases where both Style A and B apply, the # comment at the end of the line is used. # @@ -116,13 +116,9 @@ $TARGETSTR=$ARGV[2]; # path of .strings file, e.g. $#INPUTFILES = $#ARGV - 3; # truncate to actual number of files print "gend: $GENDEBUGSTRINGS, tmpdir: $TMPDIR, targetstr: $TARGETSTR\n"; -$PROGNAME="${TMPDIR}/generateErrStrings.mm"; -open PROGRAM,"> $PROGNAME" or die "can't open $PROGNAME: $!"; -select PROGRAM; - -printAdditionalIncludes(); -printInputIncludes(); -printMainProgram(); +open STRINGFILE, "> $TARGETSTR" or die "can't open $TARGETSTR: $!"; +select STRINGFILE; +binmode STRINGFILE, ":encoding(UTF-16)"; # ----------------------------------------------------------------------------------- # Parse error headers and build array of all relevant lines @@ -132,12 +128,6 @@ processInput(); close(ERR); # ----------------------------------------------------------------------------------- -printTrailer(); -select STDOUT; -close PROGRAM; - -compileLinkAndRun(); - # 4: Done! exit; @@ -147,53 +137,55 @@ exit; sub processInput { - # 3: Read input, process each line, output it. - while ( $line = ) - { - ($enum) = ($line =~ /\n\s*(?:enum|CF_ENUM\(OSStatus\))\s*{\s*([^}]*)};/); - while ($enum ne '') #basic filter for badly formed enums - { - #Drop leading whitespace - $enum =~ s/^\s+//; - # print "A:", $enum,"\n"; - ($leadingcomment) = ($enum =~ m%^(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/)|(//.*)%); - if ($leadingcomment ne '') - { - $enum = substr($enum, length($leadingcomment)); - $leadingcomment = substr($leadingcomment, 2); # drop leading "/*" - $leadingcomment = substr($leadingcomment, 0, -2); # drop trailing "*/" - $leadingcomment = cleanupComment($leadingcomment); - } - next if ($enum eq ''); #basic filter for badly formed enums - - # Check for C++ style comments at start of line - if ($enum =~ /\s*(\/\/)/) - { - #Drop everything before the end of line - $enum =~ s/[^\n]*[\n]*//; - next; - } - ($identifier) = ($enum =~ /\s*([_A-Za-z][_A-Za-z0-9]*)/); - -# print "identifier: ", $identifier,"\n" if ($identifier ne ''); - - #Drop everything before the comma, end of line or trailing comment + # 3: Read input, process each line, output it. + while ( $line = ) + { + ($enum) = ($line =~ /\n\s*(?:enum|CF_ENUM\(OSStatus\))\s*{\s*([^}]*)};/); + while ($enum ne '') #basic filter for badly formed enums + { + #Drop leading whitespace + $enum =~ s/^\s+//; + + ($leadingcomment) = ($enum =~ m%^(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/)|(//.*)%); + if ($leadingcomment ne '') + { + $enum = substr($enum, length($leadingcomment)); + $leadingcomment = substr($leadingcomment, 2); # drop leading "/*" + $leadingcomment = substr($leadingcomment, 0, -2); # drop trailing "*/" + $leadingcomment = cleanupComment($leadingcomment); + } + next if ($enum eq ''); #basic filter for badly formed enums + + # Check for C++ style comments at start of line + if ($enum =~ /\s*(\/\/)/) + { + #Drop everything before the end of line + $enum =~ s/[^\n]*[\n]*//; + next; + } + ($identifier) = ($enum =~ /\s*([_A-Za-z][_A-Za-z0-9]*)/); + #print "identifier: ", $identifier,"\n" if ($identifier ne ''); + + ($value) = ($enum =~ /\s*[_A-Za-z][_A-Za-z0-9]*\s*=\s*(-?[0-9]*),/); + #print "value: ", $value,"\n" if ($value ne ''); + + #Drop everything before the comma, end of line or trailing comment $enum =~ s/[^,]*(,|\n|(\/\*))//; - - # Now look for trailing comment. We only consider them - # trailing if they come before the end of the line - ($trailingcomment) = ($enum =~ /^[ \t]*\/\*((.)*)?\*\//); - $trailingcomment = cleanupComment($trailingcomment); - - #Drop everything before the end of line - $enum =~ s/[^\n]*[\n]*//; - # print "B:", $enum,"\n"; - # print "lc:$leadingcomment, id:$identifier, tc:$trailingcomment\n"; - # print "===========================================\n"; - - writecomment($leadingcomment, $identifier, $trailingcomment); - } - } + + # Now look for trailing comment. We only consider them + # trailing if they come before the end of the line + ($trailingcomment) = ($enum =~ /^[ \t]*\/\*((.)*)?\*\//); + $trailingcomment = cleanupComment($trailingcomment); + + #Drop everything before the end of line + $enum =~ s/[^\n]*[\n]*//; + + #print "lc:$leadingcomment, id:$identifier, v:$value, tc:$trailingcomment\n"; + #print "===========================================\n"; + + writecomment($leadingcomment, $identifier, $trailingcomment, $value); + } + } } sub writecomment @@ -205,7 +197,7 @@ sub writecomment # tmp << "/* errAuthorizationSuccess */\n\"" << errAuthorizationSuccess # << "\" = \"The operation completed successfully.\"\n" << endl; - my($mylc,$myid,$mytc) = @_; + my($mylc,$myid,$mytc,$myvalue) = @_; if ($myid =~ /(CSSM_ERRCODE|CSSMERR_|errSec|errCS|errAuth|errSSL)[_A-Za-z][_A-Za-z0-9]*/) { $errormessage = ''; @@ -218,89 +210,13 @@ sub writecomment if ($errormessage ne '') { - print "\ttmp << \"/* ", $myid, " */\\n\\\"\" << "; - print $myid, " << \"\\\" = \\\""; - print $errormessage, "\\\";\\n\" << endl;\n"; + print "/* ", $myid, " */\n\""; + print $myvalue, "\" = \""; + print $errormessage, "\";\n\n"; } } }; - -sub printAdditionalIncludes -{ - #This uses the "here" construct to dump out lines verbatim - print <<"AdditionalIncludes"; - -#include -#include -#include -#include - -using namespace std; -AdditionalIncludes -} - -sub printInputIncludes -{ - #Now "#include" each of the input files - print "\n#include \"$_\"" foreach @INPUTFILES; - print "\n"; -} - -sub printMainProgram -{ - #Output the main part of the program using the "here" construct - print <<"MAINPROGRAM"; - -void writeStrings(const char *stringsFileName); -void createStringsTemp(); - -int main (int argc, char * const argv[]) -{ - const char *stringsFileName = NULL; - - if (argc == 2) - stringsFileName = argv[1]; - else - if (argc == 1) - stringsFileName = "SecErrorMessages.strings"; - else - return -1; - - cout << "Strings file to create: " << stringsFileName << endl; - createStringsTemp(); - writeStrings(stringsFileName); -} - -void writeStrings(const char *stringsFileName) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSFileHandle *fh = [NSFileHandle fileHandleForReadingAtPath:@"generateErrStrings.tmp"]; - NSData *rawstrings = [fh readDataToEndOfFile]; - UInt32 encoding = CFStringConvertEncodingToNSStringEncoding (kCFStringEncodingUTF8); - NSString *instring = [[NSString alloc] initWithData:rawstrings encoding:(NSStringEncoding)encoding]; - - if (instring) - { - NSString *path = [NSString stringWithUTF8String:stringsFileName]; - NSFileManager *fm = [NSFileManager defaultManager]; - if ([fm fileExistsAtPath:path]) - [fm removeItemAtPath:path error:NULL]; - BOOL bx = [fm createFileAtPath:path contents:nil attributes:nil]; - NSFileHandle *fs = [NSFileHandle fileHandleForWritingAtPath:path]; - [fs writeData:[instring dataUsingEncoding:NSUnicodeStringEncoding]]; - } - - [pool release]; -} - -void createStringsTemp() -{ - ofstream tmp("generateErrStrings.tmp") ; - -MAINPROGRAM -} - sub cleanupComment { my $comment = shift @_; @@ -310,33 +226,8 @@ sub cleanupComment $comment =~ s/\s\s+/ /g; # Squeeze multiple spaces to one $comment =~ s/^\s+//; # Drop leading whitespace $comment =~ s/\s+$//; # Drop trailing whitespace - $comment =~ s/[\"]/\\\\\\"/g; # Replace double quotes with \" (backslash is sextupled to make it through regex and printf) + $comment =~ s/[\"]/\\\"/g; # Replace double quotes with \" (backslash is sextupled to make it through regex and printf) } # print "B:",$comment,"\n"; $comment; -} - -sub printTrailer -{ - print " tmp.close();\n"; - print "}\n"; } - -sub compileLinkAndRun -{ - $status = system( <<"MAINPROGRAM"); -(cd ${TMPDIR} ; /usr/bin/cc -x objective-c++ -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -g -O0 -Wreturn-type -fmessage-length=0 -F$ENV{'BUILT_PRODUCTS_DIR'} -I$ENV{'BUILT_PRODUCTS_DIR'}/SecurityPieces/Headers -I$ENV{'BUILT_PRODUCTS_DIR'}/SecurityPieces/PrivateHeaders -c generateErrStrings.mm -o generateErrStrings.o) -MAINPROGRAM - die "$compile exited funny: $?" unless $status == 0; - - $status = system( <<"LINKERSTEP"); -(cd ${TMPDIR} ; /usr/bin/clang++ -o generateErrStrings generateErrStrings.o -framework Foundation ) -LINKERSTEP - die "$linker exited funny: $?" unless $status == 0; - - $status = system( <<"RUNSTEP"); -(cd ${TMPDIR} ; ./generateErrStrings $TARGETSTR ) -RUNSTEP - die "$built program exited funny: $?" unless $status == 0; -} - diff --git a/OSX/libsecurity_apple_x509_cl/lib/clNssUtils.cpp b/OSX/libsecurity_apple_x509_cl/lib/clNssUtils.cpp index bee31697..d94b373d 100644 --- a/OSX/libsecurity_apple_x509_cl/lib/clNssUtils.cpp +++ b/OSX/libsecurity_apple_x509_cl/lib/clNssUtils.cpp @@ -50,7 +50,6 @@ void *ArenaAllocator::malloc(size_t len) throw(std::bad_alloc) /* intentionally not implemented, should never be called */ void ArenaAllocator::free(void *p) throw() { - throw std::bad_alloc(); } void *ArenaAllocator::realloc(void *p, size_t len) throw(std::bad_alloc) diff --git a/OSX/libsecurity_authorization/lib/AuthSession.h b/OSX/libsecurity_authorization/lib/AuthSession.h index d8542ed8..53ef4855 100644 --- a/OSX/libsecurity_authorization/lib/AuthSession.h +++ b/OSX/libsecurity_authorization/lib/AuthSession.h @@ -119,8 +119,8 @@ CF_ENUM(OSStatus) { errSessionAuthorizationDenied = -60502, /* you are not allowed to do this */ errSessionValueNotSet = -60503, /* the session attribute you requested has not been set */ - errSessionInternal = errAuthorizationInternal, /* internal error */ - errSessionInvalidFlags = errAuthorizationInvalidFlags /* invalid flags/options */ + errSessionInternal = -60008, /* internal error */ + errSessionInvalidFlags = -60011, /* invalid flags/options */ }; diff --git a/OSX/libsecurity_authorization/lib/AuthorizationPlugin.h b/OSX/libsecurity_authorization/lib/AuthorizationPlugin.h index f34c2366..baed6963 100644 --- a/OSX/libsecurity_authorization/lib/AuthorizationPlugin.h +++ b/OSX/libsecurity_authorization/lib/AuthorizationPlugin.h @@ -176,7 +176,7 @@ enum { interface. */ enum { - kAuthorizationCallbacksVersion = 2 + kAuthorizationCallbacksVersion = 3 }; @@ -194,8 +194,9 @@ enum { @field SetHintValue Write value to hints. AuthorizationValue and data are copied. @field GetArguments Read arguments passed. AuthorizationValueVector does not own data. @field GetSessionId Read SessionId. - @field GetLAContext Returns authenticated LAContext which can be used for operations with Tokens which would normally require PIN. Caller owns returned context and is responsible for release. - @field GetTokenIdentities Returns array of identities. Caller owns returned array and is reponsible for release. + @field GetLAContext Returns LAContext which will have LACredentialCTKPIN credential set if PIN is available otherwise context without credentials is returned. LAContext can be used for operations with Tokens which would normally require PIN. Caller owns returned context and is responsible for release. + @field GetTokenIdentities Returns array of identities. Caller owns returned array and is reponsible for release. + @field GetTKTokenWatcher Returns TKTokenWatcher object. Caller owns returned context and is responsible for release. */ typedef struct AuthorizationCallbacks { @@ -254,19 +255,25 @@ typedef struct AuthorizationCallbacks { userful for kSecUseAuthenticationContext for SecItem calls. Caller is responsible for outValue release */ OSStatus (*GetLAContext)(AuthorizationEngineRef inEngine, - CFTypeRef __nullable * __nullable outValue) __OSX_AVAILABLE_STARTING(__MAC_10_13, __PHONE_NA); + CFTypeRef __nullable * __nullable outValue) __OSX_AVAILABLE_STARTING(__MAC_10_13, __PHONE_NA); /* Available only on systems with callback version 2 or higher Returns array of available identities available on tokens. Each array item consists of two elements. The first one is SecIdentityRef and the second one is textual description of that identity - context parameter may contain CFTypeRef returned by GetLAContext. Returned identities - will contain PIN in such case so crypto operations won't display PIN prompt. + context parameter may contain CFTypeRef returned by GetLAContext. Caller is responsible for outValue release */ OSStatus (*GetTokenIdentities)(AuthorizationEngineRef inEngine, CFTypeRef context, CFArrayRef __nullable * __nullable outValue) __OSX_AVAILABLE_STARTING(__MAC_10_13, __PHONE_NA); + /* + Available only on systems with callback version 3 or higher + Constructs TKTokenWatcher object. + Caller is responsible for outValue release */ + OSStatus (*GetTKTokenWatcher)(AuthorizationEngineRef inEngine, + CFTypeRef __nullable * __nullable outValue) __OSX_AVAILABLE_STARTING(__MAC_10_13_4, __PHONE_NA); + } AuthorizationCallbacks; diff --git a/OSX/libsecurity_cdsa_utilities/lib/osxverifier.h b/OSX/libsecurity_cdsa_utilities/lib/osxverifier.h index 0703c57d..596e65b5 100644 --- a/OSX/libsecurity_cdsa_utilities/lib/osxverifier.h +++ b/OSX/libsecurity_cdsa_utilities/lib/osxverifier.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/OSX/libsecurity_cms/lib/CMSDecoder.cpp b/OSX/libsecurity_cms/lib/CMSDecoder.cpp index 83775b23..bcf4e5d6 100644 --- a/OSX/libsecurity_cms/lib/CMSDecoder.cpp +++ b/OSX/libsecurity_cms/lib/CMSDecoder.cpp @@ -1003,8 +1003,8 @@ OSStatus CMSDecoderCopySignerAppleCodesigningHashAgility( int numContentInfos = 0; CFDataRef returnedValue = NULL; - require(cmsDecoder && hashAgilityAttrValue, xit); - require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), xit); + require(cmsDecoder && hashAgilityAttrValue, exit); + require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), exit); numContentInfos = SecCmsMessageContentLevelCount(cmsg); for (int dex = 0; !signedData && dex < numContentInfos; dex++) { @@ -1018,7 +1018,7 @@ OSStatus CMSDecoderCopySignerAppleCodesigningHashAgility( break; } } -xit: +exit: if (status == errSecSuccess && returnedValue) { *hashAgilityAttrValue = (CFDataRef) CFRetain(returnedValue); } else { @@ -1026,3 +1026,49 @@ xit: } return status; } + +/* + * Obtain the Hash Agility V2 attribute value of signer 'signerIndex' + * of a CMS message, if present. + * + * Returns errSecParam if the CMS message was not signed or if signerIndex + * is greater than the number of signers of the message minus one. + * + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderCopySignerAppleCodesigningHashAgilityV2( + CMSDecoderRef cmsDecoder, + size_t signerIndex, /* usually 0 */ + CFDictionaryRef CF_RETURNS_RETAINED *hashAgilityV2AttrValues) /* RETURNED */ +{ + OSStatus status = errSecParam; + SecCmsMessageRef cmsg; + SecCmsSignedDataRef signedData = NULL; + int numContentInfos = 0; + CFDictionaryRef returnedValue = NULL; + + require(cmsDecoder && hashAgilityV2AttrValues, exit); + require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), exit); + numContentInfos = SecCmsMessageContentLevelCount(cmsg); + for (int dex = 0; !signedData && dex < numContentInfos; dex++) + { + SecCmsContentInfoRef ci = SecCmsMessageContentLevel(cmsg, dex); + SECOidTag tag = SecCmsContentInfoGetContentTypeTag(ci); + if (tag == SEC_OID_PKCS7_SIGNED_DATA) + if ((signedData = (SecCmsSignedDataRef)SecCmsContentInfoGetContent(ci))) { + SecCmsSignerInfoRef signerInfo = SecCmsSignedDataGetSignerInfo(signedData, (int)signerIndex); + if (signerInfo) + { + status = SecCmsSignerInfoGetAppleCodesigningHashAgilityV2(signerInfo, &returnedValue); + break; + } + } + } +exit: + if (status == errSecSuccess && returnedValue) { + *hashAgilityV2AttrValues = (CFDictionaryRef) CFRetain(returnedValue); + } else { + *hashAgilityV2AttrValues = NULL; + } + return status; +} diff --git a/OSX/libsecurity_cms/lib/CMSEncoder.cpp b/OSX/libsecurity_cms/lib/CMSEncoder.cpp index c3f43147..f8cb11be 100644 --- a/OSX/libsecurity_cms/lib/CMSEncoder.cpp +++ b/OSX/libsecurity_cms/lib/CMSEncoder.cpp @@ -98,6 +98,7 @@ struct _CMSEncoder { CMSCertificateChainMode chainMode; CFDataRef hashAgilityAttrValue; + CFDictionaryRef hashAgilityV2AttrValues; }; static void cmsEncoderInit(CFTypeRef enc); @@ -532,6 +533,16 @@ static OSStatus cmsSetupForSignedData( break; } } + if(cmsEncoder->signedAttributes & kCMSAttrAppleCodesigningHashAgilityV2) { + ortn = SecCmsSignerInfoAddAppleCodesigningHashAgilityV2(signerInfo, cmsEncoder->hashAgilityV2AttrValues); + /* libsecurity_smime made a copy of the attribute value. We don't need it anymore. */ + CFReleaseNull(cmsEncoder->hashAgilityV2AttrValues); + if(ortn) { + ortn = cmsRtnToOSStatus(ortn); + CSSM_PERROR("SecCmsSignerInfoAddAppleCodesigningHashAgilityV2", ortn); + break; + } + } ortn = SecCmsSignedDataAddSignerInfo(signedData, signerInfo); if(ortn) { @@ -1024,6 +1035,22 @@ OSStatus CMSEncoderSetAppleCodesigningHashAgility( return errSecSuccess; } +/* + * Set the hash agility attribute for a CMSEncoder. + * This is only used if the kCMSAttrAppleCodesigningHashAgilityV2 attribute + * is included. + */ +OSStatus CMSEncoderSetAppleCodesigningHashAgilityV2( + CMSEncoderRef cmsEncoder, + CFDictionaryRef hashAgilityV2AttrValues) +{ + if (cmsEncoder == NULL || cmsEncoder->encState != ES_Init) { + return errSecParam; + } + cmsEncoder->hashAgilityV2AttrValues = CFRetainSafe(hashAgilityV2AttrValues); + return errSecSuccess; +} + OSStatus CMSEncoderSetCertificateChainMode( CMSEncoderRef cmsEncoder, CMSCertificateChainMode chainMode) diff --git a/OSX/libsecurity_cms/lib/CMSEncoder.h b/OSX/libsecurity_cms/lib/CMSEncoder.h index 7bb5596c..a39bcbb9 100644 --- a/OSX/libsecurity_cms/lib/CMSEncoder.h +++ b/OSX/libsecurity_cms/lib/CMSEncoder.h @@ -266,7 +266,8 @@ typedef CF_OPTIONS(uint32_t, CMSSignedAttributes) { /* * Include the Apple Codesigning Hash Agility. */ - kCMSAttrAppleCodesigningHashAgility = 0x0010 + kCMSAttrAppleCodesigningHashAgility = 0x0010, + kCMSAttrAppleCodesigningHashAgilityV2 = 0x0020, }; /* diff --git a/OSX/libsecurity_cms/lib/CMSPrivate.h b/OSX/libsecurity_cms/lib/CMSPrivate.h index b61296b2..8278dbf5 100644 --- a/OSX/libsecurity_cms/lib/CMSPrivate.h +++ b/OSX/libsecurity_cms/lib/CMSPrivate.h @@ -92,6 +92,18 @@ OSStatus CMSEncoderSetAppleCodesigningHashAgility( CMSEncoderRef cmsEncoder, CFDataRef hashAgilityAttrValue); +/* + * Set the hash agility attribute for a CMSEncoder. + * This is only used if the kCMSAttrAppleCodesigningHashAgilityV2 attribute + * is included. V2 encodes the hash agility values using DER. + * The dictionary should have CFNumberRef keys, corresponding to SECOidTags + * (from SecCmsBase.h) for digest algorithms, and CFDataRef values, + * corresponding to the digest value for that digest algorithm. + */ +OSStatus CMSEncoderSetAppleCodesigningHashAgilityV2( + CMSEncoderRef cmsEncoder, + CFDictionaryRef hashAgilityV2AttrValues); + void CmsMessageSetTSAContext(CMSEncoderRef cmsEncoder, CFTypeRef tsaContext); @@ -147,6 +159,20 @@ OSStatus CMSDecoderCopySignerAppleCodesigningHashAgility( CMSDecoderRef cmsDecoder, size_t signerIndex, /* usually 0 */ CFDataRef CF_RETURNS_RETAINED *hashAgilityAttrValue); /* RETURNED */ + +/* + * Obtain the Hash Agility v2 attribute value of signer 'signerIndex' + * of a CMS message, if present. V2 encodes the hash agility values using DER. + * + * Returns errSecParam if the CMS message was not signed or if signerIndex + * is greater than the number of signers of the message minus one. + * + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderCopySignerAppleCodesigningHashAgilityV2( + CMSDecoderRef cmsDecoder, + size_t signerIndex, /* usually 0 */ + CFDictionaryRef CF_RETURNS_RETAINED * hashAgilityAttrValues); /* RETURNED */ #ifdef __cplusplus } diff --git a/OSX/libsecurity_cms/libsecurity_cms.xcodeproj/project.pbxproj b/OSX/libsecurity_cms/libsecurity_cms.xcodeproj/project.pbxproj index 85031b83..93dc2f9c 100644 --- a/OSX/libsecurity_cms/libsecurity_cms.xcodeproj/project.pbxproj +++ b/OSX/libsecurity_cms/libsecurity_cms.xcodeproj/project.pbxproj @@ -17,7 +17,7 @@ D43B9E7E1D064F0B00B9DDDA /* cms-trust-settings-test.c in Sources */ = {isa = PBXBuildFile; fileRef = D43B9E7C1D064F0B00B9DDDA /* cms-trust-settings-test.c */; }; D43B9E7F1D064F0B00B9DDDA /* cms-trust-settings-test.h in Headers */ = {isa = PBXBuildFile; fileRef = D43B9E7D1D064F0B00B9DDDA /* cms-trust-settings-test.h */; }; D4C334601BE2A2B900D8C1EF /* cms_regressions.h in Headers */ = {isa = PBXBuildFile; fileRef = D4C334571BE29F5200D8C1EF /* cms_regressions.h */; }; - D4C334631BE2A31200D8C1EF /* cms-hashagility-test.c in Sources */ = {isa = PBXBuildFile; fileRef = D4C334611BE2A31200D8C1EF /* cms-hashagility-test.c */; }; + D4C334631BE2A31200D8C1EF /* cms-hashagility-test.m in Sources */ = {isa = PBXBuildFile; fileRef = D4C334611BE2A31200D8C1EF /* cms-hashagility-test.m */; }; D4C334641BE2A31200D8C1EF /* cms-hashagility-test.h in Headers */ = {isa = PBXBuildFile; fileRef = D4C334621BE2A31200D8C1EF /* cms-hashagility-test.h */; }; /* End PBXBuildFile section */ @@ -38,7 +38,7 @@ D43B9E7D1D064F0B00B9DDDA /* cms-trust-settings-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "cms-trust-settings-test.h"; path = "regressions/cms-trust-settings-test.h"; sourceTree = ""; }; D4C334571BE29F5200D8C1EF /* cms_regressions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cms_regressions.h; path = regressions/cms_regressions.h; sourceTree = ""; }; D4C3345C1BE2A2B100D8C1EF /* libsecurity_cms_regressions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_cms_regressions.a; sourceTree = BUILT_PRODUCTS_DIR; }; - D4C334611BE2A31200D8C1EF /* cms-hashagility-test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "cms-hashagility-test.c"; path = "regressions/cms-hashagility-test.c"; sourceTree = ""; }; + D4C334611BE2A31200D8C1EF /* cms-hashagility-test.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "cms-hashagility-test.m"; path = "regressions/cms-hashagility-test.m"; sourceTree = ""; }; D4C334621BE2A31200D8C1EF /* cms-hashagility-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "cms-hashagility-test.h"; path = "regressions/cms-hashagility-test.h"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -111,7 +111,7 @@ D4C334571BE29F5200D8C1EF /* cms_regressions.h */, D43B9E7C1D064F0B00B9DDDA /* cms-trust-settings-test.c */, D43B9E7D1D064F0B00B9DDDA /* cms-trust-settings-test.h */, - D4C334611BE2A31200D8C1EF /* cms-hashagility-test.c */, + D4C334611BE2A31200D8C1EF /* cms-hashagility-test.m */, D4C334621BE2A31200D8C1EF /* cms-hashagility-test.h */, ); name = regressions; @@ -224,7 +224,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - D4C334631BE2A31200D8C1EF /* cms-hashagility-test.c in Sources */, + D4C334631BE2A31200D8C1EF /* cms-hashagility-test.m in Sources */, D43B9E7E1D064F0B00B9DDDA /* cms-trust-settings-test.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -300,6 +300,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + "ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; @@ -326,9 +327,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx.internal; }; name = Debug; }; @@ -336,6 +335,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + "ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; @@ -357,7 +357,6 @@ GCC_WARN_UNUSED_VARIABLE = YES; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx.internal; }; name = Release; }; diff --git a/OSX/libsecurity_cms/regressions/cms-hashagility-test.c b/OSX/libsecurity_cms/regressions/cms-hashagility-test.c deleted file mode 100644 index 80e9779a..00000000 --- a/OSX/libsecurity_cms/regressions/cms-hashagility-test.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (c) 2015 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include "cms-hashagility-test.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TMP_KEYCHAIN_PATH "/tmp/cms_signer.keychain" - -/* encode test */ -static void encode_test(void) -{ - CMSEncoderRef encoder = NULL; - CFDataRef attributeData = NULL, message = NULL, p12Data = NULL; - CFArrayRef imported_items = NULL; - SecIdentityRef identity = NULL; - SecKeychainRef keychain = NULL; - SecExternalFormat sef = kSecFormatPKCS12; - SecItemImportExportKeyParameters keyParams = { - .passphrase = CFSTR("password") - }; - - /* Create encoder */ - ok_status(CMSEncoderCreate(&encoder), "Create CMS encoder"); - ok_status(CMSEncoderSetSignerAlgorithm(encoder, kCMSEncoderDigestAlgorithmSHA256), - "Set digest algorithm to SHA256"); - - /* Load identity and set as signer */ - unlink(TMP_KEYCHAIN_PATH); - ok_status(SecKeychainCreate(TMP_KEYCHAIN_PATH, 8, "password", false, NULL, &keychain), - "Create keychain for identity"); - ok(p12Data = CFDataCreate(NULL, signing_identity_p12, sizeof(signing_identity_p12)), - "Create p12 data"); - ok_status(SecItemImport(p12Data, NULL, &sef, NULL, 0, &keyParams, keychain, &imported_items), - "Import identity"); - is(CFArrayGetCount(imported_items),1,"Imported 1 items"); - is(CFGetTypeID(CFArrayGetValueAtIndex(imported_items, 0)), SecIdentityGetTypeID(), - "Got back an identity"); - ok(identity = (SecIdentityRef) CFRetainSafe(CFArrayGetValueAtIndex(imported_items, 0)), - "Retrieve identity"); - ok_status(CMSEncoderAddSigners(encoder, identity), "Set Signer identity"); - - /* Add signing time attribute for 3 November 2015 */ - ok_status(CMSEncoderAddSignedAttributes(encoder, kCMSAttrSigningTime), - "Set signing time flag"); - ok_status(CMSEncoderSetSigningTime(encoder, 468295000.0), "Set Signing time"); - - /* Add hash agility attribute */ - ok_status(CMSEncoderAddSignedAttributes(encoder, kCMSAttrAppleCodesigningHashAgility), - "Set hash agility flag"); - ok(attributeData = CFDataCreate(NULL, attribute, sizeof(attribute)), - "Create atttribute object"); - ok_status(CMSEncoderSetAppleCodesigningHashAgility(encoder, attributeData), - "Set hash agility data"); - - /* Load content */ - ok_status(CMSEncoderSetHasDetachedContent(encoder, true), "Set detached content"); - ok_status(CMSEncoderUpdateContent(encoder, content, sizeof(content)), "Set content"); - - /* output cms message */ - ok_status(CMSEncoderCopyEncodedContent(encoder, &message), "Finish encoding and output message"); - - /* decode message */ - CMSDecoderRef decoder = NULL; - CFDataRef contentData = NULL; - isnt(message, NULL, "Encoded message exists"); - ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); - ok_status(CMSDecoderUpdateMessage(decoder, CFDataGetBytePtr(message), CFDataGetLength(message)), - "Update decoder with CMS message"); - ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); - ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); - ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); - - /* Cleanup */ - ok_status(SecKeychainDelete(keychain), "Delete temporary keychain"); - - CFReleaseNull(encoder); - CFReleaseNull(keychain); - CFReleaseNull(p12Data); - CFReleaseNull(imported_items); - CFReleaseNull(identity); - CFReleaseNull(attributeData); - CFReleaseNull(message); - CFReleaseNull(decoder); - CFReleaseNull(contentData); -} - -static void decode_positive_test(void) -{ - CMSDecoderRef decoder = NULL; - CFDataRef contentData = NULL, attrValue = NULL; - SecPolicyRef policy = NULL; - SecTrustRef trust = NULL; - CMSSignerStatus signerStatus; - CFAbsoluteTime signingTime = 0.0; - - /* Create decoder and decode */ - ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); - ok_status(CMSDecoderUpdateMessage(decoder, valid_message, sizeof(valid_message)), - "Update decoder with CMS message"); - ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); - ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); - ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); - - /* Get signer status */ - ok(policy = SecPolicyCreateBasicX509(), "Create policy"); - ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), - "Copy Signer status"); - is(signerStatus, kCMSSignerValid, "Valid signature"); - - /* Get Hash Agility Attribute value */ - ok_status(CMSDecoderCopySignerAppleCodesigningHashAgility(decoder, 0, &attrValue), - "Copy hash agility attribute value"); - is(CFDataGetLength(attrValue), sizeof(attribute), "Decoded attribute size"); - is(memcmp(attribute, CFDataGetBytePtr(attrValue), sizeof(attribute)), 0, - "Decoded value same as input value"); - - /* Get Signing Time Attribute value */ - ok_status(CMSDecoderCopySignerSigningTime(decoder, 0, &signingTime), - "Copy signing time attribute value"); - is(signingTime, 468295000.0, "Decoded date same as input date"); - - CFReleaseNull(decoder); - CFReleaseNull(contentData); - CFReleaseNull(policy); - CFReleaseNull(trust); - CFReleaseNull(attrValue); -} - -static void decode_negative_test(void) -{ - CMSDecoderRef decoder = NULL; - CFDataRef contentData = NULL; - SecPolicyRef policy = NULL; - SecTrustRef trust = NULL; - CMSSignerStatus signerStatus; - - /* Create decoder and decode */ - ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); - ok_status(CMSDecoderUpdateMessage(decoder, invalid_message, sizeof(invalid_message)), - "Update decoder with CMS message"); - ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); - ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); - ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); - - /* Get signer status */ - ok(policy = SecPolicyCreateBasicX509(), "Create policy"); - ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), - "Copy Signer status"); - is(signerStatus, kCMSSignerInvalidSignature, "Invalid signature"); - - CFReleaseNull(decoder); - CFReleaseNull(contentData); - CFReleaseNull(policy); - CFReleaseNull(trust); -} - -static void decode_no_attr_test(void) -{ - CMSDecoderRef decoder = NULL; - CFDataRef contentData = NULL, attrValue = NULL; - SecPolicyRef policy = NULL; - SecTrustRef trust = NULL; - CMSSignerStatus signerStatus; - - /* Create decoder and decode */ - ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); - ok_status(CMSDecoderUpdateMessage(decoder, valid_no_attr, sizeof(valid_no_attr)), - "Update decoder with CMS message"); - ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); - ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); - ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); - - /* Get signer status */ - ok(policy = SecPolicyCreateBasicX509(), "Create policy"); - ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), - "Copy Signer status"); - is(signerStatus, kCMSSignerValid, "Valid signature"); - - /* Get Hash Agility Attribute value */ - ok_status(CMSDecoderCopySignerAppleCodesigningHashAgility(decoder, 0, &attrValue), - "Copy empty hash agility attribute value"); - is(attrValue, NULL, "NULL attribute value"); - - CFReleaseNull(decoder); - CFReleaseNull(contentData); - CFReleaseNull(policy); - CFReleaseNull(trust); - CFReleaseNull(attrValue); -} - -int cms_hash_agility_test(int argc, char *const *argv) -{ - plan_tests(24+13+8+10); - - encode_test(); - decode_positive_test(); - decode_negative_test(); - decode_no_attr_test(); - - return 0; -} diff --git a/OSX/libsecurity_cms/regressions/cms-hashagility-test.h b/OSX/libsecurity_cms/regressions/cms-hashagility-test.h index 27bf5ee3..f58da959 100644 --- a/OSX/libsecurity_cms/regressions/cms-hashagility-test.h +++ b/OSX/libsecurity_cms/regressions/cms-hashagility-test.h @@ -324,6 +324,14 @@ uint8_t attribute[32] = { 0x87, 0xa0, 0x4e, 0x80, 0xf4, 0xf3, 0x5d, 0xd2, 0x68, 0x08, 0x58, 0xe6 }; +/* Random data for hash agility V2 attribute */ +unsigned char _attributev2[64] = { + 0x28, 0x4f, 0x7f, 0xf5, 0xf8, 0x14, 0x80, 0xa6, 0x6b, 0x37, 0x44, 0xeb, 0xed, 0x1e, 0xf1, 0x3d, + 0x35, 0x4e, 0x02, 0x21, 0xdc, 0x26, 0x61, 0x33, 0x71, 0x57, 0x18, 0xc7, 0xdd, 0xc2, 0x50, 0xbf, + 0xfc, 0x9d, 0x6f, 0x8e, 0x8b, 0xe2, 0x3d, 0x1d, 0x41, 0xbf, 0xe6, 0xd1, 0x7a, 0xc9, 0x3f, 0xc9, + 0x4d, 0xdd, 0x38, 0x35, 0xbd, 0xdf, 0x98, 0x95, 0x0a, 0x00, 0xc6, 0x6d, 0x30, 0xe2, 0x37, 0x3b +}; + /* Valid CMS message on content with hash agility attribute */ uint8_t valid_message[] = { 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, @@ -837,4 +845,176 @@ unsigned char valid_no_attr[] = { 0x00 }; +unsigned char _V2_valid_message[] = { + 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, + 0x80, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x07, 0x01, 0x00, 0x00, 0xa0, 0x82, 0x06, 0xb4, 0x30, 0x82, 0x06, 0xb0, 0x30, 0x82, 0x04, 0x98, + 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xdd, 0x3f, 0x19, 0x90, 0xd8, 0x99, 0xba, 0x86, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, + 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, + 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, + 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, + 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x25, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x18, + 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, + 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, + 0x32, 0x39, 0x32, 0x31, 0x35, 0x35, 0x35, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x30, 0x32, + 0x38, 0x32, 0x31, 0x35, 0x35, 0x35, 0x38, 0x5a, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, + 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, + 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x70, 0x70, 0x6c, + 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x13, 0x25, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x41, 0x72, 0x63, 0x68, 0x69, + 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0f, 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, + 0x72, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, + 0x01, 0x00, 0xc4, 0x2a, 0x38, 0x4b, 0xdd, 0x1c, 0xc7, 0x39, 0x47, 0xba, 0xbc, 0x5d, 0xd2, 0xcc, + 0x6e, 0x9e, 0x2c, 0x81, 0x26, 0x18, 0x59, 0x18, 0xb8, 0x45, 0x0c, 0xde, 0x5b, 0xbc, 0x25, 0xa4, + 0x78, 0x0b, 0x16, 0x3d, 0x3d, 0x10, 0x34, 0x48, 0xcf, 0x1f, 0x40, 0xaa, 0x4b, 0xb5, 0xbc, 0xf0, + 0x81, 0x5e, 0xa8, 0x72, 0xed, 0x6a, 0x8c, 0xf0, 0x4a, 0x9a, 0x80, 0x09, 0x3b, 0x89, 0xed, 0xad, + 0x2b, 0xb5, 0x5b, 0x0f, 0xe4, 0x3f, 0x6b, 0xc5, 0x15, 0x33, 0x5e, 0xdd, 0xa4, 0xac, 0x2f, 0xa5, + 0x13, 0x0f, 0x3c, 0xfc, 0xd8, 0xca, 0xb8, 0x88, 0x67, 0x75, 0xc4, 0x9a, 0x4c, 0x18, 0x9a, 0x38, + 0x68, 0xaa, 0x4c, 0x94, 0x35, 0xed, 0xa4, 0x0b, 0x80, 0x2b, 0xa9, 0x4d, 0xa4, 0x57, 0x22, 0xfc, + 0xd2, 0xc3, 0x12, 0x0b, 0x8a, 0x3c, 0xd7, 0x6d, 0x8b, 0x47, 0x4f, 0x24, 0xe5, 0xea, 0x1b, 0x03, + 0x78, 0xa2, 0x12, 0x36, 0x3f, 0x92, 0x16, 0x36, 0xff, 0xc5, 0xaf, 0xc3, 0xec, 0x4b, 0x6c, 0x23, + 0x04, 0x1b, 0xa9, 0xce, 0x3a, 0xa1, 0xa5, 0xe0, 0x54, 0x13, 0x43, 0x13, 0x29, 0x95, 0x5b, 0xcb, + 0x97, 0x74, 0x01, 0xbc, 0x3c, 0xb8, 0xa1, 0xb0, 0xf3, 0x3c, 0xfa, 0x21, 0x7a, 0x89, 0x90, 0x2b, + 0x1f, 0x20, 0x3f, 0xc1, 0x22, 0xda, 0x8d, 0xa5, 0x30, 0x57, 0x6d, 0xd4, 0x40, 0x99, 0x08, 0x0d, + 0xef, 0x36, 0x16, 0xa6, 0xec, 0xcf, 0x26, 0x78, 0x7c, 0x77, 0x7e, 0x50, 0x2a, 0xe3, 0xdf, 0x28, + 0xff, 0xd0, 0xc7, 0x0e, 0x8b, 0x6b, 0x56, 0x62, 0x53, 0x37, 0x5a, 0x1a, 0x85, 0x50, 0xec, 0x6a, + 0x6b, 0x2e, 0xd1, 0x35, 0x6e, 0x5d, 0x92, 0x30, 0x39, 0x82, 0x40, 0x7b, 0x6d, 0x89, 0x5b, 0x4d, + 0x30, 0x6d, 0x2e, 0x68, 0x16, 0x24, 0x63, 0x32, 0x24, 0xdc, 0x3e, 0x5b, 0x4a, 0xc4, 0x41, 0xfc, + 0x76, 0x07, 0xe6, 0xa3, 0x1b, 0x18, 0xec, 0x59, 0xed, 0x13, 0x0b, 0x2d, 0xe9, 0x86, 0x89, 0x2c, + 0x0a, 0xb0, 0x19, 0x97, 0x4d, 0x1b, 0xfb, 0xd4, 0xef, 0x54, 0xcd, 0xe5, 0xb2, 0x22, 0x70, 0x3a, + 0x50, 0x03, 0xaa, 0xc0, 0xf8, 0xb4, 0x8e, 0x16, 0xd8, 0x2a, 0xc1, 0xd1, 0x2d, 0xa0, 0x27, 0x59, + 0x63, 0x70, 0xc3, 0x74, 0x14, 0xee, 0xde, 0xa9, 0xd9, 0x73, 0xdb, 0x16, 0x6d, 0xef, 0x7f, 0x50, + 0xb6, 0xd2, 0x54, 0x0d, 0x4d, 0x31, 0x5f, 0x23, 0x2c, 0xfd, 0x8f, 0x67, 0x7c, 0xe9, 0xaa, 0x1c, + 0x29, 0xf5, 0x83, 0x1b, 0x2b, 0x0e, 0x66, 0x0e, 0x5c, 0xfe, 0xc9, 0x38, 0xb0, 0x90, 0xfa, 0x31, + 0x4c, 0xb1, 0xef, 0xea, 0xd0, 0x47, 0x17, 0xde, 0x45, 0xc1, 0x93, 0xef, 0xba, 0xde, 0x9f, 0x69, + 0xc7, 0xa6, 0x14, 0x23, 0xb1, 0x8b, 0xaa, 0xbf, 0x61, 0x37, 0x57, 0x11, 0x6a, 0xb2, 0xf7, 0xec, + 0x52, 0x7e, 0x65, 0x80, 0xff, 0xa1, 0xa8, 0x20, 0x7e, 0x0b, 0xae, 0x21, 0xfa, 0xe8, 0x20, 0x52, + 0x93, 0xc5, 0xe9, 0x39, 0x5b, 0x8e, 0xab, 0xef, 0x86, 0xa6, 0xd8, 0x43, 0x7e, 0xa9, 0x5c, 0x6d, + 0x91, 0xd8, 0x5c, 0xa4, 0x2a, 0xed, 0x26, 0xa8, 0x1b, 0xaa, 0x3b, 0xfa, 0x86, 0x75, 0x37, 0xc6, + 0x70, 0x12, 0x2b, 0x8c, 0x55, 0x96, 0x76, 0x04, 0xf6, 0xe3, 0xf9, 0xe2, 0x0d, 0x2e, 0xe0, 0x23, + 0xdf, 0xfa, 0xe0, 0x9c, 0x11, 0xf9, 0xd4, 0x51, 0x05, 0xed, 0x2b, 0x3f, 0xa3, 0x3f, 0xa2, 0xe6, + 0x30, 0x81, 0x17, 0x00, 0x8f, 0x15, 0x91, 0xfb, 0x21, 0x62, 0xf4, 0xff, 0x93, 0x1a, 0x2e, 0xfe, + 0x1a, 0xcb, 0x93, 0x3d, 0xd4, 0x6e, 0x3a, 0xb8, 0x70, 0xdf, 0x93, 0xb4, 0x02, 0xc4, 0x8c, 0x54, + 0x92, 0xde, 0xa7, 0x32, 0x65, 0x1c, 0x85, 0x95, 0x34, 0xf8, 0x8d, 0x06, 0x5b, 0x7d, 0x72, 0x00, + 0xd8, 0x31, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xfe, 0x30, 0x81, 0xfb, 0x30, 0x1d, 0x06, + 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xee, 0x16, 0xde, 0xfd, 0x11, 0xd3, 0x88, 0xfb, + 0xef, 0xfb, 0x19, 0x23, 0x8a, 0x23, 0x85, 0x7b, 0xe8, 0x41, 0x26, 0xa1, 0x30, 0x81, 0xcb, 0x06, + 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xc3, 0x30, 0x81, 0xc0, 0x80, 0x14, 0xee, 0x16, 0xde, 0xfd, + 0x11, 0xd3, 0x88, 0xfb, 0xef, 0xfb, 0x19, 0x23, 0x8a, 0x23, 0x85, 0x7b, 0xe8, 0x41, 0x26, 0xa1, + 0xa1, 0x81, 0x9c, 0xa4, 0x81, 0x99, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, + 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, + 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, + 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x25, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, + 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, + 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, + 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x82, + 0x09, 0x00, 0xdd, 0x3f, 0x19, 0x90, 0xd8, 0x99, 0xba, 0x86, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, + 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x0c, 0x0f, 0x08, 0x79, + 0x6f, 0x56, 0x21, 0xdf, 0xdd, 0xf5, 0x97, 0x8d, 0xdc, 0x97, 0x06, 0xfb, 0x2e, 0xe0, 0x21, 0x60, + 0xc3, 0x02, 0xf4, 0x41, 0x79, 0x79, 0xc2, 0x23, 0x9a, 0x8a, 0x54, 0x2e, 0x66, 0xab, 0xc0, 0x21, + 0xf6, 0x9f, 0xc5, 0x2e, 0x41, 0xb8, 0xa3, 0x32, 0x9f, 0x3d, 0x4e, 0xf4, 0x83, 0xee, 0xcc, 0x60, + 0xf6, 0x82, 0x3d, 0xb4, 0xa9, 0x9d, 0xcd, 0xa0, 0x02, 0x89, 0xb0, 0x32, 0x1b, 0xb5, 0x7c, 0xf4, + 0x8f, 0xbc, 0x9b, 0x24, 0xc2, 0xe2, 0x81, 0xd6, 0x6f, 0x0e, 0x22, 0x5e, 0x50, 0xd9, 0x5b, 0x2e, + 0x89, 0xbf, 0xa4, 0xfe, 0xa8, 0xc2, 0x9a, 0xf4, 0xec, 0x70, 0x66, 0x01, 0x4b, 0x50, 0x30, 0x97, + 0x0a, 0xcc, 0x9f, 0xac, 0xe4, 0x89, 0x1c, 0x8d, 0x88, 0x0d, 0xdb, 0x21, 0xbd, 0x2f, 0x24, 0x8e, + 0x83, 0xf9, 0xe6, 0x71, 0xed, 0x71, 0x26, 0x31, 0x99, 0x9d, 0x04, 0xeb, 0x34, 0xea, 0x6d, 0x65, + 0xb8, 0x02, 0x83, 0x57, 0x78, 0x36, 0x3a, 0x0b, 0xc7, 0x41, 0x63, 0xb5, 0xf6, 0x1c, 0xd2, 0x01, + 0x86, 0x04, 0x58, 0x40, 0x3e, 0x91, 0x98, 0x39, 0x72, 0x75, 0x11, 0xca, 0x14, 0x73, 0x90, 0x34, + 0x8b, 0x21, 0xa4, 0xd0, 0xba, 0xe7, 0x33, 0x03, 0x22, 0x0f, 0x1a, 0xf7, 0x10, 0x2b, 0x69, 0x4c, + 0x73, 0xef, 0x04, 0x18, 0xf9, 0xe1, 0x11, 0xa8, 0xb8, 0x1b, 0x57, 0x0b, 0x03, 0x10, 0x1c, 0xce, + 0x13, 0xca, 0xe4, 0xde, 0x8c, 0xf4, 0xcf, 0xf5, 0xb7, 0x80, 0x3e, 0xbc, 0x1f, 0x51, 0x9b, 0x20, + 0x8c, 0xb0, 0x2d, 0x67, 0x1c, 0x84, 0x25, 0x4c, 0x8b, 0xd3, 0xa7, 0x09, 0x8e, 0x60, 0xe2, 0x99, + 0x0d, 0x10, 0x12, 0x14, 0xfc, 0x17, 0x62, 0x69, 0xcd, 0xa4, 0x64, 0xf0, 0x7e, 0xba, 0xe0, 0xc9, + 0x51, 0x78, 0xf8, 0xb4, 0x0d, 0x7d, 0xb8, 0xa0, 0xee, 0x9c, 0x9e, 0x84, 0xd5, 0xa4, 0x02, 0xe5, + 0x7a, 0x1c, 0x65, 0xe1, 0x20, 0xfb, 0x4d, 0x61, 0x7a, 0x47, 0x25, 0x06, 0x95, 0x17, 0x62, 0x60, + 0x4b, 0x0b, 0xc6, 0xca, 0xa7, 0x35, 0x8f, 0xd4, 0x63, 0x3e, 0x5e, 0x92, 0x1a, 0x08, 0x7c, 0x6b, + 0x15, 0x41, 0x95, 0x76, 0x7d, 0x39, 0x28, 0xec, 0x3e, 0x1f, 0x49, 0xd5, 0xd5, 0x89, 0xf9, 0x5f, + 0x14, 0x02, 0x2f, 0x27, 0xb0, 0x39, 0xba, 0xf7, 0x91, 0x53, 0x75, 0x77, 0xab, 0x88, 0x40, 0x1d, + 0x77, 0xaf, 0x79, 0xfd, 0xdc, 0xac, 0x99, 0x82, 0xf2, 0x46, 0x05, 0x97, 0x60, 0xef, 0x7b, 0xf5, + 0x34, 0x38, 0xbf, 0xd7, 0x42, 0x3e, 0x8b, 0x5a, 0x4a, 0x0c, 0x22, 0x7e, 0x4d, 0x4e, 0xf6, 0xf7, + 0xcc, 0x6e, 0x31, 0x33, 0x1a, 0x84, 0xbe, 0x07, 0xf7, 0xe8, 0xe2, 0x43, 0x00, 0x54, 0x4a, 0x38, + 0xda, 0x98, 0xe3, 0x84, 0xb2, 0xd0, 0x76, 0x79, 0x94, 0x11, 0x7e, 0xa8, 0xca, 0x56, 0xa0, 0xfd, + 0x4b, 0xba, 0x7c, 0x0a, 0xa4, 0x34, 0x01, 0xad, 0xf4, 0x37, 0x4f, 0x38, 0x33, 0x9f, 0x71, 0xdc, + 0xc4, 0x4c, 0x96, 0xb0, 0x8a, 0x86, 0xe5, 0x8d, 0xd2, 0x44, 0xe3, 0x18, 0xcb, 0x81, 0xa6, 0x7c, + 0xaf, 0x8e, 0xfb, 0x41, 0x6e, 0xc5, 0x82, 0xf0, 0x51, 0xb7, 0x0f, 0x23, 0x9b, 0x77, 0xed, 0x9a, + 0x06, 0x6b, 0x77, 0x7c, 0x8e, 0xc4, 0xdf, 0x50, 0xa0, 0xd2, 0x81, 0x3e, 0x65, 0xbe, 0xe5, 0x51, + 0x79, 0x93, 0x24, 0x8e, 0xb3, 0xb5, 0x25, 0x48, 0x76, 0x0e, 0x75, 0x94, 0xef, 0x9a, 0x9d, 0xc7, + 0x95, 0x08, 0xca, 0x35, 0x6b, 0x73, 0xbc, 0x4b, 0x93, 0x7a, 0x93, 0x55, 0x2d, 0xe4, 0x5f, 0xcf, + 0x11, 0x31, 0x94, 0xb2, 0x5a, 0x05, 0x80, 0xd7, 0x59, 0x79, 0x14, 0x8a, 0x2a, 0xb9, 0xd7, 0x3d, + 0x33, 0x69, 0xa9, 0xab, 0xaa, 0xb8, 0x4c, 0x73, 0xb6, 0x71, 0x2c, 0x6f, 0x31, 0x82, 0x03, 0x99, + 0x30, 0x82, 0x03, 0x95, 0x02, 0x01, 0x01, 0x30, 0x81, 0xa4, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, + 0x69, 0x6e, 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x70, + 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x13, 0x25, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x6e, 0x67, + 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x41, 0x72, 0x63, + 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x0f, 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, + 0x6e, 0x65, 0x72, 0x02, 0x09, 0x00, 0xdd, 0x3f, 0x19, 0x90, 0xd8, 0x99, 0xba, 0x86, 0x30, 0x0d, + 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa0, 0x81, 0xc6, + 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0b, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x37, 0x31, 0x30, 0x32, + 0x36, 0x30, 0x38, 0x34, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x22, 0x04, 0x20, 0x30, 0x9e, 0x11, 0x91, 0x83, 0x14, 0xd8, + 0xb9, 0xd6, 0x24, 0x8e, 0x04, 0x7e, 0x31, 0xa7, 0x66, 0xf7, 0x3c, 0x96, 0xc6, 0x23, 0x60, 0x2e, + 0xec, 0x9e, 0x0c, 0xda, 0xab, 0x25, 0x58, 0x02, 0xf2, 0x30, 0x5b, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x63, 0x64, 0x09, 0x02, 0x31, 0x4e, 0x30, 0x2d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x01, 0x04, 0x20, 0xfc, 0x9d, 0x6f, 0x8e, 0x8b, 0xe2, 0x3d, 0x1d, 0x41, + 0xbf, 0xe6, 0xd1, 0x7a, 0xc9, 0x3f, 0xc9, 0x4d, 0xdd, 0x38, 0x35, 0xbd, 0xdf, 0x98, 0x95, 0x0a, + 0x00, 0xc6, 0x6d, 0x30, 0xe2, 0x37, 0x3b, 0x30, 0x1d, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, + 0x04, 0x14, 0x28, 0x4f, 0x7f, 0xf5, 0xf8, 0x14, 0x80, 0xa6, 0x6b, 0x37, 0x44, 0xeb, 0xed, 0x1e, + 0xf1, 0x3d, 0x35, 0x4e, 0x02, 0x21, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0x7c, 0x31, 0x1c, 0x96, 0xbd, 0x0a, 0xe5, + 0x47, 0xab, 0xa0, 0xb4, 0x29, 0x0f, 0x3e, 0xe7, 0x7a, 0x81, 0x87, 0x7e, 0x04, 0x30, 0xf3, 0x95, + 0xe7, 0x54, 0x68, 0xe9, 0x97, 0xae, 0xdc, 0x5a, 0x5d, 0x52, 0xc8, 0x82, 0x27, 0x3b, 0x0a, 0x7c, + 0xe1, 0x69, 0x2f, 0x46, 0x8d, 0xca, 0x77, 0xf3, 0xbf, 0x68, 0xd3, 0xda, 0xcb, 0xb3, 0x11, 0x93, + 0x81, 0x37, 0x22, 0x42, 0xbd, 0x6a, 0x55, 0x02, 0xe7, 0x85, 0x4c, 0x09, 0x5a, 0x02, 0x73, 0x98, + 0xdd, 0x7c, 0x03, 0x00, 0x53, 0xd2, 0x2e, 0x0a, 0x6f, 0x51, 0x8e, 0x95, 0x24, 0xdd, 0x32, 0x9c, + 0x4a, 0x22, 0x38, 0x7f, 0x65, 0x49, 0x17, 0xeb, 0x43, 0x0b, 0xbe, 0x8d, 0x14, 0xdc, 0xde, 0x48, + 0x74, 0x16, 0xbf, 0xe8, 0xed, 0x34, 0x67, 0x62, 0xca, 0x64, 0x57, 0xc4, 0x61, 0xf7, 0xf7, 0xfb, + 0xf2, 0xd0, 0xd1, 0xfd, 0x2e, 0x05, 0xe7, 0xd7, 0x99, 0x75, 0xa8, 0x76, 0x4e, 0xd4, 0x22, 0x67, + 0x2d, 0x34, 0xf6, 0x71, 0x48, 0x4f, 0x78, 0x8e, 0xe1, 0xb9, 0x55, 0x4d, 0x55, 0x87, 0x08, 0xc9, + 0xab, 0xbd, 0xb8, 0x87, 0x2c, 0x27, 0xef, 0x89, 0x93, 0x9c, 0xc0, 0xc1, 0xec, 0x89, 0x0f, 0xc2, + 0xe3, 0x55, 0x6a, 0x1d, 0xd9, 0x96, 0x1d, 0xa4, 0xdf, 0x50, 0x3d, 0x36, 0x25, 0x3e, 0xd4, 0x3e, + 0x1f, 0x44, 0x97, 0xe0, 0x46, 0xe7, 0xb7, 0x81, 0x7d, 0xc3, 0xd5, 0x36, 0xe7, 0x04, 0x34, 0xab, + 0x60, 0x27, 0xc9, 0x00, 0xdd, 0xfa, 0x7c, 0x32, 0x90, 0xa1, 0x62, 0xe4, 0x51, 0x8f, 0x54, 0x81, + 0xa6, 0x5c, 0xcd, 0xaf, 0x3b, 0xb7, 0x12, 0xa6, 0x87, 0x0a, 0x36, 0x5d, 0xc9, 0x77, 0xc3, 0x50, + 0xc6, 0x97, 0x14, 0x43, 0x36, 0x20, 0x6f, 0x40, 0xb3, 0x1f, 0x50, 0x87, 0x24, 0x47, 0x79, 0x93, + 0x9a, 0xc1, 0x61, 0x83, 0xae, 0xc8, 0x00, 0x56, 0x3c, 0x5b, 0x5f, 0xbb, 0x9b, 0xdf, 0x75, 0xea, + 0xc2, 0x3d, 0xf1, 0xd7, 0x26, 0xe5, 0x6b, 0xa1, 0x75, 0x01, 0x0a, 0x3f, 0xae, 0x43, 0x37, 0xdd, + 0xbf, 0x7a, 0x83, 0xa1, 0xb6, 0xc2, 0xb7, 0x2b, 0xda, 0x99, 0xa6, 0x75, 0xb8, 0xc6, 0xf0, 0xc4, + 0x6b, 0x6a, 0xe4, 0xda, 0xac, 0xab, 0x7c, 0xef, 0x6f, 0x7c, 0x73, 0xca, 0x22, 0x33, 0xdd, 0xee, + 0x05, 0xfc, 0x05, 0x90, 0xc5, 0x3f, 0xdd, 0xa6, 0x6f, 0x5b, 0x2d, 0xaf, 0x99, 0x89, 0x93, 0xf0, + 0xfa, 0xb0, 0x8e, 0xcf, 0x39, 0xf1, 0x03, 0xfe, 0x0c, 0x8a, 0x6d, 0x30, 0x6c, 0x2b, 0x67, 0x84, + 0x60, 0x2d, 0x98, 0x80, 0x6c, 0xa7, 0x3e, 0x44, 0xda, 0x44, 0x42, 0x22, 0x7d, 0xcc, 0x43, 0x1c, + 0x7a, 0x89, 0x8c, 0xa0, 0x07, 0xd0, 0x08, 0x45, 0xe0, 0x18, 0x6b, 0x58, 0xb1, 0x66, 0x49, 0x97, + 0xdd, 0xde, 0xa2, 0x73, 0xaf, 0x55, 0xdc, 0x9f, 0xe6, 0x82, 0x67, 0xdf, 0x14, 0x29, 0x90, 0x1a, + 0x00, 0xa8, 0x0a, 0x59, 0xa0, 0xef, 0x97, 0x3d, 0x09, 0x54, 0x0c, 0xe4, 0xa8, 0x3b, 0xdd, 0x08, + 0xb0, 0x9e, 0x48, 0x93, 0xa7, 0xea, 0xaa, 0xe2, 0x55, 0xca, 0x1b, 0xe8, 0xb0, 0x25, 0xa4, 0xf4, + 0x79, 0xad, 0x03, 0xe1, 0xa3, 0xb9, 0x9a, 0x27, 0x12, 0xe5, 0xe8, 0x08, 0x28, 0x36, 0xb2, 0x93, + 0x3a, 0xf8, 0x45, 0x38, 0xea, 0xd7, 0x2f, 0xa7, 0x37, 0xd1, 0xcf, 0x35, 0xef, 0xaf, 0x51, 0x76, + 0xc3, 0xf9, 0x9a, 0xc8, 0x7c, 0x17, 0x00, 0x48, 0xa0, 0x16, 0x10, 0x1c, 0x3f, 0xeb, 0xca, 0xa0, + 0xb5, 0xb7, 0x0b, 0xc1, 0xb8, 0xcf, 0x3a, 0xbd, 0xeb, 0xab, 0x1a, 0xf7, 0x00, 0x78, 0x34, 0xbd, + 0xe0, 0xfd, 0xc4, 0x8e, 0x51, 0x2e, 0x2e, 0x45, 0x18, 0x5e, 0x87, 0x33, 0xbb, 0x26, 0x71, 0x3f, + 0xad, 0x79, 0xc5, 0x60, 0x9c, 0xda, 0xc3, 0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + #endif /* cms_hashagility_test_h */ diff --git a/OSX/libsecurity_cms/regressions/cms-hashagility-test.m b/OSX/libsecurity_cms/regressions/cms-hashagility-test.m new file mode 100644 index 00000000..7657edc7 --- /dev/null +++ b/OSX/libsecurity_cms/regressions/cms-hashagility-test.m @@ -0,0 +1,422 @@ +/* + * Copyright (c) 2015-2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cms-hashagility-test.h" + +#define TMP_KEYCHAIN_PATH "/tmp/cms_signer.keychain" + +/* encode test */ +static void encode_test(void) +{ + CMSEncoderRef encoder = NULL; + CFDataRef attributeData = NULL, message = NULL, p12Data = NULL; + CFArrayRef imported_items = NULL; + SecIdentityRef identity = NULL; + SecKeychainRef keychain = NULL; + SecExternalFormat sef = kSecFormatPKCS12; + SecItemImportExportKeyParameters keyParams = { + .passphrase = CFSTR("password") + }; + + /* Create encoder */ + ok_status(CMSEncoderCreate(&encoder), "Create CMS encoder"); + ok_status(CMSEncoderSetSignerAlgorithm(encoder, kCMSEncoderDigestAlgorithmSHA256), + "Set digest algorithm to SHA256"); + + /* Load identity and set as signer */ + unlink(TMP_KEYCHAIN_PATH); + ok_status(SecKeychainCreate(TMP_KEYCHAIN_PATH, 8, "password", false, NULL, &keychain), + "Create keychain for identity"); + ok(p12Data = CFDataCreate(NULL, signing_identity_p12, sizeof(signing_identity_p12)), + "Create p12 data"); + ok_status(SecItemImport(p12Data, NULL, &sef, NULL, 0, &keyParams, keychain, &imported_items), + "Import identity"); + is(CFArrayGetCount(imported_items),1,"Imported 1 items"); + is(CFGetTypeID(CFArrayGetValueAtIndex(imported_items, 0)), SecIdentityGetTypeID(), + "Got back an identity"); + ok(identity = (SecIdentityRef) CFRetainSafe(CFArrayGetValueAtIndex(imported_items, 0)), + "Retrieve identity"); + ok_status(CMSEncoderAddSigners(encoder, identity), "Set Signer identity"); + + /* Add signing time attribute for 3 November 2015 */ + ok_status(CMSEncoderAddSignedAttributes(encoder, kCMSAttrSigningTime), + "Set signing time flag"); + ok_status(CMSEncoderSetSigningTime(encoder, 468295000.0), "Set Signing time"); + + /* Add hash agility attribute */ + ok_status(CMSEncoderAddSignedAttributes(encoder, kCMSAttrAppleCodesigningHashAgility), + "Set hash agility flag"); + ok(attributeData = CFDataCreate(NULL, attribute, sizeof(attribute)), + "Create atttribute object"); + ok_status(CMSEncoderSetAppleCodesigningHashAgility(encoder, attributeData), + "Set hash agility data"); + + /* Load content */ + ok_status(CMSEncoderSetHasDetachedContent(encoder, true), "Set detached content"); + ok_status(CMSEncoderUpdateContent(encoder, content, sizeof(content)), "Set content"); + + /* output cms message */ + ok_status(CMSEncoderCopyEncodedContent(encoder, &message), "Finish encoding and output message"); + + /* decode message */ + CMSDecoderRef decoder = NULL; + CFDataRef contentData = NULL; + isnt(message, NULL, "Encoded message exists"); + ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); + ok_status(CMSDecoderUpdateMessage(decoder, CFDataGetBytePtr(message), CFDataGetLength(message)), + "Update decoder with CMS message"); + ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); + ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + + /* Cleanup */ + ok_status(SecKeychainDelete(keychain), "Delete temporary keychain"); + + CFReleaseNull(encoder); + CFReleaseNull(keychain); + CFReleaseNull(p12Data); + CFReleaseNull(imported_items); + CFReleaseNull(identity); + CFReleaseNull(attributeData); + CFReleaseNull(message); + CFReleaseNull(decoder); + CFReleaseNull(contentData); +} + +static void decode_positive_test(void) +{ + CMSDecoderRef decoder = NULL; + CFDataRef contentData = NULL, attrValue = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CMSSignerStatus signerStatus; + CFAbsoluteTime signingTime = 0.0; + + /* Create decoder and decode */ + ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); + ok_status(CMSDecoderUpdateMessage(decoder, valid_message, sizeof(valid_message)), + "Update decoder with CMS message"); + ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); + ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + + /* Get signer status */ + ok(policy = SecPolicyCreateBasicX509(), "Create policy"); + ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), + "Copy Signer status"); + is(signerStatus, kCMSSignerValid, "Valid signature"); + + /* Get Hash Agility Attribute value */ + ok_status(CMSDecoderCopySignerAppleCodesigningHashAgility(decoder, 0, &attrValue), + "Copy hash agility attribute value"); + is(CFDataGetLength(attrValue), sizeof(attribute), "Decoded attribute size"); + is(memcmp(attribute, CFDataGetBytePtr(attrValue), sizeof(attribute)), 0, + "Decoded value same as input value"); + + /* Get Signing Time Attribute value */ + ok_status(CMSDecoderCopySignerSigningTime(decoder, 0, &signingTime), + "Copy signing time attribute value"); + is(signingTime, 468295000.0, "Decoded date same as input date"); + + CFReleaseNull(decoder); + CFReleaseNull(contentData); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(attrValue); +} + +static void decode_negative_test(void) +{ + CMSDecoderRef decoder = NULL; + CFDataRef contentData = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CMSSignerStatus signerStatus; + + /* Create decoder and decode */ + ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); + ok_status(CMSDecoderUpdateMessage(decoder, invalid_message, sizeof(invalid_message)), + "Update decoder with CMS message"); + ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); + ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + + /* Get signer status */ + ok(policy = SecPolicyCreateBasicX509(), "Create policy"); + ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), + "Copy Signer status"); + is(signerStatus, kCMSSignerInvalidSignature, "Invalid signature"); + + CFReleaseNull(decoder); + CFReleaseNull(contentData); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +static void decode_no_attr_test(void) +{ + CMSDecoderRef decoder = NULL; + CFDataRef contentData = NULL, attrValue = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CMSSignerStatus signerStatus; + + /* Create decoder and decode */ + ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); + ok_status(CMSDecoderUpdateMessage(decoder, valid_no_attr, sizeof(valid_no_attr)), + "Update decoder with CMS message"); + ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); + ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + + /* Get signer status */ + ok(policy = SecPolicyCreateBasicX509(), "Create policy"); + ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), + "Copy Signer status"); + is(signerStatus, kCMSSignerValid, "Valid signature"); + + /* Get Hash Agility Attribute value */ + ok_status(CMSDecoderCopySignerAppleCodesigningHashAgility(decoder, 0, &attrValue), + "Copy empty hash agility attribute value"); + is(attrValue, NULL, "NULL attribute value"); + + CFReleaseNull(decoder); + CFReleaseNull(contentData); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(attrValue); +} + +static void macOS_shim_tests(void) { + encode_test(); + decode_positive_test(); + decode_negative_test(); + decode_no_attr_test(); +} + +static void encode_V2_test(void) { + CMSEncoderRef encoder = NULL; + CMSDecoderRef decoder = NULL; + NSData *p12Data = nil; + CFArrayRef tmp_imported_items = NULL; + NSArray *imported_items = nil; + SecIdentityRef identity = NULL; + CFDataRef message = NULL; + NSDictionary *attrValues = nil, *options = @{ (__bridge NSString *)kSecImportExportPassphrase : @"password" }; + + /* Create encoder */ + require_noerr_string(CMSEncoderCreate(&encoder), exit, "Failed to create CMS encoder"); + require_noerr_string(CMSEncoderSetSignerAlgorithm(encoder, kCMSEncoderDigestAlgorithmSHA256), exit, + "Failed to set digest algorithm to SHA256"); + + /* Load identity and set as signer */ + p12Data = [NSData dataWithBytes:signing_identity_p12 length:sizeof(signing_identity_p12)]; + require_noerr_string(SecPKCS12Import((__bridge CFDataRef)p12Data, (__bridge CFDictionaryRef)options, + &tmp_imported_items), exit, + "Failed to import identity"); + imported_items = CFBridgingRelease(tmp_imported_items); + require_noerr_string([imported_items count] == 0 && + [imported_items[0] isKindOfClass:[NSDictionary class]], exit, + "Wrong imported items output"); + identity = (SecIdentityRef)CFBridgingRetain(imported_items[0][(__bridge NSString*)kSecImportItemIdentity]); + require_string(identity, exit, "Failed to get identity"); + require_noerr_string(CMSEncoderAddSigners(encoder, identity), exit, "Failed to add signer identity"); + + /* Add signing time attribute for 26 October 2017 */ + require_noerr_string(CMSEncoderAddSignedAttributes(encoder, kCMSAttrSigningTime), exit, + "Failed to set signing time flag"); + require_noerr_string(CMSEncoderSetSigningTime(encoder, 530700000.0), exit, "Failed to set signing time"); + + /* Add hash agility attribute */ + attrValues = @{ @(SEC_OID_SHA1) : [NSData dataWithBytes:_attributev2 length:20], + @(SEC_OID_SHA256) : [NSData dataWithBytes:(_attributev2 + 32) length:32], + }; + ok_status(CMSEncoderAddSignedAttributes(encoder, kCMSAttrAppleCodesigningHashAgilityV2), + "Set hash agility flag"); + ok_status(CMSEncoderSetAppleCodesigningHashAgilityV2(encoder, (__bridge CFDictionaryRef)attrValues), + "Set hash agility data"); + + /* Load content */ + require_noerr_string(CMSEncoderSetHasDetachedContent(encoder, true), exit, "Failed to set detached content"); + require_noerr_string(CMSEncoderUpdateContent(encoder, content, sizeof(content)), exit, "Failed to set content"); + + /* output cms message */ + ok_status(CMSEncoderCopyEncodedContent(encoder, &message), "Finish encoding and output message"); + isnt(message, NULL, "Encoded message exists"); + + /* decode message */ + require_noerr_string(CMSDecoderCreate(&decoder), exit, "Create CMS decoder"); + require_noerr_string(CMSDecoderUpdateMessage(decoder, CFDataGetBytePtr(message), + CFDataGetLength(message)), exit, + "Update decoder with CMS message"); + require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)[NSData dataWithBytes:content + length:sizeof(content)]), + exit, "Set detached content"); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + +exit: + CFReleaseNull(encoder); + CFReleaseNull(identity); + CFReleaseNull(message); + CFReleaseNull(decoder); +} + +/* macOS shim test - decode positive */ +static void decode_V2_positive_test(void) { + CMSDecoderRef decoder = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CMSSignerStatus signerStatus; + NSData *contentData = nil; + CFDictionaryRef tmpAttrValue = NULL; + NSDictionary *attrValue = nil; + + /* Create decoder and decode */ + require_noerr_string(CMSDecoderCreate(&decoder), exit, "Failed to create CMS decoder"); + require_noerr_string(CMSDecoderUpdateMessage(decoder, _V2_valid_message, sizeof(_V2_valid_message)), exit, + "Failed to update decoder with CMS message"); + contentData = [NSData dataWithBytes:content length:sizeof(content)]; + require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit, + "Failed to set detached content"); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + + /* Get signer status */ + require_string(policy = SecPolicyCreateBasicX509(), exit, "Failed to Create policy"); + ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), + "Copy Signer status"); + is(signerStatus, kCMSSignerValid, "Valid signature"); + + /* Get Hash Agility Attribute value */ + ok_status(CMSDecoderCopySignerAppleCodesigningHashAgilityV2(decoder, 0, &tmpAttrValue), + "Copy hash agility attribute value"); + attrValue = CFBridgingRelease(tmpAttrValue); + ok([attrValue[@(SEC_OID_SHA1)] isEqualToData:[NSData dataWithBytes:_attributev2 length:20]], + "Got wrong SHA1 agility value"); + ok([attrValue[@(SEC_OID_SHA256)] isEqualToData:[NSData dataWithBytes:(_attributev2+32) length:32]], + "Got wrong SHA256 agility value"); + +exit: + CFReleaseNull(decoder); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +/* macOS shim test - decode negative */ +static void decode_V2_negative_test(void) { + CMSDecoderRef decoder = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CMSSignerStatus signerStatus; + NSData *contentData = nil; + NSMutableData *invalid_message = nil; + + /* Create decoder and decode */ + invalid_message = [NSMutableData dataWithBytes:_V2_valid_message length:sizeof(_V2_valid_message)]; + [invalid_message resetBytesInRange:NSMakeRange(2110, 1)]; /* reset byte in hash agility attribute */ + require_noerr_string(CMSDecoderCreate(&decoder), exit, "Failed to create CMS decoder"); + require_noerr_string(CMSDecoderUpdateMessage(decoder, [invalid_message bytes], [invalid_message length]), exit, + "Failed to update decoder with CMS message"); + contentData = [NSData dataWithBytes:content length:sizeof(content)]; + require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit, + "Failed to set detached content"); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + + /* Get signer status */ + require_string(policy = SecPolicyCreateBasicX509(), exit, "Failed to Create policy"); + ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), + "Copy Signer status"); + is(signerStatus, kCMSSignerInvalidSignature, "Valid signature"); + +exit: + CFReleaseNull(decoder); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +/* macOS shim test - no attribute */ +static void decodeV2_no_attr_test(void) { + CMSDecoderRef decoder = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CMSSignerStatus signerStatus; + NSData *contentData = nil; + CFDictionaryRef attrValue = NULL; + + /* Create decoder and decode */ + require_noerr_string(CMSDecoderCreate(&decoder), exit, "Failed to create CMS decoder"); + require_noerr_string(CMSDecoderUpdateMessage(decoder, valid_message, sizeof(valid_message)), exit, + "Failed to update decoder with CMS message"); + contentData = [NSData dataWithBytes:content length:sizeof(content)]; + require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit, + "Failed to set detached content"); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + + /* Get signer status */ + require_string(policy = SecPolicyCreateBasicX509(), exit, "Failed to Create policy"); + ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), + "Copy Signer status"); + is(signerStatus, kCMSSignerValid, "Valid signature"); + + /* Get Hash Agility Attribute value */ + ok_status(CMSDecoderCopySignerAppleCodesigningHashAgilityV2(decoder, 0, &attrValue), + "Copy hash agility attribute value"); + is(attrValue, NULL, "NULL attribute value"); + +exit: + CFReleaseNull(decoder); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(attrValue); +} + +static void macOS_shim_V2_tests(void) { + encode_V2_test(); + decode_V2_positive_test(); + decode_V2_negative_test(); + decodeV2_no_attr_test(); +} + +int cms_hash_agility_test(int argc, char *const *argv) +{ + plan_tests(74); + + macOS_shim_tests(); + macOS_shim_V2_tests(); + + return 0; +} diff --git a/OSX/libsecurity_codesigning/lib/CSCommon.h b/OSX/libsecurity_codesigning/lib/CSCommon.h index 6aeef649..3ede88d9 100644 --- a/OSX/libsecurity_codesigning/lib/CSCommon.h +++ b/OSX/libsecurity_codesigning/lib/CSCommon.h @@ -84,8 +84,8 @@ CF_ENUM(OSStatus) { errSecCSStaticCodeChanged = -67034, /* the code on disk does not match what is running */ errSecCSDBDenied = -67033, /* permission to use a database denied */ errSecCSDBAccess = -67032, /* cannot access a database */ - errSecCSSigDBDenied = errSecCSDBDenied, - errSecCSSigDBAccess = errSecCSDBAccess, + errSecCSSigDBDenied = -67033, /* permission to use a database denied */ + errSecCSSigDBAccess = -67032, /* cannot access a database */ errSecCSHostProtocolInvalidAttribute = -67031, /* host returned invalid or inconsistent guest attributes */ errSecCSInfoPlistFailed = -67030, /* invalid Info.plist (plist or signature have been modified) */ errSecCSNoMainExecutable = -67029, /* the code has no main executable file */ diff --git a/OSX/libsecurity_codesigning/lib/Code.cpp b/OSX/libsecurity_codesigning/lib/Code.cpp index d5de3047..8de98a37 100644 --- a/OSX/libsecurity_codesigning/lib/Code.cpp +++ b/OSX/libsecurity_codesigning/lib/Code.cpp @@ -255,6 +255,7 @@ void SecCode::changeGuestStatus(SecCode *guest, SecCodeStatusOperation operation // SecCode *SecCode::autoLocateGuest(CFDictionaryRef attributes, SecCSFlags flags) { +#if TARGET_OS_OSX // special case: with no attributes at all, return the root of trust if (CFDictionaryGetCount(attributes) == 0) return KernelCode::active()->retain(); @@ -280,6 +281,7 @@ SecCode *SecCode::autoLocateGuest(CFDictionaryRef attributes, SecCSFlags flags) return code.yield(); } } +#endif // TARGET_OS_OSX MacOSError::throwMe(errSecCSNoSuchCode); } diff --git a/OSX/libsecurity_codesigning/lib/SecCode.cpp b/OSX/libsecurity_codesigning/lib/SecCode.cpp index 7cf85740..3d918e4b 100644 --- a/OSX/libsecurity_codesigning/lib/SecCode.cpp +++ b/OSX/libsecurity_codesigning/lib/SecCode.cpp @@ -159,6 +159,7 @@ const CFStringRef kSecGuestAttributeDynamicCodeInfoPlist = CFSTR("dynamicCodeInf const CFStringRef kSecGuestAttributeArchitecture = CFSTR("architecture"); const CFStringRef kSecGuestAttributeSubarchitecture = CFSTR("subarchitecture"); +#if TARGET_OS_OSX OSStatus SecCodeCopyGuestWithAttributes(SecCodeRef hostRef, CFDictionaryRef attributes, SecCSFlags flags, SecCodeRef *guestRef) { @@ -192,6 +193,7 @@ OSStatus SecCodeCreateWithPID(pid_t pid, SecCSFlags flags, SecCodeRef *processRe END_CSAPI } +#endif // TARGET_OS_OSX // diff --git a/OSX/libsecurity_codesigning/lib/SecCode.h b/OSX/libsecurity_codesigning/lib/SecCode.h index 1f0f831d..20ba29f4 100644 --- a/OSX/libsecurity_codesigning/lib/SecCode.h +++ b/OSX/libsecurity_codesigning/lib/SecCode.h @@ -131,6 +131,7 @@ extern const CFStringRef kSecGuestAttributeDynamicCodeInfoPlist; extern const CFStringRef kSecGuestAttributeArchitecture; extern const CFStringRef kSecGuestAttributeSubarchitecture; +#if TARGET_OS_OSX /*! @function SecCodeCopyGuestWithAttributes This is the omnibus API function for obtaining dynamic code references. @@ -188,6 +189,7 @@ extern const CFStringRef kSecGuestAttributeSubarchitecture; OSStatus SecCodeCopyGuestWithAttributes(SecCodeRef __nullable host, CFDictionaryRef __nullable attributes, SecCSFlags flags, SecCodeRef * __nonnull CF_RETURNS_RETAINED guest); +#endif // TARGET_OS_OSX /*! diff --git a/OSX/libsecurity_codesigning/lib/SecCodePriv.h b/OSX/libsecurity_codesigning/lib/SecCodePriv.h index 81038342..7faa3634 100644 --- a/OSX/libsecurity_codesigning/lib/SecCodePriv.h +++ b/OSX/libsecurity_codesigning/lib/SecCodePriv.h @@ -126,6 +126,7 @@ OSStatus SecCodeCopyInternalRequirement(SecStaticCodeRef code, SecRequirementTyp SecCSFlags flags, SecRequirementRef *requirement); +#if TARGET_OS_OSX /*! @function SecCodeCreateWithPID Asks the kernel to return a SecCode object for a process identified @@ -144,6 +145,7 @@ OSStatus SecCodeCopyInternalRequirement(SecStaticCodeRef code, SecRequirementTyp */ OSStatus SecCodeCreateWithPID(pid_t pid, SecCSFlags flags, SecCodeRef *process) AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6; +#endif /* diff --git a/OSX/libsecurity_codesigning/lib/policydb.cpp b/OSX/libsecurity_codesigning/lib/policydb.cpp index 94d1bbc8..b3398c26 100644 --- a/OSX/libsecurity_codesigning/lib/policydb.cpp +++ b/OSX/libsecurity_codesigning/lib/policydb.cpp @@ -461,7 +461,7 @@ void setAssessment(bool masterSwitch) { MutableDictionary *prefsDict = MutableDictionary::CreateMutableDictionary(prefsFile); if (prefsDict == NULL) - prefsDict = new MutableDictionary::MutableDictionary(); + prefsDict = new MutableDictionary(); prefsDict->setValue(SP_ENABLE_KEY, masterSwitch ? SP_ENABLED : SP_DISABLED); prefsDict->writePlistToFile(prefsFile); delete prefsDict; diff --git a/OSX/libsecurity_codesigning/lib/policyengine.cpp b/OSX/libsecurity_codesigning/lib/policyengine.cpp index 1335f687..fa2a971a 100644 --- a/OSX/libsecurity_codesigning/lib/policyengine.cpp +++ b/OSX/libsecurity_codesigning/lib/policyengine.cpp @@ -73,10 +73,18 @@ static CFTypeRef installerPolicy() CF_RETURNS_RETAINED; PolicyEngine::PolicyEngine() : PolicyDatabase(NULL, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE) { + try { + mOpaqueWhitelist = new OpaqueWhitelist(); + } catch (...) { + mOpaqueWhitelist = NULL; + secerror("Failed opening the gkopaque database."); + } } PolicyEngine::~PolicyEngine() -{ } +{ + delete mOpaqueWhitelist; +} // @@ -262,11 +270,27 @@ void PolicyEngine::evaluateCodeItem(SecStaticCodeRef code, CFURLRef path, Author cfadd(result, "{%O=%B}", kSecAssessmentAssessmentVerdict, false); addAuthority(flags, result, latentLabel.c_str(), latentID); } - + +CFDictionaryRef PolicyEngine::opaqueWhitelistValidationConditionsFor(SecStaticCodeRef code) +{ + return (mOpaqueWhitelist != NULL) ? mOpaqueWhitelist->validationConditionsFor(code) : NULL; +} + +bool PolicyEngine::opaqueWhiteListContains(SecStaticCodeRef code, SecAssessmentFeedback feedback, OSStatus reason) +{ + return (mOpaqueWhitelist != NULL) ? mOpaqueWhitelist->contains(code, feedback, reason) : false; +} + +void PolicyEngine::opaqueWhitelistAdd(SecStaticCodeRef code) +{ + if (mOpaqueWhitelist) { + mOpaqueWhitelist->add(code); + } +} void PolicyEngine::adjustValidation(SecStaticCodeRef code) { - CFRef conditions = mOpaqueWhitelist.validationConditionsFor(code); + CFRef conditions = opaqueWhitelistValidationConditionsFor(code); SecStaticCodeSetValidationConditions(code, conditions); } @@ -465,8 +489,9 @@ void PolicyEngine::evaluateCode(CFURLRef path, AuthorityType type, SecAssessment if (CFEqual(verdict, kCFBooleanFalse)) // nested code rejected by rule book; result was filled out there return; if (CFEqual(verdict, kCFBooleanTrue) && !(flags & kSecAssessmentFlagIgnoreWhitelist)) - if (mOpaqueWhitelist.contains(code, feedback, rc)) + if (opaqueWhiteListContains(code, feedback, rc)) { allow = true; + } } if (allow) { label = "allowed cdhash"; @@ -1144,7 +1169,7 @@ void PolicyEngine::normalizeTarget(CFRef &target, AuthorityType type, CFStringRef edit = CFStringRef(context.get(kSecAssessmentContextKeyUpdate)); if (type == kAuthorityExecute && CFEqual(edit, kSecAssessmentUpdateOperationAdd)) { // implicitly whitelist the code - mOpaqueWhitelist.add(code); + opaqueWhitelistAdd(code); } } } diff --git a/OSX/libsecurity_codesigning/lib/policyengine.h b/OSX/libsecurity_codesigning/lib/policyengine.h index 9ba82dc2..87b10df7 100644 --- a/OSX/libsecurity_codesigning/lib/policyengine.h +++ b/OSX/libsecurity_codesigning/lib/policyengine.h @@ -88,7 +88,10 @@ private: void recordOutcome(SecStaticCodeRef code, bool allow, AuthorityType type, double expires, SQLite::int64 authority); private: - OpaqueWhitelist mOpaqueWhitelist; + OpaqueWhitelist* mOpaqueWhitelist; + CFDictionaryRef opaqueWhitelistValidationConditionsFor(SecStaticCodeRef code); + bool opaqueWhiteListContains(SecStaticCodeRef code, SecAssessmentFeedback feedback, OSStatus reason); + void opaqueWhitelistAdd(SecStaticCodeRef code); friend class EvaluationManager; friend class EvaluationTask; diff --git a/OSX/libsecurity_codesigning/lib/requirement.h b/OSX/libsecurity_codesigning/lib/requirement.h index da9175d4..64cbb93a 100644 --- a/OSX/libsecurity_codesigning/lib/requirement.h +++ b/OSX/libsecurity_codesigning/lib/requirement.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "codedirectory.h" #include diff --git a/OSX/libsecurity_cryptkit/lib/CryptKit.h b/OSX/libsecurity_cryptkit/lib/CryptKit.h deleted file mode 100644 index 6c6f2bc5..00000000 --- a/OSX/libsecurity_cryptkit/lib/CryptKit.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * CryptKit.h created by blaine on Thu 22-Feb-1996 - */ - -// Encryption related protocols and types -#include -#include - -// Classes -#include -#include -#include -#include -#include - -// Misc. Functions -#include -#include -#include diff --git a/OSX/libsecurity_cryptkit/lib/CryptKitSA.h b/OSX/libsecurity_cryptkit/lib/CryptKitSA.h deleted file mode 100644 index b5a902c8..00000000 --- a/OSX/libsecurity_cryptkit/lib/CryptKitSA.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 1998-2004,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - ***************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include diff --git a/OSX/libsecurity_cryptkit/lib/NSCipherFile.h b/OSX/libsecurity_cryptkit/lib/NSCipherFile.h deleted file mode 100644 index 13f103c5..00000000 --- a/OSX/libsecurity_cryptkit/lib/NSCipherFile.h +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * NSCipherFile.h - ObjC wrapper for feeCipherFile - * - * Revision History - * ---------------- - * 28 Oct 96 at NeXT - * Created. - */ - -#import -#import - -@interface NSCipherFile : NSObject -{ - void *_priv; -} - -/* - * Alloc and return an autoreleased NSCipherFile object associated with - * the specified data. - */ -+ newFromCipherText : (NSData *)cipherText - encrType : (cipherFileEncrType)encrType - sendPubKeyData : (NSData *)sendPubKeyData - otherKeyData : (NSData *)otherKeyData - sigData : (NSData *)sigData // optional; nil means no signature - userData : (unsigned)userData; // for caller's convenience - -/* - * Obtain the contents of a feeCipherFile as NSData. - */ -- (NSData *)dataRepresentation; - -/* - * Alloc and return an autoreleased NSCipherFile object given a data - * representation. - */ -+ newFromDataRepresentation : (NSData *)dataRep; - -/* - * Given an NSCipherFile object, obtain its constituent parts. - */ -- (cipherFileEncrType)encryptionType; -- (NSData *)cipherText; -- (NSData *)sendPubKeyData; -- (NSData *)otherKeyData; -- (NSData *)sigData; -- (unsigned)userData; - -/* - * High-level cipherFile support. - */ - -/* - * Obtain the data representation of a NSCipherFile given the specified - * plainText and cipherFileEncrType. - * Receiver's public key is required for all encrTypes; sender's private - * key is required for signature generation and also for encrType - * CFE_PublicDES and CFE_FEED. - */ -+(feeReturn)createCipherFileForPrivKey : (NSFEEPublicKey *)sendPrivKey - recvPubKey : (NSFEEPublicKey *)recvPubKey - encrType : (cipherFileEncrType)encrType - plainText : (NSData *)plainText - genSig : (BOOL)genSig - doEnc64 : (BOOL)doEnc64 // YES ==> perform enc64 - userData : (unsigned)userData // for caller's convenience - cipherFileData : (NSData **)cipherFileData; // RETURNED - -/* - * Parse and decrypt a data representation of an NSCipherFile object. - * - * recvPrivKey is required in all cases. If sendPubKey is present, - * sendPubKey - rather than the embedded sender's public key - will be - * used for signature validation. - */ -+ (feeReturn)parseCipherFileData : (NSFEEPublicKey *)recvPrivKey - sendPubKey : (NSFEEPublicKey *)sendPubKey - cipherFileData : (NSData *)cipherFileData - doDec64 : (BOOL)doDec64 - encrType : (cipherFileEncrType *)encrType // RETURNED - plainText : (NSData **)plainText // RETURNED - sigStatus : (feeSigStatus *)sigStatus // RETURNED - sigSigner : (NSString **)sigSigner // RETURNED - userData : (unsigned *)userData; // RETURNED - -/* - * Parse and decrypt an NSCipherFile object obtained via - * +newFromDataRepresentation. - * - * recvPrivKey is required in all cases. If sendPubKey is present, - * sendPubKey - rather than the embedded sender's public key - will be - * used for signature validation. - */ -- (feeReturn)decryptCipherFileData : (NSFEEPublicKey *)recvPrivKey - sendPubKey : (NSFEEPublicKey *)sendPubKey - plainText : (NSData **)plainText // RETURNED - sigStatus : (feeSigStatus *)sigStatus // RETURNED - sigSigner : (NSString **)sigSigner; // RETURNED - - -@end diff --git a/OSX/libsecurity_cryptkit/lib/NSCipherFile.m b/OSX/libsecurity_cryptkit/lib/NSCipherFile.m deleted file mode 100644 index 93598d72..00000000 --- a/OSX/libsecurity_cryptkit/lib/NSCipherFile.m +++ /dev/null @@ -1,360 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * NSCipherFile.m - ObjC wrapper for feeCipherFile - * - * Revision History - * ---------------- - * 28 Oct 96 at NeXT - * Created. - */ - -#import "NSCipherFile.h" -#import "feeCipherFile.h" -#import "falloc.h" -#import "NSFEEPublicKeyPrivate.h" /* for -feePubKey */ - -/* - * Private instance data. - */ -typedef struct { - feeCipherFile cfile; -} _cfPriv; - -@implementation NSCipherFile - -- (void)dealloc -{ - if(_priv) { - _cfPriv *cfPriv = _priv; - if(cfPriv->cfile) { - feeCFileFree(cfPriv->cfile); - } - } - [super dealloc]; -} - -/* - * Alloc and return an autoreleased NSCipherFile object associated with - * the specified data. - */ -+ newFromCipherText : (NSData *)cipherText - encrType : (cipherFileEncrType)encrType - sendPubKeyData : (NSData *)sendPubKeyData - otherKeyData : (NSData *)otherKeyData - sigData : (NSData *)sigData // optional; nil means no signature - userData : (unsigned)userData // for caller's convenience -{ - NSCipherFile *result; - _cfPriv *cfPriv; - - result = [[self alloc] autorelease]; - result->_priv = cfPriv = fmalloc(sizeof(_cfPriv)); - cfPriv->cfile = feeCFileNewFromCipherText(encrType, - [cipherText bytes], - [cipherText length], - [sendPubKeyData bytes], - [sendPubKeyData length], - [otherKeyData bytes], - [otherKeyData length], - [sigData bytes], - [sigData length], - userData); - if(cfPriv->cfile) { - return result; - } - else { - return nil; - } -} - -/* - * Obtain the contents of a feeCipherFile as NSData. - */ -- (NSData *)dataRepresentation -{ - _cfPriv *cfPriv = _priv; - NSData *result; - const unsigned char *rep; - unsigned repLen; - feeReturn frtn; - - if(cfPriv == NULL) { - return nil; - } - frtn = feeCFileDataRepresentation(cfPriv->cfile, - &rep, - &repLen); - if(frtn) { - return nil; - } - result = [NSData dataWithBytesNoCopy:(unsigned char *)rep - length:repLen]; - return result; -} - -/* - * Alloc and return an autoreleased NSCipherFile object given a data - * representation. - */ -+ newFromDataRepresentation : (NSData *)dataRep -{ - NSCipherFile *result; - _cfPriv *cfPriv; - feeReturn frtn; - - result = [[self alloc] autorelease]; - result->_priv = cfPriv = fmalloc(sizeof(_cfPriv)); - frtn = feeCFileNewFromDataRep([dataRep bytes], - [dataRep length], - &cfPriv->cfile); - if(frtn) { - return nil; - } - else { - return result; - } -} - -/* - * Given an NSCipherFile object, obtain its constituent parts. - */ -- (cipherFileEncrType)encryptionType -{ - _cfPriv *cfPriv = _priv; - - if(cfPriv == NULL) { - return CFE_Other; - } - return feeCFileEncrType(cfPriv->cfile); -} - -- (NSData *)cipherText -{ - _cfPriv *cfPriv = _priv; - const unsigned char *ctext; - unsigned ctextLen; - - if(cfPriv == NULL) { - return nil; - } - ctext = feeCFileCipherText(cfPriv->cfile, &ctextLen); - return [NSData dataWithBytesNoCopy:(unsigned char *)ctext - length:ctextLen]; -} - -- (NSData *)sendPubKeyData -{ - _cfPriv *cfPriv = _priv; - const unsigned char *key; - unsigned keyLen; - - if(cfPriv == NULL) { - return nil; - } - key = feeCFileSendPubKeyData(cfPriv->cfile, &keyLen); - if(key) { - return [NSData dataWithBytesNoCopy:(unsigned char *)key - length:keyLen]; - } - else { - return nil; - } -} - -- (NSData *)otherKeyData -{ - _cfPriv *cfPriv = _priv; - const unsigned char *key; - unsigned keyLen; - - if(cfPriv == NULL) { - return nil; - } - key = feeCFileOtherKeyData(cfPriv->cfile, &keyLen); - if(key) { - return [NSData dataWithBytesNoCopy:(unsigned char *)key - length:keyLen]; - } - else { - return nil; - } -} - -- (NSData *)sigData -{ - _cfPriv *cfPriv = _priv; - const unsigned char *sig; - unsigned sigLen; - - if(cfPriv == NULL) { - return nil; - } - sig = feeCFileSigData(cfPriv->cfile, &sigLen); - if(sig) { - return [NSData dataWithBytesNoCopy:(unsigned char *)sig - length:sigLen]; - } - else { - return nil; - } -} - -- (unsigned)userData -{ - _cfPriv *cfPriv = _priv; - - if(cfPriv == NULL) { - return 0; - } - return feeCFileUserData(cfPriv->cfile); -} - -/* - * High-level cipherFile support. - */ - -/* - * Create a cipherfile of specified cipherFileEncrType for given plaintext. - */ -+(feeReturn)createCipherFileForPrivKey : (NSFEEPublicKey *)sendPrivKey - recvPubKey : (NSFEEPublicKey *)recvPubKey - encrType : (cipherFileEncrType)encrType - plainText : (NSData *)plainText - genSig : (BOOL)genSig - doEnc64 : (BOOL)doEnc64 // YES ==> perform enc64 - userData : (unsigned)userData // for caller's convenience - cipherFileData : (NSData **)cipherFileData // RETURNED -{ - feeReturn frtn; - unsigned char *cfileData; - unsigned cfileDataLen; - feePubKey privKey = NULL; - - if(sendPrivKey) { - privKey = [sendPrivKey feePubKey]; - } - frtn = createCipherFile(privKey, - [recvPubKey feePubKey], - encrType, - [plainText bytes], - [plainText length], - genSig, - doEnc64, - userData, - &cfileData, - &cfileDataLen); - if(frtn) { - return frtn; - } - *cipherFileData = - [NSData dataWithBytesNoCopy:(unsigned char *)cfileData - length:cfileDataLen]; - return frtn; -} - -/* - * Parse and decrypt a data representation of an NSCipherFile object. - */ -+ (feeReturn)parseCipherFileData : (NSFEEPublicKey *)recvPrivKey - sendPubKey : (NSFEEPublicKey *)sendPubKey - cipherFileData : (NSData *)cipherFileData - doDec64 : (BOOL)doDec64 - encrType : (cipherFileEncrType *)encrType // RETURNED - plainText : (NSData **)plainText // RETURNED - sigStatus : (feeSigStatus *)sigStatus // RETURNED - sigSigner : (NSString **)sigSigner // RETURNED - userData : (unsigned *)userData // RETURNED -{ - feeReturn frtn; - unsigned char *ptext; - unsigned ptextLen; - feeUnichar *signer; - unsigned signerLen; - feePubKey _pubKey = NULL; - - if(recvPrivKey == nil) { - return FR_IllegalArg; // always required - } - if(sendPubKey) { - _pubKey = [sendPubKey feePubKey]; - } - - frtn = parseCipherFile([recvPrivKey feePubKey], - _pubKey, - [cipherFileData bytes], - [cipherFileData length], - doDec64, - encrType, - &ptext, - &ptextLen, - sigStatus, - &signer, - &signerLen, - userData); - if(frtn) { - return frtn; - } - *plainText = [NSData dataWithBytesNoCopy:ptext length:ptextLen]; - *sigSigner = [NSString stringWithCharacters:signer length:signerLen]; - ffree(signer); - return frtn; -} - -/* - * Parse and decrypt an NSCipherFile object obtained via - * +newFromDataRepresentation. - * - * recvPrivKey is required in all cases. If sendPubKey is present, - * sendPubKey - rather than the embedded sender's public key - will be - * used for signature validation. - */ -- (feeReturn)decryptCipherFileData : (NSFEEPublicKey *)recvPrivKey - sendPubKey : (NSFEEPublicKey *)sendPubKey - plainText : (NSData **)plainText // RETURNED - sigStatus : (feeSigStatus *)sigStatus // RETURNED - sigSigner : (NSString **)sigSigner // RETURNED -{ - _cfPriv *cfPriv = _priv; - feeReturn frtn; - unsigned char *ptext; - unsigned ptextLen; - feeUnichar *signer; - unsigned signerLen; - feePubKey _pubKey = NULL; - - if(cfPriv == NULL) { - return FR_IllegalArg; - } - if(recvPrivKey == nil) { - return FR_IllegalArg; // always required - } - if(sendPubKey) { - _pubKey = [sendPubKey feePubKey]; - } - - frtn = decryptCipherFile(cfPriv->cfile, - [recvPrivKey feePubKey], - _pubKey, - &ptext, - &ptextLen, - sigStatus, - &signer, - &signerLen); - if(frtn) { - return frtn; - } - *plainText = [NSData dataWithBytesNoCopy:ptext length:ptextLen]; - *sigSigner = [NSString stringWithCharacters:signer length:signerLen]; - ffree(signer); - return frtn; - -} -@end diff --git a/OSX/libsecurity_cryptkit/lib/NSCryptors.h b/OSX/libsecurity_cryptkit/lib/NSCryptors.h deleted file mode 100644 index 33935a7d..00000000 --- a/OSX/libsecurity_cryptkit/lib/NSCryptors.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * NSCryptors.h - common cryptographic protocols - * - * Revision History - * ---------------- - * ??? 1994 Blaine Garst at NeXT - * Created. - */ - - -#import -#import -#import - - -/************ Utilities ******************************************/ - -#ifdef NeXT - -NSString *NSPromptForPassPhrase(NSString *prompt); - // useful for command line (/dev/tty) programs - -#endif NeXT - -/************ Data Hashing Protocol *****************/ - -@protocol NSDataDigester -+ digester; // provides a concrete digester - -// primitives -- (void)digestData:(NSData *)data; // use for multi-bite messages -- (NSData *)messageDigest; // provide digest; re-init - -// conveniences that only use the above primitives -// all in one gulp (eats salt first, if present) -- (NSData *)digestData:(NSData *)data withSalt:(NSData *)salt; - -@end - - -/****** Encryption/Decryption Protocol ***********/ - -@protocol NSCryptor -- (NSData *)encryptData:(NSData *)input; -- (NSData *)decryptData:(NSData *)input; -- (unsigned)keyBitsize; -@end - - -/*************** Public Key Services *************/ - -@protocol NSPublicKey -- (NSString *)publicKeyString; -- (NSString *)algorithmName; // "Diffie-Hellman" "FEE" ... -- (NSString *)usageName; // "Blaine Garst - home" -- (NSData *)padWithPublicKey:(id )otherKey; -- (unsigned)keyBitsize; -@end - -/********* Key Ring ************************/ - -@protocol NSKeyRing -- keyForUsageName:(NSString *)user; -@end - -/********** Digital Signatures **************/ - -// protocol adapted by various signature schemes (FEE, DSA, RSA...) -@protocol NSDigitalSignature -- (NSData *)digitalSignatureForData:(NSData *)message; - // generate a signature for the data - -- (BOOL)isValidDigitalSignature:(NSData *)sig forData:(NSData *)data; -@end diff --git a/OSX/libsecurity_cryptkit/lib/NSDESCryptor.h b/OSX/libsecurity_cryptkit/lib/NSDESCryptor.h deleted file mode 100644 index 6f3ed08b..00000000 --- a/OSX/libsecurity_cryptkit/lib/NSDESCryptor.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * NSDESCryptor.h created by blaine on Thu 22-Feb-1996 - */ - -#import "NSCryptors.h" - -/****** Digital Encryption Standard/Algorithm ********/ - -@interface NSDESCryptor : NSObject -{ - void *_priv; -} - -+ cryptorWithState:(NSData *)s; - -- initWithState:(NSData *)state; - // designated initializer - // 8 bytes with most sig bit ignored: 56 bits - -- (void)setCryptorState:(NSData *)state; // reset -- (void)setBlockMode:(BOOL)yorn; // default is chaining mode - -/* - * NSCryptor methods - */ -- (NSData *)encryptData:(NSData *)input; -- (NSData *)decryptData:(NSData *)input; -- (unsigned)keyBitsize; - -@end diff --git a/OSX/libsecurity_cryptkit/lib/NSDESCryptor.m b/OSX/libsecurity_cryptkit/lib/NSDESCryptor.m deleted file mode 100644 index 2e071b2e..00000000 --- a/OSX/libsecurity_cryptkit/lib/NSDESCryptor.m +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * NSDESCryptor.m - DES encrypt/decrypt class - * - * Revision History - * ---------------- - * 28 Mar 97 at Apple - * Rewrote using feeDES module. - * 22 Feb 96 at NeXT - * Created. - */ - -#import -#import "NSDESCryptor.h" -#import "feeDES.h" -#import "falloc.h" -#import "ckutilities.h" -#import "feeFunctions.h" - -/* - * Note: Our _priv ivar is actuall a feeDES pointer. - */ -@implementation NSDESCryptor - -+ cryptorWithState:(NSData *)s { - return [[[self alloc] initWithState:s] autorelease]; -} - -- (void)setCryptorState:(NSData *)state { - if(_priv == NULL) { - return; - } - feeDESSetState(_priv, [state bytes], [state length]); -} - -- initWithState:(NSData *)state { - feeReturn frtn; - - if(_priv == NULL) { - _priv = feeDESNewWithState([state bytes], [state length]); - } - else { - frtn = feeDESSetState(_priv, [state bytes], [state length]); - if(frtn) { - NSLog(@"NSDESCryptor: bad initial state\n"); - return nil; - } - } - return self; -} - -- (void)dealloc -{ - if(_priv) { - feeDESFree(_priv); - } - [super dealloc]; -} - -- (void)setBlockMode:(BOOL)yorn { - if(_priv == NULL) { - return; - } - if(yorn) { - feeDESSetBlockMode(_priv); - } - else { - feeDESSetChainMode(_priv); - } -} - -- (NSData *)encryptData:(NSData *)input { - NSData *result; - feeReturn frtn; - unsigned char *cipherText; - unsigned cipherTextLen; - - if(_priv == NULL) { - return nil; - } - frtn = feeDESEncrypt(_priv, - [input bytes], - [input length], - &cipherText, - &cipherTextLen); - if(frtn) { - NSLog(@"NSDESCryptor encrypt: %s", feeReturnString(frtn)); - return nil; - } - result = [NSData dataWithBytes:cipherText length:cipherTextLen]; - ffree(cipherText); - return result; -} - -- (NSData *)decryptData:(NSData *)input { - NSData *result; - feeReturn frtn; - unsigned char *plainText; - unsigned plainTextLen; - - if(_priv == NULL) { - return nil; - } - frtn = feeDESDecrypt(_priv, - [input bytes], - [input length], - &plainText, - &plainTextLen); - if(frtn) { - NSLog(@"NSDESCryptor decrypt: %s", feeReturnString(frtn)); - return nil; - } - result = [NSData dataWithBytes:plainText length:plainTextLen]; - ffree(plainText); - return result; -} - -- (unsigned)keyBitsize { - return feeDESKeySize(_priv); -} - -@end diff --git a/OSX/libsecurity_cryptkit/lib/NSFEEPublicKey.h b/OSX/libsecurity_cryptkit/lib/NSFEEPublicKey.h deleted file mode 100644 index 42377a28..00000000 --- a/OSX/libsecurity_cryptkit/lib/NSFEEPublicKey.h +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * NSFEEPublicKey.h - * - * Revision History - * ---------------- - * 27 Feb 1997 at Apple - * Broke out from NSCryptors.h. - */ - -#import - -@interface NSFEEPublicKey : NSObject - { -@private - void *_pubKey; -} - -+ keyWithPrivateData:(NSData *)private - depth:(unsigned)depth // depth is in range 0-23 - usageName:(NSString *)uname; - // able to encrypt/decrypt data - // able to create/verify digital signatures - -+ keyWithPublicKeyString:(NSString *)hexstr; - // able to encrypt data - // able to verify digital signatures - -/* - * Create new key with curve parameters matching existing oldKey. - */ -+ keyWithPrivateData:(NSData *)passwd - andKey:(NSFEEPublicKey *)oldKey - usageName:(NSString *)uname; - -/* - * Convenience methods. The first three use the default depth - * (FEE_DEPTH_DEFAULT). - */ -+ keyWithPrivateData:(NSData *)passwd - usageName:(NSString *)uname; -+ keyWithPrivateString:(NSString *)private - usageName:(NSString *)uname; -+ keyWithPrivateString:(NSString *)private - andKey:(NSFEEPublicKey *)oldKey - usageName:(NSString *)uname; - -+ keyWithPrivateString:(NSString *)private - depth:(unsigned)depth - usageName:(NSString *)uname; - -/* - * NSCryptor protocol - */ -- (NSData *)encryptData:(NSData *)data; // done with public knowledge -- (NSData *)decryptData:(NSData *)data; // done with private knowledge - -/* - * NSDigitalSignature protocol - */ -- (NSData *)digitalSignatureForData:(NSData *)data; - // data is hashed with MD5 and then signed with private knowledge -- (BOOL)isValidDigitalSignature:(NSData *)sig forData:(NSData *)data; - // data is hashed with MD5 and then verified with public knowledge - -@end diff --git a/OSX/libsecurity_cryptkit/lib/NSFEEPublicKey.m b/OSX/libsecurity_cryptkit/lib/NSFEEPublicKey.m deleted file mode 100644 index 034af79d..00000000 --- a/OSX/libsecurity_cryptkit/lib/NSFEEPublicKey.m +++ /dev/null @@ -1,496 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * NSFEEPublicKey.m - NSFEEPublicKey class implementation - * - * Revision History - * ---------------- - * 17 Jul 97 at Apple - * Added ECDSA signature routines. - * 21 Aug 96 at NeXT - * Modified to use C-only FeePublicKey module. - * ???? 1994 Blaine Garst at NeXT - * Created. - */ - -#import -#import - -#import "NSCryptors.h" -#import "NSFEEPublicKeyPrivate.h" -#import "feePublicKey.h" -#import "feePublicKeyPrivate.h" -#import "ckutilities.h" -#import "mutils.h" -#import "feeTypes.h" -#import "curveParams.h" -#import "falloc.h" -#import "feeDigitalSignature.h" -#import "feeHash.h" -#import "feeFunctions.h" -#import "feeFEEDExp.h" - -/* - Elliptic curve algebra over finite fields F(p**k), where p = 2**q -1 is a - Mersenne prime. - q is bit-depth. - A private key (a) is a large integer that when multiplied by an initial - curve point P yields the public key aP. - Public keys can be used to generate one-time pads because multiplication - is commutative: - - a(bP) == b(aP) - */ - -@implementation NSFEEPublicKey - -/* - * Root method to create new public key from private "password" data. - */ -+ keyWithPrivateData:(NSData *)passwd - depth:(unsigned)depth - usageName:(NSString *)uname -{ - NSFEEPublicKey *result; - feeReturn frtn; - unichar *uc; - - result = [[self alloc] autorelease]; - result->_pubKey = feePubKeyAlloc(); - uc = fmalloc([uname length] * sizeof(unichar)); - [uname getCharacters:uc]; - frtn = feePubKeyInitFromPrivData(result->_pubKey, - [passwd bytes], [passwd length], - uc, [uname length], - depth); - ffree(uc); - if(frtn) { - NSLog(@"keyWithPrivateData: %s\n", feeReturnString(frtn)); - return nil; - } - return result; -} - -/* - * Create new key with curve parameters matching existing oldKey. - */ -+ keyWithPrivateData:(NSData *)passwd - andKey:(NSFEEPublicKey *)oldKey - usageName:(NSString *)uname -{ - NSFEEPublicKey *result; - feeReturn frtn; - unichar *uc; - - result = [[self alloc] autorelease]; - result->_pubKey = feePubKeyAlloc(); - uc = fmalloc([uname length] * sizeof(unichar)); - [uname getCharacters:uc]; - frtn = feePubKeyInitFromKey(result->_pubKey, - [passwd bytes], [passwd length], - uc, [uname length], - oldKey->_pubKey); - ffree(uc); - if(frtn) { - NSLog(@"keyWithPrivateData:andKey: %s\n", - feeReturnString(frtn)); - return nil; - } - return result; -} - -+ keyWithPrivateData:(NSData *)passwd - usageName:(NSString *)uname -{ - // 4 gives 127 bits of protection - // although the RSA challenge number of 127 bits has been - // broken, FEE is much stronger at the same length - return [self keyWithPrivateData:passwd - depth:FEE_DEPTH_DEFAULT - usageName:uname]; -} - -/* - * The standard way of creating a new key given a private "password" string. - */ -+ keyWithPrivateString:(NSString *)private - usageName:(NSString *)uname -{ - NSData *pdata; - id result; - - /* - * FIXME - handle other encodings? - */ - pdata = [private dataUsingEncoding:NSUTF8StringEncoding]; - result = [self keyWithPrivateData:pdata usageName:uname]; - return result; -} - -+ keyWithPrivateString:(NSString *)private - andKey:(NSFEEPublicKey *)oldKey - usageName:(NSString *)uname -{ - NSData *pdata; - id result; - - if (!uname) return nil; - - pdata = [private dataUsingEncoding:NSUTF8StringEncoding]; - result = [self keyWithPrivateData:pdata andKey:oldKey usageName:uname]; - return result; -} - -+ keyWithPrivateString:(NSString *)private - depth:(unsigned)depth - usageName:(NSString *)uname -{ - NSData *pdata; - id result; - - if (!uname) return nil; - - pdata = [private dataUsingEncoding:NSUTF8StringEncoding]; - result = [self keyWithPrivateData:pdata depth:depth usageName:uname]; - return result; -} - -/* - * The standard way of creating a new key given a public key string. - */ -+ keyWithPublicKeyString:(NSString *)hexstr -{ - NSFEEPublicKey *result; - feeReturn frtn; - NSStringEncoding defEndoding; - const char *s; - - /* - * Protect against gross errors in the key string formatting... - */ - defEndoding = [NSString defaultCStringEncoding]; - if([hexstr canBeConvertedToEncoding:defEndoding] == NO) { - NSLog(@"NSFEEPublicKey: Bad Public Key String Format (1)\n"); - return nil; - } - - /* - * FIXME - docs say this string is "autoreleased". How is a cString - * autoreleased? - */ - s = [hexstr cString]; - result = [[self alloc] autorelease]; - result->_pubKey = feePubKeyAlloc(); - - frtn = feePubKeyInitFromKeyString(result->_pubKey, - s, strlen(s)); - if(frtn) { - NSLog(@"keyWithPublicKeyString:andKey: %s\n", - feeReturnString(frtn)); - return nil; - } - return result; -} - -- (void)dealloc -{ - if(_pubKey) { - feePubKeyFree(_pubKey); - } - [super dealloc]; -} - -/* - * Create a public key in the form of a string. This string contains an - * encoded version of all of our ivars except for _private. - * - * See KeyStringFormat.doc for info on the format of the public key string; - * PLEASE UPDATE THIS DOCUMENT WHEN YOU MAKE CHANGES TO THE STRING FORMAT. - */ -- (NSString *)publicKeyString -{ - char *keyStr; - unsigned keyStrLen; - feeReturn frtn; - NSString *result; - - if(_pubKey == NULL) { - return nil; - } - frtn = feePubKeyCreateKeyString(_pubKey, &keyStr, &keyStrLen); - if(frtn) { - NSLog(@"publicKeyString: %s\n", - feeReturnString(frtn)); - return nil; - } - result = [NSString stringWithCString:keyStr]; - ffree((void *)keyStr); - return result; -} - -- (BOOL)isEqual:(NSFEEPublicKey *)other -{ - if((other == nil) || (other->_pubKey == NULL) || (_pubKey == NULL)) { - return NO; - } - if(feePubKeyIsEqual(_pubKey, other->_pubKey)) { - return YES; - } - else { - return NO; - } -} - -- (unsigned)keyBitsize -{ - if(_pubKey == NULL) { - return 0; - } - return feePubKeyBitsize(_pubKey); -} - -- (NSString *)algorithmName -{ - return [NSString stringWithCString:feePubKeyAlgorithmName()]; -} - -- (NSString *)usageName -{ - unsigned unameLen; - const feeUnichar *uname; - NSString *result; - - if(_pubKey == NULL) { - return nil; - } - uname = feePubKeyUsageName(_pubKey, &unameLen); - result = [NSString stringWithCharacters:uname length:unameLen]; - return result; -} - -- (NSString *)signer -{ - return [self usageName]; -} - -- (NSData *)padWithPublicKey:(id )otherKey -{ - NSFEEPublicKey *other; - NSMutableData *result; - feeReturn frtn; - unsigned char *padData; - unsigned padDataLen; - - if(_pubKey == NULL) { - return nil; - } - if (![otherKey isMemberOfClass:isa]) { - return nil; - } - other = otherKey; - if(other->_pubKey == NULL) { - return nil; - } - frtn = feePubKeyCreatePad(_pubKey, - other->_pubKey, - &padData, - &padDataLen); - if(frtn) { - NSLog(@"padWithPublicKey: %s\n", feeReturnString(frtn)); - return nil; - } - result = [NSData dataWithBytesNoCopy:padData length:padDataLen]; - return result; -} - -- (NSData *)encryptData:(NSData *)data -{ - feeFEEDExp feed; - NSData *result; - feeReturn frtn; - unsigned char *ctext; - unsigned ctextLen; - - if(_pubKey == NULL) { - return nil; - } - feed = feeFEEDExpNewWithPubKey(_pubKey); - frtn = feeFEEDExpEncrypt(feed, - [data bytes], - [data length], - &ctext, - &ctextLen); - if(frtn == FR_Success) { - result = [NSData dataWithBytesNoCopy:ctext length:ctextLen]; - } - else { - NSLog(@"feeFEEDEncrypt: %s\n", feeReturnString(frtn)); - result = nil; - } - feeFEEDExpFree(feed); - return result; -} - -- (NSData *)decryptData:(NSData *)data -{ - feeFEEDExp feed; - NSData *result; - feeReturn frtn; - unsigned char *ptext; - unsigned ptextLen; - - if(_pubKey == NULL) { - return nil; - } - feed = feeFEEDExpNewWithPubKey(_pubKey); - frtn = feeFEEDExpDecrypt(feed, - [data bytes], - [data length], - &ptext, - &ptextLen); - if(frtn == FR_Success) { - result = [NSData dataWithBytesNoCopy:ptext length:ptextLen]; - } - else { - NSLog(@"feeFEEDDecrypt: %s\n", feeReturnString(frtn)); - result = nil; - } - feeFEEDExpFree(feed); - return result; -} - -/* - * When 1, we use ECDSA unless we're using a depth which does not - * have curve orders. - * WARNING - enabling ECDSA by default breaks ICE and compatibility - * with Java signatures, at least until we have a Java ECDSA - * implementation. - */ -#define ECDSA_SIG_DEFAULT 0 - -- (NSData *)digitalSignatureForData:(NSData *)data -{ - NSData *result; - unsigned char *sig; - unsigned sigLen; - feeReturn frtn; - curveParams *cp; - - if(_pubKey == NULL) { - return nil; - } - cp = feePubKeyCurveParams(_pubKey); - if(!ECDSA_SIG_DEFAULT || isZero(cp->x1OrderPlus)) { - frtn = feePubKeyCreateSignature(_pubKey, - [data bytes], - [data length], - &sig, - &sigLen); - } - else { - frtn = feePubKeyCreateECDSASignature(_pubKey, - [data bytes], - [data length], - &sig, - &sigLen); - } - if(frtn) { - NSLog(@"digitalSignatureForData: %s\n", feeReturnString(frtn)); - return nil; - } - result = [NSData dataWithBytesNoCopy:sig length:sigLen]; - return result; -} - -- (BOOL)isValidDigitalSignature:(NSData *)signa - forData:(NSData *)data -{ - feeReturn frtn; - feeUnichar *sigSigner; - unsigned sigSignerLen; - curveParams *cp; - - if(_pubKey == NULL) { - return NO; - } - cp = feePubKeyCurveParams(_pubKey); - if(!ECDSA_SIG_DEFAULT || isZero(cp->x1OrderPlus)) { - frtn = feePubKeyVerifySignature(_pubKey, - [data bytes], - [data length], - [signa bytes], - [signa length], - &sigSigner, - &sigSignerLen); - } - else { - frtn = feePubKeyVerifyECDSASignature(_pubKey, - [data bytes], - [data length], - [signa bytes], - [signa length], - &sigSigner, - &sigSignerLen); - } - - /* - * FIXME - We just throw away the signer for now... - */ - if(sigSignerLen) { - ffree(sigSigner); - } - - switch(frtn) { - case FR_Success: - return YES; - case FR_InvalidSignature: - return NO; - default: - /* - * Something other than simple signature mismatch... - */ - NSLog(@"isValidDigitalSignature: %s\n", feeReturnString(frtn)); - return NO; - } -} - -@end - -@implementation NSFEEPublicKey(Private) - -- (key)minus -{ - if(_pubKey == NULL) { - return NULL; - } - return feePubKeyMinusCurve(_pubKey); -} - -- (key)plus -{ - if(_pubKey == NULL) { - return NULL; - } - return feePubKeyPlusCurve(_pubKey); -} - -- (feePubKey)feePubKey -{ - return _pubKey; -} - -#if FEE_DEBUG -- (void)dump -{ - printPubKey(_pubKey); -} -#endif FEE_DEBUG - -@end diff --git a/OSX/libsecurity_cryptkit/lib/NSFEEPublicKeyPrivate.h b/OSX/libsecurity_cryptkit/lib/NSFEEPublicKeyPrivate.h deleted file mode 100644 index 37576972..00000000 --- a/OSX/libsecurity_cryptkit/lib/NSFEEPublicKeyPrivate.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * NSFEEPublicKeyPrivate.h - * - * Revision History - * ---------------- - * 21 Aug 96 at NeXT - * Created. - */ - -#import "NSFEEPublicKey.h" -#import "elliptic.h" -#import "feeDebug.h" -#import "feePublicKey.h" - -@interface NSFEEPublicKey(Private) - -- (key)minus; -- (key)plus; -#if 0 -- (NSData *)privData; -#endif 0 -- (feePubKey)feePubKey; - -#if FEE_DEBUG -- (void)dump; -#endif FEE_DEBUG -@end diff --git a/OSX/libsecurity_cryptkit/lib/NSMD5Hash.h b/OSX/libsecurity_cryptkit/lib/NSMD5Hash.h deleted file mode 100644 index 1553a496..00000000 --- a/OSX/libsecurity_cryptkit/lib/NSMD5Hash.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * NSMD5Hash.h - * - * Revision History - * ---------------- - * 28 Mar 97 at Apple - * Created. - */ - -#import -#import - -@interface NSMD5Hash : NSObject - -{ - void *_priv; -} - -+ digester; // provides a concrete digester -- init; // reusable -- (void)digestData:(NSData *)data; -- (NSData *)messageDigest; // provide digest; re-init -- (NSData *)digestData:(NSData *)data withSalt:(NSData *)salt; - -@end diff --git a/OSX/libsecurity_cryptkit/lib/NSMD5Hash.m b/OSX/libsecurity_cryptkit/lib/NSMD5Hash.m deleted file mode 100644 index 8e372be7..00000000 --- a/OSX/libsecurity_cryptkit/lib/NSMD5Hash.m +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * NSMD5Hash.h - * - * Revision History - * ---------------- - * 28 Mar 97 at Apple - * Created. - */ - -/* - * Note: our _priv ivar is actually a feeHash pointer. - */ -#import "NSCryptors.h" -#import "NSMD5Hash.h" -#import "feeHash.h" -#import "falloc.h" - -@implementation NSMD5Hash - -+ digester -{ - return [[self alloc] init]; -} - -- init -{ - if(_priv == NULL) { - _priv = feeHashAlloc(); - } - else { - feeHashReinit(_priv); - } - return self; -} - -- (void)digestData:(NSData *)data -{ - if(_priv == NULL) { - return; - } - feeHashAddData(_priv, [data bytes], [data length]); -} - -- (NSData *)messageDigest -{ - unsigned char *cp; - NSData *md; - - if(_priv == NULL) { - return nil; - } - cp = feeHashDigest(_priv); - md = [NSData dataWithBytes:cp length:feeHashDigestLen()]; - feeHashReinit(_priv); - return md; -} - -- (NSData *)digestData:(NSData *)data withSalt:(NSData *)salt -{ - if(_priv == NULL) { - return nil; - } - if(salt != nil) { - [self digestData:salt]; - } - [self digestData:data]; - return [self messageDigest]; -} - -@end diff --git a/OSX/libsecurity_cryptkit/lib/NSRandomNumberGenerator.h b/OSX/libsecurity_cryptkit/lib/NSRandomNumberGenerator.h deleted file mode 100644 index 1de469cd..00000000 --- a/OSX/libsecurity_cryptkit/lib/NSRandomNumberGenerator.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * NSRandomNumberGenerator.h - * - * Revision History - * ---------------- - * 28 Mar 97 at Apple - * Simplified. - * ?? 96 Blaine Garst at NeXT - * Created. - */ - -#import - -@interface NSRandomNumberGenerator : NSObject -{ - void *_priv; -} - -- initWithSeed:(unsigned)seed; // designated initializer -- init; // we'll come up with the best seed - // we can - -- (unsigned)nextNumber; -- (unsigned)nextNumberInRange:(NSRange)range; -- (NSData *)randomDataWithLength:(unsigned)l; - -@end diff --git a/OSX/libsecurity_cryptkit/lib/NSRandomNumberGenerator.m b/OSX/libsecurity_cryptkit/lib/NSRandomNumberGenerator.m deleted file mode 100644 index 4d92fc55..00000000 --- a/OSX/libsecurity_cryptkit/lib/NSRandomNumberGenerator.m +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * NSRandomNumberGenerator.m - * - * Revision History - * ---------------- - * 28 Mar 97 at Apple - * Rewrote using feeRandom module. - * ?? 96 Blaine Garst at NeXT - * Created. - */ - -/* - * Note: out _priv ivar is actually a feeRand pointer. - */ - -#import -#import "NSRandomNumberGenerator.h" -#import "feeRandom.h" -#import "falloc.h" - -@implementation NSRandomNumberGenerator - -- init -{ - if(_priv == NULL) { - _priv = feeRandAlloc(); - } - /* - * else no need to re-init - */ - return self; -} - -- initWithSeed:(unsigned)seed -{ - if(_priv != NULL) { - /* - * Free & re-init to use new seed - */ - feeRandFree(_priv); - } - _priv = feeRandAllocWithSeed(seed); - return self; -} - -- (unsigned)nextNumber -{ - if(_priv == NULL) { - return 0; - } - return feeRandNextNum(_priv); -} - -- (unsigned)nextNumberInRange:(NSRange)range -{ - if(_priv == NULL) { - return 0; - } - return range.location + ([self nextNumber] % range.length); -} - -- (NSData *)randomDataWithLength:(unsigned)l -{ - unsigned char *cp; - - if(_priv == NULL) { - return nil; - } - cp = fmalloc(l); - feeRandBytes(_priv, cp, l); - return [NSData dataWithBytesNoCopy:cp length:l]; -} - -@end diff --git a/OSX/libsecurity_cryptkit/lib/mutils.h b/OSX/libsecurity_cryptkit/lib/mutils.h deleted file mode 100644 index 57023f74..00000000 --- a/OSX/libsecurity_cryptkit/lib/mutils.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * mutils.h - general private ObjC routine declarations - * - * Revision History - * ---------------- - * 2 Aug 96 at NeXT - * Broke out from Blaine Garst's original NSCryptors.m - */ - -#ifndef _CK_MUTILS_H_ -#define _CK_MUTILS_H_ - -#include -#include "giantIntegers.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern NSMutableData *data_with_giant(giant u); -extern void canonicalize_data(NSMutableData *data); - -#ifdef __cplusplus -} -#endif - -#endif /*_CK_MUTILS_H_*/ diff --git a/OSX/libsecurity_cryptkit/lib/mutils.m b/OSX/libsecurity_cryptkit/lib/mutils.m deleted file mode 100644 index 129c905c..00000000 --- a/OSX/libsecurity_cryptkit/lib/mutils.m +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * mutils.m - general private ObjC routine declarations - * - * Revision History - * ---------------- - * 2 Aug 96 at NeXT - * Broke out from Blaine Garst's original NSCryptors.m - */ - -#import -#import "giantIntegers.h" -#import "ckutilities.h" -#import "mutils.h" -#import "feeFunctions.h" -#import - -#if defined(NeXT) && !defined(WIN32) - -/* - * Public, declared in NSCryptors.h - */ -NSString *NSPromptForPassPhrase(NSString *prompt) { - // useful for command line (/dev/tty) programs - char buffer[PHRASELEN]; - NSString *result; - - getpassword([prompt cString], buffer); - if (buffer[0] == 0) return nil; - result = [NSString stringWithCString:buffer]; - bzero(buffer, PHRASELEN); - return result; -} - - -#endif NeXT diff --git a/OSX/libsecurity_cssm/lib/cssmerr.h b/OSX/libsecurity_cssm/lib/cssmerr.h index 9d518fd5..4465dbc0 100644 --- a/OSX/libsecurity_cssm/lib/cssmerr.h +++ b/OSX/libsecurity_cssm/lib/cssmerr.h @@ -89,16 +89,11 @@ enum { /* General Error Values. */ enum { - CSSMERR_CSSM_INVALID_ADDIN_HANDLE = - CSSM_CSSM_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT + 1, - CSSMERR_CSSM_NOT_INITIALIZED = - CSSM_CSSM_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT + 2, - CSSMERR_CSSM_INVALID_HANDLE_USAGE = - CSSM_CSSM_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT + 3, - CSSMERR_CSSM_PVC_REFERENT_NOT_FOUND = - CSSM_CSSM_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT + 4, - CSSMERR_CSSM_FUNCTION_INTEGRITY_FAIL = - CSSM_CSSM_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT + 5 + CSSMERR_CSSM_INVALID_ADDIN_HANDLE = -2147417855, + CSSMERR_CSSM_NOT_INITIALIZED = -2147417854, + CSSMERR_CSSM_INVALID_HANDLE_USAGE = -2147417853, + CSSMERR_CSSM_PVC_REFERENT_NOT_FOUND = -2147417852, + CSSMERR_CSSM_FUNCTION_INTEGRITY_FAIL = -2147417851, }; /* Common Error Codes For All Module Types. */ @@ -175,155 +170,102 @@ enum { /* CSSM Error Values Derived from Common Error Codes For All Module Types. */ enum { - CSSMERR_CSSM_INTERNAL_ERROR = - CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_INTERNAL_ERROR, - CSSMERR_CSSM_MEMORY_ERROR = - CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_MEMORY_ERROR, - CSSMERR_CSSM_MDS_ERROR = - CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_MDS_ERROR, - CSSMERR_CSSM_INVALID_POINTER = - CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_INVALID_POINTER, - CSSMERR_CSSM_INVALID_INPUT_POINTER = - CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_INVALID_INPUT_POINTER, - CSSMERR_CSSM_INVALID_OUTPUT_POINTER = - CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_INVALID_OUTPUT_POINTER, - CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED = - CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED, - CSSMERR_CSSM_SELF_CHECK_FAILED = - CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_SELF_CHECK_FAILED, - CSSMERR_CSSM_OS_ACCESS_DENIED = - CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_OS_ACCESS_DENIED, - CSSMERR_CSSM_FUNCTION_FAILED = - CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_FUNCTION_FAILED, - CSSMERR_CSSM_MODULE_MANIFEST_VERIFY_FAILED = - CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_MODULE_MANIFEST_VERIFY_FAILED, - CSSMERR_CSSM_INVALID_GUID = - CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_INVALID_GUID + CSSMERR_CSSM_INTERNAL_ERROR = -2147418111, + CSSMERR_CSSM_MEMORY_ERROR = -2147418110, + CSSMERR_CSSM_MDS_ERROR = -2147418109, + CSSMERR_CSSM_INVALID_POINTER = -2147418108, + CSSMERR_CSSM_INVALID_INPUT_POINTER = -2147418107, + CSSMERR_CSSM_INVALID_OUTPUT_POINTER = -2147418106, + CSSMERR_CSSM_FUNCTION_NOT_IMPLEMENTED = -2147418105, + CSSMERR_CSSM_SELF_CHECK_FAILED = -2147418104, + CSSMERR_CSSM_OS_ACCESS_DENIED = -2147418103, + CSSMERR_CSSM_FUNCTION_FAILED = -2147418102, + CSSMERR_CSSM_MODULE_MANIFEST_VERIFY_FAILED = -2147418101, + CSSMERR_CSSM_INVALID_GUID = -2147418100, }; /* CSSM Error Values for Specific Data Types. */ enum { - CSSMERR_CSSM_INVALID_CONTEXT_HANDLE = - CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_INVALID_CONTEXT_HANDLE, - CSSMERR_CSSM_INCOMPATIBLE_VERSION = - CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_INCOMPATIBLE_VERSION, - CSSMERR_CSSM_PRIVILEGE_NOT_GRANTED = - CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_PRIVILEGE_NOT_GRANTED + CSSMERR_CSSM_INVALID_CONTEXT_HANDLE = -2147418048, + CSSMERR_CSSM_INCOMPATIBLE_VERSION = -2147418047, + CSSMERR_CSSM_PRIVILEGE_NOT_GRANTED = -2147418037, }; /* CSSM Module-Specific Error Values */ enum { CSSM_CSSM_BASE_CSSM_ERROR = CSSM_CSSM_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT + 0x10, - CSSMERR_CSSM_SCOPE_NOT_SUPPORTED = CSSM_CSSM_BASE_CSSM_ERROR + 1, - CSSMERR_CSSM_PVC_ALREADY_CONFIGURED = CSSM_CSSM_BASE_CSSM_ERROR + 2, - CSSMERR_CSSM_INVALID_PVC = CSSM_CSSM_BASE_CSSM_ERROR + 3, - CSSMERR_CSSM_EMM_LOAD_FAILED = CSSM_CSSM_BASE_CSSM_ERROR + 4, - CSSMERR_CSSM_EMM_UNLOAD_FAILED = CSSM_CSSM_BASE_CSSM_ERROR + 5, - CSSMERR_CSSM_ADDIN_LOAD_FAILED = CSSM_CSSM_BASE_CSSM_ERROR + 6, - CSSMERR_CSSM_INVALID_KEY_HIERARCHY = CSSM_CSSM_BASE_CSSM_ERROR + 7, - CSSMERR_CSSM_ADDIN_UNLOAD_FAILED = CSSM_CSSM_BASE_CSSM_ERROR + 8, - CSSMERR_CSSM_LIB_REF_NOT_FOUND = CSSM_CSSM_BASE_CSSM_ERROR + 9, - CSSMERR_CSSM_INVALID_ADDIN_FUNCTION_TABLE = CSSM_CSSM_BASE_CSSM_ERROR + 10, - CSSMERR_CSSM_EMM_AUTHENTICATE_FAILED = CSSM_CSSM_BASE_CSSM_ERROR + 11, - CSSMERR_CSSM_ADDIN_AUTHENTICATE_FAILED = CSSM_CSSM_BASE_CSSM_ERROR + 12, - CSSMERR_CSSM_INVALID_SERVICE_MASK = CSSM_CSSM_BASE_CSSM_ERROR + 13, - CSSMERR_CSSM_MODULE_NOT_LOADED = CSSM_CSSM_BASE_CSSM_ERROR + 14, - CSSMERR_CSSM_INVALID_SUBSERVICEID = CSSM_CSSM_BASE_CSSM_ERROR + 15, - CSSMERR_CSSM_BUFFER_TOO_SMALL = CSSM_CSSM_BASE_CSSM_ERROR + 16, - CSSMERR_CSSM_INVALID_ATTRIBUTE = CSSM_CSSM_BASE_CSSM_ERROR + 17, - CSSMERR_CSSM_ATTRIBUTE_NOT_IN_CONTEXT = CSSM_CSSM_BASE_CSSM_ERROR + 18, - CSSMERR_CSSM_MODULE_MANAGER_INITIALIZE_FAIL = CSSM_CSSM_BASE_CSSM_ERROR + 19, - CSSMERR_CSSM_MODULE_MANAGER_NOT_FOUND = CSSM_CSSM_BASE_CSSM_ERROR + 20, - CSSMERR_CSSM_EVENT_NOTIFICATION_CALLBACK_NOT_FOUND = CSSM_CSSM_BASE_CSSM_ERROR + 21 + CSSMERR_CSSM_SCOPE_NOT_SUPPORTED = -2147417839, + CSSMERR_CSSM_PVC_ALREADY_CONFIGURED = -2147417838, + CSSMERR_CSSM_INVALID_PVC = -2147417837, + CSSMERR_CSSM_EMM_LOAD_FAILED = -2147417836, + CSSMERR_CSSM_EMM_UNLOAD_FAILED = -2147417835, + CSSMERR_CSSM_ADDIN_LOAD_FAILED = -2147417834, + CSSMERR_CSSM_INVALID_KEY_HIERARCHY = -2147417833, + CSSMERR_CSSM_ADDIN_UNLOAD_FAILED = -2147417832, + CSSMERR_CSSM_LIB_REF_NOT_FOUND = -2147417831, + CSSMERR_CSSM_INVALID_ADDIN_FUNCTION_TABLE = -2147417830, + CSSMERR_CSSM_EMM_AUTHENTICATE_FAILED = -2147417829, + CSSMERR_CSSM_ADDIN_AUTHENTICATE_FAILED = -2147417828, + CSSMERR_CSSM_INVALID_SERVICE_MASK = -2147417827, + CSSMERR_CSSM_MODULE_NOT_LOADED = -2147417826, + CSSMERR_CSSM_INVALID_SUBSERVICEID = -2147417825, + CSSMERR_CSSM_BUFFER_TOO_SMALL = -2147417824, + CSSMERR_CSSM_INVALID_ATTRIBUTE = -2147417823, + CSSMERR_CSSM_ATTRIBUTE_NOT_IN_CONTEXT = -2147417822, + CSSMERR_CSSM_MODULE_MANAGER_INITIALIZE_FAIL = -2147417821, + CSSMERR_CSSM_MODULE_MANAGER_NOT_FOUND = -2147417820, + CSSMERR_CSSM_EVENT_NOTIFICATION_CALLBACK_NOT_FOUND = -2147417819, }; /* CSP Error Values Derived from Common Error Codes For All Module Types. */ enum { - CSSMERR_CSP_INTERNAL_ERROR = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INTERNAL_ERROR, - CSSMERR_CSP_MEMORY_ERROR = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_MEMORY_ERROR, - CSSMERR_CSP_MDS_ERROR = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_MDS_ERROR, - CSSMERR_CSP_INVALID_POINTER = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_POINTER, - CSSMERR_CSP_INVALID_INPUT_POINTER = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_INPUT_POINTER, - CSSMERR_CSP_INVALID_OUTPUT_POINTER = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_OUTPUT_POINTER, - CSSMERR_CSP_FUNCTION_NOT_IMPLEMENTED = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED, - CSSMERR_CSP_SELF_CHECK_FAILED = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_SELF_CHECK_FAILED, - CSSMERR_CSP_OS_ACCESS_DENIED = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_OS_ACCESS_DENIED, - CSSMERR_CSP_FUNCTION_FAILED = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_FUNCTION_FAILED + CSSMERR_CSP_INTERNAL_ERROR = -2147416063, + CSSMERR_CSP_MEMORY_ERROR = -2147416062, + CSSMERR_CSP_MDS_ERROR = -2147416061, + CSSMERR_CSP_INVALID_POINTER = -2147416060, + CSSMERR_CSP_INVALID_INPUT_POINTER = -2147416059, + CSSMERR_CSP_INVALID_OUTPUT_POINTER = -2147416058, + CSSMERR_CSP_FUNCTION_NOT_IMPLEMENTED = -2147416057, + CSSMERR_CSP_SELF_CHECK_FAILED = -2147416056, + CSSMERR_CSP_OS_ACCESS_DENIED = -2147416055, + CSSMERR_CSP_FUNCTION_FAILED = -2147416054, }; /* CSP Error Values Derived from ACL-based Error Codes. */ enum { - CSSMERR_CSP_OPERATION_AUTH_DENIED = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_OPERATION_AUTH_DENIED, - CSSMERR_CSP_OBJECT_USE_AUTH_DENIED = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_OBJECT_USE_AUTH_DENIED, - CSSMERR_CSP_OBJECT_MANIP_AUTH_DENIED = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_OBJECT_MANIP_AUTH_DENIED, - CSSMERR_CSP_OBJECT_ACL_NOT_SUPPORTED = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_OBJECT_ACL_NOT_SUPPORTED, - CSSMERR_CSP_OBJECT_ACL_REQUIRED = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_OBJECT_ACL_REQUIRED, - CSSMERR_CSP_INVALID_ACCESS_CREDENTIALS = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_ACCESS_CREDENTIALS, - CSSMERR_CSP_INVALID_ACL_BASE_CERTS = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_BASE_CERTS, - CSSMERR_CSP_ACL_BASE_CERTS_NOT_SUPPORTED = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_ACL_BASE_CERTS_NOT_SUPPORTED, - CSSMERR_CSP_INVALID_SAMPLE_VALUE = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_SAMPLE_VALUE, - CSSMERR_CSP_SAMPLE_VALUE_NOT_SUPPORTED = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_SAMPLE_VALUE_NOT_SUPPORTED, - CSSMERR_CSP_INVALID_ACL_SUBJECT_VALUE = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE, - CSSMERR_CSP_ACL_SUBJECT_TYPE_NOT_SUPPORTED = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_ACL_SUBJECT_TYPE_NOT_SUPPORTED, - CSSMERR_CSP_INVALID_ACL_CHALLENGE_CALLBACK = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_CHALLENGE_CALLBACK, - CSSMERR_CSP_ACL_CHALLENGE_CALLBACK_FAILED = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_ACL_CHALLENGE_CALLBACK_FAILED, - CSSMERR_CSP_INVALID_ACL_ENTRY_TAG = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG, - CSSMERR_CSP_ACL_ENTRY_TAG_NOT_FOUND = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_ACL_ENTRY_TAG_NOT_FOUND, - CSSMERR_CSP_INVALID_ACL_EDIT_MODE = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_EDIT_MODE, - CSSMERR_CSP_ACL_CHANGE_FAILED = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_ACL_CHANGE_FAILED, - CSSMERR_CSP_INVALID_NEW_ACL_ENTRY = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_NEW_ACL_ENTRY, - CSSMERR_CSP_INVALID_NEW_ACL_OWNER = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_NEW_ACL_OWNER, - CSSMERR_CSP_ACL_DELETE_FAILED = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_ACL_DELETE_FAILED, - CSSMERR_CSP_ACL_REPLACE_FAILED = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_ACL_REPLACE_FAILED, - CSSMERR_CSP_ACL_ADD_FAILED = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_ACL_ADD_FAILED + CSSMERR_CSP_OPERATION_AUTH_DENIED = -2147416032, + CSSMERR_CSP_OBJECT_USE_AUTH_DENIED = -2147416031, + CSSMERR_CSP_OBJECT_MANIP_AUTH_DENIED = -2147416030, + CSSMERR_CSP_OBJECT_ACL_NOT_SUPPORTED = -2147416029, + CSSMERR_CSP_OBJECT_ACL_REQUIRED = -2147416028, + CSSMERR_CSP_INVALID_ACCESS_CREDENTIALS = -2147416027, + CSSMERR_CSP_INVALID_ACL_BASE_CERTS = -2147416026, + CSSMERR_CSP_ACL_BASE_CERTS_NOT_SUPPORTED = -2147416025, + CSSMERR_CSP_INVALID_SAMPLE_VALUE = -2147416024, + CSSMERR_CSP_SAMPLE_VALUE_NOT_SUPPORTED = -2147416023, + CSSMERR_CSP_INVALID_ACL_SUBJECT_VALUE = -2147416022, + CSSMERR_CSP_ACL_SUBJECT_TYPE_NOT_SUPPORTED = -2147416021, + CSSMERR_CSP_INVALID_ACL_CHALLENGE_CALLBACK = -2147416020, + CSSMERR_CSP_ACL_CHALLENGE_CALLBACK_FAILED = -2147416019, + CSSMERR_CSP_INVALID_ACL_ENTRY_TAG = -2147416018, + CSSMERR_CSP_ACL_ENTRY_TAG_NOT_FOUND = -2147416017, + CSSMERR_CSP_INVALID_ACL_EDIT_MODE = -2147416016, + CSSMERR_CSP_ACL_CHANGE_FAILED = -2147416015, + CSSMERR_CSP_INVALID_NEW_ACL_ENTRY = -2147416014, + CSSMERR_CSP_INVALID_NEW_ACL_OWNER = -2147416013, + CSSMERR_CSP_ACL_DELETE_FAILED = -2147416012, + CSSMERR_CSP_ACL_REPLACE_FAILED = -2147416011, + CSSMERR_CSP_ACL_ADD_FAILED = -2147416010, }; /* CSP Error Values for Specific Data Types. */ enum { - CSSMERR_CSP_INVALID_CONTEXT_HANDLE = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_CONTEXT_HANDLE, - CSSMERR_CSP_PRIVILEGE_NOT_GRANTED = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_PRIVILEGE_NOT_GRANTED, - CSSMERR_CSP_INVALID_DATA = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_DATA, - CSSMERR_CSP_INVALID_PASSTHROUGH_ID = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_PASSTHROUGH_ID, - CSSMERR_CSP_INVALID_CRYPTO_DATA = - CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INVALID_CRYPTO_DATA + CSSMERR_CSP_INVALID_CONTEXT_HANDLE = -2147416000, + CSSMERR_CSP_PRIVILEGE_NOT_GRANTED = -2147415989, + CSSMERR_CSP_INVALID_DATA = -2147415994, + CSSMERR_CSP_INVALID_PASSTHROUGH_ID = -2147415978, + CSSMERR_CSP_INVALID_CRYPTO_DATA = -2147415976, }; /* CSP Module-Specific Error Values */ @@ -331,488 +273,375 @@ enum { /* General CSP Error Values */ CSSM_CSP_BASE_CSP_ERROR = CSSM_CSP_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT, - CSSMERR_CSP_INPUT_LENGTH_ERROR = CSSM_CSP_BASE_CSP_ERROR + 1, - CSSMERR_CSP_OUTPUT_LENGTH_ERROR = CSSM_CSP_BASE_CSP_ERROR + 2, - CSSMERR_CSP_PRIVILEGE_NOT_SUPPORTED = CSSM_CSP_BASE_CSP_ERROR + 3, - CSSMERR_CSP_DEVICE_ERROR = CSSM_CSP_BASE_CSP_ERROR + 4, - CSSMERR_CSP_DEVICE_MEMORY_ERROR = CSSM_CSP_BASE_CSP_ERROR + 5, - CSSMERR_CSP_ATTACH_HANDLE_BUSY = CSSM_CSP_BASE_CSP_ERROR + 6, - CSSMERR_CSP_NOT_LOGGED_IN = CSSM_CSP_BASE_CSP_ERROR + 7, - CSSMERR_CSP_INVALID_KEY = CSSM_CSP_BASE_CSP_ERROR + 16, - CSSMERR_CSP_INVALID_KEY_REFERENCE = CSSM_CSP_BASE_CSP_ERROR + 17, - CSSMERR_CSP_INVALID_KEY_CLASS = CSSM_CSP_BASE_CSP_ERROR + 18, - CSSMERR_CSP_ALGID_MISMATCH = CSSM_CSP_BASE_CSP_ERROR + 19, - CSSMERR_CSP_KEY_USAGE_INCORRECT = CSSM_CSP_BASE_CSP_ERROR + 20, - CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT = CSSM_CSP_BASE_CSP_ERROR + 21, - CSSMERR_CSP_KEY_HEADER_INCONSISTENT = CSSM_CSP_BASE_CSP_ERROR + 22, - CSSMERR_CSP_UNSUPPORTED_KEY_FORMAT = CSSM_CSP_BASE_CSP_ERROR + 23, - CSSMERR_CSP_UNSUPPORTED_KEY_SIZE = CSSM_CSP_BASE_CSP_ERROR + 24, - CSSMERR_CSP_INVALID_KEY_POINTER = CSSM_CSP_BASE_CSP_ERROR + 25, - CSSMERR_CSP_INVALID_KEYUSAGE_MASK = CSSM_CSP_BASE_CSP_ERROR + 26, - CSSMERR_CSP_UNSUPPORTED_KEYUSAGE_MASK = CSSM_CSP_BASE_CSP_ERROR + 27, - CSSMERR_CSP_INVALID_KEYATTR_MASK = CSSM_CSP_BASE_CSP_ERROR + 28, - CSSMERR_CSP_UNSUPPORTED_KEYATTR_MASK = CSSM_CSP_BASE_CSP_ERROR + 29, - CSSMERR_CSP_INVALID_KEY_LABEL = CSSM_CSP_BASE_CSP_ERROR + 30, - CSSMERR_CSP_UNSUPPORTED_KEY_LABEL = CSSM_CSP_BASE_CSP_ERROR + 31, - CSSMERR_CSP_INVALID_KEY_FORMAT = CSSM_CSP_BASE_CSP_ERROR + 32, - - /* CSP Vector of Buffers Error Values. */ - CSSMERR_CSP_INVALID_DATA_COUNT = CSSM_CSP_BASE_CSP_ERROR + 40, - CSSMERR_CSP_VECTOR_OF_BUFS_UNSUPPORTED = CSSM_CSP_BASE_CSP_ERROR + 41, - CSSMERR_CSP_INVALID_INPUT_VECTOR = CSSM_CSP_BASE_CSP_ERROR + 42, - CSSMERR_CSP_INVALID_OUTPUT_VECTOR = CSSM_CSP_BASE_CSP_ERROR + 43, - - /* CSP Cryptographic Context Error Values. */ - CSSMERR_CSP_INVALID_CONTEXT = CSSM_CSP_BASE_CSP_ERROR + 48, - CSSMERR_CSP_INVALID_ALGORITHM = CSSM_CSP_BASE_CSP_ERROR + 49, - CSSMERR_CSP_INVALID_ATTR_KEY = CSSM_CSP_BASE_CSP_ERROR + 54, - CSSMERR_CSP_MISSING_ATTR_KEY = CSSM_CSP_BASE_CSP_ERROR + 55, - CSSMERR_CSP_INVALID_ATTR_INIT_VECTOR = CSSM_CSP_BASE_CSP_ERROR + 56, - CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR = CSSM_CSP_BASE_CSP_ERROR + 57, - CSSMERR_CSP_INVALID_ATTR_SALT = CSSM_CSP_BASE_CSP_ERROR + 58, - CSSMERR_CSP_MISSING_ATTR_SALT = CSSM_CSP_BASE_CSP_ERROR + 59, - CSSMERR_CSP_INVALID_ATTR_PADDING = CSSM_CSP_BASE_CSP_ERROR + 60, - CSSMERR_CSP_MISSING_ATTR_PADDING = CSSM_CSP_BASE_CSP_ERROR + 61, - CSSMERR_CSP_INVALID_ATTR_RANDOM = CSSM_CSP_BASE_CSP_ERROR + 62, - CSSMERR_CSP_MISSING_ATTR_RANDOM = CSSM_CSP_BASE_CSP_ERROR + 63, - CSSMERR_CSP_INVALID_ATTR_SEED = CSSM_CSP_BASE_CSP_ERROR + 64, - CSSMERR_CSP_MISSING_ATTR_SEED = CSSM_CSP_BASE_CSP_ERROR + 65, - CSSMERR_CSP_INVALID_ATTR_PASSPHRASE = CSSM_CSP_BASE_CSP_ERROR + 66, - CSSMERR_CSP_MISSING_ATTR_PASSPHRASE = CSSM_CSP_BASE_CSP_ERROR + 67, - CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH = CSSM_CSP_BASE_CSP_ERROR + 68, - CSSMERR_CSP_MISSING_ATTR_KEY_LENGTH = CSSM_CSP_BASE_CSP_ERROR + 69, - CSSMERR_CSP_INVALID_ATTR_BLOCK_SIZE = CSSM_CSP_BASE_CSP_ERROR + 70, - CSSMERR_CSP_MISSING_ATTR_BLOCK_SIZE = CSSM_CSP_BASE_CSP_ERROR + 71, - CSSMERR_CSP_INVALID_ATTR_OUTPUT_SIZE = CSSM_CSP_BASE_CSP_ERROR + 100, - CSSMERR_CSP_MISSING_ATTR_OUTPUT_SIZE = CSSM_CSP_BASE_CSP_ERROR + 101, - CSSMERR_CSP_INVALID_ATTR_ROUNDS = CSSM_CSP_BASE_CSP_ERROR + 102, - CSSMERR_CSP_MISSING_ATTR_ROUNDS = CSSM_CSP_BASE_CSP_ERROR + 103, - CSSMERR_CSP_INVALID_ATTR_ALG_PARAMS = CSSM_CSP_BASE_CSP_ERROR + 104, - CSSMERR_CSP_MISSING_ATTR_ALG_PARAMS = CSSM_CSP_BASE_CSP_ERROR + 105, - CSSMERR_CSP_INVALID_ATTR_LABEL = CSSM_CSP_BASE_CSP_ERROR + 106, - CSSMERR_CSP_MISSING_ATTR_LABEL = CSSM_CSP_BASE_CSP_ERROR + 107, - CSSMERR_CSP_INVALID_ATTR_KEY_TYPE = CSSM_CSP_BASE_CSP_ERROR + 108, - CSSMERR_CSP_MISSING_ATTR_KEY_TYPE = CSSM_CSP_BASE_CSP_ERROR + 109, - CSSMERR_CSP_INVALID_ATTR_MODE = CSSM_CSP_BASE_CSP_ERROR + 110, - CSSMERR_CSP_MISSING_ATTR_MODE = CSSM_CSP_BASE_CSP_ERROR + 111, - CSSMERR_CSP_INVALID_ATTR_EFFECTIVE_BITS = CSSM_CSP_BASE_CSP_ERROR + 112, - CSSMERR_CSP_MISSING_ATTR_EFFECTIVE_BITS = CSSM_CSP_BASE_CSP_ERROR + 113, - CSSMERR_CSP_INVALID_ATTR_START_DATE = CSSM_CSP_BASE_CSP_ERROR + 114, - CSSMERR_CSP_MISSING_ATTR_START_DATE = CSSM_CSP_BASE_CSP_ERROR + 115, - CSSMERR_CSP_INVALID_ATTR_END_DATE = CSSM_CSP_BASE_CSP_ERROR + 116, - CSSMERR_CSP_MISSING_ATTR_END_DATE = CSSM_CSP_BASE_CSP_ERROR + 117, - CSSMERR_CSP_INVALID_ATTR_VERSION = CSSM_CSP_BASE_CSP_ERROR + 118, - CSSMERR_CSP_MISSING_ATTR_VERSION = CSSM_CSP_BASE_CSP_ERROR + 119, - CSSMERR_CSP_INVALID_ATTR_PRIME = CSSM_CSP_BASE_CSP_ERROR + 120, - CSSMERR_CSP_MISSING_ATTR_PRIME = CSSM_CSP_BASE_CSP_ERROR + 121, - CSSMERR_CSP_INVALID_ATTR_BASE = CSSM_CSP_BASE_CSP_ERROR + 122, - CSSMERR_CSP_MISSING_ATTR_BASE = CSSM_CSP_BASE_CSP_ERROR + 123, - CSSMERR_CSP_INVALID_ATTR_SUBPRIME = CSSM_CSP_BASE_CSP_ERROR + 124, - CSSMERR_CSP_MISSING_ATTR_SUBPRIME = CSSM_CSP_BASE_CSP_ERROR + 125, - CSSMERR_CSP_INVALID_ATTR_ITERATION_COUNT = CSSM_CSP_BASE_CSP_ERROR + 126, - CSSMERR_CSP_MISSING_ATTR_ITERATION_COUNT = CSSM_CSP_BASE_CSP_ERROR + 127, - CSSMERR_CSP_INVALID_ATTR_DL_DB_HANDLE = CSSM_CSP_BASE_CSP_ERROR + 128, - CSSMERR_CSP_MISSING_ATTR_DL_DB_HANDLE = CSSM_CSP_BASE_CSP_ERROR + 129, - CSSMERR_CSP_INVALID_ATTR_ACCESS_CREDENTIALS = CSSM_CSP_BASE_CSP_ERROR + 130, - CSSMERR_CSP_MISSING_ATTR_ACCESS_CREDENTIALS = CSSM_CSP_BASE_CSP_ERROR + 131, - CSSMERR_CSP_INVALID_ATTR_PUBLIC_KEY_FORMAT = CSSM_CSP_BASE_CSP_ERROR + 132, - CSSMERR_CSP_MISSING_ATTR_PUBLIC_KEY_FORMAT = CSSM_CSP_BASE_CSP_ERROR + 133, - CSSMERR_CSP_INVALID_ATTR_PRIVATE_KEY_FORMAT = CSSM_CSP_BASE_CSP_ERROR + 134, - CSSMERR_CSP_MISSING_ATTR_PRIVATE_KEY_FORMAT = CSSM_CSP_BASE_CSP_ERROR + 135, - CSSMERR_CSP_INVALID_ATTR_SYMMETRIC_KEY_FORMAT = CSSM_CSP_BASE_CSP_ERROR + 136, - CSSMERR_CSP_MISSING_ATTR_SYMMETRIC_KEY_FORMAT = CSSM_CSP_BASE_CSP_ERROR + 137, - CSSMERR_CSP_INVALID_ATTR_WRAPPED_KEY_FORMAT = CSSM_CSP_BASE_CSP_ERROR + 138, - CSSMERR_CSP_MISSING_ATTR_WRAPPED_KEY_FORMAT = CSSM_CSP_BASE_CSP_ERROR + 139, - - /* CSP Staged Cryptographic API Error Values. */ - CSSMERR_CSP_STAGED_OPERATION_IN_PROGRESS = CSSM_CSP_BASE_CSP_ERROR + 72, - CSSMERR_CSP_STAGED_OPERATION_NOT_STARTED = CSSM_CSP_BASE_CSP_ERROR + 73, - CSSMERR_CSP_VERIFY_FAILED = CSSM_CSP_BASE_CSP_ERROR + 74, - CSSMERR_CSP_INVALID_SIGNATURE = CSSM_CSP_BASE_CSP_ERROR + 75, - CSSMERR_CSP_QUERY_SIZE_UNKNOWN = CSSM_CSP_BASE_CSP_ERROR + 76, - CSSMERR_CSP_BLOCK_SIZE_MISMATCH = CSSM_CSP_BASE_CSP_ERROR + 77, - CSSMERR_CSP_PRIVATE_KEY_NOT_FOUND = CSSM_CSP_BASE_CSP_ERROR + 78, - CSSMERR_CSP_PUBLIC_KEY_INCONSISTENT = CSSM_CSP_BASE_CSP_ERROR + 79, - CSSMERR_CSP_DEVICE_VERIFY_FAILED = CSSM_CSP_BASE_CSP_ERROR + 80, - CSSMERR_CSP_INVALID_LOGIN_NAME = CSSM_CSP_BASE_CSP_ERROR + 81, - CSSMERR_CSP_ALREADY_LOGGED_IN = CSSM_CSP_BASE_CSP_ERROR + 82, - CSSMERR_CSP_PRIVATE_KEY_ALREADY_EXISTS = CSSM_CSP_BASE_CSP_ERROR + 83, - CSSMERR_CSP_KEY_LABEL_ALREADY_EXISTS = CSSM_CSP_BASE_CSP_ERROR + 84, - CSSMERR_CSP_INVALID_DIGEST_ALGORITHM = CSSM_CSP_BASE_CSP_ERROR + 85, - CSSMERR_CSP_CRYPTO_DATA_CALLBACK_FAILED = CSSM_CSP_BASE_CSP_ERROR + 86 + CSSMERR_CSP_INPUT_LENGTH_ERROR = -2147415807, + CSSMERR_CSP_OUTPUT_LENGTH_ERROR = -2147415806, + CSSMERR_CSP_PRIVILEGE_NOT_SUPPORTED = -2147415805, + CSSMERR_CSP_DEVICE_ERROR = -2147415804, + CSSMERR_CSP_DEVICE_MEMORY_ERROR = -2147415803, + CSSMERR_CSP_ATTACH_HANDLE_BUSY = -2147415802, + CSSMERR_CSP_NOT_LOGGED_IN = -2147415801, + CSSMERR_CSP_INVALID_KEY = -2147415792, + CSSMERR_CSP_INVALID_KEY_REFERENCE = -2147415791, + CSSMERR_CSP_INVALID_KEY_CLASS = -2147415790, + CSSMERR_CSP_ALGID_MISMATCH = -2147415789, + CSSMERR_CSP_KEY_USAGE_INCORRECT = -2147415788, + CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT = -2147415787, + CSSMERR_CSP_KEY_HEADER_INCONSISTENT = -2147415786, + CSSMERR_CSP_UNSUPPORTED_KEY_FORMAT = -2147415785, + CSSMERR_CSP_UNSUPPORTED_KEY_SIZE = -2147415784, + CSSMERR_CSP_INVALID_KEY_POINTER = -2147415783, + CSSMERR_CSP_INVALID_KEYUSAGE_MASK = -2147415782, + CSSMERR_CSP_UNSUPPORTED_KEYUSAGE_MASK = -2147415781, + CSSMERR_CSP_INVALID_KEYATTR_MASK = -2147415780, + CSSMERR_CSP_UNSUPPORTED_KEYATTR_MASK = -2147415779, + CSSMERR_CSP_INVALID_KEY_LABEL = -2147415778, + CSSMERR_CSP_UNSUPPORTED_KEY_LABEL = -2147415777, + CSSMERR_CSP_INVALID_KEY_FORMAT = -2147415776, + + CSSMERR_CSP_INVALID_DATA_COUNT = -2147415768, + CSSMERR_CSP_VECTOR_OF_BUFS_UNSUPPORTED = -2147415767, + CSSMERR_CSP_INVALID_INPUT_VECTOR = -2147415766, + CSSMERR_CSP_INVALID_OUTPUT_VECTOR = -2147415765, + + CSSMERR_CSP_INVALID_CONTEXT = -2147415760, + CSSMERR_CSP_INVALID_ALGORITHM = -2147415759, + CSSMERR_CSP_INVALID_ATTR_KEY = -2147415754, + CSSMERR_CSP_MISSING_ATTR_KEY = -2147415753, + CSSMERR_CSP_INVALID_ATTR_INIT_VECTOR = -2147415752, + CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR = -2147415751, + CSSMERR_CSP_INVALID_ATTR_SALT = -2147415750, + CSSMERR_CSP_MISSING_ATTR_SALT = -2147415749, + CSSMERR_CSP_INVALID_ATTR_PADDING = -2147415748, + CSSMERR_CSP_MISSING_ATTR_PADDING = -2147415747, + CSSMERR_CSP_INVALID_ATTR_RANDOM = -2147415746, + CSSMERR_CSP_MISSING_ATTR_RANDOM = -2147415745, + CSSMERR_CSP_INVALID_ATTR_SEED = -2147415744, + CSSMERR_CSP_MISSING_ATTR_SEED = -2147415743, + CSSMERR_CSP_INVALID_ATTR_PASSPHRASE = -2147415742, + CSSMERR_CSP_MISSING_ATTR_PASSPHRASE = -2147415741, + CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH = -2147415740, + CSSMERR_CSP_MISSING_ATTR_KEY_LENGTH = -2147415739, + CSSMERR_CSP_INVALID_ATTR_BLOCK_SIZE = -2147415738, + CSSMERR_CSP_MISSING_ATTR_BLOCK_SIZE = -2147415737, + CSSMERR_CSP_INVALID_ATTR_OUTPUT_SIZE = -2147415708, + CSSMERR_CSP_MISSING_ATTR_OUTPUT_SIZE = -2147415707, + CSSMERR_CSP_INVALID_ATTR_ROUNDS = -2147415706, + CSSMERR_CSP_MISSING_ATTR_ROUNDS = -2147415705, + CSSMERR_CSP_INVALID_ATTR_ALG_PARAMS = -2147415704, + CSSMERR_CSP_MISSING_ATTR_ALG_PARAMS = -2147415703, + CSSMERR_CSP_INVALID_ATTR_LABEL = -2147415702, + CSSMERR_CSP_MISSING_ATTR_LABEL = -2147415701, + CSSMERR_CSP_INVALID_ATTR_KEY_TYPE = -2147415700, + CSSMERR_CSP_MISSING_ATTR_KEY_TYPE = -2147415699, + CSSMERR_CSP_INVALID_ATTR_MODE = -2147415698, + CSSMERR_CSP_MISSING_ATTR_MODE = -2147415697, + CSSMERR_CSP_INVALID_ATTR_EFFECTIVE_BITS = -2147415696, + CSSMERR_CSP_MISSING_ATTR_EFFECTIVE_BITS = -2147415695, + CSSMERR_CSP_INVALID_ATTR_START_DATE = -2147415694, + CSSMERR_CSP_MISSING_ATTR_START_DATE = -2147415693, + CSSMERR_CSP_INVALID_ATTR_END_DATE = -2147415692, + CSSMERR_CSP_MISSING_ATTR_END_DATE = -2147415691, + CSSMERR_CSP_INVALID_ATTR_VERSION = -2147415690, + CSSMERR_CSP_MISSING_ATTR_VERSION = -2147415689, + CSSMERR_CSP_INVALID_ATTR_PRIME = -2147415688, + CSSMERR_CSP_MISSING_ATTR_PRIME = -2147415687, + CSSMERR_CSP_INVALID_ATTR_BASE = -2147415686, + CSSMERR_CSP_MISSING_ATTR_BASE = -2147415685, + CSSMERR_CSP_INVALID_ATTR_SUBPRIME = -2147415684, + CSSMERR_CSP_MISSING_ATTR_SUBPRIME = -2147415683, + CSSMERR_CSP_INVALID_ATTR_ITERATION_COUNT = -2147415682, + CSSMERR_CSP_MISSING_ATTR_ITERATION_COUNT = -2147415681, + CSSMERR_CSP_INVALID_ATTR_DL_DB_HANDLE = -2147415680, + CSSMERR_CSP_MISSING_ATTR_DL_DB_HANDLE = -2147415679, + CSSMERR_CSP_INVALID_ATTR_ACCESS_CREDENTIALS = -2147415678, + CSSMERR_CSP_MISSING_ATTR_ACCESS_CREDENTIALS = -2147415677, + CSSMERR_CSP_INVALID_ATTR_PUBLIC_KEY_FORMAT = -2147415676, + CSSMERR_CSP_MISSING_ATTR_PUBLIC_KEY_FORMAT = -2147415675, + CSSMERR_CSP_INVALID_ATTR_PRIVATE_KEY_FORMAT = -2147415674, + CSSMERR_CSP_MISSING_ATTR_PRIVATE_KEY_FORMAT = -2147415673, + CSSMERR_CSP_INVALID_ATTR_SYMMETRIC_KEY_FORMAT = -2147415672, + CSSMERR_CSP_MISSING_ATTR_SYMMETRIC_KEY_FORMAT = -2147415671, + CSSMERR_CSP_INVALID_ATTR_WRAPPED_KEY_FORMAT = -2147415670, + CSSMERR_CSP_MISSING_ATTR_WRAPPED_KEY_FORMAT = -2147415669, + + CSSMERR_CSP_STAGED_OPERATION_IN_PROGRESS = -2147415736, + CSSMERR_CSP_STAGED_OPERATION_NOT_STARTED = -2147415735, + CSSMERR_CSP_VERIFY_FAILED = -2147415734, + CSSMERR_CSP_INVALID_SIGNATURE = -2147415733, + CSSMERR_CSP_QUERY_SIZE_UNKNOWN = -2147415732, + CSSMERR_CSP_BLOCK_SIZE_MISMATCH = -2147415731, + CSSMERR_CSP_PRIVATE_KEY_NOT_FOUND = -2147415730, + CSSMERR_CSP_PUBLIC_KEY_INCONSISTENT = -2147415729, + CSSMERR_CSP_DEVICE_VERIFY_FAILED = -2147415728, + CSSMERR_CSP_INVALID_LOGIN_NAME = -2147415727, + CSSMERR_CSP_ALREADY_LOGGED_IN = -2147415726, + CSSMERR_CSP_PRIVATE_KEY_ALREADY_EXISTS = -2147415725, + CSSMERR_CSP_KEY_LABEL_ALREADY_EXISTS = -2147415724, + CSSMERR_CSP_INVALID_DIGEST_ALGORITHM = -2147415723, + CSSMERR_CSP_CRYPTO_DATA_CALLBACK_FAILED = -2147415722, }; /* TP Error Values Derived from Common Error Codes For All Module Types. */ enum { - CSSMERR_TP_INTERNAL_ERROR = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INTERNAL_ERROR, - CSSMERR_TP_MEMORY_ERROR = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_MEMORY_ERROR, - CSSMERR_TP_MDS_ERROR = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_MDS_ERROR, - CSSMERR_TP_INVALID_POINTER = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_POINTER, - CSSMERR_TP_INVALID_INPUT_POINTER = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_INPUT_POINTER, - CSSMERR_TP_INVALID_OUTPUT_POINTER = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_OUTPUT_POINTER, - CSSMERR_TP_FUNCTION_NOT_IMPLEMENTED = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED, - CSSMERR_TP_SELF_CHECK_FAILED = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_SELF_CHECK_FAILED, - CSSMERR_TP_OS_ACCESS_DENIED = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_OS_ACCESS_DENIED, - CSSMERR_TP_FUNCTION_FAILED = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_FUNCTION_FAILED, - CSSMERR_TP_INVALID_CONTEXT_HANDLE = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_CONTEXT_HANDLE, - CSSMERR_TP_INVALID_DATA = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_DATA, - CSSMERR_TP_INVALID_DB_LIST = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_DB_LIST, - CSSMERR_TP_INVALID_CERTGROUP_POINTER = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_CERTGROUP_POINTER, - CSSMERR_TP_INVALID_CERT_POINTER = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_CERT_POINTER, - CSSMERR_TP_INVALID_CRL_POINTER = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_CRL_POINTER, - CSSMERR_TP_INVALID_FIELD_POINTER = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_FIELD_POINTER, - CSSMERR_TP_INVALID_NETWORK_ADDR = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_NETWORK_ADDR, - CSSMERR_TP_CRL_ALREADY_SIGNED = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_CRL_ALREADY_SIGNED, - CSSMERR_TP_INVALID_NUMBER_OF_FIELDS = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_NUMBER_OF_FIELDS, - CSSMERR_TP_VERIFICATION_FAILURE = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_VERIFICATION_FAILURE, - CSSMERR_TP_INVALID_DB_HANDLE = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_DB_HANDLE, - CSSMERR_TP_UNKNOWN_FORMAT = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_UNKNOWN_FORMAT, - CSSMERR_TP_UNKNOWN_TAG = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_UNKNOWN_TAG, - CSSMERR_TP_INVALID_PASSTHROUGH_ID = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_PASSTHROUGH_ID, - CSSMERR_TP_INVALID_CSP_HANDLE = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_CSP_HANDLE, - CSSMERR_TP_INVALID_DL_HANDLE = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_DL_HANDLE, - CSSMERR_TP_INVALID_CL_HANDLE = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_CL_HANDLE, - CSSMERR_TP_INVALID_DB_LIST_POINTER = - CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INVALID_DB_LIST_POINTER + CSSMERR_TP_INTERNAL_ERROR = -2147409919, + CSSMERR_TP_MEMORY_ERROR = -2147409918, + CSSMERR_TP_MDS_ERROR = -2147409917, + CSSMERR_TP_INVALID_POINTER = -2147409916, + CSSMERR_TP_INVALID_INPUT_POINTER = -2147409915, + CSSMERR_TP_INVALID_OUTPUT_POINTER = -2147409914, + CSSMERR_TP_FUNCTION_NOT_IMPLEMENTED = -2147409913, + CSSMERR_TP_SELF_CHECK_FAILED = -2147409912, + CSSMERR_TP_OS_ACCESS_DENIED = -2147409911, + CSSMERR_TP_FUNCTION_FAILED = -2147409910, + CSSMERR_TP_INVALID_CONTEXT_HANDLE = -2147409856, + CSSMERR_TP_INVALID_DATA = -2147409850, + CSSMERR_TP_INVALID_DB_LIST = -2147409844, + CSSMERR_TP_INVALID_CERTGROUP_POINTER = -2147409854, + CSSMERR_TP_INVALID_CERT_POINTER = -2147409853, + CSSMERR_TP_INVALID_CRL_POINTER = -2147409852, + CSSMERR_TP_INVALID_FIELD_POINTER = -2147409851, + CSSMERR_TP_INVALID_NETWORK_ADDR = -2147409833, + CSSMERR_TP_CRL_ALREADY_SIGNED = -2147409849, + CSSMERR_TP_INVALID_NUMBER_OF_FIELDS = -2147409848, + CSSMERR_TP_VERIFICATION_FAILURE = -2147409847, + CSSMERR_TP_INVALID_DB_HANDLE = -2147409846, + CSSMERR_TP_UNKNOWN_FORMAT = -2147409842, + CSSMERR_TP_UNKNOWN_TAG = -2147409841, + CSSMERR_TP_INVALID_PASSTHROUGH_ID = -2147409834, + CSSMERR_TP_INVALID_CSP_HANDLE = -2147409840, + CSSMERR_TP_INVALID_DL_HANDLE = -2147409839, + CSSMERR_TP_INVALID_CL_HANDLE = -2147409838, + CSSMERR_TP_INVALID_DB_LIST_POINTER = -2147409843, }; /* TP Module-Specific Error Values */ enum { CSSM_TP_BASE_TP_ERROR = CSSM_TP_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT, - CSSMERR_TP_INVALID_CALLERAUTH_CONTEXT_POINTER = CSSM_TP_BASE_TP_ERROR + 1, - CSSMERR_TP_INVALID_IDENTIFIER_POINTER = CSSM_TP_BASE_TP_ERROR + 2, - CSSMERR_TP_INVALID_KEYCACHE_HANDLE = CSSM_TP_BASE_TP_ERROR + 3, - CSSMERR_TP_INVALID_CERTGROUP = CSSM_TP_BASE_TP_ERROR + 4, - CSSMERR_TP_INVALID_CRLGROUP = CSSM_TP_BASE_TP_ERROR + 5, - CSSMERR_TP_INVALID_CRLGROUP_POINTER = CSSM_TP_BASE_TP_ERROR + 6, - CSSMERR_TP_AUTHENTICATION_FAILED = CSSM_TP_BASE_TP_ERROR + 7, - CSSMERR_TP_CERTGROUP_INCOMPLETE = CSSM_TP_BASE_TP_ERROR + 8, - CSSMERR_TP_CERTIFICATE_CANT_OPERATE = CSSM_TP_BASE_TP_ERROR + 9, - CSSMERR_TP_CERT_EXPIRED = CSSM_TP_BASE_TP_ERROR + 10, - CSSMERR_TP_CERT_NOT_VALID_YET = CSSM_TP_BASE_TP_ERROR + 11, - CSSMERR_TP_CERT_REVOKED = CSSM_TP_BASE_TP_ERROR + 12, - CSSMERR_TP_CERT_SUSPENDED = CSSM_TP_BASE_TP_ERROR + 13, - CSSMERR_TP_INSUFFICIENT_CREDENTIALS = CSSM_TP_BASE_TP_ERROR + 14, - CSSMERR_TP_INVALID_ACTION = CSSM_TP_BASE_TP_ERROR + 15, - CSSMERR_TP_INVALID_ACTION_DATA = CSSM_TP_BASE_TP_ERROR + 16, - CSSMERR_TP_INVALID_ANCHOR_CERT = CSSM_TP_BASE_TP_ERROR + 18, - CSSMERR_TP_INVALID_AUTHORITY = CSSM_TP_BASE_TP_ERROR + 19, - CSSMERR_TP_VERIFY_ACTION_FAILED = CSSM_TP_BASE_TP_ERROR + 20, - CSSMERR_TP_INVALID_CERTIFICATE = CSSM_TP_BASE_TP_ERROR + 21, - CSSMERR_TP_INVALID_CERT_AUTHORITY = CSSM_TP_BASE_TP_ERROR + 22, - CSSMERR_TP_INVALID_CRL_AUTHORITY = CSSM_TP_BASE_TP_ERROR + 23, - CSSMERR_TP_INVALID_CRL_ENCODING = CSSM_TP_BASE_TP_ERROR + 24, - CSSMERR_TP_INVALID_CRL_TYPE = CSSM_TP_BASE_TP_ERROR + 25, - CSSMERR_TP_INVALID_CRL = CSSM_TP_BASE_TP_ERROR + 26, - CSSMERR_TP_INVALID_FORM_TYPE = CSSM_TP_BASE_TP_ERROR + 27, - CSSMERR_TP_INVALID_ID = CSSM_TP_BASE_TP_ERROR + 28, - CSSMERR_TP_INVALID_IDENTIFIER = CSSM_TP_BASE_TP_ERROR + 29, - CSSMERR_TP_INVALID_INDEX = CSSM_TP_BASE_TP_ERROR + 30, - CSSMERR_TP_INVALID_NAME = CSSM_TP_BASE_TP_ERROR + 31, - CSSMERR_TP_INVALID_POLICY_IDENTIFIERS = CSSM_TP_BASE_TP_ERROR + 32, - CSSMERR_TP_INVALID_TIMESTRING = CSSM_TP_BASE_TP_ERROR + 33, - CSSMERR_TP_INVALID_REASON = CSSM_TP_BASE_TP_ERROR + 34, - CSSMERR_TP_INVALID_REQUEST_INPUTS = CSSM_TP_BASE_TP_ERROR + 35, - CSSMERR_TP_INVALID_RESPONSE_VECTOR = CSSM_TP_BASE_TP_ERROR + 36, - CSSMERR_TP_INVALID_SIGNATURE = CSSM_TP_BASE_TP_ERROR + 37, - CSSMERR_TP_INVALID_STOP_ON_POLICY = CSSM_TP_BASE_TP_ERROR + 38, - CSSMERR_TP_INVALID_CALLBACK = CSSM_TP_BASE_TP_ERROR + 39, - CSSMERR_TP_INVALID_TUPLE = CSSM_TP_BASE_TP_ERROR + 40, - CSSMERR_TP_NOT_SIGNER = CSSM_TP_BASE_TP_ERROR + 41, - CSSMERR_TP_NOT_TRUSTED = CSSM_TP_BASE_TP_ERROR + 42, - CSSMERR_TP_NO_DEFAULT_AUTHORITY = CSSM_TP_BASE_TP_ERROR + 43, - CSSMERR_TP_REJECTED_FORM = CSSM_TP_BASE_TP_ERROR + 44, - CSSMERR_TP_REQUEST_LOST = CSSM_TP_BASE_TP_ERROR + 45, - CSSMERR_TP_REQUEST_REJECTED = CSSM_TP_BASE_TP_ERROR + 46, - CSSMERR_TP_UNSUPPORTED_ADDR_TYPE = CSSM_TP_BASE_TP_ERROR + 47, - CSSMERR_TP_UNSUPPORTED_SERVICE = CSSM_TP_BASE_TP_ERROR + 48, - CSSMERR_TP_INVALID_TUPLEGROUP_POINTER = CSSM_TP_BASE_TP_ERROR + 49, - CSSMERR_TP_INVALID_TUPLEGROUP = CSSM_TP_BASE_TP_ERROR + 50 + CSSMERR_TP_INVALID_CALLERAUTH_CONTEXT_POINTER = -2147409663, + CSSMERR_TP_INVALID_IDENTIFIER_POINTER = -2147409662, + CSSMERR_TP_INVALID_KEYCACHE_HANDLE = -2147409661, + CSSMERR_TP_INVALID_CERTGROUP = -2147409660, + CSSMERR_TP_INVALID_CRLGROUP = -2147409659, + CSSMERR_TP_INVALID_CRLGROUP_POINTER = -2147409658, + CSSMERR_TP_AUTHENTICATION_FAILED = -2147409657, + CSSMERR_TP_CERTGROUP_INCOMPLETE = -2147409656, + CSSMERR_TP_CERTIFICATE_CANT_OPERATE = -2147409655, + CSSMERR_TP_CERT_EXPIRED = -2147409654, + CSSMERR_TP_CERT_NOT_VALID_YET = -2147409653, + CSSMERR_TP_CERT_REVOKED = -2147409652, + CSSMERR_TP_CERT_SUSPENDED = -2147409651, + CSSMERR_TP_INSUFFICIENT_CREDENTIALS = -2147409650, + CSSMERR_TP_INVALID_ACTION = -2147409649, + CSSMERR_TP_INVALID_ACTION_DATA = -2147409648, + CSSMERR_TP_INVALID_ANCHOR_CERT = -2147409646, + CSSMERR_TP_INVALID_AUTHORITY = -2147409645, + CSSMERR_TP_VERIFY_ACTION_FAILED = -2147409644, + CSSMERR_TP_INVALID_CERTIFICATE = -2147409643, + CSSMERR_TP_INVALID_CERT_AUTHORITY = -2147409642, + CSSMERR_TP_INVALID_CRL_AUTHORITY = -2147409641, + CSSMERR_TP_INVALID_CRL_ENCODING = -2147409640, + CSSMERR_TP_INVALID_CRL_TYPE = -2147409639, + CSSMERR_TP_INVALID_CRL = -2147409638, + CSSMERR_TP_INVALID_FORM_TYPE = -2147409637, + CSSMERR_TP_INVALID_ID = -2147409636, + CSSMERR_TP_INVALID_IDENTIFIER = -2147409635, + CSSMERR_TP_INVALID_INDEX = -2147409634, + CSSMERR_TP_INVALID_NAME = -2147409633, + CSSMERR_TP_INVALID_POLICY_IDENTIFIERS = -2147409632, + CSSMERR_TP_INVALID_TIMESTRING = -2147409631, + CSSMERR_TP_INVALID_REASON = -2147409630, + CSSMERR_TP_INVALID_REQUEST_INPUTS = -2147409629, + CSSMERR_TP_INVALID_RESPONSE_VECTOR = -2147409628, + CSSMERR_TP_INVALID_SIGNATURE = -2147409627, + CSSMERR_TP_INVALID_STOP_ON_POLICY = -2147409626, + CSSMERR_TP_INVALID_CALLBACK = -2147409625, + CSSMERR_TP_INVALID_TUPLE = -2147409624, + CSSMERR_TP_NOT_SIGNER = -2147409623, + CSSMERR_TP_NOT_TRUSTED = -2147409622, + CSSMERR_TP_NO_DEFAULT_AUTHORITY = -2147409621, + CSSMERR_TP_REJECTED_FORM = -2147409620, + CSSMERR_TP_REQUEST_LOST = -2147409619, + CSSMERR_TP_REQUEST_REJECTED = -2147409618, + CSSMERR_TP_UNSUPPORTED_ADDR_TYPE = -2147409617, + CSSMERR_TP_UNSUPPORTED_SERVICE = -2147409616, + CSSMERR_TP_INVALID_TUPLEGROUP_POINTER = -2147409615, + CSSMERR_TP_INVALID_TUPLEGROUP = -2147409614, }; /* AC Error Values Derived from Common Error Codes For All Module Types. */ enum { - CSSMERR_AC_INTERNAL_ERROR = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INTERNAL_ERROR, - CSSMERR_AC_MEMORY_ERROR = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_MEMORY_ERROR, - CSSMERR_AC_MDS_ERROR = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_MDS_ERROR, - CSSMERR_AC_INVALID_POINTER = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_POINTER, - CSSMERR_AC_INVALID_INPUT_POINTER = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_INPUT_POINTER, - CSSMERR_AC_INVALID_OUTPUT_POINTER = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_OUTPUT_POINTER, - CSSMERR_AC_FUNCTION_NOT_IMPLEMENTED = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED, - CSSMERR_AC_SELF_CHECK_FAILED = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_SELF_CHECK_FAILED, - CSSMERR_AC_OS_ACCESS_DENIED = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_OS_ACCESS_DENIED, - CSSMERR_AC_FUNCTION_FAILED = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_FUNCTION_FAILED, - CSSMERR_AC_INVALID_CONTEXT_HANDLE = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_CONTEXT_HANDLE, - CSSMERR_AC_INVALID_DATA = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_DATA, - CSSMERR_AC_INVALID_DB_LIST = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_DB_LIST, - CSSMERR_AC_INVALID_PASSTHROUGH_ID = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_PASSTHROUGH_ID, - CSSMERR_AC_INVALID_DL_HANDLE = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_DL_HANDLE, - CSSMERR_AC_INVALID_CL_HANDLE = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_CL_HANDLE, - CSSMERR_AC_INVALID_TP_HANDLE = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_TP_HANDLE, - CSSMERR_AC_INVALID_DB_HANDLE = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_DB_HANDLE, - CSSMERR_AC_INVALID_DB_LIST_POINTER = - CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INVALID_DB_LIST_POINTER + CSSMERR_AC_INTERNAL_ERROR = -2147405823, + CSSMERR_AC_MEMORY_ERROR = -2147405822, + CSSMERR_AC_MDS_ERROR = -2147405821, + CSSMERR_AC_INVALID_POINTER = -2147405820, + CSSMERR_AC_INVALID_INPUT_POINTER = -2147405819, + CSSMERR_AC_INVALID_OUTPUT_POINTER = -2147405818, + CSSMERR_AC_FUNCTION_NOT_IMPLEMENTED = -2147405817, + CSSMERR_AC_SELF_CHECK_FAILED = -2147405816, + CSSMERR_AC_OS_ACCESS_DENIED = -2147405815, + CSSMERR_AC_FUNCTION_FAILED = -2147405814, + CSSMERR_AC_INVALID_CONTEXT_HANDLE = -2147405760, + CSSMERR_AC_INVALID_DATA = -2147405754, + CSSMERR_AC_INVALID_DB_LIST = -2147405748, + CSSMERR_AC_INVALID_PASSTHROUGH_ID = -2147405738, + CSSMERR_AC_INVALID_DL_HANDLE = -2147405743, + CSSMERR_AC_INVALID_CL_HANDLE = -2147405742, + CSSMERR_AC_INVALID_TP_HANDLE = -2147405741, + CSSMERR_AC_INVALID_DB_HANDLE = -2147405750, + CSSMERR_AC_INVALID_DB_LIST_POINTER = -2147405747, }; /* AC Module-Specific Error Values */ enum { CSSM_AC_BASE_AC_ERROR = CSSM_AC_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT, - CSSMERR_AC_INVALID_BASE_ACLS = CSSM_AC_BASE_AC_ERROR + 1, - CSSMERR_AC_INVALID_TUPLE_CREDENTIALS = CSSM_AC_BASE_AC_ERROR + 2, - CSSMERR_AC_INVALID_ENCODING = CSSM_AC_BASE_AC_ERROR + 3, - CSSMERR_AC_INVALID_VALIDITY_PERIOD = CSSM_AC_BASE_AC_ERROR + 4, - CSSMERR_AC_INVALID_REQUESTOR = CSSM_AC_BASE_AC_ERROR + 5, - CSSMERR_AC_INVALID_REQUEST_DESCRIPTOR = CSSM_AC_BASE_AC_ERROR + 6 + CSSMERR_AC_INVALID_BASE_ACLS = -2147405567, + CSSMERR_AC_INVALID_TUPLE_CREDENTIALS = -2147405566, + CSSMERR_AC_INVALID_ENCODING = -2147405565, + CSSMERR_AC_INVALID_VALIDITY_PERIOD = -2147405564, + CSSMERR_AC_INVALID_REQUESTOR = -2147405563, + CSSMERR_AC_INVALID_REQUEST_DESCRIPTOR = -2147405562, }; /* CL Error Values Derived from Common Error Codes For All Module Types. */ enum { - CSSMERR_CL_INTERNAL_ERROR = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INTERNAL_ERROR, - CSSMERR_CL_MEMORY_ERROR = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_MEMORY_ERROR, - CSSMERR_CL_MDS_ERROR = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_MDS_ERROR, - CSSMERR_CL_INVALID_POINTER = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_POINTER, - CSSMERR_CL_INVALID_INPUT_POINTER = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_INPUT_POINTER, - CSSMERR_CL_INVALID_OUTPUT_POINTER = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_OUTPUT_POINTER, - CSSMERR_CL_FUNCTION_NOT_IMPLEMENTED = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED, - CSSMERR_CL_SELF_CHECK_FAILED = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_SELF_CHECK_FAILED, - CSSMERR_CL_OS_ACCESS_DENIED = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_OS_ACCESS_DENIED, - CSSMERR_CL_FUNCTION_FAILED = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_FUNCTION_FAILED, - CSSMERR_CL_INVALID_CONTEXT_HANDLE = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_CONTEXT_HANDLE, - CSSMERR_CL_INVALID_CERTGROUP_POINTER = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_CERTGROUP_POINTER, - CSSMERR_CL_INVALID_CERT_POINTER = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_CERT_POINTER, - CSSMERR_CL_INVALID_CRL_POINTER = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_CRL_POINTER, - CSSMERR_CL_INVALID_FIELD_POINTER = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_FIELD_POINTER, - CSSMERR_CL_INVALID_DATA = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_DATA, - CSSMERR_CL_CRL_ALREADY_SIGNED = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_CRL_ALREADY_SIGNED, - CSSMERR_CL_INVALID_NUMBER_OF_FIELDS = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_NUMBER_OF_FIELDS, - CSSMERR_CL_VERIFICATION_FAILURE = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_VERIFICATION_FAILURE, - CSSMERR_CL_UNKNOWN_FORMAT = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_UNKNOWN_FORMAT, - CSSMERR_CL_UNKNOWN_TAG = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_UNKNOWN_TAG, - CSSMERR_CL_INVALID_PASSTHROUGH_ID = - CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INVALID_PASSTHROUGH_ID + CSSMERR_CL_INTERNAL_ERROR = -2147411967, + CSSMERR_CL_MEMORY_ERROR = -2147411966, + CSSMERR_CL_MDS_ERROR = -2147411965, + CSSMERR_CL_INVALID_POINTER = -2147411964, + CSSMERR_CL_INVALID_INPUT_POINTER = -2147411963, + CSSMERR_CL_INVALID_OUTPUT_POINTER = -2147411962, + CSSMERR_CL_FUNCTION_NOT_IMPLEMENTED = -2147411961, + CSSMERR_CL_SELF_CHECK_FAILED = -2147411960, + CSSMERR_CL_OS_ACCESS_DENIED = -2147411959, + CSSMERR_CL_FUNCTION_FAILED = -2147411958, + CSSMERR_CL_INVALID_CONTEXT_HANDLE = -2147411904, + CSSMERR_CL_INVALID_CERTGROUP_POINTER = -2147411902, + CSSMERR_CL_INVALID_CERT_POINTER = -2147411901, + CSSMERR_CL_INVALID_CRL_POINTER = -2147411900, + CSSMERR_CL_INVALID_FIELD_POINTER = -2147411899, + CSSMERR_CL_INVALID_DATA = -2147411898, + CSSMERR_CL_CRL_ALREADY_SIGNED = -2147411897, + CSSMERR_CL_INVALID_NUMBER_OF_FIELDS = -2147411896, + CSSMERR_CL_VERIFICATION_FAILURE = -2147411895, + CSSMERR_CL_UNKNOWN_FORMAT = -2147411890, + CSSMERR_CL_UNKNOWN_TAG = -2147411889, + CSSMERR_CL_INVALID_PASSTHROUGH_ID = -2147411882, }; /* CL Module-Specific Error Values */ enum { CSSM_CL_BASE_CL_ERROR = CSSM_CL_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT, - CSSMERR_CL_INVALID_BUNDLE_POINTER = CSSM_CL_BASE_CL_ERROR + 1, - CSSMERR_CL_INVALID_CACHE_HANDLE = CSSM_CL_BASE_CL_ERROR + 2, - CSSMERR_CL_INVALID_RESULTS_HANDLE = CSSM_CL_BASE_CL_ERROR + 3, - CSSMERR_CL_INVALID_BUNDLE_INFO = CSSM_CL_BASE_CL_ERROR + 4, - CSSMERR_CL_INVALID_CRL_INDEX = CSSM_CL_BASE_CL_ERROR + 5, - CSSMERR_CL_INVALID_SCOPE = CSSM_CL_BASE_CL_ERROR + 6, - CSSMERR_CL_NO_FIELD_VALUES = CSSM_CL_BASE_CL_ERROR + 7, - CSSMERR_CL_SCOPE_NOT_SUPPORTED = CSSM_CL_BASE_CL_ERROR + 8 + CSSMERR_CL_INVALID_BUNDLE_POINTER = -2147411711, + CSSMERR_CL_INVALID_CACHE_HANDLE = -2147411710, + CSSMERR_CL_INVALID_RESULTS_HANDLE = -2147411709, + CSSMERR_CL_INVALID_BUNDLE_INFO = -2147411708, + CSSMERR_CL_INVALID_CRL_INDEX = -2147411707, + CSSMERR_CL_INVALID_SCOPE = -2147411706, + CSSMERR_CL_NO_FIELD_VALUES = -2147411705, + CSSMERR_CL_SCOPE_NOT_SUPPORTED = -2147411704, }; /* DL Error Values Derived from Common Error Codes For All Module Types. */ enum { - CSSMERR_DL_INTERNAL_ERROR = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INTERNAL_ERROR, - CSSMERR_DL_MEMORY_ERROR = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_MEMORY_ERROR, - CSSMERR_DL_MDS_ERROR = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_MDS_ERROR, - CSSMERR_DL_INVALID_POINTER = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_POINTER, - CSSMERR_DL_INVALID_INPUT_POINTER = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_INPUT_POINTER, - CSSMERR_DL_INVALID_OUTPUT_POINTER = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_OUTPUT_POINTER, - CSSMERR_DL_FUNCTION_NOT_IMPLEMENTED = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED, - CSSMERR_DL_SELF_CHECK_FAILED = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_SELF_CHECK_FAILED, - CSSMERR_DL_OS_ACCESS_DENIED = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_OS_ACCESS_DENIED, - CSSMERR_DL_FUNCTION_FAILED = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_FUNCTION_FAILED, - CSSMERR_DL_INVALID_CSP_HANDLE = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_CSP_HANDLE, - CSSMERR_DL_INVALID_DL_HANDLE = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_DL_HANDLE, - CSSMERR_DL_INVALID_CL_HANDLE = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_CL_HANDLE, - CSSMERR_DL_INVALID_DB_LIST_POINTER = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_DB_LIST_POINTER + CSSMERR_DL_INTERNAL_ERROR = -2147414015, + CSSMERR_DL_MEMORY_ERROR = -2147414014, + CSSMERR_DL_MDS_ERROR = -2147414013, + CSSMERR_DL_INVALID_POINTER = -2147414012, + CSSMERR_DL_INVALID_INPUT_POINTER = -2147414011, + CSSMERR_DL_INVALID_OUTPUT_POINTER = -2147414010, + CSSMERR_DL_FUNCTION_NOT_IMPLEMENTED = -2147414009, + CSSMERR_DL_SELF_CHECK_FAILED = -2147414008, + CSSMERR_DL_OS_ACCESS_DENIED = -2147414007, + CSSMERR_DL_FUNCTION_FAILED = -2147414006, + CSSMERR_DL_INVALID_CSP_HANDLE = -2147413936, + CSSMERR_DL_INVALID_DL_HANDLE = -2147413935, + CSSMERR_DL_INVALID_CL_HANDLE = -2147413934, + CSSMERR_DL_INVALID_DB_LIST_POINTER = -2147413939, }; /* DL Error Values Derived from ACL-based Error Codes. */ enum { - CSSMERR_DL_OPERATION_AUTH_DENIED = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_OPERATION_AUTH_DENIED, - CSSMERR_DL_OBJECT_USE_AUTH_DENIED = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_OBJECT_USE_AUTH_DENIED, - CSSMERR_DL_OBJECT_MANIP_AUTH_DENIED = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_OBJECT_MANIP_AUTH_DENIED, - CSSMERR_DL_OBJECT_ACL_NOT_SUPPORTED = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_OBJECT_ACL_NOT_SUPPORTED, - CSSMERR_DL_OBJECT_ACL_REQUIRED = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_OBJECT_ACL_REQUIRED, - CSSMERR_DL_INVALID_ACCESS_CREDENTIALS = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_ACCESS_CREDENTIALS, - CSSMERR_DL_INVALID_ACL_BASE_CERTS = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_BASE_CERTS, - CSSMERR_DL_ACL_BASE_CERTS_NOT_SUPPORTED = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_ACL_BASE_CERTS_NOT_SUPPORTED, - CSSMERR_DL_INVALID_SAMPLE_VALUE = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_SAMPLE_VALUE, - CSSMERR_DL_SAMPLE_VALUE_NOT_SUPPORTED = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_SAMPLE_VALUE_NOT_SUPPORTED, - CSSMERR_DL_INVALID_ACL_SUBJECT_VALUE = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE, - CSSMERR_DL_ACL_SUBJECT_TYPE_NOT_SUPPORTED = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_ACL_SUBJECT_TYPE_NOT_SUPPORTED, - CSSMERR_DL_INVALID_ACL_CHALLENGE_CALLBACK = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_CHALLENGE_CALLBACK, - CSSMERR_DL_ACL_CHALLENGE_CALLBACK_FAILED = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_ACL_CHALLENGE_CALLBACK_FAILED, - CSSMERR_DL_INVALID_ACL_ENTRY_TAG = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG, - CSSMERR_DL_ACL_ENTRY_TAG_NOT_FOUND = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_ACL_ENTRY_TAG_NOT_FOUND, - CSSMERR_DL_INVALID_ACL_EDIT_MODE = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_ACL_EDIT_MODE, - CSSMERR_DL_ACL_CHANGE_FAILED = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_ACL_CHANGE_FAILED, - CSSMERR_DL_INVALID_NEW_ACL_ENTRY = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_NEW_ACL_ENTRY, - CSSMERR_DL_INVALID_NEW_ACL_OWNER = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_NEW_ACL_OWNER, - CSSMERR_DL_ACL_DELETE_FAILED = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_ACL_DELETE_FAILED, - CSSMERR_DL_ACL_REPLACE_FAILED = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_ACL_REPLACE_FAILED, - CSSMERR_DL_ACL_ADD_FAILED = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_ACL_ADD_FAILED + CSSMERR_DL_OPERATION_AUTH_DENIED = -2147413984, + CSSMERR_DL_OBJECT_USE_AUTH_DENIED = -2147413983, + CSSMERR_DL_OBJECT_MANIP_AUTH_DENIED = -2147413982, + CSSMERR_DL_OBJECT_ACL_NOT_SUPPORTED = -2147413981, + CSSMERR_DL_OBJECT_ACL_REQUIRED = -2147413980, + CSSMERR_DL_INVALID_ACCESS_CREDENTIALS = -2147413979, + CSSMERR_DL_INVALID_ACL_BASE_CERTS = -2147413978, + CSSMERR_DL_ACL_BASE_CERTS_NOT_SUPPORTED = -2147413977, + CSSMERR_DL_INVALID_SAMPLE_VALUE = -2147413976, + CSSMERR_DL_SAMPLE_VALUE_NOT_SUPPORTED = -2147413975, + CSSMERR_DL_INVALID_ACL_SUBJECT_VALUE = -2147413974, + CSSMERR_DL_ACL_SUBJECT_TYPE_NOT_SUPPORTED = -2147413973, + CSSMERR_DL_INVALID_ACL_CHALLENGE_CALLBACK = -2147413972, + CSSMERR_DL_ACL_CHALLENGE_CALLBACK_FAILED = -2147413971, + CSSMERR_DL_INVALID_ACL_ENTRY_TAG = -2147413970, + CSSMERR_DL_ACL_ENTRY_TAG_NOT_FOUND = -2147413969, + CSSMERR_DL_INVALID_ACL_EDIT_MODE = -2147413968, + CSSMERR_DL_ACL_CHANGE_FAILED = -2147413967, + CSSMERR_DL_INVALID_NEW_ACL_ENTRY = -2147413966, + CSSMERR_DL_INVALID_NEW_ACL_OWNER = -2147413965, + CSSMERR_DL_ACL_DELETE_FAILED = -2147413964, + CSSMERR_DL_ACL_REPLACE_FAILED = -2147413963, + CSSMERR_DL_ACL_ADD_FAILED = -2147413962, }; /* DL Error Values for Specific Data Types. */ enum { - CSSMERR_DL_INVALID_DB_HANDLE = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_DB_HANDLE, - CSSMERR_DL_INVALID_PASSTHROUGH_ID = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_PASSTHROUGH_ID, - CSSMERR_DL_INVALID_NETWORK_ADDR = - CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INVALID_NETWORK_ADDR + CSSMERR_DL_INVALID_DB_HANDLE = -2147413942, + CSSMERR_DL_INVALID_PASSTHROUGH_ID = -2147413930, + CSSMERR_DL_INVALID_NETWORK_ADDR = -2147413929, }; /* DL Module-Specific Error Values */ enum { CSSM_DL_BASE_DL_ERROR = CSSM_DL_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT, - CSSMERR_DL_DATABASE_CORRUPT = CSSM_DL_BASE_DL_ERROR + 1, - CSSMERR_DL_INVALID_RECORD_INDEX = CSSM_DL_BASE_DL_ERROR + 8, - CSSMERR_DL_INVALID_RECORDTYPE = CSSM_DL_BASE_DL_ERROR + 9, - CSSMERR_DL_INVALID_FIELD_NAME = CSSM_DL_BASE_DL_ERROR + 10, - CSSMERR_DL_UNSUPPORTED_FIELD_FORMAT = CSSM_DL_BASE_DL_ERROR + 11, - CSSMERR_DL_UNSUPPORTED_INDEX_INFO = CSSM_DL_BASE_DL_ERROR + 12, - CSSMERR_DL_UNSUPPORTED_LOCALITY = CSSM_DL_BASE_DL_ERROR + 13, - CSSMERR_DL_UNSUPPORTED_NUM_ATTRIBUTES = CSSM_DL_BASE_DL_ERROR + 14, - CSSMERR_DL_UNSUPPORTED_NUM_INDEXES = CSSM_DL_BASE_DL_ERROR + 15, - CSSMERR_DL_UNSUPPORTED_NUM_RECORDTYPES = CSSM_DL_BASE_DL_ERROR + 16, - CSSMERR_DL_UNSUPPORTED_RECORDTYPE = CSSM_DL_BASE_DL_ERROR + 17, - CSSMERR_DL_FIELD_SPECIFIED_MULTIPLE = CSSM_DL_BASE_DL_ERROR + 18, - CSSMERR_DL_INCOMPATIBLE_FIELD_FORMAT = CSSM_DL_BASE_DL_ERROR + 19, - CSSMERR_DL_INVALID_PARSING_MODULE = CSSM_DL_BASE_DL_ERROR + 20, - CSSMERR_DL_INVALID_DB_NAME = CSSM_DL_BASE_DL_ERROR + 22, - CSSMERR_DL_DATASTORE_DOESNOT_EXIST = CSSM_DL_BASE_DL_ERROR + 23, - CSSMERR_DL_DATASTORE_ALREADY_EXISTS = CSSM_DL_BASE_DL_ERROR + 24, - CSSMERR_DL_DB_LOCKED = CSSM_DL_BASE_DL_ERROR + 25, - CSSMERR_DL_DATASTORE_IS_OPEN = CSSM_DL_BASE_DL_ERROR + 26, - CSSMERR_DL_RECORD_NOT_FOUND = CSSM_DL_BASE_DL_ERROR + 27, - CSSMERR_DL_MISSING_VALUE = CSSM_DL_BASE_DL_ERROR + 28, - CSSMERR_DL_UNSUPPORTED_QUERY = CSSM_DL_BASE_DL_ERROR + 29, - CSSMERR_DL_UNSUPPORTED_QUERY_LIMITS = CSSM_DL_BASE_DL_ERROR + 30, - CSSMERR_DL_UNSUPPORTED_NUM_SELECTION_PREDS = CSSM_DL_BASE_DL_ERROR + 31, - CSSMERR_DL_UNSUPPORTED_OPERATOR = CSSM_DL_BASE_DL_ERROR + 33, - CSSMERR_DL_INVALID_RESULTS_HANDLE = CSSM_DL_BASE_DL_ERROR + 34, - CSSMERR_DL_INVALID_DB_LOCATION = CSSM_DL_BASE_DL_ERROR + 35, - CSSMERR_DL_INVALID_ACCESS_REQUEST = CSSM_DL_BASE_DL_ERROR + 36, - CSSMERR_DL_INVALID_INDEX_INFO = CSSM_DL_BASE_DL_ERROR + 37, - CSSMERR_DL_INVALID_SELECTION_TAG = CSSM_DL_BASE_DL_ERROR + 38, - CSSMERR_DL_INVALID_NEW_OWNER = CSSM_DL_BASE_DL_ERROR + 39, - CSSMERR_DL_INVALID_RECORD_UID = CSSM_DL_BASE_DL_ERROR + 40, - CSSMERR_DL_INVALID_UNIQUE_INDEX_DATA = CSSM_DL_BASE_DL_ERROR + 41, - CSSMERR_DL_INVALID_MODIFY_MODE = CSSM_DL_BASE_DL_ERROR + 42, - CSSMERR_DL_INVALID_OPEN_PARAMETERS = CSSM_DL_BASE_DL_ERROR + 43, - CSSMERR_DL_RECORD_MODIFIED = CSSM_DL_BASE_DL_ERROR + 44, - CSSMERR_DL_ENDOFDATA = CSSM_DL_BASE_DL_ERROR + 45, - CSSMERR_DL_INVALID_QUERY = CSSM_DL_BASE_DL_ERROR + 46, - CSSMERR_DL_INVALID_VALUE = CSSM_DL_BASE_DL_ERROR + 47, - CSSMERR_DL_MULTIPLE_VALUES_UNSUPPORTED = CSSM_DL_BASE_DL_ERROR + 48, - CSSMERR_DL_STALE_UNIQUE_RECORD = CSSM_DL_BASE_DL_ERROR + 49 + CSSMERR_DL_DATABASE_CORRUPT = -2147413759, + CSSMERR_DL_INVALID_RECORD_INDEX = -2147413752, + CSSMERR_DL_INVALID_RECORDTYPE = -2147413751, + CSSMERR_DL_INVALID_FIELD_NAME = -2147413750, + CSSMERR_DL_UNSUPPORTED_FIELD_FORMAT = -2147413749, + CSSMERR_DL_UNSUPPORTED_INDEX_INFO = -2147413748, + CSSMERR_DL_UNSUPPORTED_LOCALITY = -2147413747, + CSSMERR_DL_UNSUPPORTED_NUM_ATTRIBUTES = -2147413746, + CSSMERR_DL_UNSUPPORTED_NUM_INDEXES = -2147413745, + CSSMERR_DL_UNSUPPORTED_NUM_RECORDTYPES = -2147413744, + CSSMERR_DL_UNSUPPORTED_RECORDTYPE = -2147413743, + CSSMERR_DL_FIELD_SPECIFIED_MULTIPLE = -2147413742, + CSSMERR_DL_INCOMPATIBLE_FIELD_FORMAT = -2147413741, + CSSMERR_DL_INVALID_PARSING_MODULE = -2147413740, + CSSMERR_DL_INVALID_DB_NAME = -2147413738, + CSSMERR_DL_DATASTORE_DOESNOT_EXIST = -2147413737, + CSSMERR_DL_DATASTORE_ALREADY_EXISTS = -2147413736, + CSSMERR_DL_DB_LOCKED = -2147413735, + CSSMERR_DL_DATASTORE_IS_OPEN = -2147413734, + CSSMERR_DL_RECORD_NOT_FOUND = -2147413733, + CSSMERR_DL_MISSING_VALUE = -2147413732, + CSSMERR_DL_UNSUPPORTED_QUERY = -2147413731, + CSSMERR_DL_UNSUPPORTED_QUERY_LIMITS = -2147413730, + CSSMERR_DL_UNSUPPORTED_NUM_SELECTION_PREDS = -2147413729, + CSSMERR_DL_UNSUPPORTED_OPERATOR = -2147413727, + CSSMERR_DL_INVALID_RESULTS_HANDLE = -2147413726, + CSSMERR_DL_INVALID_DB_LOCATION = -2147413725, + CSSMERR_DL_INVALID_ACCESS_REQUEST = -2147413724, + CSSMERR_DL_INVALID_INDEX_INFO = -2147413723, + CSSMERR_DL_INVALID_SELECTION_TAG = -2147413722, + CSSMERR_DL_INVALID_NEW_OWNER = -2147413721, + CSSMERR_DL_INVALID_RECORD_UID = -2147413720, + CSSMERR_DL_INVALID_UNIQUE_INDEX_DATA = -2147413719, + CSSMERR_DL_INVALID_MODIFY_MODE = -2147413718, + CSSMERR_DL_INVALID_OPEN_PARAMETERS = -2147413717, + CSSMERR_DL_RECORD_MODIFIED = -2147413716, + CSSMERR_DL_ENDOFDATA = -2147413715, + CSSMERR_DL_INVALID_QUERY = -2147413714, + CSSMERR_DL_INVALID_VALUE = -2147413713, + CSSMERR_DL_MULTIPLE_VALUES_UNSUPPORTED = -2147413712, + CSSMERR_DL_STALE_UNIQUE_RECORD = -2147413711, }; diff --git a/OSX/libsecurity_cssm/lib/cssmkrapi.h b/OSX/libsecurity_cssm/lib/cssmkrapi.h index 06adece6..47375c15 100644 --- a/OSX/libsecurity_cssm/lib/cssmkrapi.h +++ b/OSX/libsecurity_cssm/lib/cssmkrapi.h @@ -107,138 +107,6 @@ typedef struct cssm_kr_policy_info { } CSSM_KR_POLICY_INFO DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_KR_POLICY_INFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -/* Key Recovery Module Mangement Operations */ - -CSSM_RETURN CSSMAPI -CSSM_KR_SetEnterpriseRecoveryPolicy (const CSSM_DATA *RecoveryPolicyFileName, - const CSSM_ACCESS_CREDENTIALS *OldPassPhrase, - const CSSM_ACCESS_CREDENTIALS *NewPassPhrase) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - - -/* Key Recovery Context Operations */ - -CSSM_RETURN CSSMAPI -CSSM_KR_CreateRecoveryRegistrationContext (CSSM_KRSP_HANDLE KRSPHandle, - CSSM_CC_HANDLE *NewContext) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -CSSM_RETURN CSSMAPI -CSSM_KR_CreateRecoveryEnablementContext (CSSM_KRSP_HANDLE KRSPHandle, - const CSSM_KR_PROFILE *LocalProfile, - const CSSM_KR_PROFILE *RemoteProfile, - CSSM_CC_HANDLE *NewContext) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -CSSM_RETURN CSSMAPI -CSSM_KR_CreateRecoveryRequestContext (CSSM_KRSP_HANDLE KRSPHandle, - const CSSM_KR_PROFILE *LocalProfile, - CSSM_CC_HANDLE *NewContext) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -CSSM_RETURN CSSMAPI -CSSM_KR_GetPolicyInfo (CSSM_CC_HANDLE CCHandle, - CSSM_KR_POLICY_FLAGS *EncryptionProhibited, - uint32 *WorkFactor) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - - -/* Key Recovery Registration Operations */ - -CSSM_RETURN CSSMAPI -CSSM_KR_RegistrationRequest (CSSM_CC_HANDLE RecoveryRegistrationContext, - const CSSM_DATA *KRInData, - const CSSM_ACCESS_CREDENTIALS *AccessCredentials, - CSSM_KR_POLICY_FLAGS KRFlags, - sint32 *EstimatedTime, - CSSM_HANDLE_PTR ReferenceHandle) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -CSSM_RETURN CSSMAPI -CSSM_KR_RegistrationRetrieve (CSSM_KRSP_HANDLE KRSPHandle, - CSSM_HANDLE ReferenceHandle, - const CSSM_ACCESS_CREDENTIALS *AccessCredentials, - sint32 *EstimatedTime, - CSSM_KR_PROFILE_PTR KRProfile) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - - -/* Key Recovery Enablement Operations */ - -CSSM_RETURN CSSMAPI -CSSM_KR_GenerateRecoveryFields (CSSM_CC_HANDLE KeyRecoveryContext, - CSSM_CC_HANDLE CCHandle, - const CSSM_DATA *KRSPOptions, - CSSM_KR_POLICY_FLAGS KRFlags, - CSSM_DATA_PTR KRFields, - CSSM_CC_HANDLE *NewCCHandle) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -CSSM_RETURN CSSMAPI -CSSM_KR_ProcessRecoveryFields (CSSM_CC_HANDLE KeyRecoveryContext, - CSSM_CC_HANDLE CryptoContext, - const CSSM_DATA *KRSPOptions, - CSSM_KR_POLICY_FLAGS KRFlags, - const CSSM_DATA *KRFields, - CSSM_CC_HANDLE *NewCryptoContext) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - - -/* Key Recovery Request Operations */ - -CSSM_RETURN CSSMAPI -CSSM_KR_RecoveryRequest (CSSM_CC_HANDLE RecoveryRequestContext, - const CSSM_DATA *KRInData, - const CSSM_ACCESS_CREDENTIALS *AccessCredentials, - sint32 *EstimatedTime, - CSSM_HANDLE_PTR ReferenceHandle) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -CSSM_RETURN CSSMAPI -CSSM_KR_RecoveryRetrieve (CSSM_KRSP_HANDLE KRSPHandle, - CSSM_HANDLE ReferenceHandle, - const CSSM_ACCESS_CREDENTIALS *AccessCredentials, - sint32 *EstimatedTime, - CSSM_HANDLE_PTR CacheHandle, - uint32 *NumberOfRecoveredKeys) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -CSSM_RETURN CSSMAPI -CSSM_KR_GetRecoveredObject (CSSM_KRSP_HANDLE KRSPHandle, - CSSM_HANDLE CacheHandle, - uint32 IndexInResults, - CSSM_CSP_HANDLE CSPHandle, - const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry, - uint32 Flags, - CSSM_KEY_PTR RecoveredKey, - CSSM_DATA_PTR OtherInfo) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -CSSM_RETURN CSSMAPI -CSSM_KR_RecoveryRequestAbort (CSSM_KRSP_HANDLE KRSPHandle, - CSSM_HANDLE CacheHandle) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -CSSM_RETURN CSSMAPI -CSSM_KR_QueryPolicyInfo (CSSM_KRSP_HANDLE KRSPHandle, - CSSM_ALGORITHMS AlgorithmID, - CSSM_ENCRYPT_MODE Mode, - CSSM_CONTEXT_TYPE Class, - CSSM_KR_POLICY_INFO_PTR *PolicyInfoData) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - - -/* Extensibility Functions */ - -CSSM_RETURN CSSMAPI -CSSM_KR_PassThrough (CSSM_KRSP_HANDLE KRSPHandle, - CSSM_CC_HANDLE KeyRecoveryContext, - CSSM_CC_HANDLE CryptoContext, - uint32 PassThroughId, - const void *InputParams, - void **OutputParams) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - #pragma clang diagnostic pop #ifdef __cplusplus diff --git a/OSX/libsecurity_cssm/lib/cssmspi.h b/OSX/libsecurity_cssm/lib/cssmspi.h index e91e553e..782f3c58 100644 --- a/OSX/libsecurity_cssm/lib/cssmspi.h +++ b/OSX/libsecurity_cssm/lib/cssmspi.h @@ -95,39 +95,6 @@ typedef struct cssm_upcalls { uint32 NumFunctions); } CSSM_UPCALLS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_UPCALLS_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; -CSSM_RETURN CSSMSPI -CSSM_SPI_ModuleLoad (const CSSM_GUID *CssmGuid, - const CSSM_GUID *ModuleGuid, - CSSM_SPI_ModuleEventHandler CssmNotifyCallback, - void *CssmNotifyCallbackCtx) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -CSSM_RETURN CSSMSPI -CSSM_SPI_ModuleUnload (const CSSM_GUID *CssmGuid, - const CSSM_GUID *ModuleGuid, - CSSM_SPI_ModuleEventHandler CssmNotifyCallback, - void *CssmNotifyCallbackCtx) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -CSSM_RETURN CSSMSPI -CSSM_SPI_ModuleAttach (const CSSM_GUID *ModuleGuid, - const CSSM_VERSION *Version, - uint32 SubserviceID, - CSSM_SERVICE_TYPE SubServiceType, - CSSM_ATTACH_FLAGS AttachFlags, - CSSM_MODULE_HANDLE ModuleHandle, - CSSM_KEY_HIERARCHY KeyHierarchy, - const CSSM_GUID *CssmGuid, - const CSSM_GUID *ModuleManagerGuid, - const CSSM_GUID *CallerGuid, - const CSSM_UPCALLS *Upcalls, - CSSM_MODULE_FUNCS_PTR *FuncTbl) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -CSSM_RETURN CSSMSPI -CSSM_SPI_ModuleDetach (CSSM_MODULE_HANDLE ModuleHandle) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - #pragma clang diagnostic pop #ifdef __cplusplus diff --git a/OSX/libsecurity_cssm/lib/cssmtype.h b/OSX/libsecurity_cssm/lib/cssmtype.h index 1cddc3e4..57481d1c 100644 --- a/OSX/libsecurity_cssm/lib/cssmtype.h +++ b/OSX/libsecurity_cssm/lib/cssmtype.h @@ -695,7 +695,7 @@ typedef struct cssm_acl_edit { #if defined(WIN32) typedef FARPROC CSSM_PROC_ADDR; #else -typedef void (CSSMAPI *CSSM_PROC_ADDR) (); +typedef void (CSSMAPI *CSSM_PROC_ADDR) (void); #endif typedef CSSM_PROC_ADDR *CSSM_PROC_ADDR_PTR; diff --git a/OSX/libsecurity_cssm/lib/eisl.h b/OSX/libsecurity_cssm/lib/eisl.h index 7c8fa941..83f02f46 100644 --- a/OSX/libsecurity_cssm/lib/eisl.h +++ b/OSX/libsecurity_cssm/lib/eisl.h @@ -32,293 +32,6 @@ extern "C" { #endif -/* Data Types for Embedded Integrity Services Library */ - -typedef const void *ISL_ITERATOR_PTR; - -typedef const void *ISL_VERIFIED_SIGNATURE_ROOT_PTR; - -typedef const void *ISL_VERIFIED_CERTIFICATE_CHAIN_PTR; - -typedef const void *ISL_VERIFIED_CERTIFICATE_PTR; - -typedef const void *ISL_MANIFEST_SECTION_PTR; - -typedef const void *ISL_VERIFIED_MODULE_PTR; - -typedef void (*ISL_FUNCTION_PTR)(void); - -typedef struct isl_data { - CSSM_SIZE Length; /* in bytes */ - uint8 *Data; -} ISL_DATA, *ISL_DATA_PTR; - -typedef struct isl_const_data { - CSSM_SIZE Length; /* in bytes */ - const uint8 *Data; -} ISL_CONST_DATA, *ISL_CONST_DATA_PTR; - -typedef enum isl_status { - ISL_OK = 0, - ISL_FAIL = -1 -} ISL_STATUS; - - -/* Embedded Integrity Services Library Functions */ - -ISL_VERIFIED_MODULE_PTR -EISL_SelfCheck (); - -ISL_VERIFIED_MODULE_PTR -EISL_VerifyAndLoadModuleAndCredentialData (const ISL_CONST_DATA CredentialsImage, - const ISL_CONST_DATA ModuleSearchPath, - const ISL_CONST_DATA Name, - const ISL_CONST_DATA Signer, - const ISL_CONST_DATA PublicKey); - -ISL_VERIFIED_MODULE_PTR -EISL_VerifyAndLoadModuleAndCredentialDataWithCertificate (const ISL_CONST_DATA CredentialsImage, - const ISL_CONST_DATA ModuleSearchPath, - const ISL_CONST_DATA Name, - const ISL_CONST_DATA Signer, - const ISL_CONST_DATA Certificate); - -ISL_VERIFIED_MODULE_PTR -EISL_VerifyAndLoadModuleAndCredentials (ISL_CONST_DATA Credentials, - ISL_CONST_DATA Name, - ISL_CONST_DATA Signer, - ISL_CONST_DATA PublicKey); - -ISL_VERIFIED_MODULE_PTR -EISL_VerifyAndLoadModuleAndCredentialsWithCertificate (const ISL_CONST_DATA Credentials, - const ISL_CONST_DATA Name, - const ISL_CONST_DATA Signer, - const ISL_CONST_DATA Certificate); - -ISL_VERIFIED_MODULE_PTR -EISL_VerifyLoadedModuleAndCredentialData (const ISL_CONST_DATA CredentialsImage, - const ISL_CONST_DATA ModuleSearchPath, - const ISL_CONST_DATA Name, - const ISL_CONST_DATA Signer, - const ISL_CONST_DATA PublicKey); - -ISL_VERIFIED_MODULE_PTR -EISL_VerifyLoadedModuleAndCredentialDataWithCertificate (const ISL_CONST_DATA CredentialsImage, - const ISL_CONST_DATA ModuleSearchPath, - const ISL_CONST_DATA Name, - const ISL_CONST_DATA Signer, - const ISL_CONST_DATA Certificate); - -ISL_VERIFIED_MODULE_PTR -EISL_VerifyLoadedModuleAndCredentials (ISL_CONST_DATA Credentials, - ISL_CONST_DATA Name, - ISL_CONST_DATA Signer, - ISL_CONST_DATA PublicKey); - -ISL_VERIFIED_MODULE_PTR -EISL_VerifyLoadedModuleAndCredentialsWithCertificate (const ISL_CONST_DATA Credentials, - const ISL_CONST_DATA Name, - const ISL_CONST_DATA Signer, - const ISL_CONST_DATA Certificate); - -ISL_VERIFIED_CERTIFICATE_CHAIN_PTR -EISL_GetCertificateChain (ISL_VERIFIED_MODULE_PTR Module); - -uint32 -EISL_ContinueVerification (ISL_VERIFIED_MODULE_PTR Module, - uint32 WorkFactor); - -ISL_VERIFIED_MODULE_PTR -EISL_DuplicateVerifiedModulePtr (ISL_VERIFIED_MODULE_PTR Module); - -ISL_STATUS -EISL_RecycleVerifiedModuleCredentials (ISL_VERIFIED_MODULE_PTR Verification); - - -/* Signature Root Methods */ - -ISL_VERIFIED_SIGNATURE_ROOT_PTR -EISL_CreateVerifiedSignatureRootWithCredentialData (const ISL_CONST_DATA CredentialsImage, - const ISL_CONST_DATA ModuleSearchPath, - const ISL_CONST_DATA Signer, - const ISL_CONST_DATA PublicKey); - -ISL_VERIFIED_SIGNATURE_ROOT_PTR -EISL_CreateVerifiedSignatureRootWithCredentialDataAndCertificate (const ISL_CONST_DATA CredentialsImage, - const ISL_CONST_DATA ModuleSearchPath, - ISL_VERIFIED_CERTIFICATE_PTR Cert); - -ISL_VERIFIED_SIGNATURE_ROOT_PTR -EISL_CreateVerfiedSignatureRoot (ISL_CONST_DATA Credentials, - ISL_CONST_DATA Signer, - ISL_CONST_DATA PublicKey); - -ISL_VERIFIED_SIGNATURE_ROOT_PTR -EISL_CreateVerfiedSignatureRootWithCertificate (ISL_CONST_DATA Credentials, - ISL_VERIFIED_CERTIFICATE_PTR Cert); - -ISL_MANIFEST_SECTION_PTR -EISL_FindManifestSection (ISL_VERIFIED_SIGNATURE_ROOT_PTR Root, - ISL_CONST_DATA Name); - -ISL_ITERATOR_PTR -EISL_CreateManifestSectionEnumerator (ISL_VERIFIED_SIGNATURE_ROOT_PTR Root); - -ISL_MANIFEST_SECTION_PTR -EISL_GetNextManifestSection (ISL_ITERATOR_PTR Iterator); - -ISL_STATUS -EISL_RecycleManifestSectionEnumerator (ISL_ITERATOR_PTR Iterator); - -ISL_STATUS -EISL_FindManifestAttribute (ISL_VERIFIED_SIGNATURE_ROOT_PTR Context, - ISL_CONST_DATA Name, - ISL_CONST_DATA_PTR Value); - -ISL_ITERATOR_PTR -EISL_CreateManifestAttributeEnumerator (ISL_VERIFIED_SIGNATURE_ROOT_PTR Context); - -ISL_STATUS -EISL_FindSignerInfoAttribute (ISL_VERIFIED_SIGNATURE_ROOT_PTR Context, - ISL_CONST_DATA Name, - ISL_CONST_DATA_PTR Value); - -ISL_ITERATOR_PTR -EISL_CreateSignerInfoAttributeEnumerator (ISL_VERIFIED_SIGNATURE_ROOT_PTR Context); - -ISL_STATUS -EISL_GetNextAttribute (ISL_ITERATOR_PTR Iterator, - ISL_CONST_DATA_PTR Name, - ISL_CONST_DATA_PTR Value); - -ISL_STATUS -EISL_RecycleAttributeEnumerator (ISL_ITERATOR_PTR Iterator); - -ISL_STATUS -EISL_FindSignatureAttribute (ISL_VERIFIED_SIGNATURE_ROOT_PTR Root, - ISL_CONST_DATA Name, - ISL_CONST_DATA_PTR Value); - -ISL_ITERATOR_PTR -EISL_CreateSignatureAttributeEnumerator (ISL_VERIFIED_SIGNATURE_ROOT_PTR Root); - -ISL_STATUS -EISL_GetNextSignatureAttribute (ISL_ITERATOR_PTR Iterator, - ISL_CONST_DATA_PTR Name, - ISL_CONST_DATA_PTR Value); - -ISL_STATUS -EISL_RecycleSignatureAttributeEnumerator (ISL_ITERATOR_PTR Iterator); - -ISL_STATUS -EISL_RecycleVerifiedSignatureRoot (ISL_VERIFIED_SIGNATURE_ROOT_PTR Root); - - -/* Certificate Chain Methods */ - -ISL_VERIFIED_CERTIFICATE_CHAIN_PTR -EISL_CreateCertificateChainWithCredentialData (const ISL_CONST_DATA RootIssuer, - const ISL_CONST_DATA PublicKey, - const ISL_CONST_DATA CredentialsImage, - const ISL_CONST_DATA ModuleSearchPath); - -ISL_VERIFIED_CERTIFICATE_CHAIN_PTR -EISL_CreateCertificateChainWithCredentialDataAndCertificate (const ISL_CONST_DATA Certificate, - const ISL_CONST_DATA CredentialsImage, - const ISL_CONST_DATA ModuleSearchPath); - -ISL_VERIFIED_CERTIFICATE_CHAIN_PTR -EISL_CreateCertificateChain (ISL_CONST_DATA RootIssuer, - ISL_CONST_DATA PublicKey, - ISL_CONST_DATA Credential); - -ISL_VERIFIED_CERTIFICATE_CHAIN_PTR -EISL_CreateCertificateChainWithCertificate (const ISL_CONST_DATA Certificate, - const ISL_CONST_DATA Credential); - -uint32 -EISL_CopyCertificateChain (ISL_VERIFIED_CERTIFICATE_CHAIN_PTR Verification, - ISL_VERIFIED_CERTIFICATE_PTR Certs[], - uint32 MaxCertificates); - -ISL_STATUS -EISL_RecycleVerifiedCertificateChain (ISL_VERIFIED_CERTIFICATE_CHAIN_PTR Chain); - - -/* Certificate Attribute Methods */ - -ISL_STATUS -EISL_FindCertificateAttribute (ISL_VERIFIED_CERTIFICATE_PTR Cert, - ISL_CONST_DATA Name, - ISL_CONST_DATA_PTR Value); - -ISL_ITERATOR_PTR -EISL_CreateCertificateAttributeEnumerator (ISL_VERIFIED_CERTIFICATE_PTR Cert); - -ISL_STATUS -EISL_GetNextCertificateAttribute (ISL_ITERATOR_PTR CertIterator, - ISL_CONST_DATA_PTR Name, - ISL_CONST_DATA_PTR Value); - -ISL_STATUS -EISL_RecycleCertificateAttributeEnumerator (ISL_ITERATOR_PTR CertIterator); - - -/* Manifest Section Object Methods */ - -ISL_VERIFIED_SIGNATURE_ROOT_PTR -EISL_GetManifestSignatureRoot (ISL_MANIFEST_SECTION_PTR Section); - -ISL_VERIFIED_MODULE_PTR -EISL_VerifyAndLoadModule (ISL_MANIFEST_SECTION_PTR Section); - -ISL_VERIFIED_MODULE_PTR -EISL_VerifyLoadedModule (ISL_MANIFEST_SECTION_PTR Section); - -ISL_STATUS -EISL_FindManifestSectionAttribute (ISL_MANIFEST_SECTION_PTR Section, - ISL_CONST_DATA Name, - ISL_CONST_DATA_PTR Value); - -ISL_ITERATOR_PTR -EISL_CreateManifestSectionAttributeEnumerator (ISL_MANIFEST_SECTION_PTR Section); - -ISL_STATUS -EISL_GetNextManifestSectionAttribute (ISL_ITERATOR_PTR Iterator, - ISL_CONST_DATA_PTR Name, - ISL_CONST_DATA_PTR Value); - -ISL_STATUS -EISL_RecycleManifestSectionAttributeEnumerator (ISL_ITERATOR_PTR Iterator); - -ISL_MANIFEST_SECTION_PTR -EISL_GetModuleManifestSection (ISL_VERIFIED_MODULE_PTR Module); - - -/* Secure Linkage Services */ - -ISL_FUNCTION_PTR -EISL_LocateProcedureAddress (ISL_VERIFIED_MODULE_PTR Module, - ISL_CONST_DATA Name); - -#ifdef MACOSX -#define EISL_GetReturnAddress(Address) \ -{\ - /* Platform specific code in here */ \ -} -#endif - -ISL_STATUS -EISL_CheckAddressWithinModule (ISL_VERIFIED_MODULE_PTR Verification, - ISL_FUNCTION_PTR Address); - -ISL_STATUS -EISL_CheckDataAddressWithinModule (ISL_VERIFIED_MODULE_PTR Verification, - const void *Address); - -void * -EISL_GetLibHandle (ISL_VERIFIED_MODULE_PTR Verification); - #ifdef __cplusplus } #endif diff --git a/OSX/libsecurity_cssm/lib/emmspi.h b/OSX/libsecurity_cssm/lib/emmspi.h index a618be9e..762972f2 100644 --- a/OSX/libsecurity_cssm/lib/emmspi.h +++ b/OSX/libsecurity_cssm/lib/emmspi.h @@ -85,13 +85,6 @@ enum { CSSM_HINT_ADDRESS_SP = 1 << 1 }; -CSSM_RETURN CSSMAPI -ModuleManagerAuthenticate (CSSM_KEY_HIERARCHY KeyHierarchy, - const CSSM_GUID *CssmGuid, - const CSSM_GUID *AppGuid, - CSSM_MANAGER_REGISTRATION_INFO_PTR FunctionTable) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - #pragma clang diagnostic pop #ifdef __cplusplus diff --git a/OSX/libsecurity_keychain/lib/Item.cpp b/OSX/libsecurity_keychain/lib/Item.cpp index ff064c1a..2ec227ef 100644 --- a/OSX/libsecurity_keychain/lib/Item.cpp +++ b/OSX/libsecurity_keychain/lib/Item.cpp @@ -196,14 +196,22 @@ ItemImpl::ItemImpl(ItemImpl &item) : } ItemImpl::~ItemImpl() -{ +try { if (secd_PersistentRef) { CFRelease(secd_PersistentRef); } +} catch (...) { +#ifndef NDEBUG + /* if we get an exception in destructor, presumably the mutex, lets throw if we + * are in a debug build (ie reach end of block) */ +#else + return; +#endif } + Mutex* ItemImpl::getMutexForObject() const { diff --git a/OSX/libsecurity_keychain/lib/MacOSErrorStrings.h b/OSX/libsecurity_keychain/lib/MacOSErrorStrings.h index 02e6195b..fb9ef2fd 100644 --- a/OSX/libsecurity_keychain/lib/MacOSErrorStrings.h +++ b/OSX/libsecurity_keychain/lib/MacOSErrorStrings.h @@ -56,6 +56,6 @@ enum errSecMisc_cantGetFlavorErr = -1854, /* The location (URL) of this item is missing or improperly formatted. */ errSecMisc_afpAccessDenied = -5000, /* Access to this item was denied. */ errSecMisc_afpUserNotAuth = -5023, /* Authentication failed. The password for this server may have changed since the item was added to the keychain. */ - errSecMisc_afpPwdPolicyErr = -5046 /* This AppleShare IP server is configured to not allow users to save passwords for automatic login. Contact the server administrator for more information. */ + errSecMisc_afpPwdPolicyErr = -5046, /* This AppleShare IP server is configured to not allow users to save passwords for automatic login. Contact the server administrator for more information. */ }; diff --git a/OSX/libsecurity_keychain/lib/SecACL.cpp b/OSX/libsecurity_keychain/lib/SecACL.cpp index d91458b3..5e5dbb7b 100644 --- a/OSX/libsecurity_keychain/lib/SecACL.cpp +++ b/OSX/libsecurity_keychain/lib/SecACL.cpp @@ -50,9 +50,6 @@ CFTypeID SecACLGetTypeID(void) { BEGIN_SECAPI - os_activity_t activity = os_activity_create("SecACLGetTypeID", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_IF_NONE_PRESENT); - os_activity_scope(activity); - os_release(activity); return gTypes().ACL.typeID; diff --git a/OSX/libsecurity_keychain/lib/SecAsn1TypesP.h b/OSX/libsecurity_keychain/lib/SecAsn1TypesP.h deleted file mode 100644 index 2a027acb..00000000 --- a/OSX/libsecurity_keychain/lib/SecAsn1TypesP.h +++ /dev/null @@ -1,241 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -/* - * Types for encoding/decoding of ASN.1 using BER/DER (Basic/Distinguished - * Encoding Rules). - */ - -#ifndef _SEC_ASN1_TYPES_H_ -#define _SEC_ASN1_TYPES_H_ - -#include /* Boolean */ -#include -#include - -#include -#if 1 /* TARGET_OS_EMBEDDED */ -/* @@@ We need something that tells us which platform we are building - for that let's us distinguish if we are doing an emulator build. */ - -typedef struct { - size_t Length; - uint8_t *Data; -} SecAsn1Item, SecAsn1Oid; - -typedef struct { - SecAsn1Oid algorithm; - SecAsn1Item parameters; -} SecAsn1AlgId; - -typedef struct { - SecAsn1AlgId algorithm; - SecAsn1Item subjectPublicKey; -} SecAsn1PubKeyInfo; - -#else -#include -#include - -typedef CSSM_DATA SecAsn1Item; -typedef CSSM_OID SecAsn1Oid; -typedef CSSM_X509_ALGORITHM_IDENTIFIER SecAsn1AlgId; -typedef CSSM_X509_SUBJECT_PUBLIC_KEY_INFO SecAsn1PubKeyInfo; - -#endif - -/* - * An array of these structures defines a BER/DER encoding for an object. - * - * The array usually starts with a dummy entry whose kind is SEC_ASN1_SEQUENCE; - * such an array is terminated with an entry where kind == 0. (An array - * which consists of a single component does not require a second dummy - * entry -- the array is only searched as long as previous component(s) - * instruct it.) - */ -typedef struct SecAsn1Template_struct { - /* - * Kind of item being decoded/encoded, including tags and modifiers. - */ - uint32_t kind; - - /* - * This value is the offset from the base of the structure (i.e., the - * (void *) passed as 'src' to SecAsn1EncodeItem, or the 'dst' argument - * passed to SecAsn1CoderRef()) to the field that holds the value being - * decoded/encoded. - */ - uint32_t offset; - - /* - * When kind suggests it (e.g., SEC_ASN1_POINTER, SEC_ASN1_GROUP, - * SEC_ASN1_INLINE, or a component that is *not* a SEC_ASN1_UNIVERSAL), - * this points to a sub-template for nested encoding/decoding. - * OR, iff SEC_ASN1_DYNAMIC is set, then this is a pointer to a pointer - * to a function which will return the appropriate template when called - * at runtime. NOTE! that explicit level of indirection, which is - * necessary because ANSI does not allow you to store a function - * pointer directly as a "void *" so we must store it separately and - * dereference it to get at the function pointer itself. - */ - const void *sub; - - /* - * In the first element of a template array, the value is the size - * of the structure to allocate when this template is being referenced - * by another template via SEC_ASN1_POINTER or SEC_ASN1_GROUP. - * In all other cases, the value is ignored. - */ - uint32_t size; -} SecAsn1Template; - - -/* - * BER/DER values for ASN.1 identifier octets. - */ -#define SEC_ASN1_TAG_MASK 0xff - -/* - * BER/DER universal type tag numbers. - */ -#define SEC_ASN1_TAGNUM_MASK 0x1f -#define SEC_ASN1_BOOLEAN 0x01 -#define SEC_ASN1_INTEGER 0x02 -#define SEC_ASN1_BIT_STRING 0x03 -#define SEC_ASN1_OCTET_STRING 0x04 -#define SEC_ASN1_NULL 0x05 -#define SEC_ASN1_OBJECT_ID 0x06 -#define SEC_ASN1_OBJECT_DESCRIPTOR 0x07 -/* External type and instance-of type 0x08 */ -#define SEC_ASN1_REAL 0x09 -#define SEC_ASN1_ENUMERATED 0x0a -#define SEC_ASN1_EMBEDDED_PDV 0x0b -#define SEC_ASN1_UTF8_STRING 0x0c -/* not used 0x0d */ -/* not used 0x0e */ -/* not used 0x0f */ -#define SEC_ASN1_SEQUENCE 0x10 -#define SEC_ASN1_SET 0x11 -#define SEC_ASN1_NUMERIC_STRING 0x12 -#define SEC_ASN1_PRINTABLE_STRING 0x13 -#define SEC_ASN1_T61_STRING 0x14 -#define SEC_ASN1_VIDEOTEX_STRING 0x15 -#define SEC_ASN1_IA5_STRING 0x16 -#define SEC_ASN1_UTC_TIME 0x17 -#define SEC_ASN1_GENERALIZED_TIME 0x18 -#define SEC_ASN1_GRAPHIC_STRING 0x19 -#define SEC_ASN1_VISIBLE_STRING 0x1a -#define SEC_ASN1_GENERAL_STRING 0x1b -#define SEC_ASN1_UNIVERSAL_STRING 0x1c -/* not used 0x1d */ -#define SEC_ASN1_BMP_STRING 0x1e -#define SEC_ASN1_HIGH_TAG_NUMBER 0x1f -#define SEC_ASN1_TELETEX_STRING SEC_ASN1_T61_STRING - -/* - * Modifiers to type tags. These are also specified by a/the - * standard, and must not be changed. - */ -#define SEC_ASN1_METHOD_MASK 0x20 -#define SEC_ASN1_PRIMITIVE 0x00 -#define SEC_ASN1_CONSTRUCTED 0x20 - -#define SEC_ASN1_CLASS_MASK 0xc0 -#define SEC_ASN1_UNIVERSAL 0x00 -#define SEC_ASN1_APPLICATION 0x40 -#define SEC_ASN1_CONTEXT_SPECIFIC 0x80 -#define SEC_ASN1_PRIVATE 0xc0 - -/* - * Our additions, used for templates. - * These are not defined by any standard; the values are used internally only. - * Just be careful to keep them out of the low 8 bits. - */ -#define SEC_ASN1_OPTIONAL 0x00100 -#define SEC_ASN1_EXPLICIT 0x00200 -#define SEC_ASN1_ANY 0x00400 -#define SEC_ASN1_INLINE 0x00800 -#define SEC_ASN1_POINTER 0x01000 -#define SEC_ASN1_GROUP 0x02000 /* with SET or SEQUENCE means - * SET OF or SEQUENCE OF */ -#define SEC_ASN1_DYNAMIC 0x04000 /* subtemplate is found by calling - * a function at runtime */ -#define SEC_ASN1_SKIP 0x08000 /* skip a field; only for decoding */ -#define SEC_ASN1_INNER 0x10000 /* with ANY means capture the - * contents only (not the id, len, - * or eoc); only for decoding */ -#define SEC_ASN1_SAVE 0x20000 /* stash away the encoded bytes first; - * only for decoding */ -#define SEC_ASN1_SKIP_REST 0x80000 /* skip all following fields; - * only for decoding */ -#define SEC_ASN1_CHOICE 0x100000 /* pick one from a template */ - -/* - * Indicate that a type SEC_ASN1_INTEGER is actually signed. - * The default is unsigned, which causes a leading zero to be - * encoded if the MS bit of the source data is 1. - */ -#define SEC_ASN1_SIGNED_INT 0X800000 - -/* Shorthand/Aliases */ -#define SEC_ASN1_SEQUENCE_OF (SEC_ASN1_GROUP | SEC_ASN1_SEQUENCE) -#define SEC_ASN1_SET_OF (SEC_ASN1_GROUP | SEC_ASN1_SET) -#define SEC_ASN1_ANY_CONTENTS (SEC_ASN1_ANY | SEC_ASN1_INNER) - -/* - * Function used for SEC_ASN1_DYNAMIC. - * "arg" is a pointer to the top-level structure being encoded or - * decoded. - * - * "enc" when true, means that we are encoding (false means decoding) - * - * "buf" For decode only; points to the start of the decoded data for - * the current template. Callee can use the tag at this location - * to infer the returned template. Not used on encode. - * - * "Dest" points to the template-specific item being decoded to - * or encoded from. (This is as opposed to arg, which - * points to the start of the struct associated with the - * current array of templates). - */ - -typedef const SecAsn1Template * SecAsn1TemplateChooser( - void *arg, - Boolean enc, - const char *buf, - void *dest); - -typedef SecAsn1TemplateChooser * SecAsn1TemplateChooserPtr; - - -#endif /* _SEC_ASN1_TYPES_H_ */ diff --git a/OSX/libsecurity_keychain/lib/SecBase.cpp b/OSX/libsecurity_keychain/lib/SecBase.cpp index 096349ed..b9633314 100644 --- a/OSX/libsecurity_keychain/lib/SecBase.cpp +++ b/OSX/libsecurity_keychain/lib/SecBase.cpp @@ -98,7 +98,7 @@ cssmErrorString(CSSM_RETURN error) CFStringRef result = copyErrorMessageFromBundle(error,CFSTR("SecErrorMessages")); if (result == NULL) result = copyErrorMessageFromBundle(error,CFSTR("SecDebugErrorMessages")); - err = cfString(result, true); + err = cfString(result, errSecErrorStringNotAvailable); CFReleaseSafe(result); } diff --git a/OSX/libsecurity_keychain/lib/SecBaseP.h b/OSX/libsecurity_keychain/lib/SecBaseP.h deleted file mode 100644 index dc4f9cd1..00000000 --- a/OSX/libsecurity_keychain/lib/SecBaseP.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2000-2009,2011 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/*! - @header SecBase - SecBase contains common declarations for the Security functions. -*/ - -#ifndef _SECURITY_SECBASEP_H_ -#define _SECURITY_SECBASEP_H_ - -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -/*! - @typedef SecCertificateRef - @abstract CFType representing a X.509 certificate, see - SecCertificate.h for details. -*/ -typedef struct __SecCertificate *SecCertificateRefP; - -/*! - @typedef SecIdentityRef - @abstract CFType representing an identity, which contains - a SecKeyRef and an ascociated SecCertificateRef, see - SecIdentity.h for details. -*/ -typedef struct __SecIdentity *SecIdentityRefP; - -/*! - @typedef SecKeyRef - @abstract CFType representing an asymetric key, see - SecKey.h for details. -*/ -typedef struct __SecKey *SecKeyRefP; - -/*********************************************** - *** OSStatus values unique to Security APIs *** - ***********************************************/ - -/* - Note: the comments that appear after these errors are used to create - SecErrorMessages.strings. The comments must not be multi-line, and - should be in a form meaningful to an end user. If a different or - additional comment is needed, it can be put in the header doc format, - or on a line that does not start with errZZZ. -*/ - -#if 0 -enum -{ - errSecSuccess = 0, /* No error. */ - errSecUnimplemented = -4, /* Function or operation not implemented. */ - errSecParam = -50, /* One or more parameters passed to a function where not valid. */ - errSecAllocate = -108, /* Failed to allocate memory. */ - errSecNotAvailable = -25291, /* No keychain is available. You may need to restart your computer. */ - errSecDuplicateItem = -25299, /* The specified item already exists in the keychain. */ - errSecItemNotFound = -25300, /* The specified item could not be found in the keychain. */ - errSecInteractionNotAllowed = -25308, /* User interaction is not allowed. */ - errSecDecode = -26275, /* Unable to decode the provided data. */ -}; -#endif - -#if defined(__cplusplus) -} -#endif - -#endif /* !_SECURITY_SECBASEP_H_ */ diff --git a/OSX/libsecurity_keychain/lib/SecFrameworkP.h b/OSX/libsecurity_keychain/lib/SecFrameworkP.h deleted file mode 100644 index da08583a..00000000 --- a/OSX/libsecurity_keychain/lib/SecFrameworkP.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2006-2007,2009-2011 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/*! - @header SecFramework - The functions provided in SecFramework.h implement generic non API class - specific functionality. -*/ - -#ifndef _SECURITY_SECFRAMEWORK_H_ -#define _SECURITY_SECFRAMEWORK_H_ - -#include -#include -#include "SecAsn1TypesP.h" - -#if defined(__cplusplus) -extern "C" { -#endif - -CFStringRef SecFrameworkCopyLocalizedString(CFStringRef key, - CFStringRef tableName) CF_FORMAT_ARGUMENT(1); - -CFURLRef SecFrameworkCopyResourceURL(CFStringRef resourceName, - CFStringRef resourceType, CFStringRef subDirName); - -CFDataRef SecFrameworkCopyResourceContents(CFStringRef resourceName, - CFStringRef resourceType, CFStringRef subDirName); - -/* Return the SHA1 digest of a chunk of data as newly allocated CFDataRef. */ -CFDataRef SecSHA1DigestCreate(CFAllocatorRef allocator, - const UInt8 *data, CFIndex length); - -/* Return the digest of a chunk of data as newly allocated CFDataRef, the - algorithm is selected based on the algorithm and params passed in. */ -CFDataRef SecDigestCreate(CFAllocatorRef allocator, - const SecAsn1Oid *algorithm, const SecAsn1Item *params, - const UInt8 *data, CFIndex length); - -#if defined(__cplusplus) -} -#endif - -#endif /* !_SECURITY_SECFRAMEWORK_H_ */ diff --git a/OSX/libsecurity_keychain/lib/SecIdentity.cpp b/OSX/libsecurity_keychain/lib/SecIdentity.cpp index 1cb7b595..79818db9 100644 --- a/OSX/libsecurity_keychain/lib/SecIdentity.cpp +++ b/OSX/libsecurity_keychain/lib/SecIdentity.cpp @@ -109,9 +109,6 @@ CFTypeID SecIdentityGetTypeID(void) { BEGIN_SECAPI - os_activity_t activity = os_activity_create("SecIdentityGetTypeID", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_IF_NONE_PRESENT); - os_activity_scope(activity); - os_release(activity); return gTypes().Identity.typeID; diff --git a/OSX/libsecurity_keychain/lib/SecIdentitySearch.cpp b/OSX/libsecurity_keychain/lib/SecIdentitySearch.cpp index 589fa93e..b3f58d60 100644 --- a/OSX/libsecurity_keychain/lib/SecIdentitySearch.cpp +++ b/OSX/libsecurity_keychain/lib/SecIdentitySearch.cpp @@ -35,9 +35,6 @@ CFTypeID SecIdentitySearchGetTypeID(void) { BEGIN_SECAPI - os_activity_t activity = os_activity_create("SecIdentitySearchGetTypeID", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_IF_NONE_PRESENT); - os_activity_scope(activity); - os_release(activity); return gTypes().IdentityCursor.typeID; diff --git a/OSX/libsecurity_keychain/lib/SecItem.cpp b/OSX/libsecurity_keychain/lib/SecItem.cpp index a59b18b5..ac9a9e6f 100644 --- a/OSX/libsecurity_keychain/lib/SecItem.cpp +++ b/OSX/libsecurity_keychain/lib/SecItem.cpp @@ -4749,45 +4749,6 @@ SecItemMergeResults(bool can_target_ios, OSStatus status_ios, CFTypeRef result_i } } -static bool -ShouldTryUnlockKeybag(CFDictionaryRef query, OSErr status) -{ - static __typeof(SASSessionStateForUser) *soft_SASSessionStateForUser = NULL; - static dispatch_once_t onceToken; - static void *framework; - - if (status != errSecInteractionNotAllowed) - return false; - - // If the query disabled authUI, respect it. - CFTypeRef authUI = NULL; - if (query) { - authUI = CFDictionaryGetValue(query, kSecUseAuthenticationUI); - if (authUI == NULL) { - authUI = CFDictionaryGetValue(query, kSecUseNoAuthenticationUI); - authUI = (authUI != NULL && CFEqual(authUI, kCFBooleanTrue)) ? kSecUseAuthenticationUIFail : NULL; - } - } - if (authUI && !CFEqual(authUI, kSecUseAuthenticationUIAllow)) - return false; - - dispatch_once(&onceToken, ^{ - framework = dlopen("/System/Library/PrivateFrameworks/login.framework/login", RTLD_LAZY); - if (framework == NULL) - return; - soft_SASSessionStateForUser = (__typeof(soft_SASSessionStateForUser)) dlsym(framework, "SASSessionStateForUser"); - }); - - if (soft_SASSessionStateForUser == NULL) - return false; - - SessionAgentState sessionState = soft_SASSessionStateForUser(getuid()); - if(sessionState != kSA_state_desktopshowing) - return false; - - return true; -} - OSStatus SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result) { @@ -4816,14 +4777,6 @@ SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result) } else { status_ios = SecItemCopyMatching_ios(attrs_ios, &result_ios); - if(ShouldTryUnlockKeybag(query, status_ios)) { - // The keybag is locked. Attempt to unlock it... - secitemlog(LOG_WARNING, "SecItemCopyMatching triggering SecurityAgent"); - if(errSecSuccess == SecKeychainVerifyKeyStorePassphrase(1)) { - CFReleaseNull(result_ios); - status_ios = SecItemCopyMatching_ios(attrs_ios, &result_ios); - } - } CFRelease(attrs_ios); } secitemlog(LOG_NOTICE, "SecItemCopyMatching_ios result: %d", status_ios); @@ -4880,14 +4833,6 @@ SecItemAdd(CFDictionaryRef attributes, CFTypeRef *result) status = errSecParam; } else { status = SecItemAdd_ios(attrs_ios, &result_ios); - if(ShouldTryUnlockKeybag(attributes, status)) { - // The keybag is locked. Attempt to unlock it... - secitemlog(LOG_WARNING, "SecItemAdd triggering SecurityAgent"); - if(errSecSuccess == SecKeychainVerifyKeyStorePassphrase(3)) { - CFReleaseNull(result_ios); - status = SecItemAdd_ios(attrs_ios, &result_ios); - } - } CFRelease(attrs_ios); } secitemlog(LOG_NOTICE, "SecItemAdd_ios result: %d", status); @@ -4937,22 +4882,8 @@ SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate) else { if (SecItemHasSynchronizableUpdate(true, attributesToUpdate)) { status_ios = SecItemChangeSynchronizability(attrs_ios, attributesToUpdate, false); - if(ShouldTryUnlockKeybag(query, status_ios)) { - // The keybag is locked. Attempt to unlock it... - secitemlog(LOG_WARNING, "SecItemUpdate triggering SecurityAgent"); - if(errSecSuccess == SecKeychainVerifyKeyStorePassphrase(1)) { - status_ios = SecItemChangeSynchronizability(attrs_ios, attributesToUpdate, false); - } - } } else { status_ios = SecItemUpdate_ios(attrs_ios, attributesToUpdate); - if(ShouldTryUnlockKeybag(query, status_ios)) { - // The keybag is locked. Attempt to unlock it... - secitemlog(LOG_WARNING, "SecItemUpdate triggering SecurityAgent"); - if(errSecSuccess == SecKeychainVerifyKeyStorePassphrase(1)) { - status_ios = SecItemUpdate_ios(attrs_ios, attributesToUpdate); - } - } } CFRelease(attrs_ios); } @@ -5035,13 +4966,6 @@ OSStatus SecItemUpdateTokenItems(CFTypeRef tokenID, CFArrayRef tokenItemsAttributes) { OSStatus status = SecItemUpdateTokenItems_ios(tokenID, tokenItemsAttributes); - if(ShouldTryUnlockKeybag(NULL, status)) { - // The keybag is locked. Attempt to unlock it... - if(errSecSuccess == SecKeychainVerifyKeyStorePassphrase(1)) { - secitemlog(LOG_WARNING, "SecItemUpdateTokenItems triggering SecurityAgent"); - status = SecItemUpdateTokenItems_ios(tokenID, tokenItemsAttributes); - } - } secitemlog(LOG_NOTICE, "SecItemUpdateTokenItems_ios result: %d", status); return status; } diff --git a/OSX/libsecurity_keychain/lib/SecKeychain.cpp b/OSX/libsecurity_keychain/lib/SecKeychain.cpp index c6427967..71485cdf 100644 --- a/OSX/libsecurity_keychain/lib/SecKeychain.cpp +++ b/OSX/libsecurity_keychain/lib/SecKeychain.cpp @@ -273,10 +273,12 @@ OSStatus SecKeychainResetLogin(UInt32 passwordLength, const void* password, Bool endpwent(); } if ( userName.length() == 0 ) // did we ultimately get one? + { MacOSError::throwMe(errAuthorizationInternal); + } SecurityServer::ClientSession().resetKeyStorePassphrase(password ? CssmData(const_cast(password), passwordLength) : CssmData()); - + secwarning("SecKeychainResetLogin: reset AKS passphrase"); if (password) { // Clear the plist and move aside (rename) the existing login.keychain @@ -295,11 +297,13 @@ OSStatus SecKeychainResetLogin(UInt32 passwordLength, const void* password, Bool // (implicitly calls resetKeychain, login, and defaultKeychain) globals().storageManager.makeLoginAuthUI(NULL, true); } + secwarning("SecKeychainResetLogin: reset osx keychain"); // Post a "list changed" event after a reset, so apps can refresh their list. // Make sure we are not holding mLock when we post this event. KCEventNotifier::PostKeychainEvent(kSecKeychainListChangedEvent); + END_SECAPI } diff --git a/OSX/libsecurity_keychain/lib/SecKeychainPriv.h b/OSX/libsecurity_keychain/lib/SecKeychainPriv.h index d504b4a1..0847e8d5 100644 --- a/OSX/libsecurity_keychain/lib/SecKeychainPriv.h +++ b/OSX/libsecurity_keychain/lib/SecKeychainPriv.h @@ -114,8 +114,6 @@ OSStatus SecKeychainSystemKeychainCheckWouldDeadlock() __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); OSStatus SecKeychainStoreUnlockKey(SecKeychainRef userKeychainRef, SecKeychainRef systemKeychainRef, CFStringRef username, CFStringRef password) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_NA); -OSStatus SecKeychainEraseUnlockKey(SecKeychainRef systemKeychainRef, CFStringRef username) - __OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_NA); /* Token login support */ OSStatus SecKeychainStoreUnlockKeyWithPubKeyHash(CFDataRef pubKeyHash, CFStringRef tokenID, CFDataRef wrapPubKeyHash, SecKeychainRef userKeychain, CFStringRef password) diff --git a/OSX/libsecurity_keychain/lib/SecPolicy.cpp b/OSX/libsecurity_keychain/lib/SecPolicy.cpp index f4d09996..35ec80ec 100644 --- a/OSX/libsecurity_keychain/lib/SecPolicy.cpp +++ b/OSX/libsecurity_keychain/lib/SecPolicy.cpp @@ -276,7 +276,7 @@ SecPolicyGetValue(SecPolicyRef policyRef, CSSM_DATA* value) (const void **)&name) && name) { break; } - if (CFDictionaryGetValueIfPresent(options, CFSTR("email") /*kSecPolicyCheckEmail*/, + if (CFDictionaryGetValueIfPresent(options, CFSTR("Email") /*kSecPolicyCheckEmail*/, (const void **)&name) && name) { break; } diff --git a/OSX/libsecurity_keychain/lib/SecRSAKeyP.h b/OSX/libsecurity_keychain/lib/SecRSAKeyP.h deleted file mode 100644 index c7fb515b..00000000 --- a/OSX/libsecurity_keychain/lib/SecRSAKeyP.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2006-2008,2010-2012 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/*! - @header SecRSAKey - The functions provided in SecRSAKey.h implement and manage a rsa - public or private key. -*/ - -#ifndef _SECURITY_SECRSAKEY_H_ -#define _SECURITY_SECRSAKEY_H_ - -#include -#include -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -/* Given an RSA public key in encoded form return a SecKeyRef representing - that key. Supported encodings are kSecKeyEncodingPkcs1. */ -SecKeyRef SecKeyCreateRSAPublicKey(CFAllocatorRef allocator, - const uint8_t *keyData, CFIndex keyDataLength, - SecKeyEncoding encoding); - -CFDataRef SecKeyCopyModulus(SecKeyRef rsaPublicKey); -CFDataRef SecKeyCopyExponent(SecKeyRef rsaPublicKey); - -/* Given an RSA private key in encoded form return a SecKeyRef representing - that key. Supported encodings are kSecKeyEncodingPkcs1. */ -SecKeyRef SecKeyCreateRSAPrivateKey(CFAllocatorRef allocator, - const uint8_t *keyData, CFIndex keyDataLength, - SecKeyEncoding encoding); - -#if defined(__cplusplus) -} -#endif - -#endif /* !_SECURITY_SECRSAKEY_H_ */ diff --git a/OSX/libsecurity_keychain/lib/SecTrust.cpp b/OSX/libsecurity_keychain/lib/SecTrust.cpp index 502d187f..a710f92a 100644 --- a/OSX/libsecurity_keychain/lib/SecTrust.cpp +++ b/OSX/libsecurity_keychain/lib/SecTrust.cpp @@ -21,6 +21,9 @@ * @APPLE_LICENSE_HEADER_END@ */ +#include +#include + #include "SecTrust.h" #include "SecTrustPriv.h" #include "Trust.h" @@ -189,8 +192,6 @@ static uint8_t convertCssmResultToPriority(CSSM_RETURN resultCode) { } } -#include -#include static bool isSoftwareUpdateDevelopment(SecTrustRef trust) { bool isPolicy = false, isEKU = false; CFArrayRef policies = NULL; diff --git a/OSX/libsecurity_keychain/lib/SecTrustOSXEntryPoints.cpp b/OSX/libsecurity_keychain/lib/SecTrustOSXEntryPoints.cpp index ffe7e3a1..f994ea1c 100644 --- a/OSX/libsecurity_keychain/lib/SecTrustOSXEntryPoints.cpp +++ b/OSX/libsecurity_keychain/lib/SecTrustOSXEntryPoints.cpp @@ -28,6 +28,12 @@ #include "SecTrustOSXEntryPoints.h" +#include +#include +#include +#include +#include + #include #include #include @@ -42,11 +48,6 @@ #include #include -#include -#include -#include -#include - void SecTrustLegacySourcesListenForKeychainEvents(void) { /* Register for CertificateTrustNotification */ @@ -229,6 +230,7 @@ static void async_ocspd_complete(async_ocspd_t *ocspd) { bool SecTrustLegacyCRLFetch(async_ocspd_t *ocspd, CFURLRef currCRLDP, CFAbsoluteTime verifyTime, SecCertificateRef cert, CFArrayRef chain) { + ocspd->start_time = mach_absolute_time(); dispatch_async(ocspd->queue, ^ { OSStatus status = fetchCRL(currCRLDP, verifyTime); switch (status) { diff --git a/OSX/libsecurity_keychain/lib/SecTrustSettings.cpp b/OSX/libsecurity_keychain/lib/SecTrustSettings.cpp index 8b25b2de..a59873d6 100644 --- a/OSX/libsecurity_keychain/lib/SecTrustSettings.cpp +++ b/OSX/libsecurity_keychain/lib/SecTrustSettings.cpp @@ -433,7 +433,7 @@ static OSStatus tsCopyCertsCommon( static void tsAddConditionalCerts(CFMutableArrayRef certArray) { -#if TARGET_OS_MAC && !TARGET_IPHONE_SIMULATOR && !TARGET_OS_IPHONE && !TARGET_OS_NANO +#if TARGET_OS_OSX struct certmap_entry_s { CFStringRef bundleId; const UInt8* data; @@ -1079,10 +1079,8 @@ void SecTrustSettingsSetTrustedCertificateForSSLHost( Boolean hasPolicyConstraint = false; Boolean hasPolicyValue = false; Boolean policyConstraintChanged = false; - Boolean changed = false; CFIndex indexOfEntryWithAllowedErrorForExpiredCert = kCFNotFound; CFIndex indexOfEntryWithAllowedErrorForHostnameMismatch = kCFNotFound; - CFIndex indexOfEntryWithAllowedErrorNotSet = kCFNotFound; CFIndex i, count; int32_t trustSettingsResultCode = kSecTrustSettingsResultTrustAsRoot; OSStatus status = errSecSuccess; @@ -1166,11 +1164,9 @@ void SecTrustSettingsSetTrustedCertificateForSSLHost( indexOfEntryWithAllowedErrorForExpiredCert = i; } else if (eOld == CSSMERR_APPLETP_HOSTNAME_MISMATCH) { indexOfEntryWithAllowedErrorForHostnameMismatch = i; - } else if (eOld == CSSM_OK) { - indexOfEntryWithAllowedErrorNotSet = i; } if (trustSettingsResultCode != rOld) { - changed = policyConstraintChanged = true; // we are changing existing policy constraint's result + policyConstraintChanged = true; // we are changing existing policy constraint's result } } } diff --git a/OSX/libsecurity_keychain/lib/StorageManager.cpp b/OSX/libsecurity_keychain/lib/StorageManager.cpp index 810f4c11..0bd0760e 100644 --- a/OSX/libsecurity_keychain/lib/StorageManager.cpp +++ b/OSX/libsecurity_keychain/lib/StorageManager.cpp @@ -1382,7 +1382,7 @@ void StorageManager::login(UInt32 nameLength, const void *name, secnotice("KCLogin", "StorageManager::login: invalid argument (NULL uid)"); MacOSError::throwMe(errSecParam); } - char *userName = pw->pw_name; + std::string userName = pw->pw_name; // make keychain path strings std::string keychainPath = DLDbListCFPref::ExpandTildesInPath(kLoginKeychainPathPrefix); diff --git a/OSX/libsecurity_keychain/lib/TokenLogin.cpp b/OSX/libsecurity_keychain/lib/TokenLogin.cpp index 64b45fc9..f0ec1fef 100644 --- a/OSX/libsecurity_keychain/lib/TokenLogin.cpp +++ b/OSX/libsecurity_keychain/lib/TokenLogin.cpp @@ -122,8 +122,7 @@ static OSStatus privKeyForPubKeyHash(CFDictionaryRef context, SecKeyRef *privKey CFStringRef pin = getPin(context); if (pin) { - CFRef LAParams = makeCFDictionary(1, CFSTR("useDaemon"), kCFBooleanFalse); - CFRef LAContext = LACreateNewContextWithACMContext(LAParams.as(), error.take()); + CFRef LAContext = LACreateNewContextWithACMContext(NULL, error.take()); if (!LAContext) { secinfo("TokenLogin", "Failed to LA Context: %@", error.get()); return errSecParam; diff --git a/OSX/libsecurity_keychain/lib/certextensionsP.h b/OSX/libsecurity_keychain/lib/certextensionsP.h deleted file mode 100644 index 93cb28fa..00000000 --- a/OSX/libsecurity_keychain/lib/certextensionsP.h +++ /dev/null @@ -1,546 +0,0 @@ -/* - * Copyright (c) 2000-2009,2011 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - * - * CertExtensions.h -- X.509 Cert Extensions as C structs - */ - -#ifndef _CERT_EXTENSIONS_H_ -#define _CERT_EXTENSIONS_H_ - -#include -#include -//#include - -/*** - *** Structs for declaring extension-specific data. - ***/ - -/* - * GeneralName, used in AuthorityKeyID, SubjectAltName, and - * IssuerAltName. - * - * For now, we just provide explicit support for the types which are - * represented as IA5Strings, OIDs, and octet strings. Constructed types - * such as EDIPartyName and x400Address are not explicitly handled - * right now and must be encoded and decoded by the caller. (See exception - * for Name and OtherName, below). In those cases the SecCEGeneralName.name.Data field - * represents the BER contents octets; SecCEGeneralName.name.Length is the - * length of the contents; the tag of the field is not needed - the BER - * encoding uses context-specific implicit tagging. The berEncoded field - * is set to true in these case. Simple types have berEncoded = false. - * - * In the case of a GeneralName in the form of a Name, we parse the Name - * into a CSSM_X509_NAME and place a pointer to the CSSM_X509_NAME in the - * SecCEGeneralName.name.Data field. SecCEGeneralName.name.Length is set to - * sizeof(CSSM_X509_NAME). In this case berEncoded is false. - * - * In the case of a GeneralName in the form of a OtherName, we parse the fields - * into a SecCEOtherName and place a pointer to the SecCEOtherName in the - * SecCEGeneralName.name.Data field. SecCEGeneralName.name.Length is set to - * sizeof(SecCEOtherName). In this case berEncoded is false. - * - * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName - * - * GeneralName ::= CHOICE { - * otherName [0] OtherName - * rfc822Name [1] IA5String, - * dNSName [2] IA5String, - * x400Address [3] ORAddress, - * directoryName [4] Name, - * ediPartyName [5] EDIPartyName, - * uniformResourceIdentifier [6] IA5String, - * iPAddress [7] OCTET STRING, - * registeredID [8] OBJECT IDENTIFIER} - * - * OtherName ::= SEQUENCE { - * type-id OBJECT IDENTIFIER, - * value [0] EXPLICIT ANY DEFINED BY type-id } - * - * EDIPartyName ::= SEQUENCE { - * nameAssigner [0] DirectoryString OPTIONAL, - * partyName [1] DirectoryString } - */ -typedef enum { - GNT_OtherName = 0, - GNT_RFC822Name, - GNT_DNSName, - GNT_X400Address, - GNT_DirectoryName, - GNT_EdiPartyName, - GNT_URI, - GNT_IPAddress, - GNT_RegisteredID -} SecCEGeneralNameType; - -typedef struct { - DERItem typeId; - DERItem value; // unparsed, BER-encoded -} SecCEOtherName; - -typedef struct { - SecCEGeneralNameType nameType; // GNT_RFC822Name, etc. - bool berEncoded; - DERItem name; -} SecCEGeneralName; - -typedef struct { - uint32_t numNames; - SecCEGeneralName *generalName; -} SecCEGeneralNames; - -/* - * id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 } - * - * AuthorityKeyIdentifier ::= SEQUENCE { - * keyIdentifier [0] KeyIdentifier OPTIONAL, - * authorityCertIssuer [1] GeneralNames OPTIONAL, - * authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } - * - * KeyIdentifier ::= OCTET STRING - * - * CSSM OID = CSSMOID_AuthorityKeyIdentifier - */ -typedef struct { - bool keyIdentifierPresent; - DERItem keyIdentifier; - bool generalNamesPresent; - SecCEGeneralNames *generalNames; - bool serialNumberPresent; - DERItem serialNumber; -} SecCEAuthorityKeyID; - -/* - * id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 } - * SubjectKeyIdentifier ::= KeyIdentifier - * - * CSSM OID = CSSMOID_SubjectKeyIdentifier - */ -typedef DERItem SecCESubjectKeyID; - -/* - * id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } - * - * KeyUsage ::= BIT STRING { - * digitalSignature (0), - * nonRepudiation (1), - * keyEncipherment (2), - * dataEncipherment (3), - * keyAgreement (4), - * keyCertSign (5), - * cRLSign (6), - * encipherOnly (7), - * decipherOnly (8) } - * - * CSSM OID = CSSMOID_KeyUsage - * - */ -typedef uint16_t SecCEKeyUsage; - -#define SecCEKU_DigitalSignature 0x8000 -#define SecCEKU_NonRepudiation 0x4000 -#define SecCEKU_KeyEncipherment 0x2000 -#define SecCEKU_DataEncipherment 0x1000 -#define SecCEKU_KeyAgreement 0x0800 -#define SecCEKU_KeyCertSign 0x0400 -#define SecCEKU_CRLSign 0x0200 -#define SecCEKU_EncipherOnly 0x0100 -#define SecCEKU_DecipherOnly 0x0080 - -/* - * id-ce-cRLReason OBJECT IDENTIFIER ::= { id-ce 21 } - * - * -- reasonCode ::= { CRLReason } - * - * CRLReason ::= ENUMERATED { - * unspecified (0), - * keyCompromise (1), - * cACompromise (2), - * affiliationChanged (3), - * superseded (4), - * cessationOfOperation (5), - * certificateHold (6), - * removeFromCRL (8) } - * - * CSSM OID = CSSMOID_CrlReason - * - */ -typedef uint32_t SecCECrlReason; - -#define SecCECR_Unspecified 0 -#define SecCECR_KeyCompromise 1 -#define SecCECR_CACompromise 2 -#define SecCECR_AffiliationChanged 3 -#define SecCECR_Superseded 4 -#define SecCECR_CessationOfOperation 5 -#define SecCECR_CertificateHold 6 -#define SecCECR_RemoveFromCRL 8 - -/* - * id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 } - * - * SubjectAltName ::= GeneralNames - * - * CSSM OID = CSSMOID_SubjectAltName - * - * GeneralNames defined above. - */ - -/* - * id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37} - * - * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId* - * - * KeyPurposeId ::= OBJECT IDENTIFIER - * - * CSSM OID = CSSMOID_ExtendedKeyUsage - */ -typedef struct { - uint32_t numPurposes; - DERItem *purposes; // in Intel pre-encoded format -} SecCEExtendedKeyUsage; - -/* - * id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 } - * - * BasicConstraints ::= SEQUENCE { - * cA BOOLEAN DEFAULT FALSE, - * pathLenConstraint INTEGER (0..MAX) OPTIONAL } - * - * CSSM OID = CSSMOID_BasicConstraints - */ -typedef struct { - bool present; - bool critical; - bool isCA; - bool pathLenConstraintPresent; - uint32_t pathLenConstraint; -} SecCEBasicConstraints; - -typedef struct { - bool present; - bool critical; - bool requireExplicitPolicyPresent; - uint32_t requireExplicitPolicy; - bool inhibitPolicyMappingPresent; - uint32_t inhibitPolicyMapping; -} SecCEPolicyConstraints; - -/* - * id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 } - * - * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation - * - * PolicyInformation ::= SEQUENCE { - * policyIdentifier CertPolicyId, - * policyQualifiers SEQUENCE SIZE (1..MAX) OF - * PolicyQualifierInfo OPTIONAL } - * - * CertPolicyId ::= OBJECT IDENTIFIER - * - * PolicyQualifierInfo ::= SEQUENCE { - * policyQualifierId PolicyQualifierId, - * qualifier ANY DEFINED BY policyQualifierId } - * - * -- policyQualifierIds for Internet policy qualifiers - * - * id-qt OBJECT IDENTIFIER ::= { id-pkix 2 } - * id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 } - * id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 } - * - * PolicyQualifierId ::= - * OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice ) - * - * Qualifier ::= CHOICE { - * cPSuri CPSuri, - * userNotice UserNotice } - * - * CPSuri ::= IA5String - * - * UserNotice ::= SEQUENCE { - * noticeRef NoticeReference OPTIONAL, - * explicitText DisplayText OPTIONAL} - * - * NoticeReference ::= SEQUENCE { - * organization DisplayText, - * noticeNumbers SEQUENCE OF INTEGER } - * - * DisplayText ::= CHOICE { - * visibleString VisibleString (SIZE (1..200)), - * bmpString BMPString (SIZE (1..200)), - * utf8String UTF8String (SIZE (1..200)) } - * - * CSSM OID = CSSMOID_CertificatePolicies - * - * We only support down to the level of Qualifier, and then only the CPSuri - * choice. UserNotice is transmitted to and from this library as a raw - * CSSM_DATA containing the BER-encoded UserNotice sequence. - */ -#if 0 -typedef struct { - DERItem policyQualifierId; // CSSMOID_QT_CPS, CSSMOID_QT_UNOTICE - DERItem qualifier; // CSSMOID_QT_CPS: IA5String contents - // CSSMOID_QT_UNOTICE : Sequence contents -} SecCEPolicyQualifierInfo; -#endif - -typedef struct { - DERItem policyIdentifier; - DERItem policyQualifiers; -} SecCEPolicyInformation; - -typedef struct { - bool present; - bool critical; - uint32_t numPolicies; // size of *policies; - SecCEPolicyInformation *policies; -} SecCECertificatePolicies; - -typedef struct { - DERItem issuerDomainPolicy; - DERItem subjectDomainPolicy; -} SecCEPolicyMapping; - -/* - PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE { - issuerDomainPolicy CertPolicyId, - subjectDomainPolicy CertPolicyId } -*/ -typedef struct { - bool present; - bool critical; - uint32_t numMappings; // size of *mappings; - SecCEPolicyMapping *mappings; -} SecCEPolicyMappings; - -#if 0 -typedef struct { - bool present; - bool critical; - uint32_t skipCerts; -} SecCEInhibitAnyPolicy; - -/* - * netscape-cert-type, a bit string. - * - * CSSM OID = CSSMOID_NetscapeCertType - * - * Bit fields defined in oidsattr.h: SecCENCT_SSL_Client, etc. - */ -typedef uint16_t SecCENetscapeCertType; - -/* - * CRLDistributionPoints. - * - * id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-ce 31 } - * - * cRLDistributionPoints ::= { - * CRLDistPointsSyntax } - * - * CRLDistPointsSyntax ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint - * - * NOTE: RFC 2459 claims that the tag for the optional DistributionPointName - * is IMPLICIT as shown here, but in practice it is EXPLICIT. It has to be - - * because the underlying type also uses an implicit tag for distinguish - * between CHOICEs. - * - * DistributionPoint ::= SEQUENCE { - * distributionPoint [0] DistributionPointName OPTIONAL, - * reasons [1] ReasonFlags OPTIONAL, - * cRLIssuer [2] GeneralNames OPTIONAL } - * - * DistributionPointName ::= CHOICE { - * fullName [0] GeneralNames, - * nameRelativeToCRLIssuer [1] RelativeDistinguishedName } - * - * ReasonFlags ::= BIT STRING { - * unused (0), - * keyCompromise (1), - * cACompromise (2), - * affiliationChanged (3), - * superseded (4), - * cessationOfOperation (5), - * certificateHold (6) } - * - * CSSM OID = CSSMOID_CrlDistributionPoints - */ - -/* - * Note that this looks similar to SecCECrlReason, but that's an enum and this - * is an OR-able bit string. - */ -typedef uint8_t SecCECrlDistReasonFlags; - -#define SecCECD_Unspecified 0x80 -#define SecCECD_KeyCompromise 0x40 -#define SecCECD_CACompromise 0x20 -#define SecCECD_AffiliationChanged 0x10 -#define SecCECD_Superseded 0x08 -#define SecCECD_CessationOfOperation 0x04 -#define SecCECD_CertificateHold 0x02 - -typedef enum { - SecCECDNT_FullName, - SecCECDNT_NameRelativeToCrlIssuer -} SecCECrlDistributionPointNameType; - -typedef struct { - SecCECrlDistributionPointNameType nameType; - union { - SecCEGeneralNames *fullName; - CSSM_X509_RDN_PTR rdn; - } dpn; -} SecCEDistributionPointName; - -/* - * The top-level CRLDistributionPoint. - * All fields are optional; NULL pointers indicate absence. - */ -typedef struct { - SecCEDistributionPointName *distPointName; - bool reasonsPresent; - SecCECrlDistReasonFlags reasons; - SecCEGeneralNames *crlIssuer; -} SecCECRLDistributionPoint; - -typedef struct { - uint32_t numDistPoints; - SecCECRLDistributionPoint *distPoints; -} SecCECRLDistPointsSyntax; - -/* - * Authority Information Access and Subject Information Access. - * - * CSSM OID = CSSMOID_AuthorityInfoAccess - * CSSM OID = CSSMOID_SubjectInfoAccess - * - * SubjAuthInfoAccessSyntax ::= - * SEQUENCE SIZE (1..MAX) OF AccessDescription - * - * AccessDescription ::= SEQUENCE { - * accessMethod OBJECT IDENTIFIER, - * accessLocation GeneralName } - */ -typedef struct { - DERItem accessMethod; - SecCEGeneralName accessLocation; -} SecCEAccessDescription; - -typedef struct { - uint32_t numAccessDescriptions; - SecCEAccessDescription *accessDescriptions; -} SecCEAuthorityInfoAccess; - -/*** CRL extensions ***/ - -/* - * cRLNumber, an integer. - * - * CSSM OID = CSSMOID_CrlNumber - */ -typedef uint32_t SecCECrlNumber; - -/* - * deltaCRLIndicator, an integer. - * - * CSSM OID = CSSMOID_DeltaCrlIndicator - */ -typedef uint32_t SecCEDeltaCrl; - -/* - * IssuingDistributionPoint - * - * id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 } - * - * issuingDistributionPoint ::= SEQUENCE { - * distributionPoint [0] DistributionPointName OPTIONAL, - * onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE, - * onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE, - * onlySomeReasons [3] ReasonFlags OPTIONAL, - * indirectCRL [4] BOOLEAN DEFAULT FALSE } - * - * CSSM OID = CSSMOID_IssuingDistributionPoint - */ -typedef struct { - SecCEDistributionPointName *distPointName; // optional - bool onlyUserCertsPresent; - bool onlyUserCerts; - bool onlyCACertsPresent; - bool onlyCACerts; - bool onlySomeReasonsPresent; - SecCECrlDistReasonFlags onlySomeReasons; - bool indirectCrlPresent; - bool indirectCrl; -} SecCEIssuingDistributionPoint; - -/* - * An enumerated list identifying one of the above per-extension - * structs. - */ -typedef enum { - DT_AuthorityKeyID, // SecCEAuthorityKeyID - DT_SubjectKeyID, // SecCESubjectKeyID - DT_KeyUsage, // SecCEKeyUsage - DT_SubjectAltName, // implies SecCEGeneralName - DT_IssuerAltName, // implies SecCEGeneralName - DT_ExtendedKeyUsage, // SecCEExtendedKeyUsage - DT_BasicConstraints, // SecCEBasicConstraints - DT_CertPolicies, // SecCECertPolicies - DT_NetscapeCertType, // SecCENetscapeCertType - DT_CrlNumber, // SecCECrlNumber - DT_DeltaCrl, // SecCEDeltaCrl - DT_CrlReason, // SecCECrlReason - DT_CrlDistributionPoints, // SecCECRLDistPointsSyntax - DT_IssuingDistributionPoint,// SecCEIssuingDistributionPoint - DT_AuthorityInfoAccess, // SecCEAuthorityInfoAccess - DT_Other // unknown, raw data as a CSSM_DATA -} SecCEDataType; - -/* - * One unified representation of all the cert adn CRL extensions we know about. - */ -typedef union { - SecCEAuthorityKeyID authorityKeyID; - SecCESubjectKeyID subjectKeyID; - SecCEKeyUsage keyUsage; - SecCEGeneralNames subjectAltName; - SecCEGeneralNames issuerAltName; - SecCEExtendedKeyUsage extendedKeyUsage; - SecCEBasicConstraints basicConstraints; - SecCECertPolicies certPolicies; - SecCENetscapeCertType netscapeCertType; - SecCECrlNumber crlNumber; - SecCEDeltaCrl deltaCrl; - SecCECrlReason crlReason; - SecCECRLDistPointsSyntax crlDistPoints; - SecCEIssuingDistributionPoint issuingDistPoint; - SecCEAuthorityInfoAccess authorityInfoAccess; - DERItem rawData; // unknown, not decoded -} SecCEData; - -typedef struct { - SecCEDataType type; - SecCEData extension; - bool critical; -} SecCEDataAndType; -#endif /* 0 */ - -#endif /* _CERT_EXTENSIONS_H_ */ diff --git a/OSX/libsecurity_keychain/libDER/.gitignore b/OSX/libsecurity_keychain/libDER/.gitignore deleted file mode 100644 index 35cfb4d3..00000000 --- a/OSX/libsecurity_keychain/libDER/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.DS_Store -xcuserdata -project.xcworkspace diff --git a/OSX/libsecurity_keychain/libDER/README.txt b/OSX/libsecurity_keychain/libDER/README.txt deleted file mode 100644 index e3e6fb18..00000000 --- a/OSX/libsecurity_keychain/libDER/README.txt +++ /dev/null @@ -1,34 +0,0 @@ - libDER Library Notes - Last update to this file Jan. 26 2006 by dmitch - -This module is a very lightweight implementation of a DER encoder and -decoder. Unlike most other DER packages, this one does no malloc or -copies when it encodes or decodes; decoding an item yields a pointer -and a byte count which refer to memory inside of the "thing" being -decoded. Likewise, when encoding, the caller mustsupply a target buffer -to which the encoded item is written. - -Support for encoding sequences and for decoding sequences and sets of -known items is also included; when you decode a sequence, you get a -sequence of pointers and byte counts - again, no mallocs or copies occur. - -The directory libDER contains the DER decoding library proper. The main -API is in DER_Decode.h. Support for RSA keys, X509 certs, X509 CRLs, and -miscellaneous OIDs can also be found in libDER. - -Command line programs to parse and display the contents of X509 certificates -and CRLs, using libDER, can be found in the Tests directory. - -Revision History ----------------- - - Date svk tag Changes --------- ----------- ---------------------------------------- -01/26/06 libDER-5 Avoid varargs macros for portability. -01/03/06 libDER-4 Initial distribution in RSACertLib. -12/23/05 libDER-3 Fix DER_DECODE_ENABLE ifdef for DER_Decode.c. - Add MD2, MD5 OID and DigestInfo capabilities. -12/13/05 libDER-2 Added Apple Custom RSA public key formats. - Added PKCS1 RSA private keys. -11/28/05 libDER-1 Initial tag. - diff --git a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/EndCertificateCP.01.01.crt b/OSX/libsecurity_keychain/libDER/Tests/certsCrls/EndCertificateCP.01.01.crt deleted file mode 100644 index d7e64d6d..00000000 Binary files a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/EndCertificateCP.01.01.crt and /dev/null differ diff --git a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/Test_CRL_CA1.crl b/OSX/libsecurity_keychain/libDER/Tests/certsCrls/Test_CRL_CA1.crl deleted file mode 100644 index 66510d35..00000000 Binary files a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/Test_CRL_CA1.crl and /dev/null differ diff --git a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/Test_CRL_CA1.crl.pem b/OSX/libsecurity_keychain/libDER/Tests/certsCrls/Test_CRL_CA1.crl.pem deleted file mode 100644 index 6a4ed3f1..00000000 --- a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/Test_CRL_CA1.crl.pem +++ /dev/null @@ -1,13 +0,0 @@ ------BEGIN X509 CRL----- -MIIB3zCByDANBgkqhkiG9w0BAQQFADBvMQswCQYDVQQGEwJkZTEgMB4GA1UEChMX -SW5zZWN1cmVUZXN0Q2VydGlmaWNhdGUxFzAVBgNVBAMTDkZvciBUZXN0cyBPbmx5 -MSUwIwYJKoZIhvcNAQkBFhZpbnNlY3VyZUB0ZXN0Lmluc2VjdXJlFw0wMTA4MTcx -MTEyMDNaFw0wNjA4MTYxMTEyMDNaMCgwEgIBAxcNMDEwODE3MTExMDM5WjASAgEF -Fw0wMTA4MTcxMTExNTlaMA0GCSqGSIb3DQEBBAUAA4IBAQB47lMVCKlPoBAgLway -76eNRq1749jt/7g/Ouh06isNM66/CgzVL2xKSC3s2FX4xKg320niWI6Dvm4H3M6I -7RvuoCvZBVpu1MA8z2No89g2UPWlSxUAvuvo2GOGRgo+8nc/84g8biLUxTSF8Vs4 -T1Hngo1qrfePM4ou1uu7LhRnR8tuIVoQT6W3RSlEsQRBRM3y+VkOPAf0GBGyl6WG -WiymXHqsqis80WbX50tr859Cltqbu2yaFAX++IEBBDB7JoVi1blumgarqfXYkoUW -n9d3F8qySNjsfhOV613fXpmfXFZ33uTFsLSoihP8f6+Cusx2rfuGap7jOPv7j7sj -l2Y1 ------END X509 CRL----- diff --git a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/TrustAnchorCP.01.01.crt b/OSX/libsecurity_keychain/libDER/Tests/certsCrls/TrustAnchorCP.01.01.crt deleted file mode 100644 index d7dfd9d4..00000000 Binary files a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/TrustAnchorCP.01.01.crt and /dev/null differ diff --git a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/TrustAnchorCRLCP.01.01.crl b/OSX/libsecurity_keychain/libDER/Tests/certsCrls/TrustAnchorCRLCP.01.01.crl deleted file mode 100644 index de65024a..00000000 Binary files a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/TrustAnchorCRLCP.01.01.crl and /dev/null differ diff --git a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/apple_v3.000.cer b/OSX/libsecurity_keychain/libDER/Tests/certsCrls/apple_v3.000.cer deleted file mode 100644 index f8705ff1..00000000 Binary files a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/apple_v3.000.cer and /dev/null differ diff --git a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/apple_v3.001.cer b/OSX/libsecurity_keychain/libDER/Tests/certsCrls/apple_v3.001.cer deleted file mode 100644 index 1c84d8b5..00000000 Binary files a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/apple_v3.001.cer and /dev/null differ diff --git a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/entrust_v3.100.cer b/OSX/libsecurity_keychain/libDER/Tests/certsCrls/entrust_v3.100.cer deleted file mode 100644 index 6956bf38..00000000 Binary files a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/entrust_v3.100.cer and /dev/null differ diff --git a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/entrust_v3.101.cer b/OSX/libsecurity_keychain/libDER/Tests/certsCrls/entrust_v3.101.cer deleted file mode 100644 index 4e45016b..00000000 Binary files a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/entrust_v3.101.cer and /dev/null differ diff --git a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/keybank_v3.100.cer b/OSX/libsecurity_keychain/libDER/Tests/certsCrls/keybank_v3.100.cer deleted file mode 100644 index 21f98293..00000000 Binary files a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/keybank_v3.100.cer and /dev/null differ diff --git a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/keybank_v3.101.cer b/OSX/libsecurity_keychain/libDER/Tests/certsCrls/keybank_v3.101.cer deleted file mode 100644 index 1c84d8b5..00000000 Binary files a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/keybank_v3.101.cer and /dev/null differ diff --git a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/keybank_v3.102.cer b/OSX/libsecurity_keychain/libDER/Tests/certsCrls/keybank_v3.102.cer deleted file mode 100644 index c61d2958..00000000 Binary files a/OSX/libsecurity_keychain/libDER/Tests/certsCrls/keybank_v3.102.cer and /dev/null differ diff --git a/OSX/libsecurity_keychain/libDER/libDER/DER_CertCrl.c b/OSX/libsecurity_keychain/libDER/libDER/DER_CertCrl.c deleted file mode 100644 index d971650b..00000000 --- a/OSX/libsecurity_keychain/libDER/libDER/DER_CertCrl.c +++ /dev/null @@ -1,370 +0,0 @@ -/* - * Copyright (c) 2005-2009,2011,2014 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -/* - * DER_Cert.c - support for decoding X509 certificates - * - */ - -#include -#include -#include -#include - -/* - * DERItemSpecs for X509 certificates. - */ - -/* top level cert with three components */ -const DERItemSpec DERSignedCertCrlItemSpecs[] = -{ - { DER_OFFSET(DERSignedCertCrl, tbs), - ASN1_CONSTR_SEQUENCE, - DER_DEC_NO_OPTS | DER_DEC_SAVE_DER}, - { DER_OFFSET(DERSignedCertCrl, sigAlg), - ASN1_CONSTR_SEQUENCE, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERSignedCertCrl, sig), - ASN1_BIT_STRING, - DER_DEC_NO_OPTS } -}; - -const DERSize DERNumSignedCertCrlItemSpecs = - sizeof(DERSignedCertCrlItemSpecs) / sizeof(DERItemSpec); - -/* TBS cert */ -const DERItemSpec DERTBSCertItemSpecs[] = -{ - { DER_OFFSET(DERTBSCert, version), - ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 0, - DER_DEC_OPTIONAL }, /* version - EXPLICIT */ - { DER_OFFSET(DERTBSCert, serialNum), - ASN1_INTEGER, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERTBSCert, tbsSigAlg), - ASN1_CONSTR_SEQUENCE, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERTBSCert, issuer), - ASN1_CONSTR_SEQUENCE, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERTBSCert, validity), - ASN1_CONSTR_SEQUENCE, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERTBSCert, subject), - ASN1_CONSTR_SEQUENCE, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERTBSCert, subjectPubKey), - ASN1_CONSTR_SEQUENCE, - DER_DEC_NO_OPTS | DER_DEC_SAVE_DER | DER_ENC_WRITE_DER }, - /* libsecurity_asn1 has these two as CONSTRUCTED, but the ASN.1 spec - * doesn't look that way to me. I don't have any certs that have these - * fields.... */ - { DER_OFFSET(DERTBSCert, issuerID), - ASN1_CONTEXT_SPECIFIC | 1, - DER_DEC_OPTIONAL }, - { DER_OFFSET(DERTBSCert, subjectID), - ASN1_CONTEXT_SPECIFIC | 2, - DER_DEC_OPTIONAL }, - { DER_OFFSET(DERTBSCert, extensions), - ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 3, - DER_DEC_OPTIONAL } -}; -const DERSize DERNumTBSCertItemSpecs = sizeof(DERTBSCertItemSpecs) / sizeof(DERItemSpec); - -/* DERValidity */ -const DERItemSpec DERValidityItemSpecs[] = -{ - { DER_OFFSET(DERValidity, notBefore), - 0, /* no tag - ANY */ - DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }, - { DER_OFFSET(DERValidity, notAfter), - 0, /* no tag - ANY */ - DER_DEC_ASN_ANY | DER_DEC_SAVE_DER } -}; -const DERSize DERNumValidityItemSpecs = - sizeof(DERValidityItemSpecs) / sizeof(DERItemSpec); - -/* DERAttributeTypeAndValue */ -const DERItemSpec DERAttributeTypeAndValueItemSpecs[] = { - { DER_OFFSET(DERAttributeTypeAndValue, type), - ASN1_OBJECT_ID, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERAttributeTypeAndValue, value), - 0, /* no tag - ANY */ - DER_DEC_ASN_ANY | DER_DEC_SAVE_DER } -}; - -const DERSize DERNumAttributeTypeAndValueItemSpecs = - sizeof(DERAttributeTypeAndValueItemSpecs) / sizeof(DERItemSpec); - -/* DERExtension */ -const DERItemSpec DERExtensionItemSpecs[] = -{ - { DER_OFFSET(DERExtension, extnID), - ASN1_OBJECT_ID, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERExtension, critical), - ASN1_BOOLEAN, - DER_DEC_OPTIONAL }, - { DER_OFFSET(DERExtension, extnValue), - ASN1_OCTET_STRING, - DER_DEC_NO_OPTS } -}; -const DERSize DERNumExtensionItemSpecs = - sizeof(DERExtensionItemSpecs) / sizeof(DERItemSpec); - -/* DERBasicConstraints */ -const DERItemSpec DERBasicConstraintsItemSpecs[] = -{ - { DER_OFFSET(DERBasicConstraints, cA), - ASN1_BOOLEAN, - DER_DEC_OPTIONAL }, - { DER_OFFSET(DERBasicConstraints, pathLenConstraint), - ASN1_INTEGER, - DER_DEC_OPTIONAL } -}; -const DERSize DERNumBasicConstraintsItemSpecs = - sizeof(DERBasicConstraintsItemSpecs) / sizeof(DERItemSpec); - -/* DERNameConstraints. */ -const DERItemSpec DERNameConstraintsItemSpecs[] = -{ - { DER_OFFSET(DERNameConstraints, permittedSubtrees), - ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0, - DER_DEC_OPTIONAL }, - { DER_OFFSET(DERNameConstraints, excludedSubtrees), - ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1, - DER_DEC_OPTIONAL } -}; -const DERSize DERNumNameConstraintsItemSpecs = -sizeof(DERNameConstraintsItemSpecs) /sizeof(DERItemSpec); - -/* DERGeneralSubtree. */ -const DERItemSpec DERGeneralSubtreeItemSpecs[] = -{ - { DER_OFFSET(DERGeneralSubtree, generalName), - 0, /* no tag - ANY */ - DER_DEC_ASN_ANY | DER_DEC_SAVE_DER}, - { DER_OFFSET(DERGeneralSubtree, minimum), - ASN1_CONTEXT_SPECIFIC | 0, - DER_DEC_OPTIONAL}, - { DER_OFFSET(DERGeneralSubtree, maximum), - ASN1_CONTEXT_SPECIFIC | 1, - DER_DEC_OPTIONAL } -}; -const DERSize DERNumGeneralSubtreeItemSpecs = -sizeof(DERGeneralSubtreeItemSpecs) /sizeof(DERItemSpec); - -/* DERPrivateKeyUsagePeriod. */ -const DERItemSpec DERPrivateKeyUsagePeriodItemSpecs[] = -{ - { DER_OFFSET(DERPrivateKeyUsagePeriod, notBefore), - ASN1_CONTEXT_SPECIFIC | 0, - DER_DEC_OPTIONAL }, - { DER_OFFSET(DERPrivateKeyUsagePeriod, notAfter), - ASN1_CONTEXT_SPECIFIC | 1, - DER_DEC_OPTIONAL } -}; -const DERSize DERNumPrivateKeyUsagePeriodItemSpecs = - sizeof(DERPrivateKeyUsagePeriodItemSpecs) / sizeof(DERItemSpec); - -/* DERDistributionPoint. */ -const DERItemSpec DERDistributionPointItemSpecs[] = -{ - { DER_OFFSET(DERDistributionPoint, distributionPoint), - ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0, - DER_DEC_OPTIONAL }, - { DER_OFFSET(DERDistributionPoint, reasons), - ASN1_CONTEXT_SPECIFIC | 1, - DER_DEC_OPTIONAL }, - { DER_OFFSET(DERDistributionPoint, cRLIssuer), - ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 2, - DER_DEC_OPTIONAL } -}; -const DERSize DERNumDistributionPointItemSpecs = - sizeof(DERDistributionPointItemSpecs) / sizeof(DERItemSpec); - -/* DERPolicyInformation. */ -const DERItemSpec DERPolicyInformationItemSpecs[] = -{ - { DER_OFFSET(DERPolicyInformation, policyIdentifier), - ASN1_OBJECT_ID, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERPolicyInformation, policyQualifiers), - ASN1_CONSTR_SEQUENCE, - DER_DEC_OPTIONAL } -}; -const DERSize DERNumPolicyInformationItemSpecs = - sizeof(DERPolicyInformationItemSpecs) / sizeof(DERItemSpec); - -/* DERPolicyQualifierInfo. */ -const DERItemSpec DERPolicyQualifierInfoItemSpecs[] = -{ - { DER_OFFSET(DERPolicyQualifierInfo, policyQualifierID), - ASN1_OBJECT_ID, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERPolicyQualifierInfo, qualifier), - 0, /* no tag - ANY */ - DER_DEC_ASN_ANY | DER_DEC_SAVE_DER } -}; -const DERSize DERNumPolicyQualifierInfoItemSpecs = - sizeof(DERPolicyQualifierInfoItemSpecs) / sizeof(DERItemSpec); - -/* DERUserNotice. */ -const DERItemSpec DERUserNoticeItemSpecs[] = -{ - { DER_OFFSET(DERUserNotice, noticeRef), - ASN1_CONSTR_SEQUENCE, - DER_DEC_OPTIONAL }, - { DER_OFFSET(DERUserNotice, explicitText), - 0, /* no tag - ANY */ - DER_DEC_ASN_ANY | DER_DEC_OPTIONAL | DER_DEC_SAVE_DER } -}; -const DERSize DERNumUserNoticeItemSpecs = - sizeof(DERUserNoticeItemSpecs) / sizeof(DERItemSpec); - -/* DERNoticeReference. */ -const DERItemSpec DERNoticeReferenceItemSpecs[] = -{ - { DER_OFFSET(DERNoticeReference, organization), - 0, /* no tag - ANY */ - DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }, - { DER_OFFSET(DERNoticeReference, noticeNumbers), - ASN1_CONSTR_SEQUENCE, - DER_DEC_NO_OPTS } -}; -const DERSize DERNumNoticeReferenceItemSpecs = - sizeof(DERNoticeReferenceItemSpecs) / sizeof(DERItemSpec); - -/* DERPolicyMapping. */ -const DERItemSpec DERPolicyMappingItemSpecs[] = -{ - { DER_OFFSET(DERPolicyMapping, issuerDomainPolicy), - ASN1_OBJECT_ID, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERPolicyMapping, subjectDomainPolicy), - ASN1_OBJECT_ID, - DER_DEC_NO_OPTS } -}; -const DERSize DERNumPolicyMappingItemSpecs = - sizeof(DERPolicyMappingItemSpecs) / sizeof(DERItemSpec); - -/* DERAccessDescription. */ -const DERItemSpec DERAccessDescriptionItemSpecs[] = -{ - { DER_OFFSET(DERAccessDescription, accessMethod), - ASN1_OBJECT_ID, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERAccessDescription, accessLocation), - 0, /* no tag - ANY */ - DER_DEC_ASN_ANY | DER_DEC_SAVE_DER } -}; -const DERSize DERNumAccessDescriptionItemSpecs = - sizeof(DERAccessDescriptionItemSpecs) / sizeof(DERItemSpec); - -/* DERAuthorityKeyIdentifier. */ -const DERItemSpec DERAuthorityKeyIdentifierItemSpecs[] = -{ - { DER_OFFSET(DERAuthorityKeyIdentifier, keyIdentifier), - ASN1_CONTEXT_SPECIFIC | 0, - DER_DEC_OPTIONAL }, - { DER_OFFSET(DERAuthorityKeyIdentifier, authorityCertIssuer), - ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1, - DER_DEC_OPTIONAL }, - { DER_OFFSET(DERAuthorityKeyIdentifier, authorityCertSerialNumber), - ASN1_CONTEXT_SPECIFIC | 2, - DER_DEC_OPTIONAL } -}; -const DERSize DERNumAuthorityKeyIdentifierItemSpecs = - sizeof(DERAuthorityKeyIdentifierItemSpecs) / sizeof(DERItemSpec); - -/* DEROtherName. */ -const DERItemSpec DEROtherNameItemSpecs[] = -{ - { DER_OFFSET(DEROtherName, typeIdentifier), - ASN1_OBJECT_ID, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DEROtherName, value), - ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0, - DER_DEC_NO_OPTS }, -}; -const DERSize DERNumOtherNameItemSpecs = - sizeof(DEROtherNameItemSpecs) / sizeof(DERItemSpec); - -/* DERPolicyConstraints. */ -const DERItemSpec DERPolicyConstraintsItemSpecs[] = -{ - { DER_OFFSET(DERPolicyConstraints, requireExplicitPolicy), - ASN1_CONTEXT_SPECIFIC | 0, - DER_DEC_OPTIONAL }, - { DER_OFFSET(DERPolicyConstraints, inhibitPolicyMapping), - ASN1_CONTEXT_SPECIFIC | 1, - DER_DEC_OPTIONAL } -}; -const DERSize DERNumPolicyConstraintsItemSpecs = - sizeof(DERPolicyConstraintsItemSpecs) / sizeof(DERItemSpec); - -/* DERTBSCrl */ -const DERItemSpec DERTBSCrlItemSpecs[] = -{ - { DER_OFFSET(DERTBSCrl, version), - ASN1_INTEGER, - DER_DEC_OPTIONAL }, - { DER_OFFSET(DERTBSCrl, tbsSigAlg), - ASN1_CONSTR_SEQUENCE, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERTBSCrl, issuer), - ASN1_CONSTR_SEQUENCE, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERTBSCrl, thisUpdate), - 0, /* no tag - ANY */ - DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }, - { DER_OFFSET(DERTBSCrl, nextUpdate), - 0, /* no tag - ANY */ - DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }, - { DER_OFFSET(DERTBSCrl, revokedCerts), - ASN1_CONSTR_SEQUENCE, - DER_DEC_OPTIONAL }, - { DER_OFFSET(DERTBSCrl, extensions), - ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 0, - DER_DEC_OPTIONAL } -}; -const DERSize DERNumTBSCrlItemSpecs = sizeof(DERTBSCrlItemSpecs) / sizeof(DERItemSpec); - -/* DERRevokedCert */ -const DERItemSpec DERRevokedCertItemSpecs[] = -{ - { DER_OFFSET(DERRevokedCert, serialNum), - ASN1_INTEGER, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERRevokedCert, revocationDate), - 0, /* no tag - ANY */ - DER_DEC_ASN_ANY | DER_DEC_SAVE_DER }, - { DER_OFFSET(DERRevokedCert, extensions), - ASN1_CONSTR_SEQUENCE, - DER_DEC_OPTIONAL } -}; - -const DERSize DERNumRevokedCertItemSpecs = - sizeof(DERRevokedCertItemSpecs) / sizeof(DERItemSpec); diff --git a/OSX/libsecurity_keychain/libDER/libDER/DER_CertCrl.h b/OSX/libsecurity_keychain/libDER/libDER/DER_CertCrl.h deleted file mode 100644 index db36e5cc..00000000 --- a/OSX/libsecurity_keychain/libDER/libDER/DER_CertCrl.h +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (c) 2005-2016 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -/* - * DER_CertCrl.h - support for decoding X509 certificates and CRLs - * - */ - -#ifndef _DER_CERT_CRL_H_ -#define _DER_CERT_CRL_H_ - -#include -#include - -__BEGIN_DECLS - -/* - * Top level cert or CRL - the two are identical at this level - three - * components. The tbs field is saved in full DER form for sig verify. - */ -typedef struct { - DERItem tbs; /* sequence, DERTBSCert, DER_DEC_SAVE_DER */ - DERItem sigAlg; /* sequence, DERAlgorithmId */ - DERItem sig; /* bit string */ -} DERSignedCertCrl; - -/* DERItemSpecs to decode into a DERSignedCertCrl */ -extern const DERItemSpec DERSignedCertCrlItemSpecs[]; -extern const DERSize DERNumSignedCertCrlItemSpecs; - -/* TBS cert components */ -typedef struct { - DERItem version; /* integer, optional, EXPLICIT */ - DERItem serialNum; /* integer */ - DERItem tbsSigAlg; /* sequence, DERAlgorithmId */ - DERItem issuer; /* sequence, TBD */ - DERItem validity; /* sequence, DERValidity */ - DERItem subject; /* sequence, TBD */ - DERItem subjectPubKey; /* sequence, DERSubjPubKeyInfo */ - DERItem issuerID; /* bit string, optional */ - DERItem subjectID; /* bit string, optional */ - DERItem extensions; /* sequence, optional, EXPLICIT */ -} DERTBSCert; - -/* DERItemSpecs to decode into a DERTBSCert */ -extern const DERItemSpec DERTBSCertItemSpecs[]; -extern const DERSize DERNumTBSCertItemSpecs; - -/* - * validity - components can be either UTC or generalized time. - * Both are ASN_ANY with DER_DEC_SAVE_DER. - */ -typedef struct { - DERItem notBefore; - DERItem notAfter; -} DERValidity; - -/* DERItemSpecs to decode into a DERValidity */ -extern const DERItemSpec DERValidityItemSpecs[]; -extern const DERSize DERNumValidityItemSpecs; - -/* AttributeTypeAndValue components. */ -typedef struct { - DERItem type; - DERItem value; -} DERAttributeTypeAndValue; - -/* DERItemSpecs to decode into DERAttributeTypeAndValue */ -extern const DERItemSpec DERAttributeTypeAndValueItemSpecs[]; -extern const DERSize DERNumAttributeTypeAndValueItemSpecs; - -/* Extension components */ -typedef struct { - DERItem extnID; - DERItem critical; - DERItem extnValue; -} DERExtension; - -/* DERItemSpecs to decode into DERExtension */ -extern const DERItemSpec DERExtensionItemSpecs[]; -extern const DERSize DERNumExtensionItemSpecs; - -/* BasicConstraints components. */ -typedef struct { - DERItem cA; - DERItem pathLenConstraint; -} DERBasicConstraints; - -/* DERItemSpecs to decode into DERBasicConstraints */ -extern const DERItemSpec DERBasicConstraintsItemSpecs[]; -extern const DERSize DERNumBasicConstraintsItemSpecs; - -/* NameConstraints components. */ -typedef struct { - DERItem permittedSubtrees; - DERItem excludedSubtrees; -} DERNameConstraints; - -/* DERItemSpecs to decode into a DERNameConstraints */ -extern const DERItemSpec DERNameConstraintsItemSpecs[]; -extern const DERSize DERNumNameConstraintsItemSpecs; - -/* GeneralSubtree components. */ -typedef struct { - DERItem generalName; - DERItem minimum; - DERItem maximum; -} DERGeneralSubtree; - -/* DERItemSpecs to decode into a DERGeneralSubtree */ -extern const DERItemSpec DERGeneralSubtreeItemSpecs[]; -extern const DERSize DERNumGeneralSubtreeItemSpecs; - -/* PrivateKeyUsagePeriod components. */ -typedef struct { - DERItem notBefore; - DERItem notAfter; -} DERPrivateKeyUsagePeriod; - -/* DERItemSpecs to decode into a DERPrivateKeyUsagePeriod */ -extern const DERItemSpec DERPrivateKeyUsagePeriodItemSpecs[]; -extern const DERSize DERNumPrivateKeyUsagePeriodItemSpecs; - -/* DistributionPoint components. */ -typedef struct { - DERItem distributionPoint; - DERItem reasons; - DERItem cRLIssuer; -} DERDistributionPoint; - -/* DERItemSpecs to decode into a DERDistributionPoint */ -extern const DERItemSpec DERDistributionPointItemSpecs[]; -extern const DERSize DERNumDistributionPointItemSpecs; - -/* PolicyInformation components. */ -typedef struct { - DERItem policyIdentifier; - DERItem policyQualifiers; -} DERPolicyInformation; - -/* DERItemSpecs to decode into a DERPolicyInformation */ -extern const DERItemSpec DERPolicyInformationItemSpecs[]; -extern const DERSize DERNumPolicyInformationItemSpecs; - -/* PolicyQualifierInfo components. */ -typedef struct { - DERItem policyQualifierID; - DERItem qualifier; -} DERPolicyQualifierInfo; - -/* DERItemSpecs to decode into a DERPolicyQualifierInfo */ -extern const DERItemSpec DERPolicyQualifierInfoItemSpecs[]; -extern const DERSize DERNumPolicyQualifierInfoItemSpecs; - -/* UserNotice components. */ -typedef struct { - DERItem noticeRef; - DERItem explicitText; -} DERUserNotice; - -/* DERItemSpecs to decode into a DERUserNotice */ -extern const DERItemSpec DERUserNoticeItemSpecs[]; -extern const DERSize DERNumUserNoticeItemSpecs; - -/* NoticeReference components. */ -typedef struct { - DERItem organization; - DERItem noticeNumbers; -} DERNoticeReference; - -/* DERItemSpecs to decode into a DERNoticeReference */ -extern const DERItemSpec DERNoticeReferenceItemSpecs[]; -extern const DERSize DERNumNoticeReferenceItemSpecs; - -/* PolicyMapping components. */ -typedef struct { - DERItem issuerDomainPolicy; - DERItem subjectDomainPolicy; -} DERPolicyMapping; - -/* DERItemSpecs to decode into a DERPolicyMapping */ -extern const DERItemSpec DERPolicyMappingItemSpecs[]; -extern const DERSize DERNumPolicyMappingItemSpecs; - -/* AccessDescription components. */ -typedef struct { - DERItem accessMethod; - DERItem accessLocation; -} DERAccessDescription; - -/* DERItemSpecs to decode into a DERAccessDescription */ -extern const DERItemSpec DERAccessDescriptionItemSpecs[]; -extern const DERSize DERNumAccessDescriptionItemSpecs; - -/* AuthorityKeyIdentifier components. */ -typedef struct { - DERItem keyIdentifier; - DERItem authorityCertIssuer; - DERItem authorityCertSerialNumber; -} DERAuthorityKeyIdentifier; - -/* DERItemSpecs to decode into a DERAuthorityKeyIdentifier */ -extern const DERItemSpec DERAuthorityKeyIdentifierItemSpecs[]; -extern const DERSize DERNumAuthorityKeyIdentifierItemSpecs; - -/* OtherName components. */ -typedef struct { - DERItem typeIdentifier; - DERItem value; -} DEROtherName; - -/* DERItemSpecs to decode into a DEROtherName */ -extern const DERItemSpec DEROtherNameItemSpecs[]; -extern const DERSize DERNumOtherNameItemSpecs; - -/* PolicyConstraints components. */ -typedef struct { - DERItem requireExplicitPolicy; - DERItem inhibitPolicyMapping; -} DERPolicyConstraints; - -/* DERItemSpecs to decode into a DERPolicyConstraints */ -extern const DERItemSpec DERPolicyConstraintsItemSpecs[]; -extern const DERSize DERNumPolicyConstraintsItemSpecs; - -/* TBS CRL */ -typedef struct { - DERItem version; /* integer, optional */ - DERItem tbsSigAlg; /* sequence, DERAlgorithmId */ - DERItem issuer; /* sequence, TBD */ - DERItem thisUpdate; /* ASN_ANY, SAVE_DER */ - DERItem nextUpdate; /* ASN_ANY, SAVE_DER */ - DERItem revokedCerts; /* sequence of DERRevokedCert, optional */ - DERItem extensions; /* sequence, optional, EXPLICIT */ -} DERTBSCrl; - -/* DERItemSpecs to decode into a DERTBSCrl */ -extern const DERItemSpec DERTBSCrlItemSpecs[]; -extern const DERSize DERNumTBSCrlItemSpecs; - -typedef struct { - DERItem serialNum; /* integer */ - DERItem revocationDate; /* time - ASN_ANY, SAVE_DER */ - DERItem extensions; /* sequence, optional, EXPLICIT */ -} DERRevokedCert; - -/* DERItemSpecs to decode into a DERRevokedCert */ -extern const DERItemSpec DERRevokedCertItemSpecs[]; -extern const DERSize DERNumRevokedCertItemSpecs; - -__END_DECLS - -#endif /* _DER_CERT_CRL_H_ */ - diff --git a/OSX/libsecurity_keychain/libDER/libDER/DER_Decode.c b/OSX/libsecurity_keychain/libDER/libDER/DER_Decode.c deleted file mode 100644 index 04374a35..00000000 --- a/OSX/libsecurity_keychain/libDER/libDER/DER_Decode.c +++ /dev/null @@ -1,759 +0,0 @@ -/* - * Copyright (c) 2005-2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * DER_Decode.c - DER decoding routines - */ - -#include -#include - -#include - -#ifndef DER_DECODE_ENABLE -#error Please define DER_DECODE_ENABLE. -#endif - -#if DER_DECODE_ENABLE - -#define DER_DECODE_DEBUG 0 -#if DER_DECODE_DEBUG -#include -#define derDecDbg(a) printf(a) -#define derDecDbg1(a, b) printf(a, b) -#define derDecDbg2(a, b, c) printf(a, b, c) -#define derDecDbg3(a, b, c, d) printf(a, b, c, d) -#else -#define derDecDbg(a) -#define derDecDbg1(a, b) -#define derDecDbg2(a, b, c) -#define derDecDbg3(a, b, c, d) -#endif /* DER_DECODE_DEBUG */ - -/* - * Basic decoding primitive. Only works with: - * - * -- definite length encoding - * -- one-byte tags (unless DER_MULTIBYTE_TAGS is defined) - * -- max content length fits in a DERSize - * - * No malloc or copy of the contents is performed; the returned - * content->content.data is a pointer into the incoming der data. - */ -DERReturn DERDecodeItem( - const DERItem *der, /* data to decode */ - DERDecodedInfo *decoded) /* RETURNED */ -{ - return DERDecodeItemPartialBufferGetLength(der, decoded, NULL); -} - -/* - * Basic decoding primitive. Allows for decoding with a partial buffer. - * if allowPartialBuffer is true. A partial buffer would normally fail - * because the encoded length would be greater than the size of the buffer passed in. - * Only works with: - * - * -- definite length encoding - * -- one-byte tags (unless DER_MULTIBYTE_TAGS is defined) - * -- max content length fits in a DERSize - * - * No malloc or copy of the contents is performed; the returned - * content->content.data is a pointer into the incoming der data. - * - * WARNING: Using a partial buffer can return a DERDecodedInfo object with - * a length larger than the buffer. It is recommended to instead use - * DERDecodeItemPartialBufferGetLength if you need partial buffers. - * - */ -DERReturn DERDecodeItemPartialBuffer( - const DERItem *der, /* data to decode */ - DERDecodedInfo *decoded, /* RETURNED */ - bool allowPartialBuffer) -{ - DERByte tag1; /* first tag byte */ - DERByte len1; /* first length byte */ - DERTag tagNumber; /* tag number without class and method bits */ - DERByte *derPtr = der->data; - DERSize derLen = der->length; - - /* The tag decoding below is fully BER complient. We support a max tag - value of 2 ^ ((sizeof(DERTag) * 8) - 3) - 1 so for tag size 1 byte we - support tag values from 0 - 0x1F. For tag size 2 tag values - from 0 - 0x1FFF and for tag size 4 values from 0 - 0x1FFFFFFF. */ - if(derLen < 2) { - return DR_DecodeError; - } - /* Grab the first byte of the tag. */ - tag1 = *derPtr++; - derLen--; - tagNumber = tag1 & 0x1F; - if(tagNumber == 0x1F) { -#ifdef DER_MULTIBYTE_TAGS - /* Long tag form: bit 8 of each octet shall be set to one unless it is - the last octet of the tag */ - const DERTag overflowMask = ((DERTag)0x7F << (sizeof(DERTag) * 8 - 7)); - DERByte tagByte; - tagNumber = 0; - if (*derPtr == 0x80 || *derPtr < 0x1F) - return DR_DecodeError; - do { - if(derLen < 2 || (tagNumber & overflowMask) != 0) { - return DR_DecodeError; - } - tagByte = *derPtr++; - derLen--; - tagNumber = (tagNumber << 7) | (tagByte & 0x7F); - } while((tagByte & 0x80) != 0); - - /* Check for any of the top 3 reserved bits being set. */ - if ((tagNumber & (overflowMask << 4)) != 0) -#endif - return DR_DecodeError; - } - /* Returned tag, top 3 bits are class/method remaining bits are number. */ - decoded->tag = ((DERTag)(tag1 & 0xE0) << ((sizeof(DERTag) - 1) * 8)) | tagNumber; - - /* Tag decoding above ensured we have at least one more input byte left. */ - len1 = *derPtr++; - derLen--; - if(len1 & 0x80) { - /* long length form - first byte is length of length */ - DERSize longLen = 0; /* long form length */ - - unsigned dex; - len1 &= 0x7f; - if((len1 > sizeof(DERSize)) || (len1 > derLen) || len1 == 0 || *derPtr == 0) { - /* no can do */ - return DR_DecodeError; - } - for(dex=0; dex derLen && !allowPartialBuffer) { - /* not enough data left for this encoding */ - return DR_DecodeError; - } - decoded->content.data = derPtr; - decoded->content.length = longLen; - } - else { - /* short length form, len1 is the length */ - if(len1 > derLen && !allowPartialBuffer) { - /* not enough data left for this encoding */ - return DR_DecodeError; - } - decoded->content.data = derPtr; - decoded->content.length = len1; - } - - return DR_Success; -} - -/* - * Same as above, but returns a DERDecodedInfo with a length no larger than the buffer. - * The actual encoded length can be retrieved from encodedLength parameter. - * encodedLength can be NULL to achieve the same behavior as DERDecodeItemPartialBuffer, - * with allowPartialBuffer=false - * - * NOTE: The DERDecoded length will never be larger than the input buffer. - * This is a key difference from DERDecodeItemPartialBuffer which could return invalid length. - * - */ -DERReturn DERDecodeItemPartialBufferGetLength( - const DERItem *der, /* data to decode */ - DERDecodedInfo *decoded, /* RETURNED */ - DERSize *encodedLength) -{ - DERByte tag1; /* first tag byte */ - DERByte len1; /* first length byte */ - DERTag tagNumber; /* tag number without class and method bits */ - DERByte *derPtr = der->data; - DERSize derLen = der->length; - - /* The tag decoding below is fully BER complient. We support a max tag - value of 2 ^ ((sizeof(DERTag) * 8) - 3) - 1 so for tag size 1 byte we - support tag values from 0 - 0x1F. For tag size 2 tag values - from 0 - 0x1FFF and for tag size 4 values from 0 - 0x1FFFFFFF. */ - if(derLen < 2) { - return DR_DecodeError; - } - /* Grab the first byte of the tag. */ - tag1 = *derPtr++; - derLen--; - tagNumber = tag1 & 0x1F; - if(tagNumber == 0x1F) { -#ifdef DER_MULTIBYTE_TAGS - /* Long tag form: bit 8 of each octet shall be set to one unless it is - the last octet of the tag */ - const DERTag overflowMask = ((DERTag)0x7F << (sizeof(DERTag) * 8 - 7)); - DERByte tagByte; - tagNumber = 0; - if (*derPtr == 0x80 || *derPtr < 0x1F) - return DR_DecodeError; - do { - if(derLen < 2 || (tagNumber & overflowMask) != 0) { - return DR_DecodeError; - } - tagByte = *derPtr++; - derLen--; - tagNumber = (tagNumber << 7) | (tagByte & 0x7F); - } while((tagByte & 0x80) != 0); - - /* Check for any of the top 3 reserved bits being set. */ - if ((tagNumber & (overflowMask << 4)) != 0) -#endif - return DR_DecodeError; - } - /* Returned tag, top 3 bits are class/method remaining bits are number. */ - decoded->tag = ((DERTag)(tag1 & 0xE0) << ((sizeof(DERTag) - 1) * 8)) | tagNumber; - - /* Tag decoding above ensured we have at least one more input byte left. */ - len1 = *derPtr++; - derLen--; - if(len1 & 0x80) { - /* long length form - first byte is length of length */ - DERSize longLen = 0; /* long form length */ - unsigned dex; - - len1 &= 0x7f; - if((len1 > sizeof(DERSize)) || (len1 > derLen) || len1 == 0 || *derPtr == 0) { - /* no can do */ - return DR_DecodeError; - } - for(dex=0; dex derLen && !encodedLength) { - /* not enough data left for this encoding */ - return DR_DecodeError; - } - if (longLencontent.data = derPtr; - decoded->content.length = derLen; - if (encodedLength) { - *encodedLength = longLen; - } - } - else { - /* short length form, len1 is the length */ - if(len1 > derLen && !encodedLength) { - /* not enough data left for this encoding */ - return DR_DecodeError; - } - if (len1content.data = derPtr; - decoded->content.length = derLen; - if (encodedLength) { - *encodedLength = len1; - } - } - - return DR_Success; -} - -/* - * Given a BIT_STRING, in the form of its raw content bytes, - * obtain the number of unused bits and the raw bit string bytes. - */ -DERReturn DERParseBitString( - const DERItem *contents, - DERItem *bitStringBytes, /* RETURNED */ - DERByte *numUnusedBits) /* RETURNED */ -{ - if(contents->length < 2) { - /* not enough room for actual bits after the unused bits field */ - *numUnusedBits = 0; - bitStringBytes->data = NULL; - bitStringBytes->length = 0; - return DR_Success; - } - *numUnusedBits = contents->data[0]; - bitStringBytes->data = contents->data + 1; - bitStringBytes->length = contents->length - 1; - return DR_Success; -} - -/* - * Given a BOOLEAN, in the form of its raw content bytes, - * obtain it's value. - */ -DERReturn DERParseBoolean( - const DERItem *contents, - bool *value) { /* RETURNED */ - if (contents->length != 1 || - (contents->data[0] != 0 && contents->data[0] != 0xFF)) - return DR_DecodeError; - - *value = contents->data[0] != 0; - return DR_Success; -} - -/* - * Given a BOOLEAN, in the form of its raw content bytes, - * obtain it's value. - */ -DERReturn DERParseBooleanWithDefault( - const DERItem *contents, - bool defaultValue, - bool *value) { /* RETURNED */ - if (contents->length == 0) { - *value = defaultValue; - return DR_Success; - } - return DERParseBoolean(contents, value); -} - - -DERReturn DERParseInteger( - const DERItem *contents, - uint32_t *result) { /* RETURNED */ - uint64_t value; - DERReturn drtn = DERParseInteger64(contents, &value); - if (drtn == DR_Success) { - if (value > UINT32_MAX) - drtn = DR_BufOverflow; - else - *result = (uint32_t)value; - } - return drtn; -} - -DERReturn DERParseInteger64( - const DERItem *contents, - uint64_t *result) { /* RETURNED */ - DERSize ix, length = contents->length; - if (length == 0) - return DR_DecodeError; - if (contents->data[0] & 0x80) - return DR_DecodeError; - if (contents->data[0] == 0) { - if (length > 1 && (contents->data[1] & 0x80) == 0) - return DR_DecodeError; - if (length > sizeof(*result) + 1) - return DR_BufOverflow; - } else if (length > sizeof(*result)) { - return DR_BufOverflow; - } - uint64_t value = 0; - for (ix = 0; ix < length; ++ix) { - value <<= 8; - value += contents->data[ix]; - } - *result = value; - return DR_Success; -} - -/* Sequence/set support */ - -/* - * To decode a set or sequence, call DERDecodeSeqInit once, then - * call DERDecodeSeqNext to get each enclosed item. - * DERDecodeSeqNext returns DR_EndOfSequence when no more - * items are available. - */ -DERReturn DERDecodeSeqInit( - const DERItem *der, /* data to decode */ - DERTag *tag, /* RETURNED tag of sequence/set. This will be - * either ASN1_CONSTR_SEQUENCE or ASN1_CONSTR_SET. */ - DERSequence *derSeq) /* RETURNED, to use in DERDecodeSeqNext */ -{ - DERDecodedInfo decoded; - DERReturn drtn; - - drtn = DERDecodeItem(der, &decoded); - if(drtn) { - return drtn; - } - *tag = decoded.tag; - switch(decoded.tag) { - case ASN1_CONSTR_SEQUENCE: - case ASN1_CONSTR_SET: - break; - default: - return DR_UnexpectedTag; - } - derSeq->nextItem = decoded.content.data; - derSeq->end = decoded.content.data + decoded.content.length; - return DR_Success; -} - -/* - * Use this to start in on decoding a sequence's content, when - * the top-level tag and content have already been decoded. - */ -DERReturn DERDecodeSeqContentInit( - const DERItem *content, - DERSequence *derSeq) /* RETURNED, to use in DERDecodeSeqNext */ -{ - /* just prepare for decoding items in content */ - derSeq->nextItem = content->data; - derSeq->end = content->data + content->length; - return DR_Success; -} - -DERReturn DERDecodeSeqNext( - DERSequence *derSeq, - DERDecodedInfo *decoded) /* RETURNED */ -{ - DERReturn drtn; - DERItem item; - - if(derSeq->nextItem >= derSeq->end) { - /* normal termination, contents all used up */ - return DR_EndOfSequence; - } - - /* decode next item */ - item.data = derSeq->nextItem; - item.length = (DERSize) (derSeq->end - derSeq->nextItem); - drtn = DERDecodeItem(&item, decoded); - if(drtn) { - return drtn; - } - - /* skip over the item we just decoded */ - derSeq->nextItem = decoded->content.data + decoded->content.length; - return DR_Success; -} - -/* - * High level sequence parse, starting with top-level tag and content. - * Top level tag must be ASN1_CONSTR_SEQUENCE - if it's not, and that's - * OK, use DERParseSequenceContent(). - */ -DERReturn DERParseSequence( - const DERItem *der, - DERShort numItems, /* size of itemSpecs[] */ - const DERItemSpec *itemSpecs, - void *dest, /* DERDecodedInfo(s) here RETURNED */ - DERSize sizeToZero) /* optional */ -{ - DERReturn drtn; - DERDecodedInfo topDecode; - - drtn = DERDecodeItem(der, &topDecode); - if(drtn) { - return drtn; - } - if(topDecode.tag != ASN1_CONSTR_SEQUENCE) { - return DR_UnexpectedTag; - } - return DERParseSequenceContent(&topDecode.content, - numItems, itemSpecs, dest, sizeToZero); -} - -/* high level sequence parse, starting with sequence's content */ -DERReturn DERParseSequenceContent( - const DERItem *content, - DERShort numItems, /* size of itemSpecs[] */ - const DERItemSpec *itemSpecs, - void *dest, /* DERDecodedInfo(s) here RETURNED */ - DERSize sizeToZero) /* optional */ -{ - DERSequence derSeq; - DERReturn drtn; - DERShort itemDex; - DERByte *currDER; /* full DER encoding of current item */ - - if(sizeToZero) { - DERMemset(dest, 0, sizeToZero); - } - - drtn = DERDecodeSeqContentInit(content, &derSeq); - if(drtn) { - return drtn; - } - - /* main loop */ - for(itemDex=0 ; itemDexoptions; - derDecDbg3("--- currItem %u expectTag 0x%llx currOptions 0x%x\n", - i, currItemSpec->tag, currOptions); - - if((currOptions & DER_DEC_ASN_ANY) || - (foundTag == currItemSpec->tag)) { - /* - * We're good with this one. Cook up destination address - * as appropriate. - */ - if(!(currOptions & DER_DEC_SKIP)) { - derDecDbg1("--- MATCH at currItem %u\n", i); - DERByte *byteDst = (DERByte *)dest + currItemSpec->offset; - DERItem *dst = (DERItem *)byteDst; - *dst = currDecoded.content; - if(currOptions & DER_DEC_SAVE_DER) { - /* recreate full DER encoding of this item */ - derDecDbg1("--- SAVE_DER at currItem %u\n", i); - dst->data = currDER; - dst->length += (currDecoded.content.data - currDER); - } - } - - /* on to next item */ - itemDex = i + 1; - - /* is this the end? */ - if(itemDex == numItems) { - /* normal termination if we consumed everything */ - if (currDecoded.content.data + currDecoded.content.length == content->data + content->length) - return DR_Success; - else - return DR_DecodeError; - } - else { - /* on to next item */ - foundMatch = 1; - break; - } - } /* ASN_ANY, or match */ - - /* - * If current itemSpec isn't optional, abort - else on to - * next item - */ - if(!(currOptions & DER_DEC_OPTIONAL)) { - derDecDbg1("--- MISMATCH at currItem %u, !OPTIONAL, abort\n", i); - return DR_UnexpectedTag; - } - - /* else this was optional, on to next item */ - } /* searching for tag match */ - - if(foundMatch == 0) { - /* - * Found an item we couldn't match to any tag spec and we're at - * the end. - */ - derDecDbg("--- TAG NOT FOUND, abort\n"); - return DR_UnexpectedTag; - } - - /* else on to next item */ - } /* main loop */ - - /* Template has 0 items if we get here. */ - /* normal termination if we consumed everything, (the sequence was empty) */ - if (derSeq.nextItem == derSeq.end) - return DR_Success; - else - return DR_DecodeError; -} - -#if 0 -/* - * High level sequence parse, starting with top-level tag and content. - * Top level tag must be ASN1_CONSTR_SEQUENCE - if it's not, and that's - * OK, use DERParseSequenceContent(). - */ -DERReturn DERParseSequenceOf( - const DERItem *der, - DERShort numItems, /* size of itemSpecs[] */ - const DERItemSpec *itemSpecs, - void *dest, /* DERDecodedInfo(s) here RETURNED */ - DERSize *numDestItems) /* output */ -{ - DERReturn drtn; - DERDecodedInfo topDecode; - - drtn = DERDecodeItem(der, &topDecode); - if(drtn) { - return drtn; - } - if(topDecode.tag != ASN1_CONSTR_SEQUENCE) { - return DR_UnexpectedTag; - } - return DERParseSequenceContent(&topDecode.content, - numItems, itemSpecs, dest, sizeToZero); -} - -/* - * High level set of parse, starting with top-level tag and content. - * Top level tag must be ASN1_CONSTR_SET - if it's not, and that's - * OK, use DERParseSetOrSequenceOfContent(). - */ -DERReturn DERParseSetOf( - const DERItem *der, - DERShort numItems, /* size of itemSpecs[] */ - const DERItemSpec *itemSpecs, - void *dest, /* DERDecodedInfo(s) here RETURNED */ - DERSize *numDestItems) /* output */ -{ - DERReturn drtn; - DERDecodedInfo topDecode; - - drtn = DERDecodeItem(der, &topDecode); - if(drtn) { - return drtn; - } - if(topDecode.tag != ASN1_CONSTR_SET) { - return DR_UnexpectedTag; - } - return DERParseSetOrSequenceOfContent(&topDecode.content, - numItems, itemSpecs, dest, numDestItems); -} - -/* High level set of or sequence of parse, starting with set or - sequence's content */ -DERReturn DERParseSetOrSequenceOfContent( - const DERItem *content, - void(*itemHandeler)(void *, const DERDecodedInfo *) - void *itemHandelerContext); -{ - DERSequence derSeq; - DERShort itemDex; - - drtn = DERDecodeSeqContentInit(content, &derSeq); - require_noerr_quiet(drtn, badCert); - - /* main loop */ - for (;;) { - DERDecodedInfo currDecoded; - DERShort i; - DERByte foundTag; - char foundMatch = 0; - - drtn = DERDecodeSeqNext(&derSeq, &currDecoded); - if(drtn) { - /* The only legal error here is DR_EndOfSequence. */ - if(drtn == DR_EndOfSequence) { - /* no more items left in the sequence; success */ - return DR_Success; - } - else { - /* any other error is fatal */ - require_noerr_quiet(drtn, badCert); - } - } /* decode error */ - - /* Each element can be anything. */ - foundTag = currDecoded.tag; - - /* - * We're good with this one. Cook up destination address - * as appropriate. - */ - DERByte *byteDst = (DERByte *)dest + currItemSpec->offset; - DERItem *dst = (DERItem *)byteDst; - *dst = currDecoded.content; - if(currOptions & DER_DEC_SAVE_DER) { - /* recreate full DER encoding of this item */ - derDecDbg1("--- SAVE_DER at currItem %u\n", i); - dst->data = currDER; - dst->length += (currDecoded.content.data - currDER); - } - - /* on to next item */ - itemDex = i + 1; - - /* is this the end? */ - if(itemDex == numItems) { - /* normal termination */ - return DR_Success; - } - else { - /* on to next item */ - foundMatch = 1; - break; - } - - /* - * If current itemSpec isn't optional, abort - else on to - * next item - */ - if(!(currOptions & DER_DEC_OPTIONAL)) { - derDecDbg1("--- MISMATCH at currItem %u, !OPTIONAL, abort\n", i); - return DR_UnexpectedTag; - } - - /* else this was optional, on to next item */ - } /* searching for tag match */ - - if(foundMatch == 0) { - /* - * Found an item we couldn't match to any tag spec and we're at - * the end. - */ - derDecDbg("--- TAG NOT FOUND, abort\n"); - return DR_UnexpectedTag; - } - - /* else on to next item */ - } /* main loop */ - - /* - * If we get here, there appears to be more to process, but we've - * given the caller everything they want. - */ - return DR_Success; - } -} -#endif - -#endif /* DER_DECODE_ENABLE */ diff --git a/OSX/libsecurity_keychain/libDER/libDER/DER_Decode.h b/OSX/libsecurity_keychain/libDER/libDER/DER_Decode.h deleted file mode 100644 index 4f2c915c..00000000 --- a/OSX/libsecurity_keychain/libDER/libDER/DER_Decode.h +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (c) 2005-2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * DER_Decode.h - DER decoding routines - */ - -#ifndef _DER_DECODE_H_ -#define _DER_DECODE_H_ - -#include -#include - -__BEGIN_DECLS - -/* - * Decoding one item consists of extracting its tag, a pointer - * to the actual content, and the length of the content. Those - * three are represented by a DERDecodedInfo. - */ -typedef struct { - DERTag tag; - DERItem content; -} DERDecodedInfo; - -/* - * Basic decoding primitive. Only works with: - * - * -- definite length encoding - * -- one-byte tags - * -- max content length fits in a DERSize - * - * No malloc or copy of the contents is performed; the returned - * content->content.data is a pointer into the incoming der data. - */ -DERReturn DERDecodeItem( - const DERItem *der, /* data to decode */ - DERDecodedInfo *decoded); /* RETURNED */ - -/* - * Basic decoding primitive. Allows for decoding with a partial buffer. - * if allowPartialBuffer is true. A partial buffer would normally fail - * because the encoded length would be greater than the size of the buffer passed in. - * Only works with: - * - * -- definite length encoding - * -- one-byte tags (unless DER_MULTIBYTE_TAGS is defined) - * -- max content length fits in a DERSize - * - * No malloc or copy of the contents is performed; the returned - * content->content.data is a pointer into the incoming der data. - * - * WARNING: Using a partial buffer can return a DERDecodedInfo object with - * a length larger than the buffer. It is recommended to instead use - * DERDecodeItemPartialBufferGetLength if you need partial buffers. - * - */ -DERReturn DERDecodeItemPartialBuffer( - const DERItem *der, /* data to decode */ - DERDecodedInfo *decoded, /* RETURNED */ - bool allowPartialBuffer); - -/* - * Same as above, but returns a DERDecodedInfo with a length no larger than the buffer. - * The actual encoded length can be retrieved from encodedLength parameter. - * encodedLength can be NULL to achieve the same behavior as DERDecodeItemPartialBuffer, - * with allowPartialBuffer=false - * - * NOTE: The DERDecoded length will never be larger than the input buffer. - * This is a key difference from DERDecodeItemPartialBuffer which could return invalid length. - * - */ -DERReturn DERDecodeItemPartialBufferGetLength( - const DERItem *der, /* data to decode */ - DERDecodedInfo *decoded, /* RETURNED */ - DERSize *encodedLength); - -/* - * Given a BIT_STRING, in the form of its raw content bytes, - * obtain the number of unused bits and the raw bit string bytes. - */ -DERReturn DERParseBitString( - const DERItem *contents, - DERItem *bitStringBytes, /* RETURNED */ - DERByte *numUnusedBits); /* RETURNED */ - -/* - * Given a BOOLEAN, in the form of its raw content bytes, - * obtain it's value. - */ -DERReturn DERParseBoolean( - const DERItem *contents, - bool *value); /* RETURNED */ - -DERReturn DERParseBooleanWithDefault( - const DERItem *contents, - bool defaultValue, - bool *value); /* RETURNED */ -/* - * Given a positive INTEGER, in the form of its raw content bytes, - * obtain it's value as a 32 bit or 64 bit quantity. - * Returns DR_BufOverflow if the value is too large to fit in the return type - */ - -DERReturn DERParseInteger( - const DERItem *contents, - uint32_t *value); /* RETURNED */ - -DERReturn DERParseInteger64( - const DERItem *contents, - uint64_t *value); /* RETURNED */ - -/* - * Sequence/set decode support. - */ - -/* state representing a sequence or set being decoded */ -typedef struct { - DERByte *nextItem; - DERByte *end; -} DERSequence; - -/* - * To decode a set or sequence, call DERDecodeSeqInit or - * DERDecodeSeqContentInit once, then call DERDecodeSeqNext to - * get each enclosed item. - * - * DERDecodeSeqNext returns DR_EndOfSequence when no more - * items are available. - */ - -/* - * Use this to parse the top level sequence's tag and content length. - */ -DERReturn DERDecodeSeqInit( - const DERItem *der, /* data to decode */ - DERTag *tag, /* RETURNED tag of sequence/set. This will be - * either ASN1_CONSTR_SEQUENCE or - * ASN1_CONSTR_SET. */ - DERSequence *derSeq); /* RETURNED, to use in DERDecodeSeqNext */ - -/* - * Use this to start in on decoding a sequence's content, when - * the top-level tag and content have already been decoded. - */ -DERReturn DERDecodeSeqContentInit( - const DERItem *content, - DERSequence *derSeq); /* RETURNED, to use in DERDecodeSeqNext */ - -/* obtain the next decoded item in a sequence or set */ -DERReturn DERDecodeSeqNext( - DERSequence *derSeq, - DERDecodedInfo *decoded); /* RETURNED */ - -/* - * High level sequence decode. - */ - -/* - * Per-item decode options. - */ - -/* Explicit default, no options */ -#define DER_DEC_NO_OPTS 0x0000 - -/* This item optional, can be skipped during decode */ -#define DER_DEC_OPTIONAL 0x0001 - -/* Skip the tag check; accept anything. */ -#define DER_DEC_ASN_ANY 0x0002 - -/* Skip item, no write to DERDecodedInfo (but tag check still performed) */ -#define DER_DEC_SKIP 0x0004 - -/* Save full DER encoding in DERDecodedInfo, including tag and length. Normally - * only the content is saved. */ -#define DER_DEC_SAVE_DER 0x0008 - -/* - * High level sequence parse, starting with top-level tag and content. - * Top level tag must be ASN1_CONSTR_SEQUENCE - if it's not, and that's - * OK, use DERParseSequenceContent(). - * - * These never return DR_EndOfSequence - if an *unexpected* end of sequence - * occurs, return DR_IncompleteSeq. - * - * Results of the decoding of one item are placed in a DERItem whose address - * is the dest arg plus the offset value in the associated DERItemSpec. - * - * Items which are optional (DER_DEC_OPTIONAL) and which are not found, - * leave their associated DERDecodedInfos unmodified. - * - * Processing of a sequence ends on detection of any error or after the - * last DERItemSpec is processed. - * - * The sizeToZero argument, if nonzero, indicates the number of bytes - * starting at dest to zero before processing the sequence. This is - * generally desirable, particularly if there are any DER_DEC_OPTIONAL - * items in the sequence; skipped optional items are detected by the - * caller via a NULL DERDecodedInfo.content.data; if this hasn't been - * explicitly zeroed (generally, by passing a nonzero value of sizeToZero), - * skipped items can't be detected. - */ -DERReturn DERParseSequence( - const DERItem *der, - DERShort numItems, /* size of itemSpecs[] */ - const DERItemSpec *itemSpecs, - void *dest, /* DERDecodedInfo(s) here RETURNED */ - DERSize sizeToZero); /* optional */ - -/* high level sequence parse, starting with sequence's content */ -DERReturn DERParseSequenceContent( - const DERItem *content, - DERShort numItems, /* size of itemSpecs[] */ - const DERItemSpec *itemSpecs, - void *dest, /* DERDecodedInfo(s) here RETURNED */ - DERSize sizeToZero); /* optional */ - -__END_DECLS - -#endif /* _DER_DECODE_H_ */ - diff --git a/OSX/libsecurity_keychain/libDER/libDER/DER_Digest.c b/OSX/libsecurity_keychain/libDER/libDER/DER_Digest.c deleted file mode 100644 index 86e67c18..00000000 --- a/OSX/libsecurity_keychain/libDER/libDER/DER_Digest.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2005-2008,2010-2011,2014 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -/* - * DER_Digest.h - DER encode a DigestInfo - * - */ - -#include - -/* - * Create an encoded DigestInfo based on the specified SHA1 digest. - * The digest must be 20 bytes long. - * - * Result is placed in caller's buffer, which must be at least of - * length DER_DIGEST_INFO_LEN bytes. - * - * The *resultLen parameter is the available size in the result - * buffer on input, and the actual length of the encoded DigestInfo - * on output. - * - * In the interest of saving code space, this just drops the caller's - * digest into an otherwise hard-coded, fixed, encoded SHA1 DigestInfo. - * Nothing is variable so we know the whole thing. It looks like this: - * - * SEQUENCE OF <33> { - * SEQUENCE OF <9> { - * OID <5>: OID : < 06 05 2B 0E 03 02 1A > - * NULL - * } - * OCTET STRING <20>: - * 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 - * 55 55 55 55 - * } - * - * - * tower.local:digestInfo> hexdump -x /tmp/encodedDigest - * 0000000 3021 3009 0605 2b0e 0302 1a05 0004 1455 - * 0000010 5555 5555 5555 5555 5555 5555 5555 5555 - * * - * 0000020 - */ - -static const unsigned char encodedSha1Digest[] = -{ - 0x30, 0x21, /* top level sequence length 33 */ - 0x30, 0x09, /* algorithm ID, sequence length 9 */ - 0x06, 0x05, /* alg OID, length 5, SHA1 */ - 0x2b, 0x0e, 0x03, 0x02, 0x1a, - 0x05, 0x00, /* NULL parameters */ - 0x04, 0x14 /* integer length 20 */ - /* digest follows */ -}; - -DERReturn DEREncodeSHA1DigestInfo( - const DERByte *sha1Digest, - DERSize sha1DigestLen, - DERByte *result, /* encoded result RETURNED here */ - DERSize *resultLen) /* IN/OUT */ -{ - DERSize totalLen = sizeof(encodedSha1Digest) + DER_SHA1_DIGEST_LEN; - - if((sha1Digest == NULL) || (sha1DigestLen != DER_SHA1_DIGEST_LEN) || - (result == NULL) || (resultLen == NULL)) { - return DR_ParamErr; - } - if(*resultLen < DER_SHA1_DIGEST_INFO_LEN) { - return DR_BufOverflow; - } - DERMemmove(result, encodedSha1Digest, sizeof(encodedSha1Digest)); - DERMemmove(result + sizeof(encodedSha1Digest), sha1Digest, DER_SHA1_DIGEST_LEN); - *resultLen = totalLen; - return DR_Success; -} - -/* - joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) - csor(3) nistalgorithm(4) hashAlgs(2) sha256(1) - - future ones to add: sha384(2) sha512(3) sha224(4) -*/ -static const unsigned char encodedSha256Digest[] = -{ - 0x30, 0x31, /* top level sequence length 49 */ - 0x30, 0x0d, /* algorithm ID, sequence length 13 */ - 0x06, 0x09, - 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, - 0x05, 0x00, /* NULL parameters */ - 0x04, 0x20 /* integer length 32 */ - /* digest follows */ -}; - -DERReturn DEREncodeSHA256DigestInfo( - const DERByte *sha256Digest, - DERSize sha256DigestLen, - DERByte *result, /* encoded result RETURNED here */ - DERSize *resultLen) /* IN/OUT */ -{ - DERSize totalLen = sizeof(encodedSha256Digest) + DER_SHA256_DIGEST_LEN; - - if((sha256Digest == NULL) || (sha256DigestLen != DER_SHA256_DIGEST_LEN) || - (result == NULL) || (resultLen == NULL)) { - return DR_ParamErr; - } - if(*resultLen < DER_SHA256_DIGEST_INFO_LEN) { - return DR_BufOverflow; - } - DERMemmove(result, encodedSha256Digest, sizeof(encodedSha256Digest)); - DERMemmove(result + sizeof(encodedSha256Digest), sha256Digest, DER_SHA256_DIGEST_LEN); - *resultLen = totalLen; - return DR_Success; -} - - -/* Same thing, MD5/MD2 */ -static const unsigned char encodedMdDigest[] = -{ - 0x30, 0x20, /* top level sequence length 32 */ - 0x30, 0x0c, /* algorithm ID, sequence length 12 */ - 0x06, 0x08, /* alg OID, length 8, MD2/MD5 */ - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, - 0x05, /* 5 = MD5, 2 = MD2 */ - 0x05, 0x00, /* NULL parameters */ - 0x04, 0x10 /* integer length 16 */ - /* digest follows */ -}; - -#define WHICH_DIGEST_INDEX 13 -#define WHICH_DIGEST_MD2 2 -#define WHICH_DIGEST_MD5 5 - -DERReturn DEREncodeMDDigestInfo( - WhichDigest whichDigest, - const DERByte *mdDigest, - DERSize mdDigestLen, - DERByte *result, /* encoded result RETURNED here */ - DERSize *resultLen) /* IN/OUT */ -{ - DERSize totalLen = sizeof(encodedMdDigest) + DER_MD_DIGEST_LEN; - - if((mdDigest == NULL) || (mdDigestLen != DER_MD_DIGEST_LEN) || - (result == NULL) || (resultLen == NULL)) { - return DR_ParamErr; - } - if(*resultLen < totalLen) { - return DR_BufOverflow; - } - DERMemmove(result, encodedMdDigest, sizeof(encodedMdDigest)); - DERMemmove(result + sizeof(encodedMdDigest), mdDigest, DER_MD_DIGEST_LEN); - switch(whichDigest) { - case WD_MD2: - result[WHICH_DIGEST_INDEX] = WHICH_DIGEST_MD2; - break; - case WD_MD5: - result[WHICH_DIGEST_INDEX] = WHICH_DIGEST_MD5; - break; - default: - return DR_ParamErr; - } - *resultLen = totalLen; - return DR_Success; -} diff --git a/OSX/libsecurity_keychain/libDER/libDER/DER_Digest.h b/OSX/libsecurity_keychain/libDER/libDER/DER_Digest.h deleted file mode 100644 index 734d752c..00000000 --- a/OSX/libsecurity_keychain/libDER/libDER/DER_Digest.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2005-2016 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -/* - * DER_Digest.h - DER encode a DigestInfo - * - */ - -#ifndef _DER_DIGEST_H_ -#define _DER_DIGEST_H_ - -#include - -__BEGIN_DECLS - -/* - * Create an encoded DigestInfo based on the specified SHA1 digest. - * The incoming digest must be 20 bytes long. - * - * Result is placed in caller's buffer, which must be at least of - * length DER_SHA1_DIGEST_INFO_LEN bytes. - * - * The *resultLen parameter is the available size in the result - * buffer on input, and the actual length of the encoded DigestInfo - * on output. - */ -#define DER_SHA1_DIGEST_LEN 20 -#define DER_SHA1_DIGEST_INFO_LEN 35 - -DERReturn DEREncodeSHA1DigestInfo( - const DERByte *sha1Digest, - DERSize sha1DigestLen, - DERByte *result, /* encoded result RETURNED here */ - DERSize *resultLen); /* IN/OUT */ - -#define DER_SHA256_DIGEST_LEN 32 -#define DER_SHA256_DIGEST_INFO_LEN 51 - -DERReturn DEREncodeSHA256DigestInfo( - const DERByte *sha256Digest, - DERSize sha256DigestLen, - DERByte *result, /* encoded result RETURNED here */ - DERSize *resultLen); /* IN/OUT */ - -/* - * Likewise, create an encoded DIgestInfo for specified MD5 or MD2 digest. - */ -#define DER_MD_DIGEST_LEN 16 -#define DER_MD_DIGEST_INFO_LEN 34 - -typedef enum { - WD_MD2 = 1, - WD_MD5 = 2 -} WhichDigest; - -DERReturn DEREncodeMDDigestInfo( - WhichDigest whichDigest, - const DERByte *mdDigest, - DERSize mdDigestLen, - DERByte *result, /* encoded result RETURNED here */ - DERSize *resultLen); /* IN/OUT */ - -/* max sizes you'll need in the general cases */ -#define DER_MAX_DIGEST_LEN DER_SHA256_DIGEST_LEN -#define DER_MAX_ENCODED_INFO_LEN DER_SHA256_DIGEST_INFO_LEN - -__END_DECLS - -#endif /* _DER_DIGEST_H_ */ - diff --git a/OSX/libsecurity_keychain/libDER/libDER/DER_Encode.c b/OSX/libsecurity_keychain/libDER/libDER/DER_Encode.c deleted file mode 100644 index bd8e607a..00000000 --- a/OSX/libsecurity_keychain/libDER/libDER/DER_Encode.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright (c) 2005-2016 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -/* - * DER_Encode.h - DER encoding routines - * - */ - -#include -#include -#include -#include - -#ifndef DER_ENCODE_ENABLE -#error Please define DER_ENCODE_ENABLE. -#endif - -#if DER_ENCODE_ENABLE - -/* calculate size of encoded tag */ -static DERSize DERLengthOfTag( - DERTag tag) -{ - DERSize rtn = 1; - - tag &= ASN1_TAGNUM_MASK; - if (tag >= 0x1F) { - /* Shift 7-bit digits out of the tag integer until it's zero. */ - while(tag != 0) { - rtn++; - tag >>= 7; - } - } - - return rtn; -} - -/* encode tag */ -static DERReturn DEREncodeTag( - DERTag tag, - DERByte *buf, /* encoded length goes here */ - DERSize *inOutLen) /* IN/OUT */ -{ - DERSize outLen = DERLengthOfTag(tag); - DERTag tagNumber = tag & ASN1_TAGNUM_MASK; - DERByte tag1 = (tag >> (sizeof(DERTag) * 8 - 8)) & 0xE0; - - if(outLen > *inOutLen) { - return DR_BufOverflow; - } - - if(outLen == 1) { - /* short form */ - *buf = (DERByte)(tag1 | tagNumber); - } - else { - /* long form */ - DERByte *tagBytes = buf + outLen; // l.s. digit of tag - *buf = tag1 | 0x1F; // tag class / method indicator - *--tagBytes = tagNumber & 0x7F; - tagNumber >>= 7; - while(tagNumber != 0) { - *--tagBytes = (tagNumber & 0x7F) | 0x80; - tagNumber >>= 7; - } - } - *inOutLen = outLen; - return DR_Success; -} - -/* calculate size of encoded length */ -DERSize DERLengthOfLength( - DERSize length) -{ - DERSize rtn; - - if(length < 0x80) { - /* short form length */ - return 1; - } - - /* long form - one length-of-length byte plus length bytes */ - rtn = 1; - while(length != 0) { - rtn++; - length >>= 8; - } - return rtn; -} - -/* encode length */ -DERReturn DEREncodeLength( - DERSize length, - DERByte *buf, /* encoded length goes here */ - DERSize *inOutLen) /* IN/OUT */ -{ - DERByte *lenBytes; - DERSize outLen = DERLengthOfLength(length); - - if(outLen > *inOutLen) { - return DR_BufOverflow; - } - - if(length < 0x80) { - /* short form */ - *buf = (DERByte)length; - *inOutLen = 1; - return DR_Success; - } - - /* long form */ - *buf = (outLen - 1) | 0x80; // length of length, long form indicator - lenBytes = buf + outLen - 1; // l.s. digit of length - while(length != 0) { - *lenBytes-- = (DERByte)length; - length >>= 8; - } - *inOutLen = outLen; - return DR_Success; -} - -DERSize DERLengthOfItem( - DERTag tag, - DERSize length) -{ - return DERLengthOfTag(tag) + DERLengthOfLength(length) + length; -} - -DERReturn DEREncodeItem( - DERTag tag, - DERSize length, - const DERByte *src, - DERByte *derOut, /* encoded item goes here */ - DERSize *inOutLen) /* IN/OUT */ -{ - DERReturn drtn; - DERSize itemLen; - DERByte *currPtr = derOut; - DERSize bytesLeft = DERLengthOfItem(tag, length); - if(bytesLeft > *inOutLen) { - return DR_BufOverflow; - } - *inOutLen = bytesLeft; - - /* top level tag */ - itemLen = bytesLeft; - drtn = DEREncodeTag(tag, currPtr, &itemLen); - if(drtn) { - return drtn; - } - currPtr += itemLen; - bytesLeft -= itemLen; - itemLen = bytesLeft; - drtn = DEREncodeLength(length, currPtr, &itemLen); - if(drtn) { - return drtn; - } - currPtr += itemLen; - bytesLeft -= itemLen; - DERMemmove(currPtr, src, length); - - // Silence unused variable warning. - (void) bytesLeft; - - return DR_Success; -} - -static /* calculate the content length of an encoded sequence */ -DERSize DERContentLengthOfEncodedSequence( - const void *src, /* generally a ptr to a struct full of - * DERItems */ - DERShort numItems, /* size of itemSpecs[] */ - const DERItemSpec *itemSpecs) -{ - DERSize contentLen = 0; - unsigned dex; - DERSize thisContentLen; - - /* find length of each item */ - for(dex=0; dexoptions; - const DERByte *byteSrc = (const DERByte *)src + currItemSpec->offset; - const DERItem *itemSrc = (const DERItem *)byteSrc; - - if(currOptions & DER_ENC_WRITE_DER) { - /* easy case - no encode */ - contentLen += itemSrc->length; - continue; - } - - if ((currOptions & DER_DEC_OPTIONAL) && itemSrc->length == 0) { - /* If an optional item isn't present we don't encode a - tag and len. */ - continue; - } - - /* - * length of this item = - * tag (one byte) + - * length of length + - * content length + - * optional zero byte for signed integer - */ - contentLen += DERLengthOfTag(currItemSpec->tag); - - /* check need for pad byte before calculating lengthOfLength... */ - thisContentLen = itemSrc->length; - if((currOptions & DER_ENC_SIGNED_INT) && - (itemSrc->length != 0)) { - if(itemSrc->data[0] & 0x80) { - /* insert zero keep it positive */ - thisContentLen++; - } - } - contentLen += DERLengthOfLength(thisContentLen); - contentLen += thisContentLen; - } - return contentLen; -} - -DERReturn DEREncodeSequence( - DERTag topTag, /* ASN1_CONSTR_SEQUENCE, ASN1_CONSTR_SET */ - const void *src, /* generally a ptr to a struct full of - * DERItems */ - DERShort numItems, /* size of itemSpecs[] */ - const DERItemSpec *itemSpecs, - DERByte *derOut, /* encoded data written here */ - DERSize *inOutLen) /* IN/OUT */ -{ - const DERByte *endPtr = derOut + *inOutLen; - DERByte *currPtr = derOut; - DERSize bytesLeft = *inOutLen; - DERSize contentLen; - DERReturn drtn; - DERSize itemLen; - unsigned dex; - - /* top level tag */ - itemLen = bytesLeft; - drtn = DEREncodeTag(topTag, currPtr, &itemLen); - if(drtn) { - return drtn; - } - currPtr += itemLen; - bytesLeft -= itemLen; - if(currPtr >= endPtr) { - return DR_BufOverflow; - } - - /* content length */ - contentLen = DERContentLengthOfEncodedSequence(src, numItems, itemSpecs); - itemLen = bytesLeft; - drtn = DEREncodeLength(contentLen, currPtr, &itemLen); - if(drtn) { - return drtn; - } - currPtr += itemLen; - bytesLeft -= itemLen; - if(currPtr + contentLen > endPtr) { - return DR_BufOverflow; - } - /* we don't have to check for overflow any more */ - - /* grind thru the items */ - for(dex=0; dexoptions; - const DERByte *byteSrc = (const DERByte *)src + currItemSpec->offset; - const DERItem *itemSrc = (const DERItem *)byteSrc; - int prependZero = 0; - - if(currOptions & DER_ENC_WRITE_DER) { - /* easy case */ - DERMemmove(currPtr, itemSrc->data, itemSrc->length); - currPtr += itemSrc->length; - bytesLeft -= itemSrc->length; - continue; - } - - if ((currOptions & DER_DEC_OPTIONAL) && itemSrc->length == 0) { - /* If an optional item isn't present we skip it. */ - continue; - } - - /* encode one item: first the tag */ - itemLen = bytesLeft; - drtn = DEREncodeTag(currItemSpec->tag, currPtr, &itemLen); - if(drtn) { - return drtn; - } - currPtr += itemLen; - bytesLeft -= itemLen; - - /* do we need to prepend a zero to content? */ - contentLen = itemSrc->length; - if((currOptions & DER_ENC_SIGNED_INT) && - (itemSrc->length != 0)) { - if(itemSrc->data[0] & 0x80) { - /* insert zero keep it positive */ - contentLen++; - prependZero = 1; - } - } - - /* encode content length */ - itemLen = bytesLeft; - drtn = DEREncodeLength(contentLen, currPtr, &itemLen); - if(drtn) { - return drtn; - } - currPtr += itemLen; - bytesLeft -= itemLen; - - /* now the content, with possible leading zero added */ - if(prependZero) { - *currPtr++ = 0; - bytesLeft--; - } - DERMemmove(currPtr, itemSrc->data, itemSrc->length); - currPtr += itemSrc->length; - bytesLeft -= itemSrc->length; - } - *inOutLen = (DERSize)(currPtr - derOut); - return DR_Success; -} - -/* calculate the length of an encoded sequence. */ -DERSize DERLengthOfEncodedSequence( - DERTag topTag, - const void *src, /* generally a ptr to a struct full of - * DERItems */ - DERShort numItems, /* size of itemSpecs[] */ - const DERItemSpec *itemSpecs) -{ - DERSize contentLen = DERContentLengthOfEncodedSequence( - src, numItems, itemSpecs); - - return DERLengthOfTag(topTag) + - DERLengthOfLength(contentLen) + - contentLen; -} - -#endif /* DER_ENCODE_ENABLE */ - diff --git a/OSX/libsecurity_keychain/libDER/libDER/DER_Encode.h b/OSX/libsecurity_keychain/libDER/libDER/DER_Encode.h deleted file mode 100644 index bcde9757..00000000 --- a/OSX/libsecurity_keychain/libDER/libDER/DER_Encode.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2005-2016 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -/* - * DER_Encode.h - DER encoding routines - * - */ - -#ifndef _DER_ENCODE_H_ -#define _DER_ENCODE_H_ - -#include - -__BEGIN_DECLS - -/* - * Max size of an encoded item given its length. - * This includes a possible leading zero prepended to a signed integer - * (see DER_ENC_SIGNED_INT below). - */ -#define DER_MAX_ENCODED_SIZE(len) \ - ( 1 + /* tag */ \ - 5 + /* max length */ \ - 1 + /* possible prepended zero */ \ - len) - -/* calculate size of encoded length */ -DERSize DERLengthOfLength( - DERSize length); - -/* encode length */ -DERReturn DEREncodeLength( - DERSize length, - DERByte *buf, /* encoded length goes here */ - DERSize *inOutLen); /* IN/OUT */ - -/* calculate size of encoded length */ -DERSize DERLengthOfItem( - DERTag tag, - DERSize length); - -/* encode item */ -DERReturn DEREncodeItem( - DERTag tag, - DERSize length, - const DERByte *src, - DERByte *derOut, /* encoded item goes here */ - DERSize *inOutLen); /* IN/OUT */ - -/* - * Per-item encode options. - */ - -/* explicit default, no options */ -#define DER_ENC_NO_OPTS 0x0000 - -/* signed integer check: if incoming m.s. bit is 1, prepend a zero */ -#define DER_ENC_SIGNED_INT 0x0100 - -/* DERItem contains fully encoded item - copy, don't encode */ -#define DER_ENC_WRITE_DER 0x0200 - - -/* - * High-level sequence or set encode support. - * - * The outgoing sequence is expressed as an array of DERItemSpecs, each - * of which corresponds to one item in the encoded sequence. - * - * Normally the tag of the encoded item comes from the associated - * DERItemSpec, and the content comes from the DERItem whose address is - * the src arg plus the offset value in the associated DERItemSpec. - * - * If the DER_ENC_WRITE_DER option is true for a given DERItemSpec then - * no per-item encoding is done; the DER - with tag, length, and content - - * is taken en masse from the associated DERItem. - */ -DERReturn DEREncodeSequence( - DERTag topTag, /* ASN1_CONSTR_SEQUENCE, ASN1_CONSTR_SET */ - const void *src, /* generally a ptr to a struct full of - * DERItems */ - DERShort numItems, /* size of itemSpecs[] */ - const DERItemSpec *itemSpecs, - DERByte *derOut, /* encoded data written here */ - DERSize *inOutLen); /* IN/OUT */ - -/* precalculate the length of an encoded sequence. */ -DERSize DERLengthOfEncodedSequence( - DERTag topTag, /* ASN1_CONSTR_SEQUENCE, ASN1_CONSTR_SET */ - const void *src, /* generally a ptr to a struct full of - * DERItems */ - DERShort numItems, /* size of itemSpecs[] */ - const DERItemSpec *itemSpecs); - - -__END_DECLS - -#endif /* _DER_ENCODE_H_ */ diff --git a/OSX/libsecurity_keychain/libDER/libDER/DER_Keys.c b/OSX/libsecurity_keychain/libDER/libDER/DER_Keys.c deleted file mode 100644 index 0d41496f..00000000 --- a/OSX/libsecurity_keychain/libDER/libDER/DER_Keys.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2005-2007,2011,2014 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -/* - * DER_Cert.c - support for decoding RSA keys - * - */ - -#include -#include -#include -#include -#include - -#ifndef DER_DECODE_ENABLE -#error Please define DER_DECODE_ENABLE. -#endif -#if DER_DECODE_ENABLE - -/* - * DERItemSpecs for decoding RSA keys. - */ - -/* Algorithm Identifier */ -const DERItemSpec DERAlgorithmIdItemSpecs[] = -{ - { DER_OFFSET(DERAlgorithmId, oid), - ASN1_OBJECT_ID, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERAlgorithmId, params), - 0, /* no tag - any */ - DER_DEC_ASN_ANY | DER_DEC_OPTIONAL | DER_DEC_SAVE_DER } -}; -const DERSize DERNumAlgorithmIdItemSpecs = - sizeof(DERAlgorithmIdItemSpecs) / sizeof(DERItemSpec); - -/* X509 SubjectPublicKeyInfo */ -const DERItemSpec DERSubjPubKeyInfoItemSpecs[] = -{ - { DER_OFFSET(DERSubjPubKeyInfo, algId), - ASN1_CONSTR_SEQUENCE, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERSubjPubKeyInfo, pubKey), - ASN1_BIT_STRING, - DER_DEC_NO_OPTS }, - -}; -const DERSize DERNumSubjPubKeyInfoItemSpecs = - sizeof(DERSubjPubKeyInfoItemSpecs) / sizeof(DERItemSpec); - -/* - * RSA private key in CRT format - */ -const DERItemSpec DERRSAPrivKeyCRTItemSpecs[] = -{ - /* version, n, e, d - skip */ - { 0, - ASN1_INTEGER, - DER_DEC_SKIP }, - { 0, - ASN1_INTEGER, - DER_DEC_SKIP }, - { 0, - ASN1_INTEGER, - DER_DEC_SKIP }, - { 0, - ASN1_INTEGER, - DER_DEC_SKIP }, - { DER_OFFSET(DERRSAPrivKeyCRT, p), - ASN1_INTEGER, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERRSAPrivKeyCRT, q), - ASN1_INTEGER, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERRSAPrivKeyCRT, dp), - ASN1_INTEGER, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERRSAPrivKeyCRT, dq), - ASN1_INTEGER, - DER_DEC_NO_OPTS }, - { DER_OFFSET(DERRSAPrivKeyCRT, qInv), - ASN1_INTEGER, - DER_DEC_NO_OPTS }, - /* ignore the (optional) rest */ -}; -const DERSize DERNumRSAPrivKeyCRTItemSpecs = - sizeof(DERRSAPrivKeyCRTItemSpecs) / sizeof(DERItemSpec); - -#endif /* DER_DECODE_ENABLE */ - -#if DER_DECODE_ENABLE || DER_ENCODE_ENABLE - -/* RSA public key in PKCS1 format - encode and decode */ -const DERItemSpec DERRSAPubKeyPKCS1ItemSpecs[] = -{ - { DER_OFFSET(DERRSAPubKeyPKCS1, modulus), - ASN1_INTEGER, - DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT }, - { DER_OFFSET(DERRSAPubKeyPKCS1, pubExponent), - ASN1_INTEGER, - DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT }, -}; -const DERSize DERNumRSAPubKeyPKCS1ItemSpecs = - sizeof(DERRSAPubKeyPKCS1ItemSpecs) / sizeof(DERItemSpec); - -/* RSA public key in Apple custome format with reciprocal - encode and decode */ -const DERItemSpec DERRSAPubKeyAppleItemSpecs[] = -{ - { DER_OFFSET(DERRSAPubKeyApple, modulus), - ASN1_INTEGER, - DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT }, - { DER_OFFSET(DERRSAPubKeyApple, reciprocal), - ASN1_INTEGER, - DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT }, - { DER_OFFSET(DERRSAPubKeyApple, pubExponent), - ASN1_INTEGER, - DER_DEC_NO_OPTS | DER_ENC_SIGNED_INT }, -}; -const DERSize DERNumRSAPubKeyAppleItemSpecs = - sizeof(DERRSAPubKeyAppleItemSpecs) / sizeof(DERItemSpec); - - -#endif /* DER_DECODE_ENABLE || DER_ENCODE_ENABLE */ - -#ifndef DER_ENCODE_ENABLE -#error Please define DER_ENCODE_ENABLE. -#endif - -#if DER_ENCODE_ENABLE - -/* RSA Key Pair, encode only */ -const DERItemSpec DERRSAKeyPairItemSpecs[] = -{ - { DER_OFFSET(DERRSAKeyPair, version), - ASN1_INTEGER, - DER_ENC_SIGNED_INT }, - { DER_OFFSET(DERRSAKeyPair, n), - ASN1_INTEGER, - DER_ENC_SIGNED_INT }, - { DER_OFFSET(DERRSAKeyPair, e), - ASN1_INTEGER, - DER_ENC_SIGNED_INT }, - { DER_OFFSET(DERRSAKeyPair, d), - ASN1_INTEGER, - DER_ENC_SIGNED_INT }, - { DER_OFFSET(DERRSAKeyPair, p), - ASN1_INTEGER, - DER_ENC_SIGNED_INT }, - { DER_OFFSET(DERRSAKeyPair, q), - ASN1_INTEGER, - DER_ENC_SIGNED_INT }, - { DER_OFFSET(DERRSAKeyPair, dp), - ASN1_INTEGER, - DER_ENC_SIGNED_INT }, - { DER_OFFSET(DERRSAKeyPair, dq), - ASN1_INTEGER, - DER_ENC_SIGNED_INT }, - { DER_OFFSET(DERRSAKeyPair, qInv), - ASN1_INTEGER, - DER_ENC_SIGNED_INT }, -}; - -const DERSize DERNumRSAKeyPairItemSpecs = - sizeof(DERRSAKeyPairItemSpecs) / sizeof(DERItemSpec); - -#endif /* DER_ENCODE_ENABLE */ - diff --git a/OSX/libsecurity_keychain/libDER/libDER/DER_Keys.h b/OSX/libsecurity_keychain/libDER/libDER/DER_Keys.h deleted file mode 100644 index 41f24d67..00000000 --- a/OSX/libsecurity_keychain/libDER/libDER/DER_Keys.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2005-2016 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -/* - * DER_Keys.h - support for decoding RSA keys - * - */ - -#ifndef _DER_KEYS_H_ -#define _DER_KEYS_H_ - -#include -#include - -__BEGIN_DECLS - -/* Algorithm Identifier components */ -typedef struct { - DERItem oid; /* OID */ - DERItem params; /* ASN_ANY, optional, DER_DEC_SAVE_DER */ -} DERAlgorithmId; - -/* DERItemSpecs to decode into a DERAlgorithmId */ -extern const DERItemSpec DERAlgorithmIdItemSpecs[]; -extern const DERSize DERNumAlgorithmIdItemSpecs; - -/* X509 SubjectPublicKeyInfo */ -typedef struct { - DERItem algId; /* sequence, DERAlgorithmId */ - DERItem pubKey; /* BIT STRING */ -} DERSubjPubKeyInfo; - -/* DERItemSpecs to decode into a DERSubjPubKeyInfo */ -extern const DERItemSpec DERSubjPubKeyInfoItemSpecs[]; -extern const DERSize DERNumSubjPubKeyInfoItemSpecs; - -/* - * RSA public key in PKCS1 format; this is inside the BIT_STRING in - * DERSubjPubKeyInfo.pubKey. - */ -typedef struct { - DERItem modulus; /* n - INTEGER */ - DERItem pubExponent; /* e - INTEGER */ -} DERRSAPubKeyPKCS1; - -/* DERItemSpecs to decode/encode into/from a DERRSAPubKeyPKCS1 */ -extern const DERItemSpec DERRSAPubKeyPKCS1ItemSpecs[]; -extern const DERSize DERNumRSAPubKeyPKCS1ItemSpecs; - -/* - * RSA public key in custom (to this library) format, including - * the reciprocal. All fields are integers. - */ -typedef struct { - DERItem modulus; /* n */ - DERItem reciprocal; /* reciprocal of modulus */ - DERItem pubExponent; /* e */ -} DERRSAPubKeyApple; - -/* DERItemSpecs to decode/encode into/from a DERRSAPubKeyApple */ -extern const DERItemSpec DERRSAPubKeyAppleItemSpecs[]; -extern const DERSize DERNumRSAPubKeyAppleItemSpecs; - -/* - * RSA Private key, PKCS1 format, CRT option. - * All fields are integers. - */ -typedef struct { - DERItem p; /* p * q = n */ - DERItem q; - DERItem dp; /* d mod (p-1) */ - DERItem dq; /* d mod (q-1) */ - DERItem qInv; -} DERRSAPrivKeyCRT; - -/* DERItemSpecs to decode into a DERRSAPrivKeyCRT */ -extern const DERItemSpec DERRSAPrivKeyCRTItemSpecs[]; -extern const DERSize DERNumRSAPrivKeyCRTItemSpecs; - -/* Fully formed RSA key pair, for generating a PKCS1 private key */ -typedef struct { - DERItem version; - DERItem n; /* modulus */ - DERItem e; /* public exponent */ - DERItem d; /* private exponent */ - DERItem p; /* n = p*q */ - DERItem q; - DERItem dp; /* d mod (p-1) */ - DERItem dq; /* d mod (q-1) */ - DERItem qInv; /* q^(-1) mod p */ -} DERRSAKeyPair; - -/* DERItemSpecs to encode a DERRSAKeyPair */ -extern const DERItemSpec DERRSAKeyPairItemSpecs[]; -extern const DERSize DERNumRSAKeyPairItemSpecs; - -__END_DECLS - -#endif /* _DER_KEYS_H_ */ - diff --git a/OSX/libsecurity_keychain/libDER/libDER/asn1Types.h b/OSX/libsecurity_keychain/libDER/libDER/asn1Types.h deleted file mode 100644 index db992d79..00000000 --- a/OSX/libsecurity_keychain/libDER/libDER/asn1Types.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2005-2016 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -/* - * asn1Types.h - ASN.1/DER #defines - strictly hard coded per the real world - * - */ - -#ifndef _ASN1_TYPES_H_ -#define _ASN1_TYPES_H_ - -#if !defined(__WIN32__) -#include -#endif - -#include - -__BEGIN_DECLS - -/* copied from libsecurity_asn1 project */ - -/* Type tag numbers */ -#define ASN1_BOOLEAN 0x01 -#define ASN1_INTEGER 0x02 -#define ASN1_BIT_STRING 0x03 -#define ASN1_OCTET_STRING 0x04 -#define ASN1_NULL 0x05 -#define ASN1_OBJECT_ID 0x06 -#define ASN1_OBJECT_DESCRIPTOR 0x07 -/* External type and instance-of type 0x08 */ -#define ASN1_REAL 0x09 -#define ASN1_ENUMERATED 0x0a -#define ASN1_EMBEDDED_PDV 0x0b -#define ASN1_UTF8_STRING 0x0c -/* 0x0d */ -/* 0x0e */ -/* 0x0f */ -#define ASN1_SEQUENCE 0x10 -#define ASN1_SET 0x11 -#define ASN1_NUMERIC_STRING 0x12 -#define ASN1_PRINTABLE_STRING 0x13 -#define ASN1_T61_STRING 0x14 -#define ASN1_VIDEOTEX_STRING 0x15 -#define ASN1_IA5_STRING 0x16 -#define ASN1_UTC_TIME 0x17 -#define ASN1_GENERALIZED_TIME 0x18 -#define ASN1_GRAPHIC_STRING 0x19 -#define ASN1_VISIBLE_STRING 0x1a -#define ASN1_GENERAL_STRING 0x1b -#define ASN1_UNIVERSAL_STRING 0x1c -/* 0x1d */ -#define ASN1_BMP_STRING 0x1e -#define ASN1_HIGH_TAG_NUMBER 0x1f -#define ASN1_TELETEX_STRING ASN1_T61_STRING - -/* Tag modifiers */ -#define ASN1_TAG_MASK ((DERTag)~0) -#define ASN1_TAGNUM_MASK ((DERTag)~((DERTag)7 << (sizeof(DERTag) * 8 - 3))) - -#define ASN1_METHOD_MASK ((DERTag)1 << (sizeof(DERTag) * 8 - 3)) -#define ASN1_PRIMITIVE ((DERTag)0 << (sizeof(DERTag) * 8 - 3)) -#define ASN1_CONSTRUCTED ((DERTag)1 << (sizeof(DERTag) * 8 - 3)) - -#define ASN1_CLASS_MASK ((DERTag)3 << (sizeof(DERTag) * 8 - 2)) -#define ASN1_UNIVERSAL ((DERTag)0 << (sizeof(DERTag) * 8 - 2)) -#define ASN1_APPLICATION ((DERTag)1 << (sizeof(DERTag) * 8 - 2)) -#define ASN1_CONTEXT_SPECIFIC ((DERTag)2 << (sizeof(DERTag) * 8 - 2)) -#define ASN1_PRIVATE ((DERTag)3 << (sizeof(DERTag) * 8 - 2)) - -/* One-byte tag modifiers */ -#define ONE_BYTE_ASN1_TAG_MASK 0xff -#define ONE_BYTE_ASN1_TAGNUM_MASK 0x1f -#define ONE_BYTE_ASN1_METHOD_MASK 0x20 -#define ONE_BYTE_ASN1_PRIMITIVE 0x00 -#define ONE_BYTE_ASN1_CONSTRUCTED 0x20 - -#define ONE_BYTE_ASN1_CLASS_MASK 0xc0 -#define ONE_BYTE_ASN1_UNIVERSAL 0x00 -#define ONE_BYTE_ASN1_APPLICATION 0x40 -#define ONE_BYTE_ASN1_CONTEXT_SPECIFIC 0x80 -#define ONE_BYTE_ASN1_PRIVATE 0xc0 - -/* sequence and set appear as the following */ -#define ASN1_CONSTR_SEQUENCE ((DERTag)(ASN1_CONSTRUCTED | ASN1_SEQUENCE)) -#define ASN1_CONSTR_SET ((DERTag)(ASN1_CONSTRUCTED | ASN1_SET)) - -#define ONE_BYTE_ASN1_CONSTR_SEQUENCE ((uint8_t)(ONE_BYTE_ASN1_CONSTRUCTED | ASN1_SEQUENCE)) -#define ONE_BYTE_ASN1_CONSTR_SET ((uint8_t)(ONE_BYTE_ASN1_CONSTRUCTED | ASN1_SET)) - -__END_DECLS - -#endif /* _ASN1_TYPES_H_ */ diff --git a/OSX/libsecurity_keychain/libDER/libDER/libDER.h b/OSX/libsecurity_keychain/libDER/libDER/libDER.h deleted file mode 100644 index e5e4b127..00000000 --- a/OSX/libsecurity_keychain/libDER/libDER/libDER.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2005-2016 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -/* - * libDER.h - main header for libDER, a ROM-capable DER decoding library. - * - */ - -#ifndef _LIB_DER_H_ -#define _LIB_DER_H_ - -#include - -__BEGIN_DECLS - -/* - * Error returns generated by this library. - */ -typedef enum { - DR_Success = 0, - DR_EndOfSequence, /* end of sequence or set */ - DR_UnexpectedTag, /* unexpected tag found while decoding */ - DR_DecodeError, /* misc. decoding error (badly formatted DER) */ - DR_Unimplemented, /* function not implemented in this configuration */ - DR_IncompleteSeq, /* incomplete sequence */ - DR_ParamErr, /* incoming parameter error */ - DR_BufOverflow /* buffer overflow */ - /* etc. */ -} DERReturn; - -/* - * The structure of a sequence during decode or encode is expressed as - * an array of DERItemSpecs. While decoding or encoding a sequence, - * each item in the sequence corresponds to one DERItemSpec. - */ -typedef struct { - DERSize offset; /* offset of destination DERItem */ - DERTag tag; /* DER tag */ - DERShort options; /* DER_DEC_xxx or DER_ENC_xxx */ -} DERItemSpec; - -/* - * Macro to obtain offset of a DERDecodedInfo within a struct. - * FIXME this is going to need reworking to avoid compiler warnings - * on 64-bit compiles. It'll work OK as long as an offset can't be larger - * than a DERSize, but the cast from a pointer to a DERSize may - * provoke compiler warnings. - */ -#define DER_OFFSET(type, field) ((DERSize)(&((type *)0)->field)) - -__END_DECLS - -#endif /* _LIB_DER_H_ */ - diff --git a/OSX/libsecurity_keychain/libDER/libDER/libDER_config.h b/OSX/libsecurity_keychain/libDER/libDER/libDER_config.h deleted file mode 100644 index 6280ee3f..00000000 --- a/OSX/libsecurity_keychain/libDER/libDER/libDER_config.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2005-2007,2011-2012,2014 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -/* - * libDER_config.h - platform dependent #defines and typedefs for libDER - * - */ - -#ifndef _LIB_DER_CONFIG_H_ -#define _LIB_DER_CONFIG_H_ - -#include -#include - -/* include defintion of DERSize and DERByte */ -#include "libDER/oids.h" - -__BEGIN_DECLS - -/* - * Basic data types: unsigned 8-bit integer, unsigned 32-bit integer - */ -typedef uint16_t DERShort; - - -/* - * Use these #defines of you have memset, memmove, and memcmp; else - * write your own equivalents. - */ - -#define DERMemset(ptr, c, len) memset(ptr, c, len) -#define DERMemmove(dst, src, len) memmove(dst, src, len) -#define DERMemcmp(b1, b2, len) memcmp(b1, b2, len) - - -/*** - *** Compile time options to trim size of the library. - ***/ - -/* enable general DER encode */ -#define DER_ENCODE_ENABLE 1 - -/* enable general DER decode */ -#define DER_DECODE_ENABLE 1 - -#ifndef DER_MULTIBYTE_TAGS -/* enable multibyte tag support. */ -#define DER_MULTIBYTE_TAGS 1 -#endif - -#ifndef DER_TAG_SIZE -/* Iff DER_MULTIBYTE_TAGS is 1 this is the sizeof(DERTag) in bytes. Note that - tags are still encoded and decoded from a minimally encoded DER - represantation. This value maintains compatibility with libImg4Decode/Encode. */ -#define DER_TAG_SIZE 8 -#endif - - -/* ---------------------- Do not edit below this line ---------------------- */ - -/* - * Logical representation of a tag (the encoded representation is always in - * the minimal number of bytes). The top 3 bits encode class and method - * The remaining bits encode the tag value. To obtain smaller DERItemSpecs - * sizes, choose the smallest type that fits your needs. Most standard ASN.1 - * usage only needs single byte tags, but ocasionally custom applications - * require a larger tag namespace. - */ -#if DER_MULTIBYTE_TAGS - -#if DER_TAG_SIZE == 1 -typedef uint8_t DERTag; -#elif DER_TAG_SIZE == 2 -typedef uint16_t DERTag; -#elif DER_TAG_SIZE == 4 -typedef uint32_t DERTag; -#elif DER_TAG_SIZE == 8 -typedef uint64_t DERTag; -#else -#error DER_TAG_SIZE invalid -#endif - -#else /* DER_MULTIBYTE_TAGS */ -typedef DERByte DERTag; -#endif /* !DER_MULTIBYTE_TAGS */ - -__END_DECLS - -#endif /* _LIB_DER_CONFIG_H_ */ diff --git a/OSX/libsecurity_keychain/libDER/libDER/module.modulemap b/OSX/libsecurity_keychain/libDER/libDER/module.modulemap deleted file mode 100644 index af2d15b0..00000000 --- a/OSX/libsecurity_keychain/libDER/libDER/module.modulemap +++ /dev/null @@ -1,3 +0,0 @@ -module libDER [extern_c] { - header "libDER.h" -} diff --git a/OSX/libsecurity_keychain/libDER/libDER/oids.c b/OSX/libsecurity_keychain/libDER/libDER/oids.c deleted file mode 100644 index 990941f7..00000000 --- a/OSX/libsecurity_keychain/libDER/libDER/oids.c +++ /dev/null @@ -1,853 +0,0 @@ -/* - * Copyright (c) 2005-2009,2011-2016 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -/* - * oids.c - OID consts - * - */ - -#include -#include - -#define OID_ISO_CCITT_DIR_SERVICE 85 -#define OID_DS OID_ISO_CCITT_DIR_SERVICE -#define OID_ATTR_TYPE OID_DS, 4 -#define OID_EXTENSION OID_DS, 29 -#define OID_ISO_STANDARD 40 -#define OID_ISO_MEMBER 42 -#define OID_US OID_ISO_MEMBER, 134, 72 - -#define OID_ISO_IDENTIFIED_ORG 43 -#define OID_OSINET OID_ISO_IDENTIFIED_ORG, 4 -#define OID_GOSIP OID_ISO_IDENTIFIED_ORG, 5 -#define OID_DOD OID_ISO_IDENTIFIED_ORG, 6 -#define OID_OIW OID_ISO_IDENTIFIED_ORG, 14 - -/* From the PKCS Standards */ -#define OID_RSA OID_US, 134, 247, 13 -#define OID_RSA_HASH OID_RSA, 2 -#define OID_RSA_ENCRYPT OID_RSA, 3 -#define OID_PKCS OID_RSA, 1 -#define OID_PKCS_1 OID_PKCS, 1 -#define OID_PKCS_2 OID_PKCS, 2 -#define OID_PKCS_3 OID_PKCS, 3 -#define OID_PKCS_4 OID_PKCS, 4 -#define OID_PKCS_5 OID_PKCS, 5 -#define OID_PKCS_6 OID_PKCS, 6 -#define OID_PKCS_7 OID_PKCS, 7 -#define OID_PKCS_8 OID_PKCS, 8 -#define OID_PKCS_9 OID_PKCS, 9 -#define OID_PKCS_10 OID_PKCS, 10 -#define OID_PKCS_11 OID_PKCS, 11 -#define OID_PKCS_12 OID_PKCS, 12 - -/* ANSI X9.62 */ -#define OID_ANSI_X9_62 OID_US, 206, 61 -#define OID_PUBLIC_KEY_TYPE OID_ANSI_X9_62, 2 -#define OID_EC_CURVE OID_ANSI_X9_62, 3, 1 -#define OID_EC_SIG_TYPE OID_ANSI_X9_62, 4 -#define OID_ECDSA_WITH_SHA2 OID_EC_SIG_TYPE, 3 - -/* Certicom */ -#define OID_CERTICOM OID_ISO_IDENTIFIED_ORG, 132 -#define OID_CERTICOM_EC_CURVE OID_CERTICOM, 0 - -/* ANSI X9.42 */ -#define OID_ANSI_X9_42 OID_US, 206, 62, 2 -#define OID_ANSI_X9_42_SCHEME OID_ANSI_X9_42, 3 -#define OID_ANSI_X9_42_NAMED_SCHEME OID_ANSI_X9_42, 4 - -/* ANSI X9.57 */ -#define OID_ANSI_X9_57 OID_US, 206, 56 -#define OID_ANSI_X9_57_ALGORITHM OID_ANSI_X9_57, 4 - -/* DOD IANA Security related objects. */ -#define OID_IANA OID_DOD, 1, 5 - -/* Kerberos PKINIT */ -#define OID_KERBv5 OID_IANA, 2 -#define OID_KERBv5_PKINIT OID_KERBv5, 3 - -/* DOD IANA Mechanisms. */ -#define OID_MECHANISMS OID_IANA, 5 - -/* PKIX */ -#define OID_PKIX OID_MECHANISMS, 7 -#define OID_PE OID_PKIX, 1 -#define OID_QT OID_PKIX, 2 -#define OID_KP OID_PKIX, 3 -#define OID_OTHER_NAME OID_PKIX, 8 -#define OID_PDA OID_PKIX, 9 -#define OID_QCS OID_PKIX, 11 -#define OID_AD OID_PKIX, 48 -#define OID_AD_OCSP OID_AD, 1 -#define OID_AD_CAISSUERS OID_AD, 2 - -/* ISAKMP */ -#define OID_ISAKMP OID_MECHANISMS, 8 - -/* ETSI */ -#define OID_ETSI 0x04, 0x00 -#define OID_ETSI_QCS 0x04, 0x00, 0x8E, 0x46, 0x01 - -#define OID_OIW_SECSIG OID_OIW, 3 - -#define OID_OIW_ALGORITHM OID_OIW_SECSIG, 2 - -/* NIST defined digest algorithm arc (2, 16, 840, 1, 101, 3, 4, 2) */ -#define OID_NIST_HASHALG 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02 - -/* - * Apple-specific OID bases - */ - -/* - * apple OBJECT IDENTIFIER ::= - * { iso(1) member-body(2) US(840) 113635 } - * - * BER = 06 06 2A 86 48 86 F7 63 - */ -#define APPLE_OID OID_US, 0x86, 0xf7, 0x63 - -/* appleDataSecurity OBJECT IDENTIFIER ::= - * { apple 100 } - * { 1 2 840 113635 100 } - * - * BER = 06 07 2A 86 48 86 F7 63 64 - */ -#define APPLE_ADS_OID APPLE_OID, 0x64 - -/* - * appleTrustPolicy OBJECT IDENTIFIER ::= - * { appleDataSecurity 1 } - * { 1 2 840 113635 100 1 } - * - * BER = 06 08 2A 86 48 86 F7 63 64 01 - */ -#define APPLE_TP_OID APPLE_ADS_OID, 1 - -/* - * appleSecurityAlgorithm OBJECT IDENTIFIER ::= - * { appleDataSecurity 2 } - * { 1 2 840 113635 100 2 } - * - * BER = 06 08 2A 86 48 86 F7 63 64 02 - */ -#define APPLE_ALG_OID APPLE_ADS_OID, 2 - -/* - * appleDotMacCertificate OBJECT IDENTIFIER ::= - * { appleDataSecurity 3 } - * { 1 2 840 113635 100 3 } - */ -#define APPLE_DOTMAC_CERT_OID APPLE_ADS_OID, 3 - -/* - * Basis of Policy OIDs for .mac TP requests - * - * dotMacCertificateRequest OBJECT IDENTIFIER ::= - * { appleDotMacCertificate 1 } - * { 1 2 840 113635 100 3 1 } - */ -#define APPLE_DOTMAC_CERT_REQ_OID APPLE_DOTMAC_CERT_OID, 1 - -/* - * Basis of .mac Certificate Extensions - * - * dotMacCertificateExtension OBJECT IDENTIFIER ::= - * { appleDotMacCertificate 2 } - * { 1 2 840 113635 100 3 2 } - */ -#define APPLE_DOTMAC_CERT_EXTEN_OID APPLE_DOTMAC_CERT_OID, 2 - -/* - * Basis of .mac Certificate request OID/value identitifiers - * - * dotMacCertificateRequestValues OBJECT IDENTIFIER ::= - * { appleDotMacCertificate 3 } - * { 1 2 840 113635 100 3 3 } - */ -#define APPLE_DOTMAC_CERT_REQ_VALUE_OID APPLE_DOTMAC_CERT_OID, 3 - -/* - * Basis of Apple-specific extended key usages - * - * appleExtendedKeyUsage OBJECT IDENTIFIER ::= - * { appleDataSecurity 4 } - * { 1 2 840 113635 100 4 } - */ -#define APPLE_EKU_OID APPLE_ADS_OID, 4 - -/* - * Basis of Apple Code Signing extended key usages - * appleCodeSigning OBJECT IDENTIFIER ::= - * { appleExtendedKeyUsage 1 } - * { 1 2 840 113635 100 4 1} - */ -#define APPLE_EKU_CODE_SIGNING APPLE_EKU_OID, 1 -#define APPLE_EKU_APPLE_ID APPLE_EKU_OID, 7 -#define APPLE_EKU_PASSBOOK APPLE_EKU_OID, 14 -#define APPLE_EKU_PROFILE_SIGNING APPLE_EKU_OID, 16 -#define APPLE_EKU_QA_PROFILE_SIGNING APPLE_EKU_OID, 17 - - -/* - * Basis of Apple-specific Certificate Policy IDs. - * appleCertificatePolicies OBJECT IDENTIFIER ::= - * { appleDataSecurity 5 } - * { 1 2 840 113635 100 5 } - */ -#define APPLE_CERT_POLICIES APPLE_ADS_OID, 5 - -#define APPLE_CERT_POLICY_MOBILE_STORE APPLE_CERT_POLICIES, 12 - -#define APPLE_CERT_POLICY_MOBILE_STORE_PRODQA APPLE_CERT_POLICY_MOBILE_STORE, 1 - -/* - * Basis of Apple-specific Signing extensions - * { appleDataSecurity 6 } - */ -#define APPLE_CERT_EXT APPLE_ADS_OID, 6 - -/* Apple Intermediate Marker OIDs */ -#define APPLE_CERT_EXT_INTERMEDIATE_MARKER APPLE_CERT_EXT, 2 - -/* Apple Worldwide Developer Relations Certification Authority */ -/* 1.2.840.113635.100.6.2.1 */ -#define APPLE_CERT_EXT_INTERMEDIATE_MARKER_WWDR APPLE_CERT_EXT_INTERMEDIATE_MARKER, 1 - -/* Apple Apple ID Intermediate Marker */ -#define APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID APPLE_CERT_EXT_INTERMEDIATE_MARKER, 3 - -/* - * Apple Apple ID Intermediate Marker (New subCA, no longer shared with push notification server cert issuer - * - * appleCertificateExtensionAppleIDIntermediate ::= - * { appleCertificateExtensionIntermediateMarker 7 } - * { 1 2 840 113635 100 6 2 7 } - */ -#define APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID_2 APPLE_CERT_EXT_INTERMEDIATE_MARKER, 7 - -#define APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID_SYSTEM_INTEGRATION_2 APPLE_CERT_EXT_INTERMEDIATE_MARKER, 10 - -#define APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID_SYSTEM_INTEGRATION_G3 APPLE_CERT_EXT_INTERMEDIATE_MARKER, 13 - -#define APPLE_CERT_EXT_APPLE_PUSH_MARKER APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID, 2 - - -#define APPLE_CERT_EXTENSION_CODESIGNING APPLE_CERT_EXT, 1 - -/* Secure Boot Embedded Image3 value, - co-opted by desktop for "Apple Released Code Signature", without value */ -#define APPLE_SBOOT_CERT_EXTEN_SBOOT_SPEC_OID APPLE_CERT_EXTENSION_CODESIGNING, 1 -#define APPLE_SBOOT_CERT_EXTEN_SBOOT_TICKET_SPEC_OID APPLE_CERT_EXTENSION_CODESIGNING, 11 -#define APPLE_SBOOT_CERT_EXTEN_IMG4_MANIFEST_SPEC_OID APPLE_CERT_EXTENSION_CODESIGNING, 15 - -/* iPhone Provisioning Profile Signing leaf - on the intermediate marker arc? */ -#define APPLE_PROVISIONING_PROFILE_OID APPLE_CERT_EXT_INTERMEDIATE_MARKER, 1 -/* iPhone Application Signing leaf */ -#define APPLE_APP_SIGNING_OID APPLE_CERT_EXTENSION_CODESIGNING, 3 - -#define APPLE_INSTALLER_PACKAGE_SIGNING_EXTERNAL_OID APPLE_CERT_EXTENSION_CODESIGNING, 16 - -/* Apple TVOS Application Signing leaf, production */ -/* 1.2.840.113635.100.6.1.24 */ -#define APPLE_TVOS_APP_SIGNING_PROD_OID APPLE_CERT_EXTENSION_CODESIGNING, 24 - -/* Apple TVOS Application Signing leaf, QA */ -/* 1.2.840.113635.100.6.1.24.1 */ - -#define APPLE_TVOS_APP_SIGNING_PRODQA_OID APPLE_CERT_EXTENSION_CODESIGNING, 24, 1 - -#define APPLE_ESCROW_ARC APPLE_CERT_EXT, 23 - -#define APPLE_ESCROW_POLICY_OID APPLE_ESCROW_ARC, 1 - -#define APPLE_CERT_EXT_APPLE_ID_VALIDATION_RECORD_SIGNING APPLE_CERT_EXT, 25 - -#define APPLE_SERVER_AUTHENTICATION APPLE_CERT_EXT, 27 -#define APPLE_CERT_EXT_APPLE_SERVER_AUTHENTICATION APPLE_SERVER_AUTHENTICATION, 1 -#define APPLE_CERT_EXT_APPLE_SERVER_AUTHENTICATION_PPQ_PRODQA APPLE_SERVER_AUTHENTICATION, 3, 1 -#define APPLE_CERT_EXT_APPLE_SERVER_AUTHENTICATION_PPQ_PROD APPLE_SERVER_AUTHENTICATION, 3, 2 -#define APPLE_CERT_EXT_APPLE_SERVER_AUTHENTICATION_IDS_PRODQA APPLE_SERVER_AUTHENTICATION, 4, 1 -#define APPLE_CERT_EXT_APPLE_SERVER_AUTHENTICATION_IDS_PROD APPLE_SERVER_AUTHENTICATION, 4, 2 -#define APPLE_CERT_EXT_APPLE_SERVER_AUTHENTICATION_APN_PRODQA APPLE_SERVER_AUTHENTICATION, 5, 1 -#define APPLE_CERT_EXT_APPLE_SERVER_AUTHENTICATION_APN_PROD APPLE_SERVER_AUTHENTICATION, 5, 2 - -#define APPLE_CERT_EXT_APPLE_SERVER_AUTHENTICATION_GS APPLE_SERVER_AUTHENTICATION, 2 - - -#define APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLE_SERVER_AUTHENTICATION APPLE_CERT_EXT_INTERMEDIATE_MARKER, 12 - -#define APPLE_CERT_EXT_APPLE_SMP_ENCRYPTION APPLE_CERT_EXT, 30 - -/* UPP fraud detection (Provisioning Profile Query) CMS signing */ - -#define APPLE_CERT_EXT_APPLE_PPQ_SIGNING_PRODQA APPLE_CERT_EXT, 38, 1 -#define APPLE_CERT_EXT_APPLE_PPQ_SIGNING_PROD APPLE_CERT_EXT, 38, 2 - -/* AppleTVOS Application Signing */ -#define APPLE_ATV_APP_SIGNING_OID APPLE_CERT_EXTENSION_CODESIGNING, 24 -#define APPLE_ATV_APP_SIGNING_OID_PRODQA APPLE_ATV_APP_SIGNING_OID, 1 - -/* Apple Pay Issuer Encryption */ -#define APPLE_CERT_EXT_CRYPTO_SERVICES_EXT_ENCRYPTION APPLE_CERT_EXT, 39 - -/* Apple OS X Provisioning Profile Signing */ -/* (note this OID is unfortunately used as a cert extension even though it's under the EKU arc) */ -#define APPLE_CERT_EXT_OSX_PROVISIONING_PROFILE_SIGNING APPLE_EKU_OID, 11 - -/* AppleTV VPN Profile Signing 1.2.840.113635.100.6.43 */ -#define APPLE_CERT_EXT_APPLE_ATV_VPN_PROFILE_SIGNING APPLE_CERT_EXT, 43 - -/* AST2 Diagnostics Server Authentication - * QA Marker OID 1.2.840.113635.100.6.27.8.1 - * Prod Marker OID 1.2.840.113635.100.6.27.8.2 - */ -#define APPLE_CERT_EXT_AST2_DIAGNOSTICS_SERVER_AUTH_PRODQA APPLE_SERVER_AUTHENTICATION, 8, 1 -#define APPLE_CERT_EXT_AST2_DIAGNOSTICS_SERVER_AUTH_PROD APPLE_SERVER_AUTHENTICATION, 8, 2 - -/* Escrow Proxy Server Authentication - * QA Marker OID 1.2.840.113635.100.6.27.7.1 - * Prod Marker OID 1.2.840.113635.100.6.27.7.2 - */ -#define APPLE_CERT_EXT_ESCROW_PROXY_SERVER_AUTH_PRODQA APPLE_SERVER_AUTHENTICATION, 7, 1 -#define APPLE_CERT_EXT_ESCROW_PROXY_SERVER_AUTH_PROD APPLE_SERVER_AUTHENTICATION, 7, 2 - -/* FMiP Server Authentication - * QA Marker OID 1.2.840.113635.100.6.27.6.1 - * Prod Marker OID 1.2.840.113635.100.6.27.6.2 - */ -#define APPLE_CERT_EXT_FMIP_SERVER_AUTH_PRODQA APPLE_SERVER_AUTHENTICATION, 6, 1 -#define APPLE_CERT_EXT_FMIP_SERVER_AUTH_PROD APPLE_SERVER_AUTHENTICATION, 6, 2 - -/* HomeKit Server Authentication - * Intermediate Marker OID: 1.2.840.113635.100.6.2.16 - * Leaf Marker OID: 1.2.840.113635.100.6.27.9 - */ -#define APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLE_HOME_KIT_SERVER_AUTH APPLE_CERT_EXT_INTERMEDIATE_MARKER, 16 -#define APPLE_CERT_EXT_HOME_KIT_SERVER_AUTH APPLE_SERVER_AUTHENTICATION, 9 - -/* MMCS Server Authentication - * QA Marker OID 1.2.840.113635.100.6.27.11.1 - * Prod Marker OID 1.2.840.113635.100.6.27.11.2 - */ -#define APPLE_CERT_EXT_MMCS_SERVER_AUTH_PRODQA APPLE_SERVER_AUTHENTICATION, 11, 1 -#define APPLE_CERT_EXT_MMCS_SERVER_AUTH_PROD APPLE_SERVER_AUTHENTICATION, 11, 2 - -/* iCloud Setup Authentication - * QA Marker OID 1.2.840.113635.100.6.27.15.1 - * Prod Marker OID 1.2.840.113635.100.6.27.15.2 - */ -#define APPLE_CERT_EXT_ICLOUD_SETUP_SERVER_AUTH_PRODQA APPLE_SERVER_AUTHENTICATION, 15, 1 -#define APPLE_CERT_EXT_ICLOUD_SETUP_SERVER_AUTH_PROD APPLE_SERVER_AUTHENTICATION, 15, 2 - -/* - * Netscape OIDs. - */ -#define NETSCAPE_BASE_OID 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42 - -/* - * Netscape cert extension. - * - * netscape-cert-extension OBJECT IDENTIFIER ::= - * { 2 16 840 1 113730 1 } - * - * BER = 06 08 60 86 48 01 86 F8 42 01 - */ -#define NETSCAPE_CERT_EXTEN NETSCAPE_BASE_OID, 0x01 - -#define NETSCAPE_CERT_POLICY NETSCAPE_BASE_OID, 0x04 - -/* Entrust OIDs. */ -#define ENTRUST_BASE_OID OID_US, 0x86, 0xf6, 0x7d - -/* - * Entrust cert extension. - * - * entrust-cert-extension OBJECT IDENTIFIER ::= - * { 1 2 840 113533 7 65 } - * - * BER = 06 08 2A 86 48 86 F6 7D 07 41 - */ -#define ENTRUST_CERT_EXTEN ENTRUST_BASE_OID, 0x07, 0x41 - -/* Microsoft OIDs. */ -#define MICROSOFT_BASE_OID OID_DOD, 0x01, 0x04, 0x01, 0x82, 0x37 -#define MICROSOFT_ENROLLMENT_OID MICROSOFT_BASE_OID, 0x14 - -/* Google OIDs: 1.3.6.1.4.1.11129. - */ -#define GOOGLE_BASE_OID OID_DOD, 0x01, 0x04, 0x01, 0xD6, 0x79 -#define GOOGLE_EMBEDDED_SCT_OID GOOGLE_BASE_OID, 0x02, 0x04, 0x02 -#define GOOGLE_OCSP_SCT_OID GOOGLE_BASE_OID, 0x02, 0x04, 0x05 - - -/* Algorithm OIDs. */ -static const DERByte - _oidRsa[] = { OID_PKCS_1, 1 }, - _oidMd2Rsa[] = { OID_PKCS_1, 2 }, - _oidMd4Rsa[] = { OID_PKCS_1, 3 }, - _oidMd5Rsa[] = { OID_PKCS_1, 4 }, - _oidSha1Rsa[] = { OID_PKCS_1, 5 }, - _oidSha256Rsa[] = { OID_PKCS_1, 11 }, /* rfc5754 */ - _oidSha384Rsa[] = { OID_PKCS_1, 12 }, /* rfc5754 */ - _oidSha512Rsa[] = { OID_PKCS_1, 13 }, /* rfc5754 */ - _oidSha224Rsa[] = { OID_PKCS_1, 14 }, /* rfc5754 */ - _oidEcPubKey[] = { OID_PUBLIC_KEY_TYPE, 1 }, - _oidSha1Ecdsa[] = { OID_EC_SIG_TYPE, 1 }, /* rfc3279 */ - _oidSha224Ecdsa[] = { OID_ECDSA_WITH_SHA2, 1 }, /* rfc5758 */ - _oidSha256Ecdsa[] = { OID_ECDSA_WITH_SHA2, 2 }, /* rfc5758 */ - _oidSha384Ecdsa[] = { OID_ECDSA_WITH_SHA2, 3 }, /* rfc5758 */ - _oidSha512Ecdsa[] = { OID_ECDSA_WITH_SHA2, 4 }, /* rfc5758 */ - _oidSha1Dsa[] = { OID_ANSI_X9_57_ALGORITHM, 3 }, - _oidMd2[] = { OID_RSA_HASH, 2 }, - _oidMd4[] = { OID_RSA_HASH, 4 }, - _oidMd5[] = { OID_RSA_HASH, 5 }, - _oidSha1[] = { OID_OIW_ALGORITHM, 26 }, - _oidSha1DsaOIW[] = { OID_OIW_ALGORITHM, 27 }, - _oidSha1DsaCommonOIW[] = { OID_OIW_ALGORITHM, 28 }, - _oidSha1RsaOIW[] = { OID_OIW_ALGORITHM, 29 }, - _oidSha256[] = { OID_NIST_HASHALG, 1 }, - _oidSha384[] = { OID_NIST_HASHALG, 2 }, - _oidSha512[] = { OID_NIST_HASHALG, 3 }, - _oidSha224[] = { OID_NIST_HASHALG, 4 }, - _oidFee[] = { APPLE_ALG_OID, 1 }, - _oidMd5Fee[] = { APPLE_ALG_OID, 3 }, - _oidSha1Fee[] = { APPLE_ALG_OID, 4 }, - _oidEcPrime192v1[] = { OID_EC_CURVE, 1 }, - _oidEcPrime256v1[] = { OID_EC_CURVE, 7 }, - _oidAnsip384r1[] = { OID_CERTICOM_EC_CURVE, 34 }, - _oidAnsip521r1[] = { OID_CERTICOM_EC_CURVE, 35 }; - -const DERItem - oidRsa = { (DERByte *)_oidRsa, - sizeof(_oidRsa) }, - oidMd2Rsa = { (DERByte *)_oidMd2Rsa, - sizeof(_oidMd2Rsa) }, - oidMd4Rsa = { (DERByte *)_oidMd4Rsa, - sizeof(_oidMd4Rsa) }, - oidMd5Rsa = { (DERByte *)_oidMd5Rsa, - sizeof(_oidMd5Rsa) }, - oidSha1Rsa = { (DERByte *)_oidSha1Rsa, - sizeof(_oidSha1Rsa) }, - oidSha256Rsa = { (DERByte *)_oidSha256Rsa, - sizeof(_oidSha256Rsa) }, - oidSha384Rsa = { (DERByte *)_oidSha384Rsa, - sizeof(_oidSha384Rsa) }, - oidSha512Rsa = { (DERByte *)_oidSha512Rsa, - sizeof(_oidSha512Rsa) }, - oidSha224Rsa = { (DERByte *)_oidSha224Rsa, - sizeof(_oidSha224Rsa) }, - oidEcPubKey = { (DERByte *)_oidEcPubKey, - sizeof(_oidEcPubKey) }, - oidSha1Ecdsa = { (DERByte *)_oidSha1Ecdsa, - sizeof(_oidSha1Ecdsa) }, - oidSha224Ecdsa = { (DERByte *)_oidSha224Ecdsa, - sizeof(_oidSha224Ecdsa) }, - oidSha256Ecdsa = { (DERByte *)_oidSha256Ecdsa, - sizeof(_oidSha256Ecdsa) }, - oidSha384Ecdsa = { (DERByte *)_oidSha384Ecdsa, - sizeof(_oidSha384Ecdsa) }, - oidSha512Ecdsa = { (DERByte *)_oidSha512Ecdsa, - sizeof(_oidSha512Ecdsa) }, - oidSha1Dsa = { (DERByte *)_oidSha1Dsa, - sizeof(_oidSha1Dsa) }, - oidMd2 = { (DERByte *)_oidMd2, - sizeof(_oidMd2) }, - oidMd4 = { (DERByte *)_oidMd4, - sizeof(_oidMd4) }, - oidMd5 = { (DERByte *)_oidMd5, - sizeof(_oidMd5) }, - oidSha1 = { (DERByte *)_oidSha1, - sizeof(_oidSha1) }, - oidSha1RsaOIW = { (DERByte *)_oidSha1RsaOIW, - sizeof(_oidSha1RsaOIW) }, - oidSha1DsaOIW = { (DERByte *)_oidSha1DsaOIW, - sizeof(_oidSha1DsaOIW) }, - oidSha1DsaCommonOIW = { (DERByte *)_oidSha1DsaCommonOIW, - sizeof(_oidSha1DsaCommonOIW) }, - oidSha256 = { (DERByte *)_oidSha256, - sizeof(_oidSha256) }, - oidSha384 = { (DERByte *)_oidSha384, - sizeof(_oidSha384) }, - oidSha512 = { (DERByte *)_oidSha512, - sizeof(_oidSha512) }, - oidSha224 = { (DERByte *)_oidSha224, - sizeof(_oidSha224) }, - oidFee = { (DERByte *)_oidFee, - sizeof(_oidFee) }, - oidMd5Fee = { (DERByte *)_oidMd5Fee, - sizeof(_oidMd5Fee) }, - oidSha1Fee = { (DERByte *)_oidSha1Fee, - sizeof(_oidSha1Fee) }, - oidEcPrime192v1 = { (DERByte *)_oidEcPrime192v1, - sizeof(_oidEcPrime192v1) }, - oidEcPrime256v1 = { (DERByte *)_oidEcPrime256v1, - sizeof(_oidEcPrime256v1) }, - oidAnsip384r1 = { (DERByte *)_oidAnsip384r1, - sizeof(_oidAnsip384r1) }, - oidAnsip521r1 = { (DERByte *)_oidAnsip521r1, - sizeof(_oidAnsip521r1) }; - - -/* Extension OIDs. */ -__unused static const DERByte - _oidSubjectKeyIdentifier[] = { OID_EXTENSION, 14 }, - _oidKeyUsage[] = { OID_EXTENSION, 15 }, - _oidPrivateKeyUsagePeriod[] = { OID_EXTENSION, 16 }, - _oidSubjectAltName[] = { OID_EXTENSION, 17 }, - _oidIssuerAltName[] = { OID_EXTENSION, 18 }, - _oidBasicConstraints[] = { OID_EXTENSION, 19 }, - _oidNameConstraints[] = { OID_EXTENSION, 30 }, - _oidCrlDistributionPoints[] = { OID_EXTENSION, 31 }, - _oidCertificatePolicies[] = { OID_EXTENSION, 32 }, - _oidAnyPolicy[] = { OID_EXTENSION, 32, 0 }, - _oidPolicyMappings[] = { OID_EXTENSION, 33 }, - _oidAuthorityKeyIdentifier[] = { OID_EXTENSION, 35 }, - _oidPolicyConstraints[] = { OID_EXTENSION, 36 }, - _oidExtendedKeyUsage[] = { OID_EXTENSION, 37 }, - _oidAnyExtendedKeyUsage[] = { OID_EXTENSION, 37, 0 }, - _oidInhibitAnyPolicy[] = { OID_EXTENSION, 54 }, - _oidAuthorityInfoAccess[] = { OID_PE, 1 }, - _oidSubjectInfoAccess[] = { OID_PE, 11 }, - _oidAdOCSP[] = { OID_AD_OCSP }, - _oidAdCAIssuer[] = { OID_AD_CAISSUERS }, - _oidNetscapeCertType[] = { NETSCAPE_CERT_EXTEN, 1 }, - _oidEntrustVersInfo[] = { ENTRUST_CERT_EXTEN, 0 }, - _oidMSNTPrincipalName[] = { MICROSOFT_ENROLLMENT_OID, 2, 3 }, - /* Policy Qualifier IDs for Internet policy qualifiers. */ - _oidQtCps[] = { OID_QT, 1 }, - _oidQtUNotice[] = { OID_QT, 2 }, - /* X.501 Name IDs. */ - _oidCommonName[] = { OID_ATTR_TYPE, 3 }, - _oidCountryName[] = { OID_ATTR_TYPE, 6 }, - _oidLocalityName[] = { OID_ATTR_TYPE, 7 }, - _oidStateOrProvinceName[] = { OID_ATTR_TYPE, 8 }, - _oidOrganizationName[] = { OID_ATTR_TYPE, 10 }, - _oidOrganizationalUnitName[] = { OID_ATTR_TYPE, 11 }, - _oidDescription[] = { OID_ATTR_TYPE, 13 }, - _oidEmailAddress[] = { OID_PKCS_9, 1 }, - _oidFriendlyName[] = { OID_PKCS_9, 20 }, - _oidLocalKeyId[] = { OID_PKCS_9, 21 }, - _oidExtendedKeyUsageServerAuth[] = { OID_KP, 1 }, - _oidExtendedKeyUsageClientAuth[] = { OID_KP, 2 }, - _oidExtendedKeyUsageCodeSigning[] = { OID_KP, 3 }, - _oidExtendedKeyUsageEmailProtection[] = { OID_KP, 4 }, - _oidExtendedKeyUsageTimeStamping[] = { OID_KP, 8 }, - _oidExtendedKeyUsageOCSPSigning[] = { OID_KP, 9 }, - _oidExtendedKeyUsageIPSec[] = { OID_ISAKMP, 2, 2 }, - _oidExtendedKeyUsageMicrosoftSGC[] = { MICROSOFT_BASE_OID, 10, 3, 3 }, - _oidExtendedKeyUsageNetscapeSGC[] = { NETSCAPE_CERT_POLICY, 1 }, - _oidAppleSecureBootCertSpec[] = { APPLE_SBOOT_CERT_EXTEN_SBOOT_SPEC_OID }, - _oidAppleSecureBootTicketCertSpec[] = { APPLE_SBOOT_CERT_EXTEN_SBOOT_TICKET_SPEC_OID }, - _oidAppleImg4ManifestCertSpec[] = { APPLE_SBOOT_CERT_EXTEN_IMG4_MANIFEST_SPEC_OID }, - _oidAppleProvisioningProfile[] = {APPLE_PROVISIONING_PROFILE_OID }, - _oidAppleApplicationSigning[] = { APPLE_APP_SIGNING_OID }, - _oidAppleInstallerPackagingSigningExternal[] = { APPLE_INSTALLER_PACKAGE_SIGNING_EXTERNAL_OID }, - _oidAppleTVOSApplicationSigningProd[] = { APPLE_TVOS_APP_SIGNING_PROD_OID }, - _oidAppleTVOSApplicationSigningProdQA[] = { APPLE_TVOS_APP_SIGNING_PRODQA_OID }, - _oidAppleExtendedKeyUsageCodeSigning[] = { APPLE_EKU_CODE_SIGNING }, - _oidAppleExtendedKeyUsageCodeSigningDev[] = { APPLE_EKU_CODE_SIGNING, 1 }, - _oidAppleExtendedKeyUsageAppleID[] = { APPLE_EKU_APPLE_ID }, - _oidAppleExtendedKeyUsagePassbook[] = { APPLE_EKU_PASSBOOK }, - _oidAppleExtendedKeyUsageProfileSigning[] = { APPLE_EKU_PROFILE_SIGNING }, - _oidAppleExtendedKeyUsageQAProfileSigning[] = { APPLE_EKU_QA_PROFILE_SIGNING }, - _oidAppleIntmMarkerAppleWWDR[] = { APPLE_CERT_EXT_INTERMEDIATE_MARKER_WWDR }, - _oidAppleIntmMarkerAppleID[] = { APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID }, - _oidAppleIntmMarkerAppleID2[] = {APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID_2 }, - _oidApplePushServiceClient[] = { APPLE_CERT_EXT_APPLE_PUSH_MARKER, 2 }, - _oidApplePolicyMobileStore[] = { APPLE_CERT_POLICY_MOBILE_STORE }, - _oidApplePolicyMobileStoreProdQA[] = { APPLE_CERT_POLICY_MOBILE_STORE_PRODQA }, - _oidApplePolicyEscrowService[] = { APPLE_ESCROW_POLICY_OID }, - _oidAppleCertExtensionAppleIDRecordValidationSigning[] = { APPLE_CERT_EXT_APPLE_ID_VALIDATION_RECORD_SIGNING }, - _oidAppleCertExtOSXProvisioningProfileSigning[] = { APPLE_CERT_EXT_OSX_PROVISIONING_PROFILE_SIGNING }, - _oidAppleIntmMarkerAppleSystemIntg2[] = {APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID_SYSTEM_INTEGRATION_2}, - _oidAppleIntmMarkerAppleSystemIntgG3[] = {APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLEID_SYSTEM_INTEGRATION_G3}, - _oidAppleCertExtAppleSMPEncryption[] = {APPLE_CERT_EXT_APPLE_SMP_ENCRYPTION}, - _oidAppleCertExtAppleServerAuthentication[] = {APPLE_CERT_EXT_APPLE_SERVER_AUTHENTICATION}, - _oidAppleCertExtAppleServerAuthenticationPPQProdQA[] = {APPLE_CERT_EXT_APPLE_SERVER_AUTHENTICATION_PPQ_PRODQA}, - _oidAppleCertExtAppleServerAuthenticationPPQProd[] = {APPLE_CERT_EXT_APPLE_SERVER_AUTHENTICATION_PPQ_PROD}, - _oidAppleCertExtAppleServerAuthenticationIDSProdQA[] = {APPLE_CERT_EXT_APPLE_SERVER_AUTHENTICATION_IDS_PRODQA}, - _oidAppleCertExtAppleServerAuthenticationIDSProd[] = {APPLE_CERT_EXT_APPLE_SERVER_AUTHENTICATION_IDS_PROD}, - _oidAppleCertExtAppleServerAuthenticationAPNProdQA[] = {APPLE_CERT_EXT_APPLE_SERVER_AUTHENTICATION_APN_PRODQA}, - _oidAppleCertExtAppleServerAuthenticationAPNProd[] = {APPLE_CERT_EXT_APPLE_SERVER_AUTHENTICATION_APN_PROD}, - _oidAppleCertExtAppleServerAuthenticationGS[] = {APPLE_CERT_EXT_APPLE_SERVER_AUTHENTICATION_GS}, - _oidAppleIntmMarkerAppleServerAuthentication[] = {APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLE_SERVER_AUTHENTICATION}, - _oidAppleCertExtApplePPQSigningProdQA[] = {APPLE_CERT_EXT_APPLE_PPQ_SIGNING_PRODQA}, - _oidAppleCertExtApplePPQSigningProd[] = {APPLE_CERT_EXT_APPLE_PPQ_SIGNING_PROD}, - _oidGoogleEmbeddedSignedCertificateTimestamp[] = {GOOGLE_EMBEDDED_SCT_OID}, - _oidGoogleOCSPSignedCertificateTimestamp[] = {GOOGLE_OCSP_SCT_OID}, - _oidAppleCertExtATVAppSigningProdQA[] = {APPLE_ATV_APP_SIGNING_OID_PRODQA}, - _oidAppleCertExtATVAppSigningProd[] = {APPLE_ATV_APP_SIGNING_OID}, - _oidAppleCertExtATVVPNProfileSigning[] = {APPLE_CERT_EXT_APPLE_ATV_VPN_PROFILE_SIGNING}, - _oidAppleCertExtCryptoServicesExtEncryption[] = {APPLE_CERT_EXT_CRYPTO_SERVICES_EXT_ENCRYPTION}, - _oidAppleCertExtAST2DiagnosticsServerAuthProdQA[] = {APPLE_CERT_EXT_AST2_DIAGNOSTICS_SERVER_AUTH_PRODQA}, - _oidAppleCertExtAST2DiagnosticsServerAuthProd[] = {APPLE_CERT_EXT_AST2_DIAGNOSTICS_SERVER_AUTH_PROD}, - _oidAppleCertExtEscrowProxyServerAuthProdQA[] = {APPLE_CERT_EXT_ESCROW_PROXY_SERVER_AUTH_PRODQA}, - _oidAppleCertExtEscrowProxyServerAuthProd[] = {APPLE_CERT_EXT_ESCROW_PROXY_SERVER_AUTH_PROD}, - _oidAppleCertExtFMiPServerAuthProdQA[] = {APPLE_CERT_EXT_FMIP_SERVER_AUTH_PRODQA}, - _oidAppleCertExtFMiPServerAuthProd[] = {APPLE_CERT_EXT_FMIP_SERVER_AUTH_PROD}, - _oidAppleCertExtHomeKitServerAuth[] = {APPLE_CERT_EXT_HOME_KIT_SERVER_AUTH}, - _oidAppleIntmMarkerAppleHomeKitServerCA[] = {APPLE_CERT_EXT_INTERMEDIATE_MARKER_APPLE_HOME_KIT_SERVER_AUTH}, - _oidAppleCertExtMMCSServerAuthProdQA[] = {APPLE_CERT_EXT_MMCS_SERVER_AUTH_PRODQA}, - _oidAppleCertExtMMCSServerAuthProd[] = {APPLE_CERT_EXT_MMCS_SERVER_AUTH_PROD}, - _oidAppleCertExtiCloudSetupServerAuthProdQA[] = {APPLE_CERT_EXT_ICLOUD_SETUP_SERVER_AUTH_PRODQA}, - _oidAppleCertExtiCloudSetupServerAuthProd[] = {APPLE_CERT_EXT_ICLOUD_SETUP_SERVER_AUTH_PROD}; - -__unused const DERItem - oidSubjectKeyIdentifier = { (DERByte *)_oidSubjectKeyIdentifier, - sizeof(_oidSubjectKeyIdentifier) }, - oidKeyUsage = { (DERByte *)_oidKeyUsage, - sizeof(_oidKeyUsage) }, - oidPrivateKeyUsagePeriod = { (DERByte *)_oidPrivateKeyUsagePeriod, - sizeof(_oidPrivateKeyUsagePeriod) }, - oidSubjectAltName = { (DERByte *)_oidSubjectAltName, - sizeof(_oidSubjectAltName) }, - oidIssuerAltName = { (DERByte *)_oidIssuerAltName, - sizeof(_oidIssuerAltName) }, - oidBasicConstraints = { (DERByte *)_oidBasicConstraints, - sizeof(_oidBasicConstraints) }, - oidNameConstraints = { (DERByte *)_oidNameConstraints, - sizeof(_oidNameConstraints) }, - oidCrlDistributionPoints = { (DERByte *)_oidCrlDistributionPoints, - sizeof(_oidCrlDistributionPoints) }, - oidCertificatePolicies = { (DERByte *)_oidCertificatePolicies, - sizeof(_oidCertificatePolicies) }, - oidAnyPolicy = { (DERByte *)_oidAnyPolicy, - sizeof(_oidAnyPolicy) }, - oidPolicyMappings = { (DERByte *)_oidPolicyMappings, - sizeof(_oidPolicyMappings) }, - oidAuthorityKeyIdentifier = { (DERByte *)_oidAuthorityKeyIdentifier, - sizeof(_oidAuthorityKeyIdentifier) }, - oidPolicyConstraints = { (DERByte *)_oidPolicyConstraints, - sizeof(_oidPolicyConstraints) }, - oidExtendedKeyUsage = { (DERByte *)_oidExtendedKeyUsage, - sizeof(_oidExtendedKeyUsage) }, - oidAnyExtendedKeyUsage = { (DERByte *)_oidAnyExtendedKeyUsage, - sizeof(_oidAnyExtendedKeyUsage) }, - oidInhibitAnyPolicy = { (DERByte *)_oidInhibitAnyPolicy, - sizeof(_oidInhibitAnyPolicy) }, - oidAuthorityInfoAccess = { (DERByte *)_oidAuthorityInfoAccess, - sizeof(_oidAuthorityInfoAccess) }, - oidSubjectInfoAccess = { (DERByte *)_oidSubjectInfoAccess, - sizeof(_oidSubjectInfoAccess) }, - oidAdOCSP = { (DERByte *)_oidAdOCSP, - sizeof(_oidAdOCSP) }, - oidAdCAIssuer = { (DERByte *)_oidAdCAIssuer, - sizeof(_oidAdCAIssuer) }, - oidNetscapeCertType = { (DERByte *)_oidNetscapeCertType, - sizeof(_oidNetscapeCertType) }, - oidEntrustVersInfo = { (DERByte *)_oidEntrustVersInfo, - sizeof(_oidEntrustVersInfo) }, - oidMSNTPrincipalName = { (DERByte *)_oidMSNTPrincipalName, - sizeof(_oidMSNTPrincipalName) }, - /* Policy Qualifier IDs for Internet policy qualifiers. */ - oidQtCps = { (DERByte *)_oidQtCps, - sizeof(_oidQtCps) }, - oidQtUNotice = { (DERByte *)_oidQtUNotice, - sizeof(_oidQtUNotice) }, - /* X.501 Name IDs. */ - oidCommonName = { (DERByte *)_oidCommonName, - sizeof(_oidCommonName) }, - oidCountryName = { (DERByte *)_oidCountryName, - sizeof(_oidCountryName) }, - oidLocalityName = { (DERByte *)_oidLocalityName, - sizeof(_oidLocalityName) }, - oidStateOrProvinceName = { (DERByte *)_oidStateOrProvinceName, - sizeof(_oidStateOrProvinceName) }, - oidOrganizationName = { (DERByte *)_oidOrganizationName, - sizeof(_oidOrganizationName) }, - oidOrganizationalUnitName = { (DERByte *)_oidOrganizationalUnitName, - sizeof(_oidOrganizationalUnitName) }, - oidDescription = { (DERByte *)_oidDescription, - sizeof(_oidDescription) }, - oidEmailAddress = { (DERByte *)_oidEmailAddress, - sizeof(_oidEmailAddress) }, - oidFriendlyName = { (DERByte *)_oidFriendlyName, - sizeof(_oidFriendlyName) }, - oidLocalKeyId = { (DERByte *)_oidLocalKeyId, - sizeof(_oidLocalKeyId) }, - oidExtendedKeyUsageServerAuth = { (DERByte *)_oidExtendedKeyUsageServerAuth, - sizeof(_oidExtendedKeyUsageServerAuth) }, - oidExtendedKeyUsageClientAuth = { (DERByte *)_oidExtendedKeyUsageClientAuth, - sizeof(_oidExtendedKeyUsageClientAuth) }, - oidExtendedKeyUsageCodeSigning = { (DERByte *)_oidExtendedKeyUsageCodeSigning, - sizeof(_oidExtendedKeyUsageCodeSigning) }, - oidExtendedKeyUsageEmailProtection = { (DERByte *)_oidExtendedKeyUsageEmailProtection, - sizeof(_oidExtendedKeyUsageEmailProtection) }, - oidExtendedKeyUsageTimeStamping = { (DERByte *)_oidExtendedKeyUsageTimeStamping, - sizeof(_oidExtendedKeyUsageTimeStamping) }, - oidExtendedKeyUsageOCSPSigning = { (DERByte *)_oidExtendedKeyUsageOCSPSigning, - sizeof(_oidExtendedKeyUsageOCSPSigning) }, - oidExtendedKeyUsageIPSec = { (DERByte *)_oidExtendedKeyUsageIPSec, - sizeof(_oidExtendedKeyUsageIPSec) }, - oidExtendedKeyUsageMicrosoftSGC = { (DERByte *)_oidExtendedKeyUsageMicrosoftSGC, - sizeof(_oidExtendedKeyUsageMicrosoftSGC) }, - oidExtendedKeyUsageNetscapeSGC = { (DERByte *)_oidExtendedKeyUsageNetscapeSGC, - sizeof(_oidExtendedKeyUsageNetscapeSGC) }, - oidAppleSecureBootCertSpec = { (DERByte *)_oidAppleSecureBootCertSpec, - sizeof(_oidAppleSecureBootCertSpec) }, - oidAppleSecureBootTicketCertSpec = { (DERByte *)_oidAppleSecureBootTicketCertSpec, - sizeof(_oidAppleSecureBootTicketCertSpec) }, - oidAppleImg4ManifestCertSpec = { (DERByte *)_oidAppleImg4ManifestCertSpec, - sizeof(_oidAppleImg4ManifestCertSpec) }, - oidAppleProvisioningProfile = { (DERByte *)_oidAppleProvisioningProfile, - sizeof(_oidAppleProvisioningProfile) }, - oidAppleApplicationSigning = { (DERByte *)_oidAppleApplicationSigning, - sizeof(_oidAppleApplicationSigning) }, - oidAppleInstallerPackagingSigningExternal = { (DERByte *)_oidAppleInstallerPackagingSigningExternal, - sizeof(_oidAppleInstallerPackagingSigningExternal) }, - oidAppleTVOSApplicationSigningProd = { (DERByte *)_oidAppleTVOSApplicationSigningProd, - sizeof(_oidAppleTVOSApplicationSigningProd) }, - oidAppleTVOSApplicationSigningProdQA = { (DERByte *)_oidAppleTVOSApplicationSigningProdQA, - sizeof(_oidAppleTVOSApplicationSigningProdQA) }, - oidAppleExtendedKeyUsageCodeSigning = { (DERByte *)_oidAppleExtendedKeyUsageCodeSigning, - sizeof(_oidAppleExtendedKeyUsageCodeSigning) }, - oidAppleExtendedKeyUsageCodeSigningDev = { (DERByte *)_oidAppleExtendedKeyUsageCodeSigningDev, - sizeof(_oidAppleExtendedKeyUsageCodeSigningDev) }, - oidAppleExtendedKeyUsageAppleID = { (DERByte *)_oidAppleExtendedKeyUsageAppleID, - sizeof(_oidAppleExtendedKeyUsageAppleID) }, - oidAppleExtendedKeyUsagePassbook = { (DERByte *)_oidAppleExtendedKeyUsagePassbook, - sizeof(_oidAppleExtendedKeyUsagePassbook) }, - oidAppleExtendedKeyUsageProfileSigning - = { (DERByte *)_oidAppleExtendedKeyUsageProfileSigning, - sizeof(_oidAppleExtendedKeyUsageProfileSigning) }, - oidAppleExtendedKeyUsageQAProfileSigning - = { (DERByte *)_oidAppleExtendedKeyUsageQAProfileSigning, - sizeof(_oidAppleExtendedKeyUsageQAProfileSigning) }, - oidAppleIntmMarkerAppleWWDR = { (DERByte *)_oidAppleIntmMarkerAppleWWDR, - sizeof(_oidAppleIntmMarkerAppleWWDR) }, - oidAppleIntmMarkerAppleID = { (DERByte *)_oidAppleIntmMarkerAppleID, - sizeof(_oidAppleIntmMarkerAppleID) }, - oidAppleIntmMarkerAppleID2 = { (DERByte *)_oidAppleIntmMarkerAppleID2, - sizeof(_oidAppleIntmMarkerAppleID2) }, - oidApplePushServiceClient = { (DERByte *)_oidAppleIntmMarkerAppleID2, - sizeof(_oidAppleIntmMarkerAppleID2) }, - oidApplePolicyMobileStore = { (DERByte *)_oidApplePolicyMobileStore, - sizeof(_oidApplePolicyMobileStore)}, - oidApplePolicyMobileStoreProdQA = { (DERByte *)_oidApplePolicyMobileStoreProdQA, - sizeof(_oidApplePolicyMobileStoreProdQA)}, - oidApplePolicyEscrowService = { (DERByte *)_oidApplePolicyEscrowService, - sizeof(_oidApplePolicyEscrowService)}, - oidAppleCertExtensionAppleIDRecordValidationSigning = { (DERByte *)_oidAppleCertExtensionAppleIDRecordValidationSigning, - sizeof(_oidAppleCertExtensionAppleIDRecordValidationSigning)}, - oidAppleCertExtOSXProvisioningProfileSigning = { (DERByte *)_oidAppleCertExtOSXProvisioningProfileSigning, - sizeof(_oidAppleCertExtOSXProvisioningProfileSigning) }, - oidAppleIntmMarkerAppleSystemIntg2 = { (DERByte *) _oidAppleIntmMarkerAppleSystemIntg2, - sizeof(_oidAppleIntmMarkerAppleSystemIntg2)}, - oidAppleIntmMarkerAppleSystemIntgG3 = { (DERByte *) _oidAppleIntmMarkerAppleSystemIntgG3, - sizeof(_oidAppleIntmMarkerAppleSystemIntgG3)}, - oidAppleCertExtAppleSMPEncryption = { (DERByte *)_oidAppleCertExtAppleSMPEncryption, - sizeof(_oidAppleCertExtAppleSMPEncryption)}, - oidAppleCertExtAppleServerAuthentication - = { (DERByte *)_oidAppleCertExtAppleServerAuthentication, - sizeof(_oidAppleCertExtAppleServerAuthentication) }, - oidAppleCertExtAppleServerAuthenticationIDSProdQA - = { (DERByte *)_oidAppleCertExtAppleServerAuthenticationIDSProdQA, - sizeof(_oidAppleCertExtAppleServerAuthenticationIDSProdQA) }, - oidAppleCertExtAppleServerAuthenticationIDSProd - = { (DERByte *)_oidAppleCertExtAppleServerAuthenticationIDSProd, - sizeof(_oidAppleCertExtAppleServerAuthenticationIDSProd) }, - oidAppleCertExtAppleServerAuthenticationAPNProdQA - = { (DERByte *)_oidAppleCertExtAppleServerAuthenticationAPNProdQA, - sizeof(_oidAppleCertExtAppleServerAuthenticationAPNProdQA) }, - oidAppleCertExtAppleServerAuthenticationAPNProd - = { (DERByte *)_oidAppleCertExtAppleServerAuthenticationAPNProd, - sizeof(_oidAppleCertExtAppleServerAuthenticationAPNProd) }, - oidAppleCertExtAppleServerAuthenticationGS - = { (DERByte *)_oidAppleCertExtAppleServerAuthenticationGS, - sizeof(_oidAppleCertExtAppleServerAuthenticationGS) }, - oidAppleCertExtAppleServerAuthenticationPPQProdQA - = { (DERByte *)_oidAppleCertExtAppleServerAuthenticationPPQProdQA, - sizeof(_oidAppleCertExtAppleServerAuthenticationPPQProdQA) }, - oidAppleCertExtAppleServerAuthenticationPPQProd - = { (DERByte *)_oidAppleCertExtAppleServerAuthenticationPPQProd, - sizeof(_oidAppleCertExtAppleServerAuthenticationPPQProd) }, - oidAppleIntmMarkerAppleServerAuthentication - = { (DERByte *)_oidAppleIntmMarkerAppleServerAuthentication, - sizeof(_oidAppleIntmMarkerAppleServerAuthentication) }, - oidAppleCertExtApplePPQSigningProd = { (DERByte *)_oidAppleCertExtApplePPQSigningProd, - sizeof(_oidAppleCertExtApplePPQSigningProd)}, - oidAppleCertExtApplePPQSigningProdQA = { (DERByte *)_oidAppleCertExtApplePPQSigningProdQA, - sizeof(_oidAppleCertExtApplePPQSigningProdQA)}, - oidGoogleEmbeddedSignedCertificateTimestamp - = { (DERByte *)_oidGoogleEmbeddedSignedCertificateTimestamp, - sizeof(_oidGoogleEmbeddedSignedCertificateTimestamp) }, - oidGoogleOCSPSignedCertificateTimestamp - = { (DERByte *)_oidGoogleOCSPSignedCertificateTimestamp, - sizeof(_oidGoogleOCSPSignedCertificateTimestamp) }, - oidAppleCertExtATVAppSigningProd = { (DERByte *)_oidAppleCertExtATVAppSigningProd, - sizeof(_oidAppleCertExtATVAppSigningProd)}, - oidAppleCertExtATVAppSigningProdQA = { (DERByte *)_oidAppleCertExtATVAppSigningProdQA, - sizeof(_oidAppleCertExtATVAppSigningProdQA)}, - oidAppleCertExtATVVPNProfileSigning = { (DERByte *) _oidAppleCertExtATVVPNProfileSigning, - sizeof(_oidAppleCertExtATVVPNProfileSigning)}, - oidAppleCertExtCryptoServicesExtEncryption = { (DERByte *)_oidAppleCertExtCryptoServicesExtEncryption, - sizeof(_oidAppleCertExtCryptoServicesExtEncryption)}, - oidAppleCertExtAST2DiagnosticsServerAuthProdQA = { (DERByte *)_oidAppleCertExtAST2DiagnosticsServerAuthProdQA, - sizeof(_oidAppleCertExtAST2DiagnosticsServerAuthProdQA)}, - oidAppleCertExtAST2DiagnosticsServerAuthProd = { (DERByte *)_oidAppleCertExtAST2DiagnosticsServerAuthProd, - sizeof(_oidAppleCertExtAST2DiagnosticsServerAuthProd)}, - oidAppleCertExtEscrowProxyServerAuthProdQA = { (DERByte *)_oidAppleCertExtEscrowProxyServerAuthProdQA, - sizeof(_oidAppleCertExtEscrowProxyServerAuthProdQA)}, - oidAppleCertExtEscrowProxyServerAuthProd = { (DERByte *)_oidAppleCertExtEscrowProxyServerAuthProd, - sizeof(_oidAppleCertExtEscrowProxyServerAuthProd)}, - oidAppleCertExtFMiPServerAuthProdQA = { (DERByte *)_oidAppleCertExtFMiPServerAuthProdQA, - sizeof(_oidAppleCertExtFMiPServerAuthProdQA)}, - oidAppleCertExtFMiPServerAuthProd = { (DERByte *)_oidAppleCertExtFMiPServerAuthProd, - sizeof(_oidAppleCertExtFMiPServerAuthProd)}, - oidAppleCertExtHomeKitServerAuth = { (DERByte *)_oidAppleCertExtHomeKitServerAuth, - sizeof(_oidAppleCertExtHomeKitServerAuth)}, - oidAppleIntmMarkerAppleHomeKitServerCA = { (DERByte *)_oidAppleIntmMarkerAppleHomeKitServerCA, - sizeof(_oidAppleIntmMarkerAppleHomeKitServerCA) }, - oidAppleCertExtAppleServerAuthenticationMMCSProdQA - = { (DERByte *)_oidAppleCertExtMMCSServerAuthProdQA, - sizeof(_oidAppleCertExtMMCSServerAuthProdQA) }, - oidAppleCertExtAppleServerAuthenticationMMCSProd - = { (DERByte *)_oidAppleCertExtMMCSServerAuthProd, - sizeof(_oidAppleCertExtMMCSServerAuthProd) }, - oidAppleCertExtAppleServerAuthenticationiCloudSetupProdQA - = { (DERByte *)_oidAppleCertExtiCloudSetupServerAuthProdQA, - sizeof(_oidAppleCertExtiCloudSetupServerAuthProdQA) }, - oidAppleCertExtAppleServerAuthenticationiCloudSetupProd - = { (DERByte *)_oidAppleCertExtiCloudSetupServerAuthProd, - sizeof(_oidAppleCertExtiCloudSetupServerAuthProd) }; - - - - -bool DEROidCompare(const DERItem *oid1, const DERItem *oid2) { - if ((oid1 == NULL) || (oid2 == NULL)) { - return false; - } - if (oid1->length != oid2->length) { - return false; - } - if (!DERMemcmp(oid1->data, oid2->data, oid1->length)) { - return true; - } else { - return false; - } -} diff --git a/OSX/libsecurity_keychain/libDER/libDER/oids.h b/OSX/libsecurity_keychain/libDER/libDER/oids.h deleted file mode 100644 index 7f78053d..00000000 --- a/OSX/libsecurity_keychain/libDER/libDER/oids.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2005-2009,2011-2016 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -/* - * oids.h - declaration of OID consts - * - */ - -#ifndef _LIB_DER_OIDS_H_ -#define _LIB_DER_OIDS_H_ - -#include -#include - -__BEGIN_DECLS - -/* - * Basic data types - */ -typedef uint8_t DERByte; -typedef size_t DERSize; - -/* - * Primary representation of a block of memory. - */ -typedef struct { - DERByte *data; - DERSize length; -} DERItem; - -/* Algorithm oids. */ -extern const DERItem - oidRsa, /* PKCS1 RSA encryption, used to identify RSA keys */ - oidMd2Rsa, /* PKCS1 md2withRSAEncryption signature alg */ - oidMd4Rsa, /* PKCS1 md4withRSAEncryption signature alg */ - oidMd5Rsa, /* PKCS1 md5withRSAEncryption signature alg */ - oidSha1Rsa, /* PKCS1 sha1withRSAEncryption signature alg */ - oidSha256Rsa, /* PKCS1 sha256WithRSAEncryption signature alg */ - oidSha384Rsa, /* PKCS1 sha384WithRSAEncryption signature alg */ - oidSha512Rsa, /* PKCS1 sha512WithRSAEncryption signature alg */ - oidSha224Rsa, /* PKCS1 sha224WithRSAEncryption signature alg */ - oidEcPubKey, /* ECDH or ECDSA public key in a certificate */ - oidSha1Ecdsa, /* ECDSA with SHA1 signature alg */ - oidSha224Ecdsa, /* ECDSA with SHA224 signature alg */ - oidSha256Ecdsa, /* ECDSA with SHA256 signature alg */ - oidSha384Ecdsa, /* ECDSA with SHA384 signature alg */ - oidSha512Ecdsa, /* ECDSA with SHA512 signature alg */ - oidSha1Dsa, /* ANSI X9.57 DSA with SHA1 signature alg */ - oidMd2, /* OID_RSA_HASH 2 */ - oidMd4, /* OID_RSA_HASH 4 */ - oidMd5, /* OID_RSA_HASH 5 */ - oidSha1, /* OID_OIW_ALGORITHM 26 */ - oidSha1DsaOIW, /* OID_OIW_ALGORITHM 27 */ - oidSha1DsaCommonOIW,/* OID_OIW_ALGORITHM 28 */ - oidSha1RsaOIW, /* OID_OIW_ALGORITHM 29 */ - oidSha256, /* OID_NIST_HASHALG 1 */ - oidSha384, /* OID_NIST_HASHALG 2 */ - oidSha512, /* OID_NIST_HASHALG 3 */ - oidSha224, /* OID_NIST_HASHALG 4 */ - oidFee, /* APPLE_ALG_OID 1 */ - oidMd5Fee, /* APPLE_ALG_OID 3 */ - oidSha1Fee, /* APPLE_ALG_OID 4 */ - oidEcPrime192v1, /* OID_EC_CURVE 1 prime192v1/secp192r1/ansiX9p192r1*/ - oidEcPrime256v1, /* OID_EC_CURVE 7 prime256v1/secp256r1*/ - oidAnsip384r1, /* OID_CERTICOM_EC_CURVE 34 ansip384r1/secp384r1*/ - oidAnsip521r1; /* OID_CERTICOM_EC_CURVE 35 ansip521r1/secp521r1*/ - -/* Standard X.509 Cert and CRL extensions. */ -extern const DERItem - oidSubjectKeyIdentifier, - oidKeyUsage, - oidPrivateKeyUsagePeriod, - oidSubjectAltName, - oidIssuerAltName, - oidBasicConstraints, - oidNameConstraints, - oidCrlDistributionPoints, - oidCertificatePolicies, - oidAnyPolicy, - oidPolicyMappings, - oidAuthorityKeyIdentifier, - oidPolicyConstraints, - oidExtendedKeyUsage, - oidAnyExtendedKeyUsage, - oidInhibitAnyPolicy, - oidAuthorityInfoAccess, - oidSubjectInfoAccess, - oidAdOCSP, - oidAdCAIssuer, - oidNetscapeCertType, - oidEntrustVersInfo, - oidMSNTPrincipalName; - -/* Policy Qualifier IDs for Internet policy qualifiers. */ -extern const DERItem - oidQtCps, - oidQtUNotice; - -/* X.501 Name IDs. */ -extern const DERItem - oidCommonName, - oidCountryName, - oidLocalityName, - oidStateOrProvinceName, - oidOrganizationName, - oidOrganizationalUnitName, - oidDescription, - oidEmailAddress, - oidFriendlyName, - oidLocalKeyId; - -/* X.509 Extended Key Usages */ -extern const DERItem - oidExtendedKeyUsageServerAuth, - oidExtendedKeyUsageClientAuth, - oidExtendedKeyUsageCodeSigning, - oidExtendedKeyUsageEmailProtection, - oidExtendedKeyUsageTimeStamping, - oidExtendedKeyUsageOCSPSigning, - oidExtendedKeyUsageIPSec, - oidExtendedKeyUsageMicrosoftSGC, - oidExtendedKeyUsageNetscapeSGC; - -/* Google Certificate Transparency OIDs */ -extern const DERItem - oidGoogleEmbeddedSignedCertificateTimestamp, - oidGoogleOCSPSignedCertificateTimestamp; - -__END_DECLS - -#endif /* _LIB_DER_OIDS_H_ */ diff --git a/OSX/libsecurity_keychain/libDER/libDER/oidsPriv.h b/OSX/libsecurity_keychain/libDER/libDER/oidsPriv.h deleted file mode 100644 index 3d64f628..00000000 --- a/OSX/libsecurity_keychain/libDER/libDER/oidsPriv.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2005-2009,2011-2016 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -/* - * oids.h - declaration of OID consts - * - */ - -#ifndef _LIB_DER_OIDSPRIV_H_ -#define _LIB_DER_OIDSPRIV_H_ - -#include -#include - -__BEGIN_DECLS - -/* Apple Oids */ -extern const DERItem - oidAppleSecureBootCertSpec, - oidAppleSecureBootTicketCertSpec, - oidAppleImg4ManifestCertSpec, - oidAppleProvisioningProfile, - oidAppleApplicationSigning, - oidAppleTVOSApplicationSigningProd, - oidAppleTVOSApplicationSigningProdQA, - oidAppleInstallerPackagingSigningExternal, - oidAppleExtendedKeyUsageCodeSigning, - oidAppleExtendedKeyUsageCodeSigningDev, - oidAppleExtendedKeyUsageAppleID, - oidAppleExtendedKeyUsagePassbook, - oidAppleExtendedKeyUsageProfileSigning, - oidAppleExtendedKeyUsageQAProfileSigning, - oidAppleIntmMarkerAppleWWDR, - oidAppleIntmMarkerAppleID, - oidAppleIntmMarkerAppleID2, - oidApplePushServiceClient, - oidApplePolicyMobileStore, - oidApplePolicyMobileStoreProdQA, - oidApplePolicyEscrowService, - oidAppleCertExtensionAppleIDRecordValidationSigning, - oidAppleCertExtOSXProvisioningProfileSigning, - oidAppleIntmMarkerAppleSystemIntg2, - oidAppleIntmMarkerAppleSystemIntgG3, - oidAppleCertExtAppleSMPEncryption, - oidAppleCertExtAppleServerAuthentication, - oidAppleCertExtAppleServerAuthenticationIDSProdQA, - oidAppleCertExtAppleServerAuthenticationIDSProd, - oidAppleCertExtAppleServerAuthenticationAPNProdQA, - oidAppleCertExtAppleServerAuthenticationAPNProd, - oidAppleCertExtAppleServerAuthenticationGS, - oidAppleCertExtAppleServerAuthenticationPPQProdQA, - oidAppleCertExtAppleServerAuthenticationPPQProd, - oidAppleIntmMarkerAppleServerAuthentication, - oidAppleCertExtApplePPQSigningProd, - oidAppleCertExtApplePPQSigningProdQA, - oidAppleCertExtATVAppSigningProd, - oidAppleCertExtATVAppSigningProdQA, - oidAppleCertExtATVVPNProfileSigning, - oidAppleCertExtCryptoServicesExtEncryption, - oidAppleCertExtAST2DiagnosticsServerAuthProdQA, - oidAppleCertExtAST2DiagnosticsServerAuthProd, - oidAppleCertExtEscrowProxyServerAuthProdQA, - oidAppleCertExtEscrowProxyServerAuthProd, - oidAppleCertExtFMiPServerAuthProdQA, - oidAppleCertExtFMiPServerAuthProd, - oidAppleCertExtHomeKitServerAuth, - oidAppleIntmMarkerAppleHomeKitServerCA, - oidAppleCertExtAppleServerAuthenticationMMCSProdQA, - oidAppleCertExtAppleServerAuthenticationMMCSProd, - oidAppleCertExtAppleServerAuthenticationiCloudSetupProdQA, - oidAppleCertExtAppleServerAuthenticationiCloudSetupProd; - - /* Compare two decoded OIDs. Returns true iff they are equivalent. */ - bool DEROidCompare(const DERItem *oid1, const DERItem *oid2); - -__END_DECLS - -#endif /* _LIB_DER_UTILS_H_ */ diff --git a/OSX/libsecurity_keychain/regressions/kc-12-key-create-symmetric-and-use.m b/OSX/libsecurity_keychain/regressions/kc-12-key-create-symmetric-and-use.m index a6074bb8..d5b37eed 100644 --- a/OSX/libsecurity_keychain/regressions/kc-12-key-create-symmetric-and-use.m +++ b/OSX/libsecurity_keychain/regressions/kc-12-key-create-symmetric-and-use.m @@ -137,7 +137,7 @@ static SecKeyRef findExistingEncryptionKey(SecKeychainRef kc) return nullptr; } -static SecKeyRef generateEncryptionKey(SecKeychainRef kc) +static CF_RETURNS_RETAINED SecKeyRef generateEncryptionKey(SecKeychainRef kc) { SecAccessRef access = createAccess(nil, EncryptionKeyLabel, false); if (!access) { diff --git a/OSX/libsecurity_keychain/regressions/kc-23-key-export-symmetric.m b/OSX/libsecurity_keychain/regressions/kc-23-key-export-symmetric.m index 81e9bafc..7e9b69bc 100644 --- a/OSX/libsecurity_keychain/regressions/kc-23-key-export-symmetric.m +++ b/OSX/libsecurity_keychain/regressions/kc-23-key-export-symmetric.m @@ -59,7 +59,7 @@ static void checkCryptoError(OSStatus status, NSString *functionName) { } #endif -static SecKeyRef generateSymmetricKey(SecKeychainRef keychainRef, CFStringRef label) +static CF_RETURNS_RETAINED SecKeyRef generateSymmetricKey(SecKeychainRef keychainRef, CFStringRef label) { CFMutableDictionaryRef parameters; int32_t rawnum; diff --git a/OSX/libsecurity_keychain/regressions/kc-26-key-import-public.m b/OSX/libsecurity_keychain/regressions/kc-26-key-import-public.m index 7a85ff7d..00ba7f7d 100644 --- a/OSX/libsecurity_keychain/regressions/kc-26-key-import-public.m +++ b/OSX/libsecurity_keychain/regressions/kc-26-key-import-public.m @@ -21,6 +21,13 @@ * @APPLE_LICENSE_HEADER_END@ */ +#include +#include +#include +#include + +#import + #import #import @@ -36,15 +43,6 @@ // // -#import -#import - -#include -#include -#include -#include - - /* test RSA public key to import */ static const uint8_t kPublicKey[] = { diff --git a/OSX/libsecurity_keychain/regressions/kc-30-xara-helpers.h b/OSX/libsecurity_keychain/regressions/kc-30-xara-helpers.h index 5d461e64..affd4fc6 100644 --- a/OSX/libsecurity_keychain/regressions/kc-30-xara-helpers.h +++ b/OSX/libsecurity_keychain/regressions/kc-30-xara-helpers.h @@ -37,7 +37,7 @@ #pragma clang diagnostic ignored "-Wunused-function" /* name is the name of the test, not the name of the keychain */ -static SecKeychainRef newKeychain(const char * name) { +static CF_RETURNS_RETAINED SecKeychainRef newKeychain(const char * name) { SecKeychainRef kc = NULL; char* password = "password"; @@ -74,7 +74,7 @@ static SecKeychainRef newCustomKeychain(const char * name, const char * path, co } #define newCustomKeychainTests 1 -static SecKeychainRef openCustomKeychain(const char * name, const char * path, const char * password) { +static CF_RETURNS_RETAINED SecKeychainRef openCustomKeychain(const char * name, const char * path, const char * password) { SecKeychainRef kc = NULL; ok_status(SecKeychainOpen(path, &kc), "%s: SecKeychainOpen", name); @@ -88,7 +88,7 @@ static SecKeychainRef openCustomKeychain(const char * name, const char * path, c } #define openCustomKeychainTests 2 -static SecKeychainRef openKeychain(const char * name) { +static CF_RETURNS_RETAINED SecKeychainRef openKeychain(const char * name) { return openCustomKeychain(name, keychainName, NULL); } #define openKeychainTests (openCustomKeychainTests) diff --git a/OSX/libsecurity_keychain/regressions/kc-42-trust-revocation.c b/OSX/libsecurity_keychain/regressions/kc-42-trust-revocation.c index 6fafcc22..7c6d545d 100644 --- a/OSX/libsecurity_keychain/regressions/kc-42-trust-revocation.c +++ b/OSX/libsecurity_keychain/regressions/kc-42-trust-revocation.c @@ -31,128 +31,129 @@ /* s:/jurisdictionC=US/jurisdictionST=Delaware/businessCategory=Private Organization/serialNumber=3014267/C=US/postalCode=95131-2021/ST=California/L=San Jose/street=2211 N 1st St/O=PayPal, Inc./OU=CDN Support/CN=www.paypal.com */ /* i:/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 EV SSL CA - G3 */ -/* SHA1 Fingerprint=A5:AF:1D:73:96:A7:74:F8:8B:B7:43:FD:07:7A:97:47:D3:FA:EF:2F */ -/* EXPIRES Oct 30 23:59:59 2017 GMT */ - -unsigned char leaf_certificate[1873]={ - 0x30,0x82,0x07,0x4D,0x30,0x82,0x06,0x35,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x7F, - 0xC0,0x32,0xB3,0x6F,0x9F,0x9E,0x1A,0xC1,0xED,0xAB,0x97,0x13,0x65,0x29,0x35,0x30, - 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x77, - 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1D,0x30, - 0x1B,0x06,0x03,0x55,0x04,0x0A,0x13,0x14,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63, - 0x20,0x43,0x6F,0x72,0x70,0x6F,0x72,0x61,0x74,0x69,0x6F,0x6E,0x31,0x1F,0x30,0x1D, - 0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63,0x20, - 0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x28,0x30, - 0x26,0x06,0x03,0x55,0x04,0x03,0x13,0x1F,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63, - 0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x45,0x56,0x20,0x53,0x53,0x4C,0x20, - 0x43,0x41,0x20,0x2D,0x20,0x47,0x33,0x30,0x1E,0x17,0x0D,0x31,0x35,0x30,0x39,0x30, - 0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x37,0x31,0x30,0x33,0x30, - 0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x82,0x01,0x09,0x31,0x13,0x30,0x11,0x06, - 0x0B,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,0x13,0x02,0x55,0x53, - 0x31,0x19,0x30,0x17,0x06,0x0B,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01, - 0x02,0x0C,0x08,0x44,0x65,0x6C,0x61,0x77,0x61,0x72,0x65,0x31,0x1D,0x30,0x1B,0x06, - 0x03,0x55,0x04,0x0F,0x13,0x14,0x50,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x4F,0x72, - 0x67,0x61,0x6E,0x69,0x7A,0x61,0x74,0x69,0x6F,0x6E,0x31,0x10,0x30,0x0E,0x06,0x03, - 0x55,0x04,0x05,0x13,0x07,0x33,0x30,0x31,0x34,0x32,0x36,0x37,0x31,0x0B,0x30,0x09, - 0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55, - 0x04,0x11,0x0C,0x0A,0x39,0x35,0x31,0x33,0x31,0x2D,0x32,0x30,0x32,0x31,0x31,0x13, - 0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72, - 0x6E,0x69,0x61,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x07,0x0C,0x08,0x53,0x61, - 0x6E,0x20,0x4A,0x6F,0x73,0x65,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x09,0x0C, - 0x0D,0x32,0x32,0x31,0x31,0x20,0x4E,0x20,0x31,0x73,0x74,0x20,0x53,0x74,0x31,0x15, - 0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0C,0x50,0x61,0x79,0x50,0x61,0x6C,0x2C, - 0x20,0x49,0x6E,0x63,0x2E,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0B,0x0C,0x0B, - 0x43,0x44,0x4E,0x20,0x53,0x75,0x70,0x70,0x6F,0x72,0x74,0x31,0x17,0x30,0x15,0x06, - 0x03,0x55,0x04,0x03,0x0C,0x0E,0x77,0x77,0x77,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C, - 0x2E,0x63,0x6F,0x6D,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, - 0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A, - 0x02,0x82,0x01,0x01,0x00,0xDC,0x6F,0x1C,0x60,0xDA,0x9C,0x32,0xF8,0x82,0x72,0x77, - 0xFD,0x51,0x80,0x59,0x6B,0xDB,0xC5,0x6A,0x36,0x4D,0x6E,0x8A,0x49,0x83,0xDE,0x75, - 0x1F,0x90,0xCB,0xB6,0x53,0xB9,0x3C,0x42,0xB9,0x1C,0xB5,0x53,0xAF,0x50,0x88,0x8D, - 0xE8,0xA8,0x7F,0xA6,0xA6,0x1F,0x0D,0x21,0xD4,0x5C,0x6F,0x0C,0x33,0x7E,0x3A,0x19, - 0x58,0xD9,0x5D,0x01,0xD3,0x08,0xE2,0xD2,0x59,0x54,0xA9,0xC7,0xAB,0x4D,0xC6,0xFF, - 0x05,0xA6,0x0B,0xBF,0xB6,0x11,0x12,0x34,0xEA,0xD7,0x23,0xCE,0x3E,0x60,0x21,0xBE, - 0xFE,0xCD,0xDB,0x65,0x1C,0xAF,0x62,0x96,0x3E,0x73,0xBD,0x08,0x05,0x6E,0xEA,0x33, - 0x1E,0xD5,0x59,0xC2,0x71,0xA5,0xE5,0x22,0xCE,0xD0,0x17,0xA5,0xD2,0xAC,0x7C,0xDC, - 0xEA,0xE8,0xBA,0x70,0x16,0x8B,0xE5,0x90,0x6C,0x7C,0xA0,0xB4,0x79,0x73,0x50,0x5E, - 0x26,0x88,0xA3,0x5F,0xF8,0x47,0x63,0x73,0x52,0x62,0x1F,0xC6,0xE2,0xEA,0xF5,0xF6, - 0x21,0x40,0x5D,0xF2,0x19,0xF2,0x73,0x05,0x25,0x39,0xEF,0x6F,0xCF,0xA0,0x84,0xE9, - 0xA4,0xEF,0x57,0xAC,0x6C,0x25,0xCD,0x7C,0x7C,0xD4,0x34,0x24,0x20,0x07,0xDD,0x0D, - 0x09,0x45,0xBD,0x98,0xA9,0xEE,0x83,0xD5,0xF2,0x8B,0x05,0xA2,0x29,0x37,0x0C,0xF4, - 0x62,0x17,0xC2,0x27,0x57,0x9D,0xE3,0x03,0xE3,0xAB,0x02,0x9D,0xFA,0xC9,0xFF,0x81, - 0x16,0xAB,0x2A,0x94,0x9B,0x3E,0x04,0xB7,0x78,0x2F,0xE9,0x7D,0x76,0x3B,0x22,0x85, - 0xB6,0x45,0x9F,0x42,0x55,0x36,0x2A,0xCB,0x49,0x0A,0xC0,0xFB,0xB8,0x0F,0x5B,0x85, - 0xD1,0x87,0x26,0x1B,0xE9,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x03,0x3F,0x30,0x82, - 0x03,0x3B,0x30,0x6E,0x06,0x03,0x55,0x1D,0x11,0x04,0x67,0x30,0x65,0x82,0x0C,0x63, - 0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F,0x6D,0x82,0x0D,0x63,0x36,0x2E, - 0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F,0x6D,0x82,0x14,0x64,0x65,0x76,0x65, - 0x6C,0x6F,0x70,0x65,0x72,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F,0x6D, - 0x82,0x12,0x68,0x69,0x73,0x74,0x6F,0x72,0x79,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C, - 0x2E,0x63,0x6F,0x6D,0x82,0x0C,0x74,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63, - 0x6F,0x6D,0x82,0x0E,0x77,0x77,0x77,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63, - 0x6F,0x6D,0x30,0x09,0x06,0x03,0x55,0x1D,0x13,0x04,0x02,0x30,0x00,0x30,0x0E,0x06, - 0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x1D,0x06, - 0x03,0x55,0x1D,0x25,0x04,0x16,0x30,0x14,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07, - 0x03,0x01,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x30,0x66,0x06,0x03, - 0x55,0x1D,0x20,0x04,0x5F,0x30,0x5D,0x30,0x5B,0x06,0x0B,0x60,0x86,0x48,0x01,0x86, - 0xF8,0x45,0x01,0x07,0x17,0x06,0x30,0x4C,0x30,0x23,0x06,0x08,0x2B,0x06,0x01,0x05, - 0x05,0x07,0x02,0x01,0x16,0x17,0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x64,0x2E, - 0x73,0x79,0x6D,0x63,0x62,0x2E,0x63,0x6F,0x6D,0x2F,0x63,0x70,0x73,0x30,0x25,0x06, - 0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02,0x30,0x19,0x1A,0x17,0x68,0x74,0x74, - 0x70,0x73,0x3A,0x2F,0x2F,0x64,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E,0x63,0x6F,0x6D, - 0x2F,0x72,0x70,0x61,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80, - 0x14,0x01,0x59,0xAB,0xE7,0xDD,0x3A,0x0B,0x59,0xA6,0x64,0x63,0xD6,0xCF,0x20,0x07, - 0x57,0xD5,0x91,0xE7,0x6A,0x30,0x2B,0x06,0x03,0x55,0x1D,0x1F,0x04,0x24,0x30,0x22, - 0x30,0x20,0xA0,0x1E,0xA0,0x1C,0x86,0x1A,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73, - 0x72,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E,0x63,0x6F,0x6D,0x2F,0x73,0x72,0x2E,0x63, - 0x72,0x6C,0x30,0x57,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x4B, - 0x30,0x49,0x30,0x1F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x13, - 0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x72,0x2E,0x73,0x79,0x6D,0x63,0x64,0x2E, - 0x63,0x6F,0x6D,0x30,0x26,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86, - 0x1A,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x72,0x2E,0x73,0x79,0x6D,0x63,0x62, - 0x2E,0x63,0x6F,0x6D,0x2F,0x73,0x72,0x2E,0x63,0x72,0x74,0x30,0x82,0x01,0x7E,0x06, - 0x0A,0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x02,0x04,0x82,0x01,0x6E,0x04, - 0x82,0x01,0x6A,0x01,0x68,0x00,0x76,0x00,0xA4,0xB9,0x09,0x90,0xB4,0x18,0x58,0x14, - 0x87,0xBB,0x13,0xA2,0xCC,0x67,0x70,0x0A,0x3C,0x35,0x98,0x04,0xF9,0x1B,0xDF,0xB8, - 0xE3,0x77,0xCD,0x0E,0xC8,0x0D,0xDC,0x10,0x00,0x00,0x01,0x4F,0x90,0x71,0x2A,0x7C, - 0x00,0x00,0x04,0x03,0x00,0x47,0x30,0x45,0x02,0x21,0x00,0xB4,0x81,0x1F,0xE7,0x9F, - 0xB6,0xA2,0x06,0xC9,0x0B,0x93,0xBB,0x21,0x87,0x27,0x65,0x05,0x01,0x2D,0x66,0x40, - 0x64,0x14,0x1F,0x13,0x6D,0xF1,0x4B,0x9A,0x91,0x4F,0x53,0x02,0x20,0x37,0x17,0x0D, - 0xF8,0x66,0xBD,0xFD,0x6C,0xFE,0x55,0x62,0x2D,0xCD,0xBC,0x79,0x0B,0x0A,0x3F,0x81, - 0x91,0xCE,0xD5,0x86,0x27,0x11,0xA1,0x18,0x62,0x57,0x54,0xEB,0x8F,0x00,0x76,0x00, - 0x56,0x14,0x06,0x9A,0x2F,0xD7,0xC2,0xEC,0xD3,0xF5,0xE1,0xBD,0x44,0xB2,0x3E,0xC7, - 0x46,0x76,0xB9,0xBC,0x99,0x11,0x5C,0xC0,0xEF,0x94,0x98,0x55,0xD6,0x89,0xD0,0xDD, - 0x00,0x00,0x01,0x4F,0x90,0x71,0x2A,0xDB,0x00,0x00,0x04,0x03,0x00,0x47,0x30,0x45, - 0x02,0x21,0x00,0xE8,0xAA,0x58,0x90,0x87,0x74,0x96,0x5C,0xFB,0x69,0x28,0x83,0xEF, - 0x2E,0x40,0xD5,0x57,0xFF,0x5A,0x84,0x65,0x65,0x2E,0x27,0x4C,0x4C,0x91,0xE5,0x14, - 0xB1,0xBF,0xF8,0x02,0x20,0x0F,0x13,0x6B,0xF9,0x53,0x98,0xC9,0xAC,0x81,0xA0,0x09, - 0x52,0xDD,0x85,0x07,0xB7,0xD5,0x83,0x70,0xDF,0x68,0x96,0xA1,0x4D,0xFC,0x80,0x03, - 0xEC,0x68,0x88,0x5F,0xB5,0x00,0x76,0x00,0x68,0xF6,0x98,0xF8,0x1F,0x64,0x82,0xBE, - 0x3A,0x8C,0xEE,0xB9,0x28,0x1D,0x4C,0xFC,0x71,0x51,0x5D,0x67,0x93,0xD4,0x44,0xD1, - 0x0A,0x67,0xAC,0xBB,0x4F,0x4F,0xFB,0xC4,0x00,0x00,0x01,0x4F,0x90,0x71,0x2A,0x71, - 0x00,0x00,0x04,0x03,0x00,0x47,0x30,0x45,0x02,0x21,0x00,0xB5,0x0A,0x2B,0x5C,0x21, - 0x90,0x66,0x47,0x9C,0x12,0x8D,0xD4,0x5C,0x8E,0x98,0x5B,0x35,0x48,0x8D,0x0C,0xB9, - 0x77,0xB2,0x36,0xBB,0xEE,0x0C,0x62,0x7F,0x04,0x3D,0xBC,0x02,0x20,0x5A,0xCA,0xCD, - 0x03,0xF8,0x6D,0xAF,0x25,0x75,0x15,0x0B,0xA4,0x95,0x47,0x9A,0x04,0x24,0x49,0xCB, - 0x79,0x18,0x87,0xC1,0x28,0x75,0x5D,0x47,0x37,0x45,0x06,0x1B,0x6B,0x30,0x0D,0x06, - 0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01, - 0x00,0x9B,0x81,0x01,0x7F,0xE6,0x12,0x3B,0x64,0x51,0xBF,0x25,0xFF,0x1A,0xF9,0x2C, - 0x8F,0x11,0xEC,0x15,0x5B,0xC8,0x7C,0xA1,0x7C,0xCB,0xB9,0x37,0xA4,0xAA,0x8B,0xE5, - 0x15,0xAE,0x1F,0xCC,0x2E,0x6F,0xEA,0xA0,0xD0,0x22,0x97,0x04,0xAE,0x34,0xB8,0xC1, - 0x78,0xEE,0x67,0x06,0xE2,0x8E,0xDC,0x28,0x48,0xD8,0xDD,0x6A,0xF1,0xAE,0xEB,0xBA, - 0xB8,0xEF,0x1B,0x1B,0x6D,0xEE,0xF4,0xF9,0xF3,0x93,0x2F,0x48,0xD7,0x05,0xC7,0x08, - 0x49,0x42,0x5B,0x98,0xDA,0xFC,0xC6,0x7E,0xA0,0xAB,0xC8,0xC5,0xF6,0x0B,0x6C,0x1B, - 0x5F,0x43,0x56,0x8B,0x90,0x3E,0xF7,0xC7,0x23,0xF5,0xA8,0xC4,0x21,0xFA,0x80,0x70, - 0x8E,0xD9,0xF5,0xF5,0x41,0x9E,0xBF,0x5A,0x8B,0xBC,0xEA,0xE6,0xCA,0xE8,0x0A,0x0D, - 0x58,0xDC,0xB1,0xA3,0xFD,0x58,0x3D,0x4C,0xDD,0x65,0x1C,0x43,0x13,0xE9,0x38,0x9F, - 0x43,0xC7,0x72,0xB2,0x19,0xEF,0x2A,0x52,0xE3,0x87,0xD4,0x63,0xE9,0x5A,0x37,0xEB, - 0xDE,0x21,0xCF,0xC5,0x10,0xED,0x71,0xE8,0xEF,0x74,0xA2,0xD6,0xBC,0x1F,0xCA,0xDA, - 0x50,0x9F,0x79,0xFF,0x13,0x5D,0x28,0xDA,0xF9,0xAE,0x66,0x97,0x40,0x13,0x60,0xD4, - 0x03,0x44,0x9C,0x26,0x64,0x5C,0xE8,0x6C,0xCF,0xC6,0x2E,0xB9,0x78,0x9A,0x87,0x64, - 0x25,0xD2,0x06,0xB8,0x98,0x70,0x1A,0x3B,0xD8,0xBD,0x57,0xE0,0x94,0x9F,0x9D,0x5C, - 0x41,0x5C,0x4E,0x16,0xFB,0xEA,0x52,0x75,0xFC,0x0D,0xE9,0xE6,0x27,0x92,0x36,0x93, - 0xC2,0x8C,0x80,0x40,0x2B,0x44,0xE8,0xD5,0x14,0xBF,0x45,0x18,0x8D,0x59,0xC7,0xC8, - 0x9C, +/* SHA1 Fingerprint=BB:20:B0:3F:FB:93:E1:77:FF:23:A7:43:89:49:60:1A:41:AE:C6:1C */ +/* EXPIRES Oct 30 23:59:59 2019 GMT */ + +unsigned char leaf_certificate[1896]={ + 0x30,0x82,0x07,0x64,0x30,0x82,0x06,0x4C,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x57, + 0xCB,0x7E,0x15,0xE2,0xE3,0xE2,0x44,0xD8,0x2B,0x01,0x63,0x29,0x46,0xEB,0xF0,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x77, + 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1D,0x30, + 0x1B,0x06,0x03,0x55,0x04,0x0A,0x13,0x14,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63, + 0x20,0x43,0x6F,0x72,0x70,0x6F,0x72,0x61,0x74,0x69,0x6F,0x6E,0x31,0x1F,0x30,0x1D, + 0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63,0x20, + 0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x28,0x30, + 0x26,0x06,0x03,0x55,0x04,0x03,0x13,0x1F,0x53,0x79,0x6D,0x61,0x6E,0x74,0x65,0x63, + 0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x45,0x56,0x20,0x53,0x53,0x4C,0x20, + 0x43,0x41,0x20,0x2D,0x20,0x47,0x33,0x30,0x1E,0x17,0x0D,0x31,0x37,0x30,0x39,0x32, + 0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x39,0x31,0x30,0x33,0x30, + 0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x82,0x01,0x09,0x31,0x13,0x30,0x11,0x06, + 0x0B,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,0x13,0x02,0x55,0x53, + 0x31,0x19,0x30,0x17,0x06,0x0B,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01, + 0x02,0x0C,0x08,0x44,0x65,0x6C,0x61,0x77,0x61,0x72,0x65,0x31,0x1D,0x30,0x1B,0x06, + 0x03,0x55,0x04,0x0F,0x13,0x14,0x50,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x4F,0x72, + 0x67,0x61,0x6E,0x69,0x7A,0x61,0x74,0x69,0x6F,0x6E,0x31,0x10,0x30,0x0E,0x06,0x03, + 0x55,0x04,0x05,0x13,0x07,0x33,0x30,0x31,0x34,0x32,0x36,0x37,0x31,0x0B,0x30,0x09, + 0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55, + 0x04,0x11,0x0C,0x0A,0x39,0x35,0x31,0x33,0x31,0x2D,0x32,0x30,0x32,0x31,0x31,0x13, + 0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72, + 0x6E,0x69,0x61,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x07,0x0C,0x08,0x53,0x61, + 0x6E,0x20,0x4A,0x6F,0x73,0x65,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x09,0x0C, + 0x0D,0x32,0x32,0x31,0x31,0x20,0x4E,0x20,0x31,0x73,0x74,0x20,0x53,0x74,0x31,0x15, + 0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0C,0x50,0x61,0x79,0x50,0x61,0x6C,0x2C, + 0x20,0x49,0x6E,0x63,0x2E,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0B,0x0C,0x0B, + 0x43,0x44,0x4E,0x20,0x53,0x75,0x70,0x70,0x6F,0x72,0x74,0x31,0x17,0x30,0x15,0x06, + 0x03,0x55,0x04,0x03,0x0C,0x0E,0x77,0x77,0x77,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C, + 0x2E,0x63,0x6F,0x6D,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A, + 0x02,0x82,0x01,0x01,0x00,0xBF,0xF7,0x98,0x4B,0x4E,0xAA,0xF2,0x2F,0xC6,0x77,0xAB, + 0x26,0x76,0x60,0x2E,0xAB,0x50,0xBD,0x47,0xFF,0x8B,0x7C,0xB7,0x4A,0x75,0x0D,0x81, + 0xF7,0x46,0xE2,0x6B,0x03,0x9F,0xE4,0x07,0xFF,0xC0,0xAC,0xE5,0x15,0x7C,0x0B,0x81, + 0xAA,0xD0,0x32,0x88,0xB0,0x58,0x4E,0xEB,0xC1,0x13,0xCC,0x27,0xDD,0x1A,0x27,0x40, + 0xE8,0xF8,0x16,0x39,0x9A,0x4D,0x55,0xD5,0x0D,0x47,0x7C,0xD1,0x58,0xDB,0x41,0x8E, + 0x41,0x0E,0x3E,0xF2,0x3B,0x05,0x78,0x5D,0x8B,0xBF,0x28,0x71,0x41,0x11,0xC9,0x14, + 0xDB,0xE5,0xE2,0xAA,0x80,0x84,0xD0,0xE8,0xA7,0x2C,0xAA,0xC2,0x06,0xC8,0xDC,0xD3, + 0x18,0x35,0x42,0xA0,0x47,0xD5,0xB5,0xBA,0x57,0x66,0xC3,0x01,0x1F,0xC1,0x3A,0x58, + 0xE8,0x39,0x94,0xF5,0x5E,0x50,0x73,0x7E,0xB6,0x84,0x45,0x27,0xFC,0x52,0x4C,0xEF, + 0x1E,0x32,0x30,0x13,0x0C,0xF5,0x93,0xE5,0xB9,0xA8,0xA0,0x1C,0x05,0xA9,0x69,0xB7, + 0xA4,0x07,0x27,0xB9,0x6E,0x30,0x99,0x3A,0x6F,0x33,0xD7,0xFF,0x24,0xAE,0x02,0x12, + 0x08,0xF8,0x55,0x3F,0x30,0xEC,0xA2,0x5F,0x93,0x34,0x8B,0xAB,0x05,0xE6,0x8D,0xD5, + 0x93,0xBE,0x93,0x78,0x3E,0x97,0xA8,0x66,0xDC,0xA9,0x25,0x9B,0xF0,0x18,0x1A,0xFA, + 0xAE,0x80,0x99,0xC6,0x0F,0xE2,0x67,0xAA,0x26,0xA8,0xED,0xE8,0xFF,0x45,0x8F,0x45, + 0x0E,0xC8,0xC3,0x28,0x51,0x12,0xA6,0x17,0x1E,0x27,0xC8,0x61,0x71,0xC7,0x34,0x40, + 0xD0,0xC9,0xBA,0x49,0x72,0x9B,0xBD,0x57,0xCD,0xEA,0xD5,0x86,0x63,0x51,0x1D,0x48, + 0x14,0x70,0xBE,0xD4,0xD5,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x03,0x56,0x30,0x82, + 0x03,0x52,0x30,0x7C,0x06,0x03,0x55,0x1D,0x11,0x04,0x75,0x30,0x73,0x82,0x12,0x68, + 0x69,0x73,0x74,0x6F,0x72,0x79,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F, + 0x6D,0x82,0x0C,0x74,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F,0x6D,0x82, + 0x0C,0x63,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F,0x6D,0x82,0x0D,0x63, + 0x36,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F,0x6D,0x82,0x14,0x64,0x65, + 0x76,0x65,0x6C,0x6F,0x70,0x65,0x72,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63, + 0x6F,0x6D,0x82,0x0C,0x70,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F,0x6D, + 0x82,0x0E,0x77,0x77,0x77,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x2E,0x63,0x6F,0x6D, + 0x30,0x09,0x06,0x03,0x55,0x1D,0x13,0x04,0x02,0x30,0x00,0x30,0x0E,0x06,0x03,0x55, + 0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x1D,0x06,0x03,0x55, + 0x1D,0x25,0x04,0x16,0x30,0x14,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01, + 0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x30,0x6F,0x06,0x03,0x55,0x1D, + 0x20,0x04,0x68,0x30,0x66,0x30,0x5B,0x06,0x0B,0x60,0x86,0x48,0x01,0x86,0xF8,0x45, + 0x01,0x07,0x17,0x06,0x30,0x4C,0x30,0x23,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07, + 0x02,0x01,0x16,0x17,0x68,0x74,0x74,0x70,0x73,0x3A,0x2F,0x2F,0x64,0x2E,0x73,0x79, + 0x6D,0x63,0x62,0x2E,0x63,0x6F,0x6D,0x2F,0x63,0x70,0x73,0x30,0x25,0x06,0x08,0x2B, + 0x06,0x01,0x05,0x05,0x07,0x02,0x02,0x30,0x19,0x0C,0x17,0x68,0x74,0x74,0x70,0x73, + 0x3A,0x2F,0x2F,0x64,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E,0x63,0x6F,0x6D,0x2F,0x72, + 0x70,0x61,0x30,0x07,0x06,0x05,0x67,0x81,0x0C,0x01,0x01,0x30,0x1F,0x06,0x03,0x55, + 0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x01,0x59,0xAB,0xE7,0xDD,0x3A,0x0B,0x59, + 0xA6,0x64,0x63,0xD6,0xCF,0x20,0x07,0x57,0xD5,0x91,0xE7,0x6A,0x30,0x2B,0x06,0x03, + 0x55,0x1D,0x1F,0x04,0x24,0x30,0x22,0x30,0x20,0xA0,0x1E,0xA0,0x1C,0x86,0x1A,0x68, + 0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x72,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E,0x63, + 0x6F,0x6D,0x2F,0x73,0x72,0x2E,0x63,0x72,0x6C,0x30,0x57,0x06,0x08,0x2B,0x06,0x01, + 0x05,0x05,0x07,0x01,0x01,0x04,0x4B,0x30,0x49,0x30,0x1F,0x06,0x08,0x2B,0x06,0x01, + 0x05,0x05,0x07,0x30,0x01,0x86,0x13,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73,0x72, + 0x2E,0x73,0x79,0x6D,0x63,0x64,0x2E,0x63,0x6F,0x6D,0x30,0x26,0x06,0x08,0x2B,0x06, + 0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x1A,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x73, + 0x72,0x2E,0x73,0x79,0x6D,0x63,0x62,0x2E,0x63,0x6F,0x6D,0x2F,0x73,0x72,0x2E,0x63, + 0x72,0x74,0x30,0x82,0x01,0x7E,0x06,0x0A,0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02, + 0x04,0x02,0x04,0x82,0x01,0x6E,0x04,0x82,0x01,0x6A,0x01,0x68,0x00,0x75,0x00,0xDD, + 0xEB,0x1D,0x2B,0x7A,0x0D,0x4F,0xA6,0x20,0x8B,0x81,0xAD,0x81,0x68,0x70,0x7E,0x2E, + 0x8E,0x9D,0x01,0xD5,0x5C,0x88,0x8D,0x3D,0x11,0xC4,0xCD,0xB6,0xEC,0xBE,0xCC,0x00, + 0x00,0x01,0x5E,0xAB,0x85,0x57,0xB1,0x00,0x00,0x04,0x03,0x00,0x46,0x30,0x44,0x02, + 0x20,0x07,0xE3,0x40,0xE7,0x2A,0x3C,0x38,0xEC,0xF4,0xFB,0x7D,0xBC,0x99,0x23,0xBA, + 0xD6,0x39,0x0D,0x7B,0x87,0x4C,0xF0,0x8B,0xAC,0x88,0x76,0x16,0x98,0xAD,0xED,0xAC, + 0x34,0x02,0x20,0x5E,0xA4,0x5A,0xF6,0xBD,0xD0,0xF2,0x4D,0x77,0x31,0x31,0x65,0x94, + 0xC1,0x2C,0x2D,0x16,0x2D,0x4C,0x8A,0xF3,0xAA,0x2C,0x63,0x3A,0x26,0x94,0x8F,0x5C, + 0x04,0x32,0xB4,0x00,0x77,0x00,0xA4,0xB9,0x09,0x90,0xB4,0x18,0x58,0x14,0x87,0xBB, + 0x13,0xA2,0xCC,0x67,0x70,0x0A,0x3C,0x35,0x98,0x04,0xF9,0x1B,0xDF,0xB8,0xE3,0x77, + 0xCD,0x0E,0xC8,0x0D,0xDC,0x10,0x00,0x00,0x01,0x5E,0xAB,0x85,0x57,0xEC,0x00,0x00, + 0x04,0x03,0x00,0x48,0x30,0x46,0x02,0x21,0x00,0xE4,0x54,0x30,0xB7,0x22,0x75,0x2E, + 0x6B,0x3F,0xE9,0x65,0x5D,0x59,0x8B,0x0E,0x9F,0x44,0x9D,0x8C,0x05,0xB1,0xFB,0x11, + 0xD7,0x59,0x98,0x3C,0x35,0xEA,0x52,0xEA,0x9E,0x02,0x21,0x00,0xBD,0x07,0x6C,0x78, + 0x5B,0x81,0xFF,0x45,0x6E,0x8C,0x68,0x99,0x41,0x72,0xC1,0xE5,0x36,0x71,0x81,0x00, + 0x85,0x1D,0x2A,0xC4,0xFD,0x9E,0x7D,0x85,0xC0,0xD5,0x8F,0x6A,0x00,0x76,0x00,0xEE, + 0x4B,0xBD,0xB7,0x75,0xCE,0x60,0xBA,0xE1,0x42,0x69,0x1F,0xAB,0xE1,0x9E,0x66,0xA3, + 0x0F,0x7E,0x5F,0xB0,0x72,0xD8,0x83,0x00,0xC4,0x7B,0x89,0x7A,0xA8,0xFD,0xCB,0x00, + 0x00,0x01,0x5E,0xAB,0x85,0x59,0xB0,0x00,0x00,0x04,0x03,0x00,0x47,0x30,0x45,0x02, + 0x21,0x00,0xD5,0x8C,0xD3,0x11,0xE6,0x08,0xAA,0xCC,0x98,0x35,0xFC,0xED,0x49,0xF0, + 0x34,0x8B,0xE2,0x68,0x0D,0x66,0x65,0x8F,0x1D,0x56,0x7A,0x7E,0xC7,0x35,0x19,0xD1, + 0xB7,0x0A,0x02,0x20,0x6A,0x96,0x22,0xEC,0x63,0x63,0x79,0xE5,0x5E,0x27,0x98,0x19, + 0xDE,0x4F,0xFC,0x69,0x0A,0x22,0x64,0x97,0x70,0x92,0x67,0x9C,0x7C,0xF4,0x00,0xD1, + 0xDF,0xC2,0x61,0xE6,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, + 0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x88,0x75,0x7C,0xEE,0x8C,0x6F,0x9E,0xE3, + 0xDA,0xB9,0x40,0x53,0x78,0xED,0x57,0x11,0x4C,0xE4,0x3F,0x11,0x4A,0xC3,0xDA,0x80, + 0x97,0xF4,0xF8,0x8E,0x0F,0x8E,0xB1,0x73,0x67,0x83,0xDE,0x3E,0x9E,0x2C,0x85,0x6B, + 0x02,0xB5,0x73,0x48,0x26,0x4D,0x43,0xD7,0x04,0xBD,0xC7,0x7D,0xC4,0xDC,0x03,0xB8, + 0x0B,0x35,0x7C,0x39,0x2C,0x42,0x24,0xB3,0xDC,0x15,0x78,0xF6,0x54,0x70,0xFC,0xE0, + 0x9B,0xF5,0x9F,0x30,0x08,0xB0,0x2F,0x4B,0xF1,0xA1,0x49,0x96,0x08,0x76,0x5C,0xAE, + 0xDC,0x3E,0x95,0x0D,0x1A,0x89,0x0C,0xDA,0x32,0xAD,0x2A,0x4B,0xD7,0x63,0x50,0x8C, + 0x0C,0xE3,0x08,0xEC,0x6F,0x78,0x55,0x67,0x05,0x68,0x65,0x22,0x39,0xE3,0x7E,0x36, + 0xD9,0x90,0xD2,0x3D,0x06,0x36,0xC7,0xDE,0xEE,0xF4,0xD6,0xDD,0xDA,0xC3,0xFB,0xAC, + 0x43,0xFE,0x2F,0x1C,0x64,0x9B,0xE2,0xDD,0xC0,0x89,0x8B,0x52,0x98,0x8D,0x0E,0xF6, + 0x09,0x2D,0xE4,0x4D,0x62,0x9C,0x16,0x22,0x96,0xFB,0x68,0x5B,0x94,0x87,0x87,0xCE, + 0x18,0x7E,0x41,0x60,0x79,0xA4,0x17,0x3E,0x71,0xF2,0xB1,0xA2,0x06,0xD8,0x71,0xD8, + 0x33,0x0B,0x6A,0xD4,0x67,0x68,0x24,0x3E,0xBA,0xC6,0x21,0x94,0x5D,0x6A,0xF6,0x21, + 0x84,0x5F,0xD0,0xFF,0xAC,0xE4,0x3D,0xAA,0xAD,0x95,0x85,0xFC,0x4B,0x69,0x30,0x72, + 0xB7,0xBA,0x4D,0xDA,0x3A,0xED,0xD9,0x7D,0x40,0x1D,0x02,0x29,0xB8,0xD5,0x0C,0x09, + 0x9E,0x0D,0x74,0x8B,0xFA,0x62,0x02,0x4A,0x88,0x6E,0x7C,0x13,0x56,0xBA,0x99,0x3F, + 0x13,0x78,0x48,0x82,0xAC,0x43,0x8E,0x61, }; /* s:/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 EV SSL CA - G3 */ @@ -691,7 +692,7 @@ static void tests(void) CFDateRef VerifyDate; isnt(VerifyDate = CFDateCreate(NULL, 332900000.0), NULL, "Create verify date"); - // Standard evaluation should succeed for the given verify date + // Standard evaluation for the given verify date { SecTrustRef trust = NULL; SecTrustResultType trust_result; @@ -704,7 +705,9 @@ static void tests(void) ok_status(status = SecTrustEvaluate(trust, &trust_result), "SecTrustEvaluate"); // Check results - is_status(trust_result, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); + // %%% This is now expected to fail, since the "TC TrustCenter Class 1 L1 CA IX" CA is revoked + // and the revocation information is present in the Valid database. + is_status(trust_result, kSecTrustResultFatalTrustFailure, "trust is kSecTrustResultFatalTrustFailure"); CFReleaseNull(trust); } @@ -723,7 +726,9 @@ static void tests(void) ok_status(status = SecTrustEvaluate(trust, &trust_result), "SecTrustEvaluate"); // Check results - is_status(trust_result, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure"); + // %%% This is now expected to fail, since the "TC TrustCenter Class 1 L1 CA IX" CA is revoked + // and the revocation information is present in the Valid database. + is_status(trust_result, kSecTrustResultFatalTrustFailure, "trust is kSecTrustResultFatalTrustFailure"); CFReleaseNull(trust); } diff --git a/OSX/libsecurity_keychain/regressions/kc-43-seckey-interop.m b/OSX/libsecurity_keychain/regressions/kc-43-seckey-interop.m index 1e75f44e..7577325a 100644 --- a/OSX/libsecurity_keychain/regressions/kc-43-seckey-interop.m +++ b/OSX/libsecurity_keychain/regressions/kc-43-seckey-interop.m @@ -117,7 +117,6 @@ static void test_generate_nolegacy() { CFReleaseNull(pubKey); } -#if !RC_HIDE_J79 && !RC_HIDE_J80 static const int kTestGenerateAccessControlCount = 4; static void test_generate_access_control() { SecAccessControlRef ac = SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleAlways, @@ -149,9 +148,6 @@ static void test_generate_access_control() { CFReleaseSafe(privKey); CFReleaseSafe(pubKey); } -#else -static const int kTestGenerateAccessControlCount = 0; -#endif static const int kTestAddIOSKeyCount = 6; static void test_add_ios_key() { @@ -624,9 +620,7 @@ int kc_43_seckey_interop(int argc, char *const *argv) { plan_tests(kTestCount); test_generate_nolegacy(); -#if !RC_HIDE_J79 && !RC_HIDE_J80 test_generate_access_control(); -#endif test_add_ios_key(); test_store_cert_to_ios(); test_store_identity_to_ios(); diff --git a/OSX/libsecurity_smime/lib/SecCMS.c b/OSX/libsecurity_smime/lib/SecCMS.c index 11026ca4..9cfc874e 100644 --- a/OSX/libsecurity_smime/lib/SecCMS.c +++ b/OSX/libsecurity_smime/lib/SecCMS.c @@ -55,6 +55,7 @@ CFTypeRef kSecCMSSignedAttributes = CFSTR("kSecCMSSignedAttributes"); CFTypeRef kSecCMSSignDate = CFSTR("kSecCMSSignDate"); CFTypeRef kSecCMSAllCerts = CFSTR("kSecCMSAllCerts"); CFTypeRef kSecCMSHashAgility = CFSTR("kSecCMSHashAgility"); +CFTypeRef kSecCMSHashAgilityV2 = CFSTR("kSecCMSHashAgilityV2"); CFTypeRef kSecCMSBulkEncryptionAlgorithm = CFSTR("kSecCMSBulkEncryptionAlgorithm"); CFTypeRef kSecCMSEncryptionAlgorithmDESCBC = CFSTR("kSecCMSEncryptionAlgorithmDESCBC"); @@ -394,6 +395,13 @@ static OSStatus SecCMSVerifySignedData_internal(CFDataRef message, CFDataRef det CFDictionarySetValue(attrs, kSecCMSHashAgility, hash_agility_value); } } + + CFDictionaryRef hash_agility_values = NULL; + if (errSecSuccess == SecCmsSignerInfoGetAppleCodesigningHashAgilityV2(sigd->signerInfos[0], &hash_agility_values)) { + if (hash_agility_values) { + CFDictionarySetValue(attrs, kSecCMSHashAgilityV2, hash_agility_values); + } + } *signed_attributes = attrs; if (certs) CFRelease(certs); diff --git a/OSX/libsecurity_smime/lib/SecCMS.h b/OSX/libsecurity_smime/lib/SecCMS.h index 3c07a0ad..de9a7520 100644 --- a/OSX/libsecurity_smime/lib/SecCMS.h +++ b/OSX/libsecurity_smime/lib/SecCMS.h @@ -38,6 +38,7 @@ extern const void * kSecCMSSignedAttributes; extern const void * kSecCMSSignDate; extern const void * kSecCMSAllCerts; extern const void * kSecCMSHashAgility; +extern const void * kSecCMSHashAgilityV2; extern const void * kSecCMSHashingAlgorithmSHA1; extern const void * kSecCMSHashingAlgorithmSHA256; diff --git a/OSX/libsecurity_smime/lib/SecCmsBase.h b/OSX/libsecurity_smime/lib/SecCmsBase.h index 69c3ed86..ae85fe2a 100644 --- a/OSX/libsecurity_smime/lib/SecCmsBase.h +++ b/OSX/libsecurity_smime/lib/SecCmsBase.h @@ -484,8 +484,9 @@ typedef enum { SEC_OID_ECDSA_WITH_SHA384 = 212, SEC_OID_ECDSA_WITH_SHA512 = 213, - /* Apple CMS Attribute */ + /* Apple CMS Attributes */ SEC_OID_APPLE_HASH_AGILITY = 214, + SEC_OID_APPLE_HASH_AGILITY_V2 = 215, SEC_OID_TOTAL } SECOidTag; diff --git a/OSX/libsecurity_smime/lib/SecCmsSignerInfo.h b/OSX/libsecurity_smime/lib/SecCmsSignerInfo.h index 49894c45..f72605fb 100644 --- a/OSX/libsecurity_smime/lib/SecCmsSignerInfo.h +++ b/OSX/libsecurity_smime/lib/SecCmsSignerInfo.h @@ -112,6 +112,12 @@ SecCmsSignerInfoGetCertList(SecCmsSignerInfoRef signerinfo); extern CFArrayRef SecCmsSignerInfoGetTimestampCertList(SecCmsSignerInfoRef signerinfo); +/*! + @function + */ +extern SecCertificateRef +SecCmsSignerInfoGetTimestampSigningCert(SecCmsSignerInfoRef signerinfo); + /*! @function @abstract Return the signing time, in UTCTime format, of a CMS signerInfo. @@ -152,6 +158,17 @@ SecCmsSignerInfoGetTimestampTimeWithPolicy(SecCmsSignerInfoRef sinfo, CFTypeRef OSStatus SecCmsSignerInfoGetAppleCodesigningHashAgility(SecCmsSignerInfoRef sinfo, CFDataRef *sdata); +/*! + @function + @abstract Return the data in the signed Codesigning Hash Agility V2 attribute. + @param sinfo SignerInfo data for this signer, pointer to a CFDictionaryRef for attribute values + @discussion Returns a CFDictionaryRef containing the values of the attribute. V2 encodes the hash + agility values using DER. + @result A return value of SECFailure is an error. + */ +extern OSStatus +SecCmsSignerInfoGetAppleCodesigningHashAgilityV2(SecCmsSignerInfoRef sinfo, CFDictionaryRef *sdict); + /*! @function @abstract Return the signing cert of a CMS signerInfo. @@ -237,11 +254,21 @@ SecCmsSignerInfoAddCounterSignature(SecCmsSignerInfoRef signerinfo, /*! @function @abstract Add the Apple Codesigning Hash Agility attribute to the authenticated (i.e. signed) attributes of "signerinfo". - @discussion This is expected to be included in outgoing signed Apple code signatures. + @discussion This is expected to be included in outgoing Apple code signatures. */ OSStatus SecCmsSignerInfoAddAppleCodesigningHashAgility(SecCmsSignerInfoRef signerinfo, CFDataRef attrValue); +/*! + @function + @abstract Add the Apple Codesigning Hash Agility V2 attribute to the authenticated (i.e. signed) attributes of "signerinfo". + @discussion This is expected to be included in outgoing Apple code signatures. V2 encodes the hash agility values using DER. + The dictionary should have CFNumberRef keys, corresponding to SECOidTags for digest algorithms, and CFDataRef values, + corresponding to the digest value for that digest algorithm. + */ +OSStatus +SecCmsSignerInfoAddAppleCodesigningHashAgilityV2(SecCmsSignerInfoRef signerinfo, CFDictionaryRef attrValues); + /*! @function @abstract The following needs to be done in the S/MIME layer code after signature of a signerinfo has been verified. diff --git a/OSX/libsecurity_smime/lib/cmsattr.c b/OSX/libsecurity_smime/lib/cmsattr.c index 39c72172..28e9ba11 100644 --- a/OSX/libsecurity_smime/lib/cmsattr.c +++ b/OSX/libsecurity_smime/lib/cmsattr.c @@ -111,19 +111,23 @@ loser: OSStatus SecCmsAttributeAddValue(PLArenaPool *poolp, SecCmsAttribute *attr, CSSM_DATA_PTR value) { - CSSM_DATA copiedvalue; + CSSM_DATA_PTR copiedvalue; void *mark; PORT_Assert (poolp != NULL); mark = PORT_ArenaMark(poolp); - /* XXX we need an object memory model #$%#$%! */ - if (SECITEM_CopyItem(poolp, &copiedvalue, value) != SECSuccess) - goto loser; + if (value != NULL) { + if ((copiedvalue = SECITEM_AllocItem(poolp, NULL, value->Length)) == NULL) + goto loser; - if (SecCmsArrayAdd(poolp, (void ***)&(attr->values), (void *)&copiedvalue) != SECSuccess) - goto loser; + if (SECITEM_CopyItem(poolp, copiedvalue, value) != SECSuccess) + goto loser; + + if (SecCmsArrayAdd(poolp, (void ***)&(attr->values), (void *)copiedvalue) != SECSuccess) + goto loser; + } PORT_ArenaUnmark(poolp, mark); return SECSuccess; @@ -234,6 +238,7 @@ cms_attr_choose_attr_value_template(void *src_or_dest, Boolean encoding, const c switch (oiddata->offset) { case SEC_OID_PKCS9_SMIME_CAPABILITIES: case SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE: + case SEC_OID_APPLE_HASH_AGILITY_V2: /* these guys need to stay DER-encoded */ default: /* same goes for OIDs that are not handled here */ diff --git a/OSX/libsecurity_smime/lib/cmsdecode.c b/OSX/libsecurity_smime/lib/cmsdecode.c index 42107222..fdc69f3f 100644 --- a/OSX/libsecurity_smime/lib/cmsdecode.c +++ b/OSX/libsecurity_smime/lib/cmsdecode.c @@ -177,12 +177,15 @@ nss_cms_decoder_notify(void *arg, Boolean before, void *dest, int depth) if (nss_cms_before_data(p7dcx) != SECSuccess) { SEC_ASN1DecoderClearFilterProc(p7dcx->dcx); /* stop all processing */ p7dcx->error = PORT_GetError(); + PORT_SetError(0); // Clean the thread error since we've returned the error } } if (after && dest == &(cinfo->rawContent)) { /* we're right after of the data */ - if (nss_cms_after_data(p7dcx) != SECSuccess) + if (nss_cms_after_data(p7dcx) != SECSuccess) { p7dcx->error = PORT_GetError(); + PORT_SetError(0); // Clean the thread error since we've returned the error + } /* we don't need to see the contents anymore */ SEC_ASN1DecoderClearFilterProc(p7dcx->dcx); @@ -485,6 +488,7 @@ nss_cms_decoder_work_data(SecCmsDecoderRef p7dcx, data, len, final); if (rv != SECSuccess) { p7dcx->error = PORT_GetError(); + PORT_SetError(0); // Clean the thread error since we've returned the error goto loser; } @@ -600,6 +604,9 @@ SecCmsDecoderCreate(SecArenaPoolRef pool, SecCmsMessageRef cmsg; OSStatus result; + /* Clear the thread error to clean up dirty threads */ + PORT_SetError(0); + cmsg = SecCmsMessageCreate(pool); if (cmsg == NULL) goto loser; @@ -633,6 +640,7 @@ SecCmsDecoderCreate(SecArenaPoolRef pool, loser: result = PORT_GetError(); + PORT_SetError(0); // Clean the thread error since we've returned the error return result; } @@ -664,7 +672,7 @@ SecCmsDecoderUpdate(SecCmsDecoderRef p7dcx, const void *buf, CFIndex len) (void) SEC_ASN1DecoderFinish (p7dcx->dcx); p7dcx->dcx = NULL; } - PORT_SetError (p7dcx->error); + PORT_SetError (0); // Clean the thread error since we've returned the error return p7dcx->error; } @@ -719,6 +727,7 @@ loser: p7dcx->dcx = NULL; p7dcx->childp7dcx = NULL; PORT_Free(p7dcx); + PORT_SetError(0); // Clean the thread error since we've returned the error return result; } diff --git a/OSX/libsecurity_smime/lib/cmsencode.c b/OSX/libsecurity_smime/lib/cmsencode.c index 9d2db04e..04d20168 100644 --- a/OSX/libsecurity_smime/lib/cmsencode.c +++ b/OSX/libsecurity_smime/lib/cmsencode.c @@ -193,8 +193,10 @@ nss_cms_encoder_notify(void *arg, Boolean before, void *dest, int depth) /* we're right before encoding the data (if we have some or not) */ /* (for encrypted data, we're right before the contentEncAlg which may change */ /* in nss_cms_before_data because of IV calculation when setting up encryption) */ - if (nss_cms_before_data(p7ecx) != SECSuccess) - p7ecx->error = PORT_GetError(); + if (nss_cms_before_data(p7ecx) != SECSuccess) { + p7ecx->error = PORT_GetError(); + PORT_SetError(0); // Clean the thread error since we've returned the error + } } if (before && dest == &(cinfo->rawContent)) { if ( ((childtype == SEC_OID_PKCS7_DATA) || (childtype == SEC_OID_OTHER)) && @@ -206,8 +208,10 @@ nss_cms_encoder_notify(void *arg, Boolean before, void *dest, int depth) SEC_ASN1EncoderSetTakeFromBuf(p7ecx->ecx); } if (after && dest == &(cinfo->rawContent)) { - if (nss_cms_after_data(p7ecx) != SECSuccess) - p7ecx->error = PORT_GetError(); + if (nss_cms_after_data(p7ecx) != SECSuccess) { + p7ecx->error = PORT_GetError(); + PORT_SetError(0); // Clean the thread error since we've returned the error + } SEC_ASN1EncoderClearNotifyProc(p7ecx->ecx); /* no need to get notified anymore */ } break; @@ -528,6 +532,9 @@ SecCmsEncoderCreate(SecCmsMessageRef cmsg, OSStatus result; SecCmsContentInfoRef cinfo; + /* Clear the thread error to clean up dirty threads */ + PORT_SetError(0); + SecCmsMessageSetEncodingParams(cmsg, pwfn, pwfn_arg, decrypt_key_cb, decrypt_key_cb_arg, detached_digestalgs, detached_digests); @@ -577,6 +584,7 @@ SecCmsEncoderCreate(SecCmsMessageRef cmsg, if (p7ecx->ecx == NULL) { result = PORT_GetError(); PORT_Free(p7ecx); + PORT_SetError(0); // Clean the thread error since we've returned the error goto loser; } p7ecx->ecxupdated = PR_FALSE; @@ -598,6 +606,7 @@ SecCmsEncoderCreate(SecCmsMessageRef cmsg, if (SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0) != SECSuccess) { result = PORT_GetError(); PORT_Free(p7ecx); + PORT_SetError(0); // Clean the thread error since we've returned the error goto loser; } @@ -647,8 +656,10 @@ SecCmsEncoderUpdate(SecCmsEncoderRef p7ecx, const void *data, CFIndex len) /* hand it the data so it can encode it (let DER trickle up the chain) */ result = nss_cms_encoder_work_data(p7ecx, NULL, (const unsigned char *)data, len, PR_FALSE, PR_TRUE); - if (result) + if (result) { result = PORT_GetError(); + PORT_SetError(0); // Clean the thread error since we've returned the error + } } return result; } @@ -754,6 +765,7 @@ SecCmsEncoderFinish(SecCmsEncoderRef p7ecx) loser: SEC_ASN1EncoderFinish(p7ecx->ecx); PORT_Free (p7ecx); + PORT_SetError(0); // Clean the thread error since we've returned the error return result; } diff --git a/OSX/libsecurity_smime/lib/cmspubkey.c b/OSX/libsecurity_smime/lib/cmspubkey.c index 19ff2065..ea27d7ce 100644 --- a/OSX/libsecurity_smime/lib/cmspubkey.c +++ b/OSX/libsecurity_smime/lib/cmspubkey.c @@ -65,22 +65,15 @@ * according to PKCS#1 and RFC2633 (S/MIME) */ OSStatus -SecCmsUtilEncryptSymKeyRSA(PLArenaPool *poolp, SecCertificateRef cert, +SecCmsUtilEncryptSymKeyRSA(PLArenaPool *poolp, SecCertificateRef cert, SecSymmetricKeyRef bulkkey, CSSM_DATA_PTR encKey) { - OSStatus rv; - SecPublicKeyRef publickey; - -#if TARGET_OS_MAC && !TARGET_OS_IPHONE - rv = SecCertificateCopyPublicKey(cert,&publickey); -#else - publickey = SecCertificateCopyPublicKey(cert); -#endif + SecPublicKeyRef publickey = SecCertificateCopyPublicKey_ios(cert); if (publickey == NULL) return SECFailure; - rv = SecCmsUtilEncryptSymKeyRSAPubKey(poolp, publickey, bulkkey, encKey); + OSStatus rv = SecCmsUtilEncryptSymKeyRSAPubKey(poolp, publickey, bulkkey, encKey); CFRelease(publickey); return rv; } @@ -94,6 +87,7 @@ SecCmsUtilEncryptSymKeyRSAPubKey(PLArenaPool *poolp, unsigned int data_len; //KeyType keyType; void *mark = NULL; + CFDictionaryRef theirKeyAttrs = NULL; mark = PORT_ArenaMark(poolp); if (!mark) @@ -108,15 +102,17 @@ SecCmsUtilEncryptSymKeyRSAPubKey(PLArenaPool *poolp, } #endif /* allocate memory for the encrypted key */ -#if TARGET_OS_MAC && !TARGET_OS_IPHONE - rv = SecKeyGetStrengthInBits(publickey, NULL, &data_len); - if (rv) + theirKeyAttrs = SecKeyCopyAttributes(publickey); + if (!theirKeyAttrs) { + goto loser; + } + + CFNumberRef keySizeNum = CFDictionaryGetValue(theirKeyAttrs, kSecAttrKeySizeInBits); + if (!CFNumberGetValue(keySizeNum, kCFNumberIntType, &data_len)) { goto loser; + } // Convert length to bytes; - data_len = data_len / 8; -#else - data_len = SecKeyGetSize(publickey, kSecKeyEncryptedDataSize); -#endif + data_len /= 8; encKey->Data = (unsigned char*)PORT_ArenaAlloc(poolp, data_len); encKey->Length = data_len; @@ -132,6 +128,9 @@ SecCmsUtilEncryptSymKeyRSAPubKey(PLArenaPool *poolp, return SECSuccess; loser: + if (theirKeyAttrs) { + CFRelease(theirKeyAttrs); + } if (mark) { PORT_ArenaRelease(poolp, mark); } diff --git a/OSX/libsecurity_smime/lib/cmssiginfo.c b/OSX/libsecurity_smime/lib/cmssiginfo.c index ac389d3c..ea597eeb 100644 --- a/OSX/libsecurity_smime/lib/cmssiginfo.c +++ b/OSX/libsecurity_smime/lib/cmssiginfo.c @@ -338,11 +338,21 @@ SecCmsSignerInfoDestroy(SecCmsSignerInfoRef si) (int)CFGetRetainCount(si->timestampCertList)); CFRelease(si->timestampCertList); } + if (si->timestampCert != NULL) { + dprintfRC("SecCmsSignerInfoDestroy top: timestampCert.rc %d\n", + (int)CFGetRetainCount(si->timestampCert)); + CFRelease(si->timestampCert); + } if (si->hashAgilityAttrValue != NULL) { dprintfRC("SecCmsSignerInfoDestroy top: hashAgilityAttrValue.rc %d\n", (int)CFGetRetainCount(si->hashAgilityAttrValue)); CFRelease(si->hashAgilityAttrValue); } + if (si->hashAgilityV2AttrValues != NULL) { + dprintfRC("SecCmsSignerInfoDestroy top: hashAgilityV2AttrValues.rc %d\n", + (int)CFGetRetainCount(si->hashAgilityV2AttrValues)); + CFRelease(si->hashAgilityV2AttrValues); + } /* XXX storage ??? */ } @@ -856,12 +866,18 @@ SecCmsSignerInfoGetCertList(SecCmsSignerInfoRef signerinfo) CFArrayRef SecCmsSignerInfoGetTimestampCertList(SecCmsSignerInfoRef signerinfo) { - dprintfRC("SecCmsSignerInfoGetCertList: timestampCertList.rc %d\n", + dprintfRC("SecCmsSignerInfoGetTimestampCertList: timestampCertList.rc %d\n", (int)CFGetRetainCount(signerinfo->timestampCertList)); return signerinfo->timestampCertList; } - +SecCertificateRef +SecCmsSignerInfoGetTimestampSigningCert(SecCmsSignerInfoRef signerinfo) +{ + dprintfRC("SecCmsSignerInfoGetTimestampSigningCert: timestampCert.rc %d\n", + (int)CFGetRetainCount(signerinfo->timestampCert)); + return signerinfo->timestampCert; +} int SecCmsSignerInfoGetVersion(SecCmsSignerInfoRef signerinfo) @@ -972,6 +988,113 @@ SecCmsSignerInfoGetAppleCodesigningHashAgility(SecCmsSignerInfoRef sinfo, CFData return errSecAllocate; } +/* AgileHash ::= SEQUENCE { + hashType OBJECT IDENTIFIER, + hashValues OCTET STRING } + */ +typedef struct { + SecAsn1Item digestOID; + SecAsn1Item digestValue; +} CMSAppleAgileHash; + +static const SecAsn1Template CMSAppleAgileHashTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(CMSAppleAgileHash) }, + { SEC_ASN1_OBJECT_ID, + offsetof(CMSAppleAgileHash, digestOID), }, + { SEC_ASN1_OCTET_STRING, + offsetof(CMSAppleAgileHash, digestValue), }, + { 0, } +}; + +static OSStatus CMSAddAgileHashToDictionary(CFMutableDictionaryRef dictionary, SecAsn1Item *DERAgileHash) { + PLArenaPool *tmppoolp = NULL; + OSStatus status = errSecSuccess; + CMSAppleAgileHash agileHash; + CFDataRef digestValue = NULL; + CFNumberRef digestTag = NULL; + + tmppoolp = PORT_NewArena(1024); + if (tmppoolp == NULL) { + return errSecAllocate; + } + + if ((status = SEC_ASN1DecodeItem(tmppoolp, &agileHash, CMSAppleAgileHashTemplate, DERAgileHash)) != errSecSuccess) { + goto loser; + } + + int64_t tag = SECOID_FindOIDTag(&agileHash.digestOID); + digestTag = CFNumberCreate(NULL, kCFNumberSInt64Type, &tag); + digestValue = CFDataCreate(NULL, agileHash.digestValue.Data, agileHash.digestValue.Length); + CFDictionaryAddValue(dictionary, digestTag, digestValue); + +loser: + CFReleaseNull(digestValue); + CFReleaseNull(digestTag); + if (tmppoolp) { + PORT_FreeArena(tmppoolp, PR_FALSE); + } + return status; +} + +/*! + @function + @abstract Return the data in the signed Codesigning Hash Agility V2 attribute. + @param sinfo SignerInfo data for this signer, pointer to a CFDictionaryRef for attribute values + @discussion Returns a CFDictionaryRef containing the values of the attribute + @result A return value of errSecInternal is an error trying to look up the oid. + A status value of success with null result data indicates the attribute was not present. + */ +OSStatus +SecCmsSignerInfoGetAppleCodesigningHashAgilityV2(SecCmsSignerInfoRef sinfo, CFDictionaryRef *sdict) +{ + SecCmsAttribute *attr; + + if (sinfo == NULL || sdict == NULL) { + return errSecParam; + } + + *sdict = NULL; + + if (sinfo->hashAgilityV2AttrValues != NULL) { + *sdict = sinfo->hashAgilityV2AttrValues; /* cached copy */ + return SECSuccess; + } + + attr = SecCmsAttributeArrayFindAttrByOidTag(sinfo->authAttr, SEC_OID_APPLE_HASH_AGILITY_V2, PR_TRUE); + + /* attribute not found */ + if (attr == NULL) { + return SECSuccess; + } + + /* attrValues SET OF AttributeValue + * AttributeValue ::= ANY + */ + CSSM_DATA_PTR *values = attr->values; + if (values == NULL) { /* There must be values */ + return errSecDecode; + } + + CFMutableDictionaryRef agileHashValues = CFDictionaryCreateMutable(NULL, SecCmsArrayCount((void **)values), + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + while (*values != NULL) { + (void)CMSAddAgileHashToDictionary(agileHashValues, *values++); + } + if (CFDictionaryGetCount(agileHashValues) != SecCmsArrayCount((void **)attr->values)) { + CFReleaseNull(agileHashValues); + return errSecDecode; + } + + sinfo->hashAgilityV2AttrValues = agileHashValues; /* make cached copy */ + if (sinfo->hashAgilityV2AttrValues) { + *sdict = sinfo->hashAgilityV2AttrValues; + return SECSuccess; + } + return errSecAllocate; +} + /* * Return the signing cert of a CMS signerInfo. * @@ -1241,7 +1364,7 @@ loser: /* * SecCmsSignerInfoAddMSSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the - * authenticated (i.e. signed) attributes of "signerinfo", using the OID prefered by Microsoft. + * authenticated (i.e. signed) attributes of "signerinfo", using the OID preferred by Microsoft. * * This is expected to be included in outgoing signed messages for email (S/MIME), * if compatibility with Microsoft mail clients is wanted. @@ -1369,7 +1492,7 @@ SecCmsSignerInfoAddCounterSignature(SecCmsSignerInfoRef signerinfo, /*! @function @abstract Add the Apple Codesigning Hash Agility attribute to the authenticated (i.e. signed) attributes of "signerinfo". - @discussion This is expected to be included in outgoing signed Apple code signatures. + @discussion This is expected to be included in outgoing Apple code signatures. */ OSStatus SecCmsSignerInfoAddAppleCodesigningHashAgility(SecCmsSignerInfoRef signerinfo, CFDataRef attrValue) @@ -1414,6 +1537,91 @@ loser: return status; } +static OSStatus CMSAddAgileHashToAttribute(PLArenaPool *poolp, SecCmsAttribute *attr, CFNumberRef cftag, CFDataRef value) { + PLArenaPool *tmppoolp = NULL; + int64_t tag; + SECOidData *digestOid = NULL; + CMSAppleAgileHash agileHash; + SecAsn1Item attrValue = { .Data = NULL, .Length = 0 }; + OSStatus status = errSecSuccess; + + memset(&agileHash, 0, sizeof(agileHash)); + + if(!CFNumberGetValue(cftag, kCFNumberSInt64Type, &tag)) { + return errSecParam; + } + digestOid = SECOID_FindOIDByTag((SECOidTag)tag); + + agileHash.digestValue.Data = (uint8_t *)CFDataGetBytePtr(value); + agileHash.digestValue.Length = CFDataGetLength(value); + agileHash.digestOID.Data = digestOid->oid.Data; + agileHash.digestOID.Length = digestOid->oid.Length; + + tmppoolp = PORT_NewArena(1024); + if (tmppoolp == NULL) { + return errSecAllocate; + } + + if (SEC_ASN1EncodeItem(tmppoolp, &attrValue, &agileHash, CMSAppleAgileHashTemplate) == NULL) { + status = errSecParam; + goto loser; + } + + status = SecCmsAttributeAddValue(poolp, attr, &attrValue); + +loser: + if (tmppoolp) { + PORT_FreeArena(tmppoolp, PR_FALSE); + } + return status; +} + +/*! + @function + @abstract Add the Apple Codesigning Hash Agility attribute to the authenticated (i.e. signed) attributes of "signerinfo". + @discussion This is expected to be included in outgoing Apple code signatures. + */ +OSStatus +SecCmsSignerInfoAddAppleCodesigningHashAgilityV2(SecCmsSignerInfoRef signerinfo, CFDictionaryRef attrValues) +{ + __block SecCmsAttribute *attr; + __block PLArenaPool *poolp = signerinfo->cmsg->poolp; + void *mark = PORT_ArenaMark(poolp); + OSStatus status = SECFailure; + + /* The value is required for this attribute. */ + if (!attrValues) { + status = errSecParam; + goto loser; + } + + if ((attr = SecCmsAttributeCreate(poolp, SEC_OID_APPLE_HASH_AGILITY_V2, + NULL, PR_TRUE)) == NULL) { + status = errSecAllocate; + goto loser; + } + + CFDictionaryForEach(attrValues, ^(const void *key, const void *value) { + if (!isNumber(key) || !isData(value)) { + return; + } + (void)CMSAddAgileHashToAttribute(poolp, attr, (CFNumberRef)key, (CFDataRef)value); + }); + + if (SecCmsSignerInfoAddAuthAttr(signerinfo, attr) != SECSuccess) { + status = errSecInternal; + goto loser; + } + + PORT_ArenaUnmark(poolp, mark); + return SECSuccess; + +loser: + PORT_ArenaRelease(poolp, mark); + return status; +} + + SecCertificateRef SecCmsSignerInfoCopyCertFromEncryptionKeyPreference(SecCmsSignerInfoRef signerinfo) { SecCertificateRef cert = NULL; SecCmsAttribute *attr; @@ -1426,6 +1634,12 @@ SecCertificateRef SecCmsSignerInfoCopyCertFromEncryptionKeyPreference(SecCmsSign if (signerinfo->verificationStatus != SecCmsVSGoodSignature) return NULL; + /* Prep the raw certs */ + CSSM_DATA_PTR *rawCerts = NULL; + if (signerinfo->sigd) { + rawCerts = signerinfo->sigd->rawCerts; + } + /* find preferred encryption cert */ if (!SecCmsArrayIsEmpty((void **)signerinfo->authAttr) && (attr = SecCmsAttributeArrayFindAttrByOidTag(signerinfo->authAttr, @@ -1434,11 +1648,17 @@ SecCertificateRef SecCmsSignerInfoCopyCertFromEncryptionKeyPreference(SecCmsSign ekp = SecCmsAttributeGetValue(attr); if (ekp == NULL) return NULL; + cert = SecSMIMEGetCertFromEncryptionKeyPreference(keychainOrArray, rawCerts, ekp); + } + if(cert) return cert; - CSSM_DATA_PTR *rawCerts = NULL; - if (signerinfo->sigd) { - rawCerts = signerinfo->sigd->rawCerts; - } + if (!SecCmsArrayIsEmpty((void **)signerinfo->authAttr) && + (attr = SecCmsAttributeArrayFindAttrByOidTag(signerinfo->authAttr, + SEC_OID_MS_SMIME_ENCRYPTION_KEY_PREFERENCE, PR_TRUE)) != NULL) + { /* we have a MS_SMIME_ENCRYPTION_KEY_PREFERENCE attribute! Find the cert. */ + ekp = SecCmsAttributeGetValue(attr); + if (ekp == NULL) + return NULL; cert = SecSMIMEGetCertFromEncryptionKeyPreference(keychainOrArray, rawCerts, ekp); } return cert; diff --git a/OSX/libsecurity_smime/lib/cmstpriv.h b/OSX/libsecurity_smime/lib/cmstpriv.h index 012ff496..483c1985 100644 --- a/OSX/libsecurity_smime/lib/cmstpriv.h +++ b/OSX/libsecurity_smime/lib/cmstpriv.h @@ -226,7 +226,9 @@ struct SecCmsSignerInfoStr { CFAbsoluteTime tsaLeafNotBefore; /* Start date for Timestamp Authority leaf */ CFAbsoluteTime tsaLeafNotAfter; /* Expiration date for Timestamp Authority leaf */ CFMutableArrayRef timestampCertList; + SecCertificateRef timestampCert; CFDataRef hashAgilityAttrValue; + CFDictionaryRef hashAgilityV2AttrValues; }; #define SEC_CMS_SIGNER_INFO_VERSION_ISSUERSN 1 /* what we *create* */ #define SEC_CMS_SIGNER_INFO_VERSION_SUBJKEY 3 /* what we *create* */ diff --git a/OSX/libsecurity_smime/lib/secoid.c b/OSX/libsecurity_smime/lib/secoid.c index d5bdd5cc..54904fb8 100644 --- a/OSX/libsecurity_smime/lib/secoid.c +++ b/OSX/libsecurity_smime/lib/secoid.c @@ -475,6 +475,7 @@ CONST_OID mqvSinglePassSha1kdf[] = {ANSI_X9_63_SCHEME, 4 }; /* Apple Hash Agility */ CONST_OID appleHashAgility[] = {APPLE_CMS_ATTRIBUTES, 1}; +CONST_OID appleHashAgilityV2[] = {APPLE_CMS_ATTRIBUTES, 2}; /* a special case: always associated with a caller-specified OID */ CONST_OID noOid[] = { 0 }; @@ -1151,7 +1152,9 @@ const static SECOidData oids[] = { OD( appleHashAgility, SEC_OID_APPLE_HASH_AGILITY, "appleCodesigningHashAgilityAttribute", CSSM_ALGID_NONE, INVALID_CERT_EXTENSION), - + OD( appleHashAgilityV2, SEC_OID_APPLE_HASH_AGILITY_V2, + "appleCodesigningHashAgilityAttribute", CSSM_ALGID_NONE, + INVALID_CERT_EXTENSION), }; /* diff --git a/OSX/libsecurity_smime/lib/tsaSupport.c b/OSX/libsecurity_smime/lib/tsaSupport.c index f2faff0e..bf92c7bd 100644 --- a/OSX/libsecurity_smime/lib/tsaSupport.c +++ b/OSX/libsecurity_smime/lib/tsaSupport.c @@ -165,8 +165,7 @@ static void printDataAsHex(const char *title, const CSSM_DATA *d, unsigned maxTo int offset, sz = 0; const int wrapwid = 24; // large enough so SHA-1 hashes fit on one line... - if ((maxToPrint != 0) && (len > maxToPrint)) - { + if ((maxToPrint != 0) && (len > maxToPrint)) { len = maxToPrint; more = true; } @@ -178,22 +177,19 @@ static void printDataAsHex(const char *title, const CSSM_DATA *d, unsigned maxTo dtprintf("%s", buffer); offset = 0; - for (i=0; (i < len) && (offset+3 < bufferSize); i++, offset += sz) - { + for (i=0; (i < len) && (offset+3 < bufferSize); i++, offset += sz) { sz = sprintf(buffer + offset, " %02x", (unsigned int)cp[i] & 0xff); - if ((i % wrapwid) == (wrapwid-1)) - { - dtprintf("%s", buffer); + if ((i % wrapwid) == (wrapwid-1)) { + dtprintf("%s\n", buffer); offset = 0; sz = 0; } } sz=sprintf(buffer + offset, more?" ...\n":"\n"); - offset += sz; + offset += sz; buffer[offset+1]=0; -// fprintf(stderr, "%s", buffer); dtprintf("%s", buffer); free(buffer); @@ -1244,8 +1240,9 @@ OSStatus decodeTimeStampTokenWithPolicy(SecCmsSignerInfoRef signerinfo, CFTypeRe inData comes from the unAuthAttr section of the CMS message These are set in signerinfo as side effects: - timestampTime - + timestampTime timestampCertList + timestampCert */ SecCmsDecoderRef decoderContext = NULL; @@ -1349,6 +1346,11 @@ OSStatus decodeTimeStampTokenWithPolicy(SecCmsSignerInfoRef signerinfo, CFTypeRe int numberOfSigners = SecCmsSignedDataSignerInfoCount (signedData); + if (numberOfSigners > 0) { + /* @@@ assume there's only one signer since SecCms can't handle multiple signers anyway */ + signerinfo->timestampCert = CFRetainSafe(SecCmsSignerInfoGetSigningCertificate(signedData->signerInfos[0], NULL)); + } + result = verifySigners(signedData, numberOfSigners, timeStampPolicy); if (result) dtprintf("verifySigners failed: %ld\n", (long)result); // warning @@ -1368,7 +1370,7 @@ OSStatus decodeTimeStampTokenWithPolicy(SecCmsSignerInfoRef signerinfo, CFTypeRe case SEC_OID_PKCS9_ID_CT_TSTInfo: { SecAsn1TSATSTInfo tstInfo = {{0},}; - SecCertificateRef signerCert = SecCmsSignerInfoGetSigningCertificate(signerinfo, NULL); + SecCertificateRef signerCert = SecCmsSignerInfoGetTimestampSigningCert(signerinfo); result = verifyTSTInfo(contentInfo->rawContent, signerCert, &tstInfo, &signerinfo->timestampTime, expectedNonce); if (signerinfo->timestampTime) { diff --git a/OSX/libsecurity_smime/libsecurity_smime.xcodeproj/project.pbxproj b/OSX/libsecurity_smime/libsecurity_smime.xcodeproj/project.pbxproj index 7d783184..d8597b00 100644 --- a/OSX/libsecurity_smime/libsecurity_smime.xcodeproj/project.pbxproj +++ b/OSX/libsecurity_smime/libsecurity_smime.xcodeproj/project.pbxproj @@ -69,11 +69,11 @@ 4CDA0D6604200AE000CA2E66 /* cmssiginfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C27420403E9FC5B00A80181 /* cmssiginfo.c */; }; 4CDA0D6704200B0F00CA2E66 /* smimeutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C27420F03E9FC5B00A80181 /* smimeutil.c */; }; 4CEC5CDF042A721300CA2E66 /* cmspriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CEC5CDE042A721300CA2E66 /* cmspriv.h */; }; - 4CEC5CE1042A722000CA2E66 /* cmstpriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CEC5CE0042A722000CA2E66 /* cmstpriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 4CEC5CE1042A722000CA2E66 /* cmstpriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CEC5CE0042A722000CA2E66 /* cmstpriv.h */; }; 4CEDC82106371B1700B7E254 /* SecCmsEncryptedData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CEDC82006371B1700B7E254 /* SecCmsEncryptedData.h */; settings = {ATTRIBUTES = (); }; }; - 5232A822150AD71A00E6BB48 /* tsaSupportPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 5232A821150AD71A00E6BB48 /* tsaSupportPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 5232A822150AD71A00E6BB48 /* tsaSupportPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 5232A821150AD71A00E6BB48 /* tsaSupportPriv.h */; }; 52B609D514F4665700134209 /* tsaTemplates.c in Sources */ = {isa = PBXBuildFile; fileRef = 52B609D314F4665700134209 /* tsaTemplates.c */; }; - 52B609D614F4665700134209 /* tsaTemplates.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B609D414F4665700134209 /* tsaTemplates.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 52B609D614F4665700134209 /* tsaTemplates.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B609D414F4665700134209 /* tsaTemplates.h */; }; 52D7A24A15092A0600CF48F7 /* tsaSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = 52D7A24915092A0600CF48F7 /* tsaSupport.c */; }; 52D7A24D15094B8B00CF48F7 /* tsaSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 52D7A24C15092AAD00CF48F7 /* tsaSupport.h */; settings = {ATTRIBUTES = (Private, ); }; }; AC62F5F418B4358B00704BBD /* smime-cms-test.c in Sources */ = {isa = PBXBuildFile; fileRef = ACBEE91018B420BC0021712D /* smime-cms-test.c */; }; @@ -337,6 +337,7 @@ 4CEC5CDF042A721300CA2E66 /* cmspriv.h in Headers */, 4C27422203E9FC7600A80181 /* cmsreclist.h in Headers */, 4CEC5CE1042A722000CA2E66 /* cmstpriv.h in Headers */, + 5232A822150AD71A00E6BB48 /* tsaSupportPriv.h in Headers */, 4CA51CE00420246F00CA2E66 /* cryptohi.h in Headers */, 4C8E16750438EF5700CA2E66 /* plhash.h in Headers */, 4CCC260E0635F1A200CBF0D4 /* SecCmsBase.h in Headers */, @@ -355,10 +356,9 @@ 4C8E167A0438EFD700CA2E66 /* secitem.h in Headers */, 4C8E16700438EEE700CA2E66 /* secoid.h in Headers */, 4C424BE8063F28F600E9831A /* SecSMIMEPriv.h in Headers */, - 52B609D614F4665700134209 /* tsaTemplates.h in Headers */, 52D7A24D15094B8B00CF48F7 /* tsaSupport.h in Headers */, ACBEE90E18B415B60021712D /* SecCMS.h in Headers */, - 5232A822150AD71A00E6BB48 /* tsaSupportPriv.h in Headers */, + 52B609D614F4665700134209 /* tsaTemplates.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/OSX/libsecurity_ssl/lib/SecureTransport.h b/OSX/libsecurity_ssl/lib/SecureTransport.h index c753a278..f884dee9 100644 --- a/OSX/libsecurity_ssl/lib/SecureTransport.h +++ b/OSX/libsecurity_ssl/lib/SecureTransport.h @@ -290,6 +290,26 @@ CF_ENUM(OSStatus) { /* non-fatal result codes */ errSSLClientHelloReceived = -9851, /* SNI */ + + /* fatal errors resulting from transport or networking errors */ + errSSLTransportReset = -9852, /* transport (socket) shutdown, e.g., TCP RST or FIN. */ + errSSLNetworkTimeout = -9853, /* network timeout triggered */ + + /* fatal errors resulting from software misconfiguration */ + errSSLConfigurationFailed = -9854, /* TLS configuration failed */ + + /* additional errors */ + errSSLUnsupportedExtension = -9855, /* unsupported TLS extension */ + errSSLUnexpectedMessage = -9856, /* peer rejected unexpected message */ + errSSLDecompressFail = -9857, /* decompression failed */ + errSSLHandshakeFail = -9858, /* handshake failed */ + errSSLDecodeError = -9859, /* decode failed */ + errSSLInappropriateFallback = -9860, /* inappropriate fallback */ + errSSLMissingExtension = -9861, /* missing extension */ + errSSLBadCertificateStatusResponse = -9862, /* bad OCSP response */ + errSSLCertificateRequired = -9863, /* certificate required */ + errSSLUnknownPSKIdentity = -9864, /* unknown PSK identity */ + errSSLUnrecognizedName = -9865, /* unknown or unrecognized name */ }; /* DEPRECATED aliases for errSSLPeerAuthCompleted */ diff --git a/OSX/libsecurity_transform/lib/SecDigestTransform.h b/OSX/libsecurity_transform/lib/SecDigestTransform.h index 83415105..d61f6e2d 100644 --- a/OSX/libsecurity_transform/lib/SecDigestTransform.h +++ b/OSX/libsecurity_transform/lib/SecDigestTransform.h @@ -140,7 +140,7 @@ SecTransformRef SecDigestTransformCreate(CFTypeRef __nullable digestType, @result The CFTypeID */ -CFTypeID SecDigestTransformGetTypeID() + CFTypeID SecDigestTransformGetTypeID(void) __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA); CF_IMPLICIT_BRIDGING_DISABLED diff --git a/OSX/libsecurity_transform/lib/SecEncryptTransform.cpp b/OSX/libsecurity_transform/lib/SecEncryptTransform.cpp index 5ee1c15d..8a2703a3 100644 --- a/OSX/libsecurity_transform/lib/SecEncryptTransform.cpp +++ b/OSX/libsecurity_transform/lib/SecEncryptTransform.cpp @@ -24,6 +24,7 @@ #include "SecEncryptTransform.h" #include "SecTransformInternal.h" #include "EncryptTransform.h" +#include /* -------------------------------------------------------------------------- Create the declared CFStringRefs diff --git a/OSX/libsecurity_transform/lib/SecEncryptTransform.h b/OSX/libsecurity_transform/lib/SecEncryptTransform.h index 00bdff8d..0a744fcf 100644 --- a/OSX/libsecurity_transform/lib/SecEncryptTransform.h +++ b/OSX/libsecurity_transform/lib/SecEncryptTransform.h @@ -172,7 +172,7 @@ CF_IMPLICIT_BRIDGING_ENABLED @return the CFTypeID */ - CFTypeID SecDecryptTransformGetTypeID() + CFTypeID SecDecryptTransformGetTypeID(void) __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA); /*! @@ -181,7 +181,7 @@ CF_IMPLICIT_BRIDGING_ENABLED @return the CFTypeID */ - CFTypeID SecEncryptTransformGetTypeID() + CFTypeID SecEncryptTransformGetTypeID(void) __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_NA); CF_IMPLICIT_BRIDGING_DISABLED diff --git a/OSX/libsecurity_transform/lib/SecTransformInternal.h b/OSX/libsecurity_transform/lib/SecTransformInternal.h index b339ff8d..8eac2905 100644 --- a/OSX/libsecurity_transform/lib/SecTransformInternal.h +++ b/OSX/libsecurity_transform/lib/SecTransformInternal.h @@ -7,7 +7,6 @@ extern "C" { #endif #include "SecTransform.h" -#include "SecCFRelease.h" CFErrorRef SecTransformConnectTransformsInternal(SecGroupTransformRef groupRef, SecTransformRef sourceTransformRef, CFStringRef sourceAttributeName, SecTransformRef destinationTransformRef, CFStringRef destinationAttributeName); diff --git a/OSX/libsecurity_utilities/lib/alloc.h b/OSX/libsecurity_utilities/lib/alloc.h index 411b58cb..8d276227 100644 --- a/OSX/libsecurity_utilities/lib/alloc.h +++ b/OSX/libsecurity_utilities/lib/alloc.h @@ -55,10 +55,23 @@ public: { return reinterpret_cast(malloc(sizeof(T))); } template T *alloc(UInt32 count) throw(std::bad_alloc) - { return reinterpret_cast(malloc(sizeof(T) * count)); } + { + size_t bytes = 0; + if (__builtin_mul_overflow(sizeof(T), count, &bytes)) { + throw std::bad_alloc(); + } + return reinterpret_cast(malloc(bytes)); + + } template T *alloc(T *old, UInt32 count) throw(std::bad_alloc) - { return reinterpret_cast(realloc(old, sizeof(T) * count)); } + { + size_t bytes = 0; + if (__builtin_mul_overflow(sizeof(T), count, &bytes)) { + throw std::bad_alloc(); + } + return reinterpret_cast(realloc(old, bytes)); + } // diff --git a/OSX/libsecurity_utilities/lib/debugging.h b/OSX/libsecurity_utilities/lib/debugging.h deleted file mode 120000 index ac6a54fc..00000000 --- a/OSX/libsecurity_utilities/lib/debugging.h +++ /dev/null @@ -1 +0,0 @@ -./../utilities/src/debugging.h \ No newline at end of file diff --git a/OSX/libsecurity_utilities/lib/pcsc++.h b/OSX/libsecurity_utilities/lib/pcsc++.h index 46e045d1..5ca469d7 100644 --- a/OSX/libsecurity_utilities/lib/pcsc++.h +++ b/OSX/libsecurity_utilities/lib/pcsc++.h @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/OSX/libsecurity_utilities/lib/threading_internal.h b/OSX/libsecurity_utilities/lib/threading_internal.h index dc7af307..03c8076f 100644 --- a/OSX/libsecurity_utilities/lib/threading_internal.h +++ b/OSX/libsecurity_utilities/lib/threading_internal.h @@ -38,7 +38,11 @@ namespace Security { // // Do we have 64-bit atomic operations? // -#define _HAVE_64BIT_ATOMIC (defined(__ppc64__) || defined(__i386__) || defined(__x86_64__)) +#if (defined(__ppc64__) || defined(__i386__) || defined(__x86_64__)) +#define _HAVE_64BIT_ATOMIC 1 +#else +#define _HAVE_64BIT_ATOMIC 0 +#endif // diff --git a/OSX/libsecurityd/lib/SharedMemoryClient.cpp b/OSX/libsecurityd/lib/SharedMemoryClient.cpp index 3acb37d2..2a54ec17 100644 --- a/OSX/libsecurityd/lib/SharedMemoryClient.cpp +++ b/OSX/libsecurityd/lib/SharedMemoryClient.cpp @@ -17,6 +17,7 @@ using namespace Security; // SharedMemoryClient //================================================================================= +#if !defined(NDEBUG) static std::string unixerrorstr(int errnum) { string errstr; char buf[1024]; @@ -26,6 +27,7 @@ static std::string unixerrorstr(int errnum) { errstr += "(" + to_string(errnum) + ")"; return errstr; } +#endif SharedMemoryClient::SharedMemoryClient (const char* segmentName, SegmentOffsetType segmentSize, uid_t uid) { diff --git a/OSX/macos_tapi_hacks.h b/OSX/macos_tapi_hacks.h new file mode 100644 index 00000000..c5b25793 --- /dev/null +++ b/OSX/macos_tapi_hacks.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#ifndef macos_tapi_hack_h +#define macos_tapi_hack_h + +// This file is to work around TAPI's insistence that every exported symbol is in a header file. +// The Security project just simply rejects such ideas, so this is the pressure valve: +// +// One-offs in header files that shouldn't be exported in the real-live macOS Security framework +// can be added here, and TAPI will accept them. +// +// Please don't add anything here. + +#ifndef SECURITY_PROJECT_TAPI_HACKS +#error This header is not for inclusion; it's a nasty hack to get the macOS Security framework to build with TAPI. +#endif + +#include +#include + +CFDataRef SecDistinguishedNameCopyNormalizedContent(CFDataRef distinguished_name); +CFDataRef _SecItemCreatePersistentRef(CFTypeRef iclass, sqlite_int64 rowid, CFDictionaryRef attributes); +CFDictionaryRef SecTokenItemValueCopy(CFDataRef db_value, CFErrorRef *error); +CFArrayRef SecTrustCopyProperties_ios(SecTrustRef trust); +CFArrayRef SecItemCopyParentCertificates_ios(CFDataRef normalizedIssuer, CFArrayRef accessGroups, CFErrorRef *error); +bool SecItemCertificateExists(CFDataRef normalizedIssuer, CFDataRef serialNumber, CFArrayRef accessGroups, CFErrorRef *error); +bool _SecItemParsePersistentRef(CFDataRef persistent_ref, CFStringRef *return_class, + sqlite_int64 *return_rowid, CFDictionaryRef *return_token_attrs); + +// iOS-only SecKey functions +size_t SecKeyGetSize(SecKeyRef key, int whichSize); +CFDataRef SecKeyCopyPublicKeyHash(SecKeyRef key); + +// SecItemPriv.h +extern const CFStringRef kSecUseSystemKeychain; + +// securityd_client.h + +typedef struct SecurityClient { +} SecurityClient; + +extern struct securityd *gSecurityd; +extern struct trustd *gTrustd; +extern SecurityClient * SecSecurityClientGet(void); +bool securityd_send_sync_and_do(enum SecXPCOperation op, CFErrorRef *error, + bool (^add_to_message)(xpc_object_t message, CFErrorRef* error), + bool (^handle_response)(xpc_object_t response, CFErrorRef* error)); +XPC_RETURNS_RETAINED xpc_object_t securityd_message_with_reply_sync(xpc_object_t message, CFErrorRef *error); +XPC_RETURNS_RETAINED xpc_object_t securityd_create_message(enum SecXPCOperation op, CFErrorRef *error); +bool securityd_message_no_error(xpc_object_t message, CFErrorRef *error); + +@interface SecuritydXPCClient : NSObject +@end + +void SecAccessGroupsSetCurrent(CFArrayRef accessGroups); +CFArrayRef SecAccessGroupsGetCurrent(void); + +// checkpw.c +int checkpw_internal( const struct passwd* pw, const char* password ); + +// SecFramework.h +CFDataRef SecDigestCreate(CFAllocatorRef allocator, + const SecAsn1Oid *algorithm, const SecAsn1Item *params, + const UInt8 *data, CFIndex length); +CFDataRef SecSHA256DigestCreateFromData(CFAllocatorRef allocator, CFDataRef data); +CFStringRef SecFrameworkCopyLocalizedString(CFStringRef key, + CFStringRef tableName); + +#endif /* macos_tapi_hack_h */ diff --git a/OSX/regressions/test/testcert.h b/OSX/regressions/test/testcert.h index 0babe8db..b06b07df 100644 --- a/OSX/regressions/test/testcert.h +++ b/OSX/regressions/test/testcert.h @@ -35,6 +35,7 @@ SecIdentityRef test_cert_create_root_certificate(CFStringRef subject, SecKeyRef public_key, SecKeyRef private_key); +CF_RETURNS_RETAINED SecCertificateRef test_cert_issue_certificate(SecIdentityRef ca_identity, SecKeyRef public_key, CFStringRef subject, diff --git a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.c b/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.c index dcce498e..771179a5 100644 --- a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.c +++ b/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.c @@ -67,15 +67,8 @@ static CFStringRef sErrorDomain = CFSTR("com.apple.security.sos.transport.error" // MARK: ---------- SOSCloudTransport ---------- -/* SOSCloudTransport, a statically initialized transport singleton. */ -static SOSCloudTransportRef sTransport = NULL; - static SOSCloudTransportRef SOSCloudTransportCreateXPCTransport(void); -void SOSCloudKeychainSetTransport(SOSCloudTransportRef transport) { - sTransport = transport; -} - void SOSCloudTransportGet(SOSCloudTransportRef transport, CFArrayRef keysToGet, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); @@ -141,9 +134,9 @@ errOut: static SOSCloudTransportRef SOSCloudTransportDefaultTransport(void) { static dispatch_once_t sTransportOnce; + static SOSCloudTransportRef sTransport = NULL; dispatch_once(&sTransportOnce, ^{ - if (!sTransport) - SOSCloudKeychainSetTransport(SOSCloudTransportCreateXPCTransport()); + sTransport = SOSCloudTransportCreateXPCTransport(); // provide state handler to sysdiagnose and logging os_state_add_handler(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), kvsStateBlock); }); @@ -222,11 +215,6 @@ static bool xpc_event_filter(const xpc_connection_t peer, xpc_object_t event, CF // The client of an XPC service does not get connection events // For now, we log this and keep going describeXPCObject("handle_xpc_event: XPC_TYPE_CONNECTION, obj : ", event); -#if 0 - if (error) - *error = makeError(kSOSOUnexpectedConnectionEvent); // FIX - assert(true); -#endif } else if (XPC_TYPE_ERROR == xtype) @@ -234,17 +222,7 @@ static bool xpc_event_filter(const xpc_connection_t peer, xpc_object_t event, CF #ifndef NDEBUG const char *estr = xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION); #endif - secdebug(SOSCKCSCOPE, "default: xpc error: %s\n", estr); -#if 0 // just log for now - CFStringRef errStr = CFStringCreateWithCString(kCFAllocatorDefault, estr, kCFStringEncodingUTF8); - CFMutableDictionaryRef userInfo = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - if (errStr) - CFDictionaryAddValue(userInfo, kCFErrorLocalizedDescriptionKey, errStr); - if (error) - *error = CFErrorCreate(kCFAllocatorDefault, sErrorDomain, kSOSOXPCErrorEvent, userInfo); - CFReleaseSafe(errStr); - CFReleaseSafe(userInfo); -#endif + secdebug(SOSCKCSCOPE, "default: xpc error: %s\n", estr); } else if (XPC_TYPE_DICTIONARY == xtype) @@ -277,12 +255,12 @@ static void setupIDSProxyServiceConnection(SOSXPCCloudTransportRef transport) }); xpc_connection_activate(transport->idsProxyServiceConnection); - xpc_retain(transport->idsProxyServiceConnection); } static void teardownIDSProxyServiceConnection(SOSXPCCloudTransportRef transport) { secnotice(SOSCKCSCOPE, "IDS Transport: tearing down xpc connection"); + dispatch_assert_queue(transport->xpc_queue); xpc_release(transport->idsProxyServiceConnection); transport->idsProxyServiceConnection = NULL; } @@ -302,12 +280,12 @@ static void setupServiceConnection(SOSXPCCloudTransportRef transport) }); xpc_connection_activate(transport->serviceConnection); - xpc_retain(transport->serviceConnection); } static void teardownServiceConnection(SOSXPCCloudTransportRef transport) { secnotice(SOSCKCSCOPE, "CKP Transport: tearing down xpc connection"); + dispatch_assert_queue(transport->xpc_queue); xpc_release(transport->serviceConnection); transport->serviceConnection = NULL; } @@ -347,13 +325,11 @@ static void talkWithIDS(SOSXPCCloudTransportRef transport, xpc_object_t message, CFTypeRef object = NULL; if (xpc_event_filter(transport->idsProxyServiceConnection, reply, &serverError) && reply) { - describeXPCObject("IDS Proxy: reply : ", reply); if (serverError) secerror("Error from xpc_event_filter: %@", serverError); xpc_object_t xrv = xpc_dictionary_get_value(reply, kMessageKeyValue); if (xrv) { - describeXPCObject("talkwithIDS: xrv: ", xrv); /* * The given XPC object must be one that was previously returned by * _CFXPCCreateXPCMessageWithCFObject(). @@ -397,13 +373,15 @@ xit: typedef void (^ProxyReplyBlock)(xpc_object_t reply); static bool messageToProxy(SOSXPCCloudTransportRef transport, xpc_object_t message, CFErrorRef *error, dispatch_queue_t processQueue, ProxyReplyBlock replyBlock) { - CFErrorRef connectionError = NULL; - - require_action(transport->serviceConnection, xit, connectionError = makeError(kSOSConnectionNotOpen)); - require_action(message, xit, connectionError = makeError(kSOSObjectNotFoundError)); + __block CFErrorRef connectionError = NULL; - xpc_connection_send_message_with_reply(transport->serviceConnection, message, processQueue, replyBlock); -xit: + dispatch_sync(transport->xpc_queue, ^{ + if (transport->serviceConnection && message) { + xpc_connection_send_message_with_reply(transport->serviceConnection, message, processQueue, replyBlock); + } else { + connectionError = makeError(kSOSConnectionNotOpen); + } + }); return CFErrorPropagate(connectionError, error); } @@ -417,19 +395,16 @@ static void talkWithKVS(SOSXPCCloudTransportRef transport, xpc_object_t message, CFTypeRef object = NULL; if (xpc_event_filter(transport->serviceConnection, reply, &serverError) && reply) { - describeXPCObject("getValuesFromKVS: reply : ", reply); if (serverError) secerror("Error from xpc_event_filter: %@", serverError); xpc_object_t xrv = xpc_dictionary_get_value(reply, kMessageKeyValue); if (xrv) { - describeXPCObject("talkWithKVS: xrv: ", xrv); /* * The given XPC object must be one that was previously returned by * _CFXPCCreateXPCMessageWithCFObject(). */ object = _CFXPCCreateCFObjectFromXPCObject(xrv); // CF object is retained; release in callback - secnotice("talkwithkvs", "converted CF object: %@", object); } else secerror("missing value reply"); @@ -575,7 +550,7 @@ static void SOSCloudTransportGetPerformanceStats(SOSCloudTransportRef transport, xpc_release(message); } -static void SOSCloudTransportSendFragmentedIDSMessage(SOSCloudTransportRef transport, CFDictionaryRef messageData, CFStringRef deviceName, CFStringRef peerID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock){ +static void SOSCloudTransportSendFragmentedIDSMessage(SOSCloudTransportRef transport, CFDictionaryRef messageData, CFStringRef deviceName, CFStringRef peerID, CFStringRef myDeviceID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock){ SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport; xpc_object_t xmessageData = _CFXPCCreateXPCObjectFromCFObject(messageData); @@ -587,6 +562,8 @@ static void SOSCloudTransportSendFragmentedIDSMessage(SOSCloudTransportRef trans xpc_dictionary_set_value(message, kMessageKeyValue, xmessageData); SecXPCDictionarySetCFObject(message, kMessageKeyDeviceName, deviceName); SecXPCDictionarySetCFObject(message, kMessageKeyPeerID, peerID); + SecXPCDictionarySetCFObject(message, kMessageKeyDeviceID, myDeviceID); + talkWithIDS(xpcTransport, message, processQueue, replyBlock); xpc_release(xmessageData); @@ -627,7 +604,7 @@ static void SOSCloudTransportCheckIDSDeviceIDAvailability(SOSCloudTransportRef t } -static void SOSCloudTransportSendIDSMessage(SOSCloudTransportRef transport, CFDictionaryRef messageData, CFStringRef deviceName, CFStringRef peerID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock){ +static void SOSCloudTransportSendIDSMessage(SOSCloudTransportRef transport, CFDictionaryRef messageData, CFStringRef deviceName, CFStringRef peerID, CFStringRef myDeviceID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock){ SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport; xpc_object_t xmessageData = _CFXPCCreateXPCObjectFromCFObject(messageData); @@ -639,6 +616,7 @@ static void SOSCloudTransportSendIDSMessage(SOSCloudTransportRef transport, CFDi xpc_dictionary_set_value(message, kMessageKeyValue, xmessageData); SecXPCDictionarySetCFObject(message, kMessageKeyDeviceName, deviceName); SecXPCDictionarySetCFObject(message, kMessageKeyPeerID, peerID); + SecXPCDictionarySetCFObject(message, kMessageKeyDeviceID, myDeviceID); talkWithIDS(xpcTransport, message, processQueue, replyBlock); xpc_release(xmessageData); @@ -915,14 +893,14 @@ void SOSCloudKeychainRemoveKeys(CFArrayRef keys, CFStringRef accountUUID, dispat cTransportRef->removeKeys(cTransportRef, keys, accountUUID, processQueue, replyBlock); } -void SOSCloudKeychainSendIDSMessage(CFDictionaryRef message, CFStringRef deviceName, CFStringRef peerID, dispatch_queue_t processQueue, CFBooleanRef fragmentation, CloudKeychainReplyBlock replyBlock) +void SOSCloudKeychainSendIDSMessage(CFDictionaryRef message, CFStringRef deviceName, CFStringRef peerID, CFStringRef myDeviceID, dispatch_queue_t processQueue, CFBooleanRef fragmentation, CloudKeychainReplyBlock replyBlock) { SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport(); if(cTransportRef && fragmentation == kCFBooleanTrue) - cTransportRef->sendFragmentedIDSMessage(cTransportRef, message, deviceName, peerID, processQueue, replyBlock); + cTransportRef->sendFragmentedIDSMessage(cTransportRef, message, deviceName, peerID, myDeviceID, processQueue, replyBlock); else if(cTransportRef) - cTransportRef->sendIDSMessage(cTransportRef, message, deviceName, peerID, processQueue, replyBlock); + cTransportRef->sendIDSMessage(cTransportRef, message, deviceName, peerID, myDeviceID, processQueue, replyBlock); } diff --git a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.h b/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.h index ee8174e8..b3e2ffd0 100644 --- a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.h +++ b/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.h @@ -67,8 +67,8 @@ struct SOSCloudTransport void (*put)(SOSCloudTransportRef transport, CFDictionaryRef valuesToPut, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); void (*updateKeys)(SOSCloudTransportRef transport, CFDictionaryRef keys, CFStringRef accountUUID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); - void (*sendIDSMessage)(SOSCloudTransportRef transport, CFDictionaryRef data, CFStringRef deviceName, CFStringRef peerID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); - void (*sendFragmentedIDSMessage)(SOSCloudTransportRef transport, CFDictionaryRef data, CFStringRef deviceName, CFStringRef peerID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); + void (*sendIDSMessage)(SOSCloudTransportRef transport, CFDictionaryRef data, CFStringRef deviceName, CFStringRef peerID, CFStringRef myDeviceID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); + void (*sendFragmentedIDSMessage)(SOSCloudTransportRef transport, CFDictionaryRef data, CFStringRef deviceName, CFStringRef peerID, CFStringRef myDeviceID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); void (*retrieveMessages) (SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); void (*getDeviceID)(SOSCloudTransportRef transport, CloudKeychainReplyBlock replyBlock); @@ -96,16 +96,10 @@ struct SOSCloudTransport }; -/* Call this function before calling any other function in this header to provide - an alternate transport, the default transport talks to CloudKeychainProxy via xpc. */ -void SOSCloudKeychainSetTransport(SOSCloudTransportRef transport); - void SOSCloudKeychainGetIDSDeviceID(CloudKeychainReplyBlock replyBlock); -void SOSCloudKeychainSendIDSMessage(CFDictionaryRef message, CFStringRef deviceName, CFStringRef peerID, dispatch_queue_t processQueue, CFBooleanRef fragmentation, CloudKeychainReplyBlock replyBlock); void SOSCloudKeychainRetrievePendingMessageFromProxy(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); void SOSCloudKeychainUpdateKeys(CFDictionaryRef keys, CFStringRef accountUUID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); -void SOSCloudKeychainUnRegisterKeys(CFArrayRef keysToUnregister, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); void SOSCloudKeychainPutObjectsInCloud(CFDictionaryRef objects, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); @@ -133,6 +127,7 @@ CFDictionaryRef SOSCloudCopyKVSState(void); void SOSCloudKeychainGetIDSDeviceAvailability(CFArrayRef ids, CFStringRef peerID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); void SOSCloudKeychainRemoveKeys(CFArrayRef keys, CFStringRef accountUUID, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); void SOSCloudKeychainRetrieveCountersFromIDSProxy(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); +void SOSCloudKeychainSendIDSMessage(CFDictionaryRef message, CFStringRef deviceName, CFStringRef peerID, CFStringRef myDeviceID, dispatch_queue_t processQueue, CFBooleanRef fragmentation, CloudKeychainReplyBlock replyBlock); __END_DECLS diff --git a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.c b/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.c index a2099527..fed2fc46 100644 --- a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.c +++ b/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.c @@ -73,6 +73,7 @@ const char *kMessageKeyDeviceID = "deviceID"; const char *kMessageKeyPeerID = "peerID"; const char *kMessageKeySendersPeerID = "sendersPeerID"; const char *kMessageKeyAccountUUID = "AcctUUID"; +const char *kMessageKeySenderDeviceID = "SendersDeviceID"; const char *kMessageOperationItemChanged = "ItemChanged"; diff --git a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.h b/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.h index e4a3c6cf..46879416 100644 --- a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.h +++ b/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.h @@ -54,6 +54,7 @@ extern const char *kMessageKeyPeerID; extern const char *kMessageKeySendersPeerID; extern const char *kMessageKeyAccountUUID; extern const char *kOperationSendDeviceList; +extern const char *kMessageKeySenderDeviceID; extern const char *kMessageContext; extern const char *kMessageKeyParameter; diff --git a/OSX/sec/SOSCircle/Regressions/SOSTestDataSource.c b/OSX/sec/SOSCircle/Regressions/SOSTestDataSource.c index 79a61542..0ab10983 100644 --- a/OSX/sec/SOSCircle/Regressions/SOSTestDataSource.c +++ b/OSX/sec/SOSCircle/Regressions/SOSTestDataSource.c @@ -484,6 +484,12 @@ SOSObjectRef SOSDataSourceCreateGenericItemWithData(SOSDataSourceRef ds, CFStrin CFNumberRef one = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value); CFAbsoluteTime timestamp = 3700000 + (is_tomb ? 1 : 0); CFDateRef now = CFDateCreate(kCFAllocatorDefault, timestamp); + + CFDataRef defaultData = NULL; + if (!is_tomb && !data) { + defaultData = CFDataCreate(NULL, (UInt8*)"some data", 9); + data = defaultData; + } CFDictionaryRef dict = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, kSecClass, kSecClassGenericPassword, kSecAttrSynchronizable, one, @@ -499,6 +505,7 @@ SOSObjectRef SOSDataSourceCreateGenericItemWithData(SOSDataSourceRef ds, CFStrin CFRelease(one); CFRelease(zero); CFReleaseSafe(now); + CFReleaseNull(defaultData); CFErrorRef localError = NULL; SOSObjectRef object = ds->objectCreateWithPropertyList(dict, &localError); if (!object) { diff --git a/OSX/sec/SOSCircle/Regressions/SOSTestDevice.c b/OSX/sec/SOSCircle/Regressions/SOSTestDevice.c index f803683b..74147521 100644 --- a/OSX/sec/SOSCircle/Regressions/SOSTestDevice.c +++ b/OSX/sec/SOSCircle/Regressions/SOSTestDevice.c @@ -255,15 +255,15 @@ bool SOSTestDeviceEngineLoad(SOSTestDeviceRef td, CFErrorRef *error) { CFDataRef SOSTestDeviceCreateMessage(SOSTestDeviceRef td, CFStringRef peerID) { setup("create message"); CFErrorRef error = NULL; - SOSEnginePeerMessageSentBlock sent = NULL; + SOSEnginePeerMessageSentCallback* sent = NULL; CFDataRef msgData; CFMutableArrayRef attributeList = NULL; ok(msgData = SOSEngineCreateMessageToSyncToPeer(td->ds->engine, peerID, &attributeList, &sent, &error), "create message to %@: %@", peerID, error); - if (sent) - sent(true); - Block_release(sent); + SOSEngineMessageCallCallback(sent, true); + SOSEngineFreeMessageCallback(sent); + return msgData; } diff --git a/OSX/sec/SOSCircle/Regressions/sc-153-backupslicekeybag.c b/OSX/sec/SOSCircle/Regressions/sc-153-backupslicekeybag.c index 3bf87c7a..c037d864 100644 --- a/OSX/sec/SOSCircle/Regressions/sc-153-backupslicekeybag.c +++ b/OSX/sec/SOSCircle/Regressions/sc-153-backupslicekeybag.c @@ -34,7 +34,7 @@ #define encode_decode_count 2 #if !TARGET_IPHONE_SIMULATOR -static SOSBackupSliceKeyBagRef EncodeDecode(SOSBackupSliceKeyBagRef bag) +static CF_RETURNS_RETAINED SOSBackupSliceKeyBagRef EncodeDecode(SOSBackupSliceKeyBagRef bag) { SOSBackupSliceKeyBagRef result = NULL; CFErrorRef localError = NULL; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.h index 9c21a109..a0baeb5d 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.h @@ -137,7 +137,7 @@ CFArrayRef SOSAccountCopyRetired(SOSAccount* account, CFErrorRef *error); CFArrayRef SOSAccountCopyViewUnaware(SOSAccount* account, CFErrorRef *error); CFArrayRef SOSAccountCopyPeers(SOSAccount* account, CFErrorRef *error); CFArrayRef SOSAccountCopyActivePeers(SOSAccount* account, CFErrorRef *error); -CFArrayRef SOSAccountCopyActiveValidPeers(SOSAccount* account, CFErrorRef *error); +CFArrayRef CF_RETURNS_RETAINED SOSAccountCopyActiveValidPeers(SOSAccount* account, CFErrorRef *error); CFArrayRef SOSAccountCopyConcurringPeers(SOSAccount* account, CFErrorRef *error); bool SOSAccountIsAccountIdentity(SOSAccount* account, SOSPeerInfoRef peer_info, CFErrorRef *error); @@ -198,7 +198,7 @@ bool SOSAccountSyncWithKVSUsingIDSID(SOSAccount* account, CFStringRef deviceID, // bool SOSAccountScanForRetired(SOSAccount* account, SOSCircleRef circle, CFErrorRef *error); -SOSCircleRef SOSAccountCloneCircleWithRetirement(SOSAccount* account, SOSCircleRef starting_circle, CFErrorRef *error); +CF_RETURNS_RETAINED SOSCircleRef SOSAccountCloneCircleWithRetirement(SOSAccount* account, SOSCircleRef starting_circle, CFErrorRef *error); // // MARK: Version incompatibility Functions @@ -216,7 +216,7 @@ bool SOSAccountSetBackupPublicKey(SOSAccountTransaction* aTxn, CFDataRef backupK bool SOSAccountRemoveBackupPublickey(SOSAccountTransaction* aTxn, CFErrorRef *error); bool SOSAccountSetBSKBagForAllSlices(SOSAccount* account, CFDataRef backupSlice, bool setupV0Only, CFErrorRef *error); -SOSBackupSliceKeyBagRef SOSAccountBackupSliceKeyBagForView(SOSAccount* account, CFStringRef viewName, CFErrorRef* error); +CF_RETURNS_RETAINED SOSBackupSliceKeyBagRef SOSAccountBackupSliceKeyBagForView(SOSAccount* account, CFStringRef viewName, CFErrorRef* error); bool SOSAccountIsLastBackupPeer(SOSAccount* account, CFErrorRef *error); @@ -293,11 +293,11 @@ bool SOSAccountSendToPeerIsPending(SOSAccountTransaction* txn, SOSPeerInfoRef pe // // MARK: OTR // -void SOSAccountResetOTRNegotiationCoder(SOSAccountTransaction* txn, CFStringRef peerid); +void SOSAccountResetOTRNegotiationCoder(SOSAccount* account, CFStringRef peerid); void SOSAccountTimerFiredSendNextMessage(SOSAccountTransaction* txn, NSString* peerid, NSString* accessGroup); NSMutableArray* SOSAccountGetAllTLKs(void); -CFMutableArrayRef SOSAccountCopyiCloudIdentities(SOSAccount* account); +CF_RETURNS_RETAINED CFMutableArrayRef SOSAccountCopyiCloudIdentities(SOSAccount* account); __END_DECLS diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.m index b76fbef8..c289643a 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.m @@ -8,9 +8,6 @@ */ #import -#import -#import - #include #include @@ -44,8 +41,11 @@ #import "Security/SecureObjectSync/SOSPeerOTRTimer.h" #import "Security/SecureObjectSync/SOSPeerRateLimiter.h" #import "Security/SecureObjectSync/SOSTypes.h" +#if OCTAGON #import "keychain/ckks/CKKSViewManager.h" - +#import "keychain/ckks/CKKSLockStateTracker.h" +#import "keychain/ot/OTContext.h" +#endif #include #include #include @@ -67,7 +67,6 @@ #include #include -const CFStringRef kSOSDSIDKey = CFSTR("AccountDSID"); const CFStringRef kSOSEscrowRecord = CFSTR("EscrowRecord"); const CFStringRef kSOSUnsyncedViewsKey = CFSTR("unsynced"); const CFStringRef kSOSInitialSyncTimeoutV0 = CFSTR("initialsynctimeout"); @@ -92,143 +91,6 @@ const uint64_t max_packet_size_over_idms = 500; #define DATE_LENGTH 25 const CFStringRef kSOSAccountDebugScope = CFSTR("Scope"); -@interface SOSAccount () -@property (retain,nonnull) NSXPCListener *listener; -@end - - -@interface SOSClient : NSObject -@property (weak) NSXPCConnection * connection; -@property (strong) SOSAccount * account; - -- (instancetype)initWithConnection:(NSXPCConnection *)connection account:(SOSAccount *)account; -@end - -@implementation SOSClient - -@synthesize account = _account; -@synthesize connection = _connection; - -- (instancetype)initWithConnection:(NSXPCConnection *)connection account:(SOSAccount *)account -{ - if ((self = [super init])) { - _connection = connection; - _account = account; - } - return self; -} - -- (bool)checkEntitlement:(NSString *)entitlement -{ - NSXPCConnection *strongConnection = _connection; - - NSNumber *num = [strongConnection valueForEntitlement:entitlement]; - if (![num isKindOfClass:[NSNumber class]] || ![num boolValue]) { - secinfo("sos", "Client pid: %d doesn't have entitlement: %@", - [strongConnection processIdentifier], entitlement); - return false; - } - return true; -} - -- (void)userPublicKey:(void ((^))(BOOL trusted, NSData *spki, NSError *error))reply -{ - [self.account userPublicKey:reply]; -} - -- (void)kvsPerformanceCounters:(void(^)(NSDictionary *))reply -{ - [self.account kvsPerformanceCounters:reply]; -} - -- (void)idsPerformanceCounters:(void(^)(NSDictionary *))reply -{ - [self.account idsPerformanceCounters:reply]; -} - -- (void)rateLimitingPerformanceCounters:(void(^)(NSDictionary *))reply -{ - [self.account rateLimitingPerformanceCounters:reply]; -} - -- (void)stashedCredentialPublicKey:(void(^)(NSData *, NSError *error))reply -{ - [self.account stashedCredentialPublicKey:reply]; -} - -- (void)assertStashedAccountCredential:(void(^)(BOOL result, NSError *error))reply -{ - [self.account assertStashedAccountCredential:reply]; -} - -- (void)validatedStashedAccountCredential:(void(^)(NSData *credential, NSError *error))complete -{ - [self.account validatedStashedAccountCredential:complete]; -} - -- (void)stashAccountCredential:(NSData *)credential complete:(void(^)(bool success, NSError *error))complete -{ - [self.account stashAccountCredential:credential complete:complete]; -} - -- (void)myPeerInfo:(void (^)(NSData *, NSError *))complete -{ - [self.account myPeerInfo:complete]; -} - -- (void)circleJoiningBlob:(NSData *)applicant complete:(void (^)(NSData *blob, NSError *))complete -{ - [self.account circleJoiningBlob:applicant complete:complete]; -} - -- (void)joinCircleWithBlob:(NSData *)blob version:(PiggyBackProtocolVersion)version complete:(void (^)(bool success, NSError *))complete -{ - [self.account joinCircleWithBlob:blob version:version complete:complete]; -} - -- (void)initialSyncCredentials:(uint32_t)flags complete:(void (^)(NSArray *, NSError *))complete -{ - if (![self checkEntitlement:(__bridge NSString *)kSecEntitlementKeychainInitialSync]) { - complete(@[], [NSError errorWithDomain:(__bridge NSString *)kSOSErrorDomain code:kSOSEntitlementMissing userInfo:NULL]); - return; - } - - [self.account initialSyncCredentials:flags complete:complete]; -} - -- (void)importInitialSyncCredentials:(NSArray *)items complete:(void (^)(bool success, NSError *))complete -{ - if (![self checkEntitlement:(__bridge NSString *)kSecEntitlementKeychainInitialSync]) { - complete(false, [NSError errorWithDomain:(__bridge NSString *)kSOSErrorDomain code:kSOSEntitlementMissing userInfo:NULL]); - return; - } - - [self.account importInitialSyncCredentials:items complete:complete]; -} - -- (void)triggerSync:(NSArray *)peers complete:(void(^)(bool success, NSError *))complete -{ - if (![self checkEntitlement:(__bridge NSString *)kSecEntitlementKeychainCloudCircle]) { - complete(false, [NSError errorWithDomain:(__bridge NSString *)kSOSErrorDomain code:kSOSEntitlementMissing userInfo:NULL]); - return; - } - - [self.account triggerSync:peers complete:complete]; -} - -- (void)getWatchdogParameters:(void (^)(NSDictionary* parameters, NSError* error))complete -{ - [self.account getWatchdogParameters:complete]; -} - -- (void)setWatchdogParmeters:(NSDictionary*)parameters complete:(void (^)(NSError* error))complete -{ - [self.account setWatchdogParmeters:parameters complete:complete]; -} - -@end - - @implementation SOSAccount // Auto synthesis for most fields works great. @@ -275,20 +137,16 @@ const CFStringRef kSOSAccountDebugScope = CFSTR("Scope"); self.previousAccountKey = NULL; self.saveBlock = nil; - - self.listener = [NSXPCListener anonymousListener]; - self.listener.delegate = self; - [self.listener resume]; } return self; } -- (void) finalize { - // All the CF objects stored here need clearing (implicitly releasing them). - self.accountKey = NULL; - self.accountPrivateKey = NULL; - self.previousAccountKey = NULL; - [super finalize]; +- (void)dealloc { + if(self) { + CFReleaseNull(self->_accountKey); + CFReleaseNull(self->_accountPrivateKey); + CFReleaseNull(self->_previousAccountKey); + } } @synthesize accountKey = _accountKey; @@ -327,33 +185,6 @@ const CFStringRef kSOSAccountDebugScope = CFSTR("Scope"); return self.trust.peerID; } - -- (xpc_endpoint_t)xpcControlEndpoint { - return [self.listener.endpoint _endpoint]; -} - -- (BOOL)listener:(__unused NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection -{ - NSNumber *num = [newConnection valueForEntitlement:(__bridge NSString *)kSecEntitlementKeychainCloudCircle]; - if (![num isKindOfClass:[NSNumber class]] || ![num boolValue]) { - secinfo("sos", "Client pid: %d doesn't have entitlement: %@", - [newConnection processIdentifier], kSecEntitlementKeychainCloudCircle); - return NO; - } - - - SOSClient *sosClient = [[SOSClient alloc] initWithConnection:newConnection account:self]; - - newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(SOSControlProtocol)]; - _SOSControlSetupInterface(newConnection.exportedInterface); - newConnection.exportedObject = sosClient; - - [newConnection resume]; - - return YES; -} - - -(bool) ensureFactoryCircles { if (!self){ @@ -370,14 +201,19 @@ const CFStringRef kSOSAccountDebugScope = CFSTR("Scope"); return false; } - SOSAccountEnsureCircle(self, (__bridge CFStringRef) circle_name, NULL); + CFReleaseSafe(SOSAccountEnsureCircle(self, (__bridge CFStringRef) circle_name, NULL)); return SOSAccountInflateTransports(self, (__bridge CFStringRef) circle_name, NULL); } -(void)ensureOctagonPeerKeys { - [self.trust ensureOctagonPeerKeys:self.circle_transport]; +#if OCTAGON + CKKSLockStateTracker *tracker = [CKKSViewManager manager].lockStateTracker; + if (tracker && tracker.isLocked == false) { + [self.trust ensureOctagonPeerKeys:self.circle_transport]; + } +#endif } -(id) initWithGestalt:(CFDictionaryRef)newGestalt factory:(SOSDataSourceFactoryRef)f @@ -424,10 +260,6 @@ const CFStringRef kSOSAccountDebugScope = CFSTR("Scope"); self.previousAccountKey = NULL; self.saveBlock = nil; - - self.listener = [NSXPCListener anonymousListener]; - self.listener.delegate = self; - [self.listener resume]; } return self; } @@ -802,7 +634,6 @@ static bool Flush(CFErrorRef *error) { } } - // // MARK: Save Block // @@ -880,6 +711,7 @@ SOSAccount* SOSAccountCreate(CFAllocatorRef allocator, SOSAccount* a = [[SOSAccount alloc] initWithGestalt:gestalt factory:factory]; [a ensureFactoryCircles]; SOSAccountEnsureUUID(a); + secnotice("circleop", "Setting account.key_interests_need_updating to true in SOSAccountCreate"); a.key_interests_need_updating = true; return a; @@ -1020,7 +852,7 @@ void SOSAccountSetToNew(SOSAccount* a) // By resetting our expansion dictionary we've reset our UUID, so we'll be notified properly SOSAccountEnsureUUID(a); - + secnotice("circleop", "Setting account.key_interests_need_updating to true in SOSAccountSetToNew"); a.key_interests_need_updating = true; } @@ -1044,16 +876,6 @@ bool SOSAccountIsNew(SOSAccount* account, CFErrorRef *error){ return result; } -CFStringRef SOSAccountCreateCompactDescription(SOSAccount* a) { - - CFStringRef gestaltDescription = CFDictionaryCopySuperCompactDescription((__bridge CFDictionaryRef)(a.gestalt)); - - CFStringRef result = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@"), gestaltDescription); - - CFReleaseNull(gestaltDescription); - - return result; -} dispatch_queue_t SOSAccountGetQueue(SOSAccount* account) { return account.queue; } @@ -1064,12 +886,19 @@ void SOSAccountSetUserPublicTrustedForTesting(SOSAccount* account){ -(SOSCCStatus) getCircleStatus:(CFErrorRef*) error { - SOSCCStatus circleStatus = kSOSCCError; - if (SOSAccountHasPublicKey(self, error)) { - circleStatus = [self.trust getCircleStatus:error]; + SOSCCStatus circleStatus = [self.trust getCircleStatus:error]; + if (!SOSAccountHasPublicKey(self, error)) { + if(circleStatus == kSOSCCInCircle) { + if(error) { + CFReleaseNull(*error); + SOSCreateError(kSOSErrorPublicKeyAbsent, CFSTR("Public Key isn't available, this peer is in the circle, but invalid. The iCloud Password must be provided to keychain syncing subsystem to repair this."), NULL, error); + } + } + circleStatus = kSOSCCError; } return circleStatus; } + bool SOSAccountScanForRetired(SOSAccount* account, SOSCircleRef circle, CFErrorRef *error) { SOSAccountTrustClassic *trust = account.trust; @@ -1126,7 +955,7 @@ SOSCircleRef SOSAccountCloneCircleWithRetirement(SOSAccount* account, SOSCircle } } else { // This case is when we aren't an applicant and the circle is retirement-empty. - secnotice("resetToEmpty", "Reset to empty with last retirement"); + secnotice("circleOps", "Reset to empty with last retirement"); SOSCircleResetToEmpty(new_circle, NULL); } } @@ -1366,21 +1195,24 @@ bool SOSAccountEnsureInBackupRings(SOSAccount* account) { return SOSFullPeerInfoUpdateBackupKey(fpi, (__bridge CFDataRef)(account.backup_key), error); }); if (!result) { - secnotice("backupkey", "Failed to setup backup public key: %@", error ? (CFTypeRef) error : (CFTypeRef) CFSTR("No error space provided")); + secnotice("backupkey", "Failed to setup backup public key: %@", error); + CFReleaseNull(error); return result; } } if(!account.backup_key) { if (!result) { - secnotice("backupkey", "Failed to setup backup public key: %@", error ? (CFTypeRef) error : (CFTypeRef) CFSTR("No error space provided")); + secnotice("backupkey", "Failed to setup backup public key: %@", error); } + CFReleaseNull(error); return result; } if(!SOSBSKBIsGoodBackupPublic((__bridge CFDataRef)account.backup_key, &error)){ if (!result) { - secnotice("backupkey", "Failed to setup backup public key: %@", error ? (CFTypeRef) error : (CFTypeRef) CFSTR("No error space provided")); + secnotice("backupkey", "Failed to setup backup public key: %@", error); } + CFReleaseNull(error); return result; } @@ -1406,8 +1238,9 @@ bool SOSAccountEnsureInBackupRings(SOSAccount* account) { } if (!result) { - secnotice("backupkey", "Failed to setup backup public key: %@", error ? (CFTypeRef) error : (CFTypeRef) CFSTR("No error space provided")); + secnotice("backupkey", "Failed to setup backup public key: %@", error); } + CFReleaseNull(error); return result; } @@ -1529,7 +1362,7 @@ done: } bool SOSAccountJoinCircles(SOSAccountTransaction* aTxn, CFErrorRef* error) { - secnotice("circleJoin", "Normal path circle join (SOSAccountJoinCircles)"); + secnotice("circleOps", "Normal path circle join (SOSAccountJoinCircles)"); return SOSAccountJoinCircles_internal(aTxn, false, error); } @@ -1560,7 +1393,7 @@ bool SOSAccountSetMyDSID(SOSAccountTransaction* txn, CFStringRef IDS, CFErrorRef result = [trust modifyCircle:account.circle_transport err:error action:^bool(SOSCircleRef circle) { SOSFullPeerInfoUpdateDeviceID(trust.fullPeerInfo, IDS, error); - SOSFullPeerInfoUpdateTransportType(trust.fullPeerInfo, SOSTransportMessageTypeIDSV2, error); + SOSFullPeerInfoUpdateTransportType(trust.fullPeerInfo, SOSTransportMessageTypeKVS, error); SOSFullPeerInfoUpdateTransportPreference(trust.fullPeerInfo, kCFBooleanFalse, error); SOSFullPeerInfoUpdateTransportFragmentationPreference(trust.fullPeerInfo, kCFBooleanTrue, error); SOSFullPeerInfoUpdateTransportAckModelPreference(trust.fullPeerInfo, kCFBooleanTrue, error); @@ -1665,7 +1498,7 @@ bool SOSAccountRetrieveDeviceIDFromKeychainSyncingOverIDSProxy(SOSAccount* acco } bool SOSAccountJoinCirclesAfterRestore(SOSAccountTransaction* aTxn, CFErrorRef* error) { - secnotice("circleJoin", "Joining after restore (SOSAccountJoinCirclesAfterRestore)"); + secnotice("circleOps", "Joining after restore (SOSAccountJoinCirclesAfterRestore)"); return SOSAccountJoinCircles_internal(aTxn, true, error); } @@ -1675,14 +1508,14 @@ bool SOSAccountRemovePeersFromCircle(SOSAccount* account, CFArrayRef peers, CFE CFMutableSetRef peersToRemove = NULL; SecKeyRef user_key = SOSAccountGetPrivateCredential(account, error); if(!user_key){ - secnotice("removePeers", "Can't remove without userKey"); + secnotice("circleOps", "Can't remove without userKey"); return result; } SOSFullPeerInfoRef me_full = account.fullPeerInfo; SOSPeerInfoRef me = account.peerInfo; if(!(me_full && me)) { - secnotice("removePeers", "Can't remove without being active peer"); + secnotice("circleOps", "Can't remove without being active peer"); SOSErrorCreate(kSOSErrorPeerNotFound, error, NULL, CFSTR("Can't remove without being active peer")); return result; } @@ -1693,7 +1526,7 @@ bool SOSAccountRemovePeersFromCircle(SOSAccount* account, CFArrayRef peers, CFE if(!peersToRemove) { CFReleaseNull(peersToRemove); - secnotice("removePeers", "No peerSet to remove"); + secnotice("circleOps", "No peerSet to remove"); return result; } @@ -1710,7 +1543,7 @@ bool SOSAccountRemovePeersFromCircle(SOSAccount* account, CFArrayRef peers, CFE } else success = true; if (success && leaveCircle) { - secnotice("leaveCircle", "Leaving circle by client request"); + secnotice("circleOps", "Leaving circle by client request (SOSAccountRemovePeersFromCircle)"); success = sosAccountLeaveCircle(account, circle, error); } @@ -1718,6 +1551,12 @@ bool SOSAccountRemovePeersFromCircle(SOSAccount* account, CFArrayRef peers, CFE return success; }]; + + if(result) { + CFStringSetPerformWithDescription(peersToRemove, ^(CFStringRef description) { + secnotice("circleOps", "Removed Peers from circle %@", description); + }); + } CFReleaseNull(peersToRemove); return result; @@ -1733,7 +1572,7 @@ bool SOSAccountBail(SOSAccount* account, uint64_t limit_in_seconds, CFErrorRef* // Add a task to the group dispatch_group_async(group, queue, ^{ [trust modifyCircle:account.circle_transport err:error action:^(SOSCircleRef circle) { - secnotice("leaveCircle", "Leaving circle by client request"); + secnotice("circleOps", "Leaving circle by client request (Bail)"); return sosAccountLeaveCircle(account, circle, error); }]; }); @@ -2024,7 +1863,6 @@ static CFDictionaryRef SOSAccountGetObjectsFromCloud(dispatch_queue_t processQue CloudKeychainReplyBlock replyBlock = ^ (CFDictionaryRef returnedValues, CFErrorRef error) { - secnotice("key-cleanup", "SOSCloudKeychainGetObjectsFromCloud returned: %@", returnedValues); object = returnedValues; if (object) CFRetain(object); @@ -2032,7 +1870,6 @@ static CFDictionaryRef SOSAccountGetObjectsFromCloud(dispatch_queue_t processQue { secerror("SOSCloudKeychainGetObjectsFromCloud returned error: %@", error); } - secnotice("key-cleanup", "SOSCloudKeychainGetObjectsFromCloud block exit: %@", object); dispatch_semaphore_signal(waitSemaphore); }; @@ -2044,8 +1881,7 @@ static CFDictionaryRef SOSAccountGetObjectsFromCloud(dispatch_queue_t processQue CFRelease(object); object = NULL; } - secnotice("key-cleanup", "returned: %@", object); - return asDictionary(object, error); + return asDictionary(object, NULL); // don't propogate "NULL is not a dictionary" errors } @@ -2064,7 +1900,7 @@ static void SOSAccountRemoveKVSKeys(SOSAccount* account, NSArray* keysToRemove, SOSCloudKeychainRemoveKeys((__bridge CFArrayRef)(keysToRemove), uuid, processQueue, replyBlock); dispatch_semaphore_wait(waitSemaphore, finishTime); - + CFReleaseNull(uuid); } static void SOSAccountWriteLastCleanupTimestampToKVS(SOSAccount* account) @@ -2080,6 +1916,7 @@ static void SOSAccountWriteLastCleanupTimestampToKVS(SOSAccount* account) CFStringAppend(timeDescription, CFSTR("]")); [writeTimestamp setObject:(__bridge NSString*)(timeDescription) forKey:(__bridge NSString*)kSOSKVSLastCleanupTimestampKey]; + CFReleaseNull(timeDescription); dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0); dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, maxTimeToWaitInSeconds); @@ -2104,8 +1941,9 @@ bool SOSAccountCleanupAllKVSKeys(SOSAccount* account, CFErrorRef* error) NSDictionary *keysAndValues = (__bridge_transfer NSDictionary*)SOSAccountGetObjectsFromCloud(processQueue, error); NSMutableArray *peerIDs = [NSMutableArray array]; NSMutableArray *keysToRemove = [NSMutableArray array]; - - CFArrayForEach(SOSAccountCopyActiveValidPeers(account, error), ^(const void *value) { + + CFArrayRef peers = SOSAccountCopyActiveValidPeers(account, error); + CFArrayForEach(peers, ^(const void *value) { SOSPeerInfoRef peer = (SOSPeerInfoRef)value; NSString* peerID = (__bridge NSString*) SOSPeerInfoGetPeerID(peer); @@ -2113,6 +1951,7 @@ bool SOSAccountCleanupAllKVSKeys(SOSAccount* account, CFErrorRef* error) if(![[account.trust peerID] isEqualToString:peerID]) [peerIDs addObject:peerID]; }); + CFReleaseNull(peers); [keysAndValues enumerateKeysAndObjectsUsingBlock:^(NSString * KVSKey, NSNumber * KVSValue, BOOL *stop) { __block bool keyMatchesPeerID = false; @@ -2525,7 +2364,7 @@ SOSPiggyCreateInitialSyncData(NSArray* identities, NSArray -#include +#include #include #include @@ -58,7 +58,6 @@ extern const CFStringRef kSOSTestV2Settings; extern const CFStringRef kSOSRateLimitingCounters; extern const CFStringRef kSOSAccountPeerLastSentTimestamp; extern const CFStringRef kSOSAccountRenegotiationRetryCount; -extern const CFStringRef kOTRConfigVersion; extern const CFStringRef kSOSInitialSyncTimeoutV0; #define kSecServerPeerInfoAvailable "com.apple.security.fpiAvailable" @@ -73,7 +72,7 @@ typedef void (^SOSAccountSaveBlock)(CFDataRef flattenedAccount, CFErrorRef flatt @class SOSCircleStorageTransport; @class SOSCKCircleStorage; -@interface SOSAccount : NSObject +@interface SOSAccount : NSObject @property (nonatomic, retain) NSDictionary *gestalt; @property (nonatomic, retain) NSData *backup_key; @@ -124,7 +123,6 @@ typedef void (^SOSAccountSaveBlock)(CFDataRef flattenedAccount, CFErrorRef flatt -(id) init; -(id) initWithGestalt:(CFDictionaryRef)gestalt factory:(SOSDataSourceFactoryRef)factory; -- (xpc_endpoint_t)xpcControlEndpoint; void SOSAccountAddSyncablePeerBlock(SOSAccount* a, CFStringRef ds_name, @@ -207,7 +205,6 @@ bool SOSAccountIsPeerInBackupAndCurrentInView(SOSAccount* account, SOSPeerInfoRe bool SOSDeleteV0Keybag(CFErrorRef *error); void SOSAccountForEachBackupView(SOSAccount* account, void (^operation)(const void *value)); bool SOSAccountUpdatePeerInfo(SOSAccount* account, CFStringRef updateDescription, CFErrorRef *error, bool (^update)(SOSFullPeerInfoRef fpi, CFErrorRef *error)); -CFStringRef SOSAccountCreateCompactDescription(SOSAccount* a); // Currently permitted backup rings. void SOSAccountForEachBackupRingName(SOSAccount* account, void (^operation)(CFStringRef value)); @@ -215,7 +212,7 @@ void SOSAccountForEachRingName(SOSAccount* account, void (^operation)(CFStringRe // My Circle bool SOSAccountHasCircle(SOSAccount* account, CFErrorRef* error); -SOSCircleRef SOSAccountEnsureCircle(SOSAccount* a, CFStringRef name, CFErrorRef *error); +SOSCircleRef CF_RETURNS_RETAINED SOSAccountEnsureCircle(SOSAccount* a, CFStringRef name, CFErrorRef *error); void AppendCircleKeyName(CFMutableArrayRef array, CFStringRef name); @@ -227,7 +224,7 @@ SOSFullPeerInfoRef CopyCloudKeychainIdentity(SOSPeerInfoRef cloudPeer, CFErrorRe bool SOSAccountIsAccountIdentity(SOSAccount* account, SOSPeerInfoRef peer_info, CFErrorRef *error); bool SOSAccountFullPeerInfoVerify(SOSAccount* account, SecKeyRef privKey, CFErrorRef *error); -SOSPeerInfoRef GenerateNewCloudIdentityPeerInfo(CFErrorRef *error); +CF_RETURNS_RETAINED SOSPeerInfoRef GenerateNewCloudIdentityPeerInfo(CFErrorRef *error); // Credentials bool SOSAccountHasPublicKey(SOSAccount* account, CFErrorRef* error); @@ -244,7 +241,7 @@ void SOSAccountAssertDSID(SOSAccount* account, CFStringRef dsid); // SecKeyRef SOSAccountCopyDeviceKey(SOSAccount* account, CFErrorRef *error); -SecKeyRef GeneratePermanentFullECKey(int keySize, CFStringRef name, CFErrorRef* error); +SecKeyRef CF_RETURNS_RETAINED GeneratePermanentFullECKey(int keySize, CFStringRef name, CFErrorRef* error); // Testing void SOSAccountSetLastDepartureReason(SOSAccount* account, enum DepartureReason reason); @@ -312,7 +309,7 @@ bool SOSAccountIsNew(SOSAccount* account, CFErrorRef *error); bool SOSAccountCheckForAlwaysOnViews(SOSAccount* account); // UUID, no setter just getter and ensuring value. void SOSAccountEnsureUUID(SOSAccount* account); -CFStringRef SOSAccountCopyUUID(SOSAccount* account); +CFStringRef CF_RETURNS_RETAINED SOSAccountCopyUUID(SOSAccount* account); const uint8_t* der_decode_cloud_parameters(CFAllocatorRef allocator, CFIndex algorithmID, SecKeyRef* publicKey, CFDataRef *parameters, diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRingUpdate.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRingUpdate.m index b50d0bf8..d7409e06 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRingUpdate.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRingUpdate.m @@ -15,22 +15,6 @@ #include #import -static const char * __unused concordstring[] = { - "kSOSConcordanceTrusted", - "kSOSConcordanceGenOld", // kSOSErrorReplay - "kSOSConcordanceNoUserSig", // kSOSErrorBadSignature - "kSOSConcordanceNoUserKey", // kSOSErrorNoKey - "kSOSConcordanceNoPeer", // kSOSErrorPeerNotFound - "kSOSConcordanceBadUserSig", // kSOSErrorBadSignature - "kSOSConcordanceBadPeerSig", // kSOSErrorBadSignature - "kSOSConcordanceNoPeerSig", - "kSOSConcordanceWeSigned", - "kSOSConcordanceInvalidMembership", - "kSOSConcordanceMissingMe", - "kSOSConcordanceImNotWorthy", -}; - - bool SOSAccountIsPeerRetired(SOSAccount* account, CFSetRef peers){ CFMutableArrayRef peerInfos = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); bool result = false; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRings.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRings.m index 83551638..680c174c 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRings.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRings.m @@ -170,6 +170,7 @@ SOSRingRef SOSAccountCopyRingNamed(SOSAccount* a, CFStringRef ringName, CFErrorR secerror("Non ring in ring table: %@, purging!", found); SOSAccountRemoveRing(a, ringName); } + CFReleaseNull(found); // I'm very skeptical of this function... found = NULL; return found; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountSync.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountSync.m index 993d7db8..461d3b54 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountSync.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountSync.m @@ -20,6 +20,7 @@ #import #include #include +#include #include @@ -355,7 +356,7 @@ CF_RETURNS_RETAINED CFMutableSetRef SOSAccountSyncWithPeers(SOSAccountTransactio peerInfo = SOSCircleCopyPeerWithID(circle, peerID, NULL); if (peerInfo && SOSCircleHasValidSyncingPeer(circle, peerInfo, account.accountKey, NULL)) { - if (canUseIDS && SOSPeerInfoShouldUseIDSTransport(myPeerInfo, peerInfo) && SOSPeerInfoShouldUseACKModel(myPeerInfo, peerInfo)) { + if (ENABLE_IDS && canUseIDS && SOSPeerInfoShouldUseIDSTransport(myPeerInfo, peerInfo) && SOSPeerInfoShouldUseACKModel(myPeerInfo, peerInfo)) { CFSetAddValue(peersForIDS, peerID); } else { CFSetAddValue(peersForKVS, peerID); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTransaction.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTransaction.h index 061c17ea..d31c4212 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTransaction.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTransaction.h @@ -18,7 +18,7 @@ NS_ASSUME_NONNULL_BEGIN @interface SOSAccount (Transaction) -+ (void)performOnAccountQueue:(void (^)(void))action; ++ (void)performOnQuietAccountQueue:(void (^)(void))action; + (void)performWhileHoldingAccountQueue:(void (^)(void))action; - (void) performTransaction: (void (^)(SOSAccountTransaction* txn)) action; @@ -28,10 +28,8 @@ NS_ASSUME_NONNULL_BEGIN @interface SOSAccountTransaction : NSObject -+ (instancetype) transactionWithAccount: (SOSAccount*) account; - - (instancetype) init NS_UNAVAILABLE; -- (instancetype) initWithAccount: (SOSAccount*) account NS_DESIGNATED_INITIALIZER; +- (instancetype) initWithAccount: (SOSAccount*) account quiet:(bool)quiet NS_DESIGNATED_INITIALIZER; - (void) finish; - (void) restart; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTransaction.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTransaction.m index 09e6fbe8..f1003698 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTransaction.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTransaction.m @@ -21,6 +21,7 @@ #import "Security/SecureObjectSync/SOSTransportMessageKVS.h" #include + #define kPublicKeyNotAvailable "com.apple.security.publickeynotavailable" // Account dumping state stuff @@ -38,6 +39,8 @@ @property BOOL initialTrusted; @property NSData* initialKeyParameters; +@property bool quiet; + @property NSMutableSet* peersToRequestSync; - (void) start; @@ -48,18 +51,15 @@ @implementation SOSAccountTransaction -+ (instancetype) transactionWithAccount: (SOSAccount*) account { - return [[SOSAccountTransaction new] initWithAccount: account]; -} - - (NSString*) description { return [NSString stringWithFormat:@"", self, (unsigned long)(self.initialViews ? [self.initialViews count] : 0)]; } -- (instancetype) initWithAccount:(SOSAccount *)account { +- (instancetype) initWithAccount:(SOSAccount *)account quiet:(bool)quiet { if (self = [super init]) { self.account = account; + _quiet = quiet; [self start]; } return self; @@ -83,9 +83,11 @@ } self.peersToRequestSync = nil; - CFStringSetPerformWithDescription((__bridge CFSetRef) self.initialViews, ^(CFStringRef description) { - secnotice("acct-txn", "Starting as:%s v:%@", self.initialInCircle ? "member" : "non-member", description); - }); + if(!self.quiet) { + CFStringSetPerformWithDescription((__bridge CFSetRef) self.initialViews, ^(CFStringRef description) { + secnotice("acct-txn", "Starting as:%s v:%@", self.initialInCircle ? "member" : "non-member", description); + }); + } } - (void) restart { @@ -96,6 +98,9 @@ - (void) finish { static int do_account_state_at_zero = 0; + bool doCircleChanged = false; + bool doViewChanged = false; + CFErrorRef localError = NULL; bool notifyEngines = false; @@ -184,9 +189,11 @@ mpi = self.account.peerInfo; CFSetRef views = mpi ? SOSPeerInfoCopyEnabledViews(mpi) : NULL; - CFStringSetPerformWithDescription(views, ^(CFStringRef description) { - secnotice("acct-txn", "Finished as:%s v:%@", isInCircle ? "member" : "non-member", description); - }); + if(!self.quiet) { + CFStringSetPerformWithDescription(views, ^(CFStringRef description) { + secnotice("acct-txn", "Finished as:%s v:%@", isInCircle ? "member" : "non-member", description); + }); + } // This is the logic to detect a new userKey: bool userKeyChanged = !NSIsEqualSafe(self.initialKeyParameters, self.account.accountKeyDerivationParamters); @@ -198,19 +205,21 @@ self.account.accountKeyIsTrusted); if(self.initialInCircle != isInCircle) { - notify_post(kSOSCCCircleChangedNotification); - notify_post(kSOSCCViewMembershipChangedNotification); + doCircleChanged = true; + doViewChanged = true; do_account_state_at_zero = 0; secnotice("secdNotify", "Notified clients of kSOSCCCircleChangedNotification && kSOSCCViewMembershipChangedNotification for circle/view change"); } else if(isInCircle && !NSIsEqualSafe(self.initialViews, (__bridge NSSet*)views)) { - notify_post(kSOSCCViewMembershipChangedNotification); + doViewChanged = true; do_account_state_at_zero = 0; secnotice("secdNotify", "Notified clients of kSOSCCViewMembershipChangedNotification for viewchange(only)"); } else if(weInitiatedKeyChange) { // We consider this a circleChange so (PCS) can tell the userkey trust changed. - notify_post(kSOSCCCircleChangedNotification); + doCircleChanged = true; do_account_state_at_zero = 0; secnotice("secdNotify", "Notified clients of kSOSCCCircleChangedNotification for userKey change"); } + + // This is the case of we used to trust the key, were in the circle, the key changed, we don't trust it now. bool fellOutOfTrust = (self.initialTrusted && @@ -221,8 +230,20 @@ if(fellOutOfTrust) { secnotice("userKeyTrust", "No longer trust user public key - prompting for password."); notify_post(kPublicKeyNotAvailable); + doCircleChanged = true; do_account_state_at_zero = 0; } + + bool userKeyTrustChangedToTrueAndNowInCircle = (!self.initialTrusted && self.account.accountKeyIsTrusted && isInCircle); + + if(userKeyTrustChangedToTrueAndNowInCircle) { + secnotice("userKeyTrust", "UserKey is once again trusted and we're valid in circle."); + doCircleChanged = true; + doViewChanged = true; + } + + if(doCircleChanged) notify_post(kSOSCCCircleChangedNotification); + if(doViewChanged) notify_post(kSOSCCViewMembershipChangedNotification); if(do_account_state_at_zero <= 0) { SOSAccountLogState(self.account); @@ -269,28 +290,40 @@ __thread bool __hasAccountQueue = false; __hasAccountQueue = hadAccountQueue; } -+ (void)performOnAccountQueue:(void (^)(void))action ++ (void)performOnQuietAccountQueue:(void (^)(void))action { SOSAccount* account = (__bridge SOSAccount*)GetSharedAccountRef(); - [account performTransaction:^(SOSAccountTransaction * _Nonnull txn) { + [account performTransaction:true action:^(SOSAccountTransaction * _Nonnull txn) { action(); }]; } - (void) performTransaction_Locked: (void (^)(SOSAccountTransaction* txn)) action { - SOSAccountTransaction* transaction = [SOSAccountTransaction transactionWithAccount:self]; - action(transaction); - [transaction finish]; + [self performTransaction_Locked:false action:action]; +} + +- (void) performTransaction_Locked:(bool)quiet action:(void (^)(SOSAccountTransaction* txn))action { + @autoreleasepool { + SOSAccountTransaction* transaction = [[SOSAccountTransaction new] initWithAccount:self quiet:quiet]; + action(transaction); + [transaction finish]; + } } - (void) performTransaction: (void (^)(SOSAccountTransaction* txn)) action { + [self performTransaction:false action:action]; +} + +- (void)performTransaction:(bool)quiet action:(void (^)(SOSAccountTransaction* txn))action { + if (__hasAccountQueue) { - [self performTransaction_Locked:action]; + // Be quiet; we're already in a transaction + [self performTransaction_Locked:true action:action]; } else { dispatch_sync(self.queue, ^{ __hasAccountQueue = true; - [self performTransaction_Locked:action]; + [self performTransaction_Locked:quiet action:action]; __hasAccountQueue = false; }); } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrust.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrust.h index fcd013be..4a87ee90 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrust.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrust.h @@ -28,6 +28,9 @@ typedef void (^SOSModifyPeersInCircleBlock)(SOSCircleRef circle, CFMutableArrayR SOSCircleRef trustedCircle; NSMutableSet * retirees; enum DepartureReason departureCode; + + SecKeyRef _cachedOctagonSigningKey; + SecKeyRef _cachedOctagonEncryptionKey; } @property (strong, nonatomic) NSMutableDictionary * expansion; @@ -42,6 +45,9 @@ typedef void (^SOSModifyPeersInCircleBlock)(SOSCircleRef circle, CFMutableArrayR @property (strong, nonatomic) NSMutableSet * retirees; @property (nonatomic) enum DepartureReason departureCode; +@property (assign) SecKeyRef cachedOctagonSigningKey; +@property (assign) SecKeyRef cachedOctagonEncryptionKey; + +(instancetype)trust; -(id)init; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrust.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrust.m index 00ef816f..9fa0ce11 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrust.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrust.m @@ -6,6 +6,8 @@ #import "Security/SecureObjectSync/SOSAccountTrust.h" @implementation SOSAccountTrust +@synthesize cachedOctagonEncryptionKey = _cachedOctagonEncryptionKey; +@synthesize cachedOctagonSigningKey = _cachedOctagonSigningKey; +(instancetype)trust { @@ -41,6 +43,15 @@ } return self; } +- (void)dealloc { + if(self) { + CFReleaseNull(self->fullPeerInfo); + CFReleaseNull(self->peerInfo); + CFReleaseNull(self->trustedCircle); + CFReleaseNull(self->_cachedOctagonSigningKey); + CFReleaseNull(self->_cachedOctagonEncryptionKey); + } +} - (SOSPeerInfoRef) peerInfo { return SOSFullPeerInfoGetPeerInfo(self.fullPeerInfo); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Circle.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Circle.m index e699457e..662d5dd2 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Circle.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Circle.m @@ -16,18 +16,6 @@ #import "Security/SecureObjectSync/SOSAccountGhost.h" #import "Security/SecureObjectSync/SOSViews.h" -static const char *concordstring[] = { - "kSOSConcordanceTrusted", - "kSOSConcordanceGenOld", // kSOSErrorReplay - "kSOSConcordanceNoUserSig", // kSOSErrorBadSignature - "kSOSConcordanceNoUserKey", // kSOSErrorNoKey - "kSOSConcordanceNoPeer", // kSOSErrorPeerNotFound - "kSOSConcordanceBadUserSig", // kSOSErrorBadSignature - "kSOSConcordanceBadPeerSig", // kSOSErrorBadSignature - "kSOSConcordanceNoPeerSig", - "kSOSConcordanceWeSigned", -}; - @implementation SOSAccountTrustClassic (Circle) -(bool) isInCircle:(CFErrorRef *)error @@ -96,7 +84,10 @@ fail: { CFErrorRef localError = NULL; if (self.trustedCircle == NULL) { - self.trustedCircle = SOSCircleCreate(NULL, name, NULL); + SOSCircleRef newCircle = SOSCircleCreate(NULL, name, NULL); + self.trustedCircle = newCircle; // Note that this setter adds a retain + CFReleaseNull(newCircle); + secnotice("circleop", "Setting key_interests_need_updating to true in ensureCircle"); a.key_interests_need_updating = true; } @@ -161,8 +152,10 @@ fail: if(!myPubKey) return false; if(SOSCircleVerify(prospective_circle, myPubKey, NULL) && SOSCircleIsOlderGeneration(self.trustedCircle, prospective_circle)) { [self setTrustedCircle:prospective_circle]; + CFReleaseNull(myPubKey); return true; } + CFReleaseNull(myPubKey); return false; } @@ -188,10 +181,24 @@ static bool SOSCirclePeerOctagonKeysChanged(SOSPeerInfoRef oldPeer, SOSPeerInfoR if(!oldHasOctagonBits && !newHasOctagonBits) { // both peers have no keys: no change return false; + } + SecKeyRef oldSigningKey = SOSPeerInfoCopyOctagonSigningPublicKey(oldPeer, NULL); + SecKeyRef newSigningKey = SOSPeerInfoCopyOctagonSigningPublicKey(newPeer, NULL); + + bool signingKeyChanged = CFEqualSafe(oldSigningKey, newSigningKey); + + CFReleaseNull(oldSigningKey); + CFReleaseNull(newSigningKey); + - bool signingKeyChanged = CFEqualSafe(SOSPeerInfoCopyOctagonSigningPublicKey(oldPeer, NULL), SOSPeerInfoCopyOctagonSigningPublicKey(newPeer, NULL)); - bool encryptionKeyChanged = CFEqualSafe(SOSPeerInfoCopyOctagonEncryptionPublicKey(oldPeer, NULL), SOSPeerInfoCopyOctagonEncryptionPublicKey(newPeer, NULL)); + SecKeyRef oldEncryptionKey = SOSPeerInfoCopyOctagonEncryptionPublicKey(oldPeer, NULL); + SecKeyRef newEncryptionKey = SOSPeerInfoCopyOctagonEncryptionPublicKey(newPeer, NULL); + + bool encryptionKeyChanged = CFEqualSafe(oldEncryptionKey, newEncryptionKey); + + CFReleaseNull(oldEncryptionKey); + CFReleaseNull(newEncryptionKey); return signingKeyChanged || encryptionKeyChanged; } @@ -203,11 +210,13 @@ static bool SOSCircleHasUpdatedPeerInfoWithOctagonKey(SOSCircleRef oldCircle, SO SOSCircleForEachPeer(oldCircle, ^(SOSPeerInfoRef oldPeer) { SOSPeerInfoRef equivalentNewPeer = SOSCircleCopyPeerWithID(newCircle, SOSPeerInfoGetPeerID(oldPeer), NULL); hasUpdated |= SOSCirclePeerOctagonKeysChanged(oldPeer, equivalentNewPeer); + CFReleaseNull(equivalentNewPeer); }); SOSCircleForEachPeer(newCircle, ^(SOSPeerInfoRef newPeer) { SOSPeerInfoRef equivalentOldPeer = SOSCircleCopyPeerWithID(oldCircle, SOSPeerInfoGetPeerID(newPeer), NULL); hasUpdated |= SOSCirclePeerOctagonKeysChanged(equivalentOldPeer, newPeer); + CFReleaseNull(equivalentOldPeer); }); return hasUpdated; @@ -236,6 +245,7 @@ static bool SOSCircleHasUpdatedPeerInfoWithOctagonKey(SOSCircleRef oldCircle, SO // sponsored the only signer. if(!writeUpdate && [ self checkForSponsorshipTrust: prospective_circle ]){ SOSCCEnsurePeerRegistration(); + secnotice("circleop", "Setting key_interests_need_updating to true in handleUpdateCircle"); account.key_interests_need_updating = true; return true; @@ -352,7 +362,7 @@ static bool SOSCircleHasUpdatedPeerInfoWithOctagonKey(SOSCircleRef oldCircle, SO break; } - secnotice("signing", "Decided on action [%s] based on concordance state [%s] and [%s] circle. My PeerID is %@", actionstring[circle_action], concordstring[concstat], userTrustedOldCircle ? "trusted" : "untrusted", myPeerID); + secnotice("signing", "Decided on action [%s] based on concordance state [%@] and [%s] circle. My PeerID is %@", actionstring[circle_action], concStr, userTrustedOldCircle ? "trusted" : "untrusted", myPeerID); SOSCircleRef circleToPush = NULL; @@ -368,7 +378,7 @@ static bool SOSCircleHasUpdatedPeerInfoWithOctagonKey(SOSCircleRef oldCircle, SO account.accountKey, account.previousAccountKey, old_circle_key); if (sosAccountLeaveCircle(account, newCircle, error)) { - secnotice("leaveCircle", "Leaving circle by newcircle state"); + secnotice("circleOps", "Leaving circle by newcircle state"); circleToPush = newCircle; } else { secnotice("signing", "Can't leave circle, but dumping identities"); @@ -418,7 +428,7 @@ static bool SOSCircleHasUpdatedPeerInfoWithOctagonKey(SOSCircleRef oldCircle, SO if (me && SOSCircleHasActivePeer(oldCircle, me, NULL) && !SOSCircleHasPeer(newCircle, me, NULL)) { // Don't destroy evidence of other code determining reason for leaving. if(![self hasLeft]) self.departureCode = kSOSMembershipRevoked; - secnotice("account", "Member of old circle but not of new circle"); + secnotice("circleOps", "Member of old circle but not of new circle (%d)", self.departureCode); debugDumpCircle(CFSTR("oldCircle"), oldCircle); debugDumpCircle(CFSTR("newCircle"), newCircle); } @@ -451,6 +461,7 @@ static bool SOSCircleHasUpdatedPeerInfoWithOctagonKey(SOSCircleRef oldCircle, SO SOSCircleRequestReadmission(newCircle, account.accountKey, me, NULL); writeUpdate = true; } + CFReleaseNull(reject); } CFRetainSafe(oldCircle); @@ -484,6 +495,7 @@ static bool SOSCircleHasUpdatedPeerInfoWithOctagonKey(SOSCircleRef oldCircle, SO if (writeUpdate) circleToPush = newCircle; + secnotice("circleop", "Setting key_interests_need_updating to true in handleUpdateCircle"); account.key_interests_need_updating = true; } @@ -517,7 +529,7 @@ static bool SOSCircleHasUpdatedPeerInfoWithOctagonKey(SOSCircleRef oldCircle, SO //posting new circle to peers success &= [circleTransport postCircle:SOSCircleGetName(circleToPush) circleData:circle_data err:error]; //cleanup old KVS keys - SOSAccountCleanupAllKVSKeys(account, error); + (void) SOSAccountCleanupAllKVSKeys(account, NULL); } else { success = false; } @@ -526,6 +538,11 @@ static bool SOSCircleHasUpdatedPeerInfoWithOctagonKey(SOSCircleRef oldCircle, SO CFReleaseSafe(newCircle); CFReleaseNull(emptyCircle); + // There are errors collected above that are soft (worked around) + if(success && error && *error) { + CFReleaseNull(*error); + } + return success; } @@ -601,7 +618,7 @@ fail: -(bool) leaveCircle:(SOSAccount*)account err:(CFErrorRef*) error { bool result = true; - secnotice("leaveCircle", "Leaving circle by client request"); + secnotice("circleOps", "Leaving circle by client request"); result &= [self modifyCircle:account.circle_transport err:error action:^(SOSCircleRef circle) { return sosAccountLeaveCircle(account, circle, error); }]; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Expansion.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Expansion.m index 08ce8cc4..f59341ab 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Expansion.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Expansion.m @@ -25,18 +25,6 @@ typedef enum { } ringAction_t; #if !defined(NDEBUG) -static const char *concordstring[] = { - "kSOSConcordanceTrusted", - "kSOSConcordanceGenOld", // kSOSErrorReplay - "kSOSConcordanceNoUserSig", // kSOSErrorBadSignature - "kSOSConcordanceNoUserKey", // kSOSErrorNoKey - "kSOSConcordanceNoPeer", // kSOSErrorPeerNotFound - "kSOSConcordanceBadUserSig", // kSOSErrorBadSignature - "kSOSConcordanceBadPeerSig", // kSOSErrorBadSignature - "kSOSConcordanceNoPeerSig", - "kSOSConcordanceWeSigned", -}; - static const char * __unused actionstring[] = { "accept", "countersign", "leave", "revert", "modify", "ignore", }; @@ -222,7 +210,7 @@ errOut: self.fullPeerInfo = nil; self.departureCode = kSOSWithdrewMembership; - secnotice("resetToEmpty", "Reset Circle to empty by client request"); + secnotice("circleOps", "Reset Circle to empty by client request"); result &= [self modifyCircle:circleTransport err:error action:^bool(SOSCircleRef circle) { result = SOSCircleResetToEmpty(circle, error); @@ -401,7 +389,8 @@ static bool SOSAccountBackupSliceKeyBagNeedsFix(SOSAccount* account, SOSBackupSl (void)concStr; - secdebug("ringSigning", "Decided on action [%s] based on concordance state [%s] and [%s] circle.", actionstring[ringAction], concordstring[concstat], userTrustedoldRing ? "trusted" : "untrusted"); + secdebug("ringSigning", "Decided on action [%s] based on concordance state [%@] and [%s] circle.", + actionstring[ringAction], concStr, userTrustedoldRing ? "trusted" : "untrusted"); SOSRingRef ringToPush = NULL; bool iWasInOldRing = peerID && SOSRingHasPeerID(oldRing, peerID); @@ -519,6 +508,7 @@ static bool SOSAccountBackupSliceKeyBagNeedsFix(SOSAccount* account, SOSBackupSl if (writeUpdate) ringToPush = newRing; + secnotice("circleop", "Setting account.key_interests_need_updating to true in handleUpdateRing"); account.key_interests_need_updating = true; } @@ -594,6 +584,7 @@ errOut: CFReleaseNull(ring); retval = SOSAccountUpdateRing(account, newring, error); errOut: + CFReleaseNull(ring); CFReleaseNull(newring); return retval; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Identity.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Identity.h index 9f06f2a2..e7e78c2f 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Identity.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Identity.h @@ -16,7 +16,7 @@ -(SOSFullPeerInfoRef) getMyFullPeerInfo; -(bool) fullPeerInfoVerify:(SecKeyRef) privKey err:(CFErrorRef *)error; -(bool) hasFullPeerInfo:(CFErrorRef*) error; --(SOSFullPeerInfoRef) CopyAccountIdentityPeerInfo; +-(SOSFullPeerInfoRef) CopyAccountIdentityPeerInfo CF_RETURNS_RETAINED; -(bool) ensureFullPeerAvailable:(CFDictionaryRef)gestalt deviceID:(CFStringRef)deviceID backupKey:(CFDataRef)backup err:(CFErrorRef *) error; -(bool) isMyPeerActive:(CFErrorRef*) error; -(void) purgeIdentity; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Identity.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Identity.m index 6c8a90fe..1d22def5 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Identity.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Identity.m @@ -1,4 +1,4 @@ - // +// // SOSAccountTrustClassicIdentity.m // Security // @@ -10,11 +10,20 @@ #import "Security/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" #import "Security/SecureObjectSync/SOSAccountTrustClassic+Identity.h" #import "Security/SecureObjectSync/SOSAccountTrustClassic+Circle.h" +#if __OBJC2__ +#import "Analytics/Clients/SOSAnalytics.h" +#endif // __OBJC2__ #import "Security/SecureObjectSync/SOSViews.h" @implementation SOSAccountTrustClassic (Identity) +-(bool)isLockedError:(NSError *)error { + return error && + ([error.domain isEqualToString:(__bridge NSString*)kSecErrorDomain]) + && error.code == errSecInteractionNotAllowed; +} + -(bool) updateFullPeerInfo:(SOSAccount*)account minimum:(CFSetRef)minimumViews excluded:(CFSetRef)excludedViews { if (self.trustedCircle && self.fullPeerInfo) { @@ -62,80 +71,150 @@ return SOSFullPeerInfoCopyFullPeerInfo(self.fullPeerInfo); } -- (SecKeyRef)randomPermanentFullECKey:(int)keysize name:(NSString *)name error:(CFErrorRef*)cferror +- (SecKeyRef)randomPermanentFullECKey:(int)keysize name:(NSString *)name error:(CFErrorRef*)cferror CF_RETURNS_RETAINED { return GeneratePermanentFullECKey(keysize, (__bridge CFStringRef)name, cferror); } +// Check that cached values of what is in keychain with what we have in the peer info, +// if they ware the same, we could read the items while this process was alive, assume +// all is swell. +#if OCTAGON +- (bool)haveConfirmedOctagonKeys +{ + bool haveSigningKey = false; + bool haveEncryptionKey = false; + + SecKeyRef signingKey = SOSFullPeerInfoCopyOctagonPublicSigningKey(self.fullPeerInfo, NULL); + if (self.cachedOctagonSigningKey && CFEqualSafe(signingKey, self.cachedOctagonSigningKey)) { + haveSigningKey = true; + } else { + secerror("circleChange: No extant octagon signing key"); + } + + SecKeyRef encrytionKey = SOSFullPeerInfoCopyOctagonPublicEncryptionKey(self.fullPeerInfo, NULL); + if (self.cachedOctagonEncryptionKey && CFEqualSafe(encrytionKey, self.cachedOctagonEncryptionKey)) { + haveEncryptionKey = true; + } else { + secerror("circleChange: No extant octagon encryption key"); + } + + CFReleaseNull(signingKey); + CFReleaseNull(encrytionKey); + + return haveSigningKey && haveEncryptionKey; +} +#endif + - (void)ensureOctagonPeerKeys:(SOSKVSCircleStorageTransport*)circleTransport { +#if OCTAGON NSString* octagonKeyName; - SecKeyRef publicKey; + SecKeyRef octagonSigningFullKey = NULL; + SecKeyRef octagonEncryptionFullKey = NULL; - if (SOSFullPeerInfoHaveOctagonKeys(self.fullPeerInfo)) { + // check if we already confirmed the keys + if ([self haveConfirmedOctagonKeys]) { return; } bool changedSelf = false; CFErrorRef copyError = NULL; - publicKey = SOSFullPeerInfoCopyOctagonSigningKey(self.fullPeerInfo, ©Error); - if(copyError) { + octagonSigningFullKey = SOSFullPeerInfoCopyOctagonSigningKey(self.fullPeerInfo, ©Error); + if(copyError && ![self isLockedError:(__bridge NSError *)copyError]) { secerror("circleChange: Error fetching Octagon signing key: %@", copyError); - CFReleaseNull(copyError); } - if (publicKey == NULL) { + // Cache that public key we found, to so that we don't need to make the roundtrip though + // keychain to get them item, if we don't find a key, try to create a new key if the error + // is specifically "couldn't find key", "couldn't read key", or "something went very very wrong". + // Otherwise, log a fatal error. + + if (octagonSigningFullKey) { + secnotice("circleChange", "Already have Octagon signing key"); + CFReleaseNull(self->_cachedOctagonSigningKey); + _cachedOctagonSigningKey = SecKeyCopyPublicKey(octagonSigningFullKey); + } else if (octagonSigningFullKey == NULL && copyError && + ((CFEqualSafe(CFErrorGetDomain(copyError), kCFErrorDomainOSStatus) && CFErrorGetCode(copyError) == errSecItemNotFound) || + (CFEqualSafe(CFErrorGetDomain(copyError), kCFErrorDomainOSStatus) && CFErrorGetCode(copyError) == errSecDecode) || + (CFEqualSafe(CFErrorGetDomain(copyError), kCFErrorDomainOSStatus) && CFErrorGetCode(copyError) == errSecParam))) + { octagonKeyName = [NSString stringWithFormat:@"Octagon Peer Signing ID for %@", SOSCircleGetName(self.trustedCircle)]; CFErrorRef cferror = NULL; - SecKeyRef octagonSigningFullKey = [self randomPermanentFullECKey:384 name:octagonKeyName error:&cferror]; + octagonSigningFullKey = [self randomPermanentFullECKey:384 name:octagonKeyName error:&cferror]; if(cferror || !octagonSigningFullKey) { - secerror("circleChange: Error upgrading Octagon signing key: %@", cferror); + secerror("circleChange: Error creating Octagon signing key: %@", cferror); } else { SOSFullPeerInfoUpdateOctagonSigningKey(self.fullPeerInfo, octagonSigningFullKey, &cferror); if(cferror) { secerror("circleChange: Error upgrading Octagon signing key: %@", cferror); + } else { + secnotice("circleChange", "Successfully created new Octagon signing key"); } changedSelf = true; } CFReleaseNull(cferror); - CFReleaseNull(octagonSigningFullKey); + } else if((octagonSigningFullKey == NULL || copyError) && ![self isLockedError:(__bridge NSError *)copyError]) { + secerror("error is too scary, not creating new Octagon signing key: %@", copyError); +#if __OBJC2__ + [[SOSAnalytics logger] logResultForEvent:@"SOSCheckOctagonSigningKey" hardFailure:true result:(__bridge NSError*)copyError]; +#endif // __OBJC2__ } - CFReleaseNull(publicKey); CFReleaseNull(copyError); - publicKey = SOSFullPeerInfoCopyOctagonEncryptionKey(self.fullPeerInfo, ©Error); - if(copyError) { + CFReleaseNull(octagonSigningFullKey); + + // Now do the same thing for encryption key + + CFReleaseNull(copyError); + octagonEncryptionFullKey = SOSFullPeerInfoCopyOctagonEncryptionKey(self.fullPeerInfo, ©Error); + if(copyError && ![self isLockedError:(__bridge NSError *)copyError]) { secerror("circleChange: Error fetching Octagon encryption key: %@", copyError); - CFReleaseNull(copyError); } - if (publicKey == NULL) { + if (octagonEncryptionFullKey) { + secnotice("circleChange", "Already have Octagon encryption key"); + CFReleaseNull(self->_cachedOctagonEncryptionKey); + _cachedOctagonEncryptionKey = SecKeyCopyPublicKey(octagonEncryptionFullKey); + } else if (octagonEncryptionFullKey == NULL && copyError && + ((CFEqualSafe(CFErrorGetDomain(copyError), kCFErrorDomainOSStatus) && CFErrorGetCode(copyError) == errSecItemNotFound) || + (CFEqualSafe(CFErrorGetDomain(copyError), kCFErrorDomainOSStatus) && CFErrorGetCode(copyError) == errSecDecode) || + (CFEqualSafe(CFErrorGetDomain(copyError), kCFErrorDomainOSStatus) && CFErrorGetCode(copyError) == errSecParam))) + { octagonKeyName = [NSString stringWithFormat:@"Octagon Peer Encryption ID for %@", SOSCircleGetName(self.trustedCircle)]; CFErrorRef cferror = NULL; - SecKeyRef octagonEncryptionFullKey = [self randomPermanentFullECKey:384 name:octagonKeyName error:&cferror]; + octagonEncryptionFullKey = [self randomPermanentFullECKey:384 name:octagonKeyName error:&cferror]; if(cferror || !octagonEncryptionFullKey) { - secerror("circleChange: Error upgrading Octagon encryption key: %@", cferror); + secerror("circleChange: Error creating Octagon encryption key: %@", cferror); } else { - SOSFullPeerInfoUpdateOctagonEncryptionKey(self.fullPeerInfo, octagonEncryptionFullKey, &cferror); if(cferror) { secerror("circleChange: Error upgrading Octagon encryption key: %@", cferror); + } else { + secnotice("circleChange", "Successfully created new Octagon encryption key"); } changedSelf = true; } CFReleaseNull(cferror); - CFReleaseNull(octagonEncryptionFullKey); + + } else if((octagonEncryptionFullKey == NULL || copyError) && ![self isLockedError:(__bridge NSError *)copyError]) { + secerror("error is too scary, not creating new Octagon encryption key: %@", copyError); +#if __OBJC2__ + [[SOSAnalytics logger] logResultForEvent:@"SOSCheckOctagonEncryptionKey" hardFailure:true result:(__bridge NSError*)copyError]; +#endif } - CFReleaseNull(publicKey); + CFReleaseNull(copyError); + CFReleaseNull(octagonEncryptionFullKey); if(changedSelf) { [self modifyCircle:circleTransport err:NULL action:^bool (SOSCircleRef circle_to_change) { return SOSCircleUpdatePeerInfo(circle_to_change, SOSFullPeerInfoGetPeerInfo(self.fullPeerInfo)); }]; } +#endif /* OCTAGON */ } -(bool) ensureFullPeerAvailable:(CFDictionaryRef)gestalt deviceID:(CFStringRef)deviceID backupKey:(CFDataRef)backup err:(CFErrorRef *) error @@ -157,12 +236,15 @@ CFSetRef initialViews = SOSViewCopyViewSet(kViewSetInitial); self.fullPeerInfo = nil; - self.fullPeerInfo = SOSFullPeerInfoCreateWithViews(kCFAllocatorDefault, gestalt, backup, initialViews, full_key, octagonSigningFullKey, octagonEncryptionFullKey, error); + + // setting fullPeerInfo takes an extra ref, so... + SOSFullPeerInfoRef fpi = SOSFullPeerInfoCreateWithViews(kCFAllocatorDefault, gestalt, backup, initialViews, full_key, octagonSigningFullKey, octagonEncryptionFullKey, error); + self.fullPeerInfo = fpi; + CFReleaseNull(fpi); CFDictionaryRef v2dictionaryTestUpdates = [self getValueFromExpansion:kSOSTestV2Settings err:NULL]; if(v2dictionaryTestUpdates) SOSFullPeerInfoUpdateV2Dictionary(self.fullPeerInfo, v2dictionaryTestUpdates, NULL); CFReleaseNull(initialViews); - CFReleaseNull(full_key); CFSetRef pendingDefaultViews = SOSViewCopyViewSet(kViewSetDefault); [self pendEnableViewSet:pendingDefaultViews]; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.h index 28c0cfb7..6b6895bd 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.h @@ -39,7 +39,6 @@ -(SOSViewResultCode) viewStatus:(SOSAccount*)account name:(CFStringRef) viewname err:(CFErrorRef *)error; -(bool) updateViewSets:(SOSAccount*)account enabled:(CFSetRef) origEnabledViews disabled:(CFSetRef) origDisabledViews; -(CFSetRef) copyPeerSetForView:(CFStringRef) viewName; --(void) peerGotInSync:(SOSAccountTransaction*) aTxn peerID:(CFStringRef) peerID views:(CFSetRef) views; //DER -(size_t) getDEREncodedSize:(SOSAccount*)account err:(NSError**)error; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.m index 7c401525..0fa63766 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.m @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -465,13 +466,6 @@ fail: } //Views --(void) peerGotInSync:(SOSAccountTransaction*) aTxn peerID:(CFStringRef) peerID views:(CFSetRef) views -{ - secnotice("initial-sync", "Peer %@ synced views: %@", peerID, views); - if (self.trustedCircle && [self isInCircle:NULL] && SOSCircleHasActivePeerWithID(self.trustedCircle, peerID, NULL)) { - SOSAccountUpdateOutOfSyncViews(aTxn, views); - } -} -(void) removeInvalidApplications:(SOSCircleRef) circle userPublic:(SecKeyRef)userPublic { CFMutableSetRef peersToRemove = CFSetCreateMutableForSOSPeerInfosByID(kCFAllocatorDefault); @@ -495,6 +489,7 @@ fail: require_quiet(SOSFullPeerInfoUpgradeSignatures(cloud_fpi, privKey, NULL), errOut); retval = SOSCircleUpdatePeerInfo(circle, SOSFullPeerInfoGetPeerInfo(cloud_fpi)); errOut: + CFReleaseNull(cloud_fpi); return retval; } const CFStringRef kSOSHsaPreApprovedPeerKeyInfo = CFSTR("HSAPreApprovedPeer"); @@ -523,12 +518,15 @@ const CFStringRef kSOSHsaPreApprovedPeerKeyInfo = CFSTR("HSAPreApprovedPeer"); CFReleaseNull(cloud_peer); if(!cloud_identity) return result; - if(!SOSCircleRequestAdmission(circle, userKey, cloud_identity, error)) + if(!SOSCircleRequestAdmission(circle, userKey, cloud_identity, error)) { + CFReleaseNull(cloud_identity); return result; + } require_quiet(SOSCircleAcceptRequest(circle, userKey, self.fullPeerInfo, SOSFullPeerInfoGetPeerInfo(cloud_identity), error), err_out); result = true; err_out: + CFReleaseNull(cloud_identity); return result; } -(bool) addEscrowToPeerInfo:(SOSFullPeerInfoRef) myPeer err:(CFErrorRef *)error @@ -643,8 +641,10 @@ static uint8_t* der_encode_data_optional(CFDataRef data, CFErrorRef *error, SOSAccount* account = txn.account; // Kick getting our device ID if we don't have it, and find out if we're setup to use IDS. + [account.ids_message_transport SOSTransportMessageIDSGetIDSDeviceID:account]; + bool canUseIDS = [account.ids_message_transport SOSTransportMessageIDSGetIDSDeviceID:account]; - + if(![self isInCircle:error]) { handledPeerIDs = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, peerIDs); @@ -680,7 +680,7 @@ static uint8_t* der_encode_data_optional(CFDataRef data, CFErrorRef *error, peerInfo = SOSCircleCopyPeerWithID(self.trustedCircle, peerID, NULL); if (peerInfo && SOSCircleHasValidSyncingPeer(self.trustedCircle, peerInfo, account.accountKey, NULL)) { - if (canUseIDS && SOSPeerInfoShouldUseIDSTransport(myPeerInfo, peerInfo)) { + if (ENABLE_IDS && canUseIDS && SOSPeerInfoShouldUseIDSTransport(myPeerInfo, peerInfo)) { CFSetAddValue(peersForIDS, peerID); } else { CFSetAddValue(peersForKVS, peerID); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountUpdate.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountUpdate.m index 9978c662..d5ac122f 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountUpdate.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountUpdate.m @@ -275,7 +275,7 @@ CFDictionaryRef SOSAccountHandleRetirementMessages(SOSAccount* account, CFDictio if(!trust.trustedCircle) // We don't fail, we intentionally handle nothing. return CFDictionaryCreateForCFTypes(kCFAllocatorDefault, NULL); - CFDictionaryRef retirement_dictionary = asDictionary(CFDictionaryGetValue(circle_retirement_messages, circle_name), error); + CFDictionaryRef retirement_dictionary = asDictionary(CFDictionaryGetValue(circle_retirement_messages, circle_name), NULL); if(!retirement_dictionary) return CFDictionaryCreateForCFTypes(kCFAllocatorDefault, NULL); @@ -312,7 +312,7 @@ CFDictionaryRef SOSAccountHandleRetirementMessages(SOSAccount* account, CFDictio static SOSCircleRef SOSAccountCreateCircleFrom(CFStringRef circleName, CFTypeRef value, CFErrorRef *error) { if (value && !isData(value) && !isNull(value)) { - secnotice("circleCreat", "Value provided not appropriate for a circle"); + secnotice("circleOps", "Value provided not appropriate for a circle"); CFStringRef description = CFCopyTypeIDDescription(CFGetTypeID(value)); SOSCreateErrorWithFormat(kSOSErrorUnexpectedType, NULL, error, NULL, CFSTR("Expected data or NULL got %@"), description); @@ -322,20 +322,20 @@ static SOSCircleRef SOSAccountCreateCircleFrom(CFStringRef circleName, CFTypeRef SOSCircleRef circle = NULL; if (!value || isNull(value)) { - secnotice("circleCreat", "No circle found in data: %@", value); + secnotice("circleOps", "No circle found in data: %@", value); circle = NULL; } else { circle = SOSCircleCreateFromData(NULL, (CFDataRef) value, error); if (circle) { CFStringRef name = SOSCircleGetName(circle); if (!CFEqualSafe(name, circleName)) { - secnotice("circleCreat", "Expected circle named %@, got %@", circleName, name); + secnotice("circleOps", "Expected circle named %@, got %@", circleName, name); SOSCreateErrorWithFormat(kSOSErrorNameMismatch, NULL, error, NULL, CFSTR("Expected circle named %@, got %@"), circleName, name); CFReleaseNull(circle); } } else { - secnotice("circleCreat", "SOSCircleCreateFromData returned NULL."); + secnotice("circleOps", "SOSCircleCreateFromData returned NULL."); } } return circle; @@ -379,27 +379,27 @@ bool SOSAccountHandleParametersChange(SOSAccount* account, CFDataRef parameters, if(SOSAccountRetrieveCloudParameters(account, &newKey, parameters, &newParameters, error)) { debugDumpUserParameters(CFSTR("SOSAccountHandleParametersChange got new user key parameters:"), parameters); - secnotice("keygen", "SOSAccountHandleParametersChange got new public key: %@", newKey); + secnotice("circleOps", "SOSAccountHandleParametersChange got new public key: %@", newKey); if (CFEqualSafe(account.accountKey, newKey)) { - secnotice("updates", "Got same public key sent our way. Ignoring."); + secnotice("circleOps", "Got same public key sent our way. Ignoring."); success = true; } else if (CFEqualSafe(account.previousAccountKey, newKey)) { - secnotice("updates", "Got previous public key repeated. Ignoring."); + secnotice("circleOps", "Got previous public key repeated. Ignoring."); success = true; } else { SOSAccountSetUnTrustedUserPublicKey(account, newKey); + CFReleaseNull(newKey); SOSAccountSetParameters(account, newParameters); - newKey = NULL; if(SOSAccountRetryUserCredentials(account)) { - secnotice("keygen", "Successfully used cached password with new parameters"); + secnotice("circleOps", "Successfully used cached password with new parameters"); SOSAccountGenerationSignatureUpdate(account, error); } else { - secnotice("keygen", "Got new parameters for public key - could not find or use cached password"); + secnotice("circleOps", "Got new parameters for public key - could not find or use cached password"); SOSAccountPurgePrivateCredential(account); } - + secnotice("circleop", "Setting account.key_interests_need_updating to true in SOSAccountHandleParametersChange"); account.circle_rings_retirements_need_attention = true; account.key_interests_need_updating = true; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupSliceKeyBag.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupSliceKeyBag.h index 0376e096..1b9a40c5 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupSliceKeyBag.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupSliceKeyBag.h @@ -39,8 +39,6 @@ typedef int32_t bskb_keybag_handle_t; typedef struct CF_BRIDGED_TYPE(id) __OpaqueSOSBackupSliceKeyBag *SOSBackupSliceKeyBagRef; -CFTypeRef SOSBackupSliceKeyBageGetTypeID(void); - SOSBackupSliceKeyBagRef SOSBackupSliceKeyBagCreate(CFAllocatorRef allocator, CFSetRef peers, CFErrorRef* error); SOSBackupSliceKeyBagRef SOSBackupSliceKeyBagCreateDirect(CFAllocatorRef allocator, CFDataRef aks_bag, CFErrorRef *error); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.c b/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.c index 98b3db56..8df24f6d 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.c +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.c @@ -449,8 +449,9 @@ errOut: static bool SOSCircleGenerationSign_Internal(SOSCircleRef circle, SecKeyRef userKey, SOSFullPeerInfoRef fpi, CFErrorRef *error) { // require_quiet(SOSCircleEnsureRingConsistency(circle, error), fail); Placeholder - this was never implemented bool retval = false; + SecKeyRef ourKey = NULL; if (SOSCircleCountPeers(circle) != 0) { - SecKeyRef ourKey = SOSFullPeerInfoCopyDeviceKey(fpi, error); + ourKey = SOSFullPeerInfoCopyDeviceKey(fpi, error); require_quiet(ourKey, errOut); // Check if we're using an invalid peerinfo for this op. There are cases where we might not be "upgraded". @@ -463,6 +464,7 @@ static bool SOSCircleGenerationSign_Internal(SOSCircleRef circle, SecKeyRef user retval = true; errOut: + CFReleaseNull(ourKey); return retval; } @@ -1260,7 +1262,7 @@ void SOSCircleForEachiCloudIdentityPeer(SOSCircleRef circle, void (^action)(SOSP SOSCircleForEachPeerMatching(circle, action, ^bool(SOSPeerInfoRef peer) { return SOSPeerInfoIsCloudIdentity(peer); }); -} +} void SOSCircleForEachActivePeer(SOSCircleRef circle, void (^action)(SOSPeerInfoRef peer)) { @@ -1433,20 +1435,20 @@ bool SOSCircleAcceptPeerFromHSA2(SOSCircleRef circle, SecKeyRef userKey, SOSGenC // Gen sign first, then add signature from our approver - remember gensign removes all existing sigs. res = SOSCircleGenerationSignWithGenCount(circle, userKey, fpi, gencount, error); if (!res) { - secnotice("circleJoin", "Failed to regenerate circle with new gen count: %@", error ? *error : NULL); + secnotice("circleOps", "Failed to regenerate circle with new gen count: %@", error ? *error : NULL); return res; } res = SOSCircleSetSignature(circle, pPubKey, signature, error); if (!res) { - secnotice("circleJoin", "Failed to set signature: %@", error ? *error : NULL); + secnotice("circleOps", "Failed to set signature: %@", error ? *error : NULL); return res; } res = SOSCircleVerify(circle, pPubKey, error); if (!res) { - secnotice("circleJoin", "Circle failed to validate after peer signature: %@", error ? *error : NULL); + secnotice("circleOps", "Circle failed to validate after peer signature: %@", error ? *error : NULL); return res; } - secnotice("circleJoin", "Circle accepted successfullyed"); + secnotice("circleOps", "Circle accepted successfully"); return true; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.h index e43c0adb..9de6fb18 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.h @@ -44,7 +44,7 @@ __BEGIN_DECLS typedef struct __OpaqueSOSCircle *SOSCircleRef; -CFTypeID SOSCircleGetTypeID(); +CFTypeID SOSCircleGetTypeID(void); SOSCircleRef SOSCircleCreate(CFAllocatorRef allocator, CFStringRef circleName, CFErrorRef *error); SOSCircleRef SOSCircleCreateFromDER(CFAllocatorRef allocator, CFErrorRef* error, @@ -150,7 +150,7 @@ bool SOSCircleAcceptRequests(SOSCircleRef circle, SecKeyRef user_privkey, SOSFul // Stuff above this line is really SOSCircleInfo below the line is the active SOSCircle functionality -SOSFullPeerInfoRef SOSCircleCopyiCloudFullPeerInfoRef(SOSCircleRef circle, CFErrorRef *error); +CF_RETURNS_RETAINED SOSFullPeerInfoRef SOSCircleCopyiCloudFullPeerInfoRef(SOSCircleRef circle, CFErrorRef *error); bool SOSCircleConcordanceSign(SOSCircleRef circle, SOSFullPeerInfoRef peerinfo, CFErrorRef *error); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h index ed513c96..ba1ecd99 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h @@ -129,6 +129,11 @@ bool SOSCCSetUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_passw bool SOSCCTryUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error); +/*! + This variant adds the dsid to the call + */ + +bool SOSCCTryUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error); /*! @function SOSCCCopyDeviceID @abstract Retrieves this device's IDS device ID diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.m index 824a84b4..1e006242 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.m @@ -365,7 +365,7 @@ static int simple_int_error_request(enum SecXPCOperation op, CFErrorRef* error) return result; } -static SOSPeerInfoRef peer_info_error_request(enum SecXPCOperation op, CFErrorRef* error) +static CF_RETURNS_RETAINED SOSPeerInfoRef peer_info_error_request(enum SecXPCOperation op, CFErrorRef* error) { SOSPeerInfoRef result = NULL; __block CFDataRef data = NULL; @@ -559,11 +559,11 @@ static bool cfstring_and_cfdata_to_cfdata_cfdata_error_request(enum SecXPCOperat result = xpc_dictionary_get_bool(response, kSecXPCKeyResult); xpc_object_t temp_result = xpc_dictionary_get_value(response, kSecXPCData); - if (response && (NULL != temp_result) && data) { + if ((NULL != temp_result) && data) { *data = _CFXPCCreateCFObjectFromXPCObject(temp_result); } temp_result = xpc_dictionary_get_value(response, kSecXPCKeyKeybag); - if (response && (NULL != temp_result) && data2) { + if ((NULL != temp_result) && data2) { *data2 = _CFXPCCreateCFObjectFromXPCObject(temp_result); } @@ -1075,8 +1075,11 @@ static CF_RETURNS_RETAINED SOSPeerInfoRef SOSSetNewPublicBackupKey(CFDataRef pub } SOSPeerInfoRef SOSCCCopyMyPeerWithNewDeviceRecoverySecret(CFDataRef secret, CFErrorRef *error){ + secnotice("devRecovery", "Enter SOSCCCopyMyPeerWithNewDeviceRecoverySecret()"); CFDataRef publicKeyData = SOSCopyDeviceBackupPublicKey(secret, error); + secnotice("devRecovery", "SOSCopyDeviceBackupPublicKey (%@)", publicKeyData); SOSPeerInfoRef copiedPeer = publicKeyData ? SOSSetNewPublicBackupKey(publicKeyData, error) : NULL; + secnotice("devRecovery", "SOSSetNewPublicBackupKey (%@)", copiedPeer); CFReleaseNull(publicKeyData); return copiedPeer; } @@ -1228,13 +1231,13 @@ static bool idscommand_to_bool_error_request(enum SecXPCOperation op, bool SOSCCRegisterUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error) { - secnotice("sosops", "SOSCCRegisterUserCredentials - calling SOSCCSetUserCredentials!! %@\n", user_label); + secnotice("circleOps", "SOSCCRegisterUserCredentials - calling SOSCCSetUserCredentials for %@\n", user_label); return SOSCCSetUserCredentials(user_label, user_password, error); } bool SOSCCSetUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error) { - secnotice("sosops", "SOSCCSetUserCredentials!! %@\n", user_label); + secnotice("circleOps", "SOSCCSetUserCredentials for %@\n", user_label); sec_trace_enter_api(CFSTR("user_label=%@"), user_label); sec_trace_return_bool_api(^{ do_if_registered(soscc_SetUserCredentials, user_label, user_password, error); @@ -1245,7 +1248,7 @@ bool SOSCCSetUserCredentials(CFStringRef user_label, CFDataRef user_password, CF bool SOSCCSetUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error) { - secnotice("sosops", "SOSCCSetUserCredentialsAndDSID!! %@\n", user_label); + secnotice("circleOps", "SOSCCSetUserCredentialsAndDSID for %@\n", user_label); sec_trace_enter_api(CFSTR("user_label=%@"), user_label); sec_trace_return_bool_api(^{ do_if_registered(soscc_SetUserCredentialsAndDSID, user_label, user_password, dsid, error); @@ -1265,6 +1268,8 @@ bool SOSCCSetUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_passw }, NULL) } + + bool SOSCCSetDeviceID(CFStringRef IDS, CFErrorRef* error) { secnotice("sosops", "SOSCCSetDeviceID!! %@\n", IDS); @@ -1347,14 +1352,41 @@ bool SOSCCRequestSyncWithPeerOverKVS(CFStringRef peerID, CFDataRef message, CFEr }, NULL) } -bool SOSCCTryUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error) -{ - sec_trace_enter_api(CFSTR("user_label=%@"), user_label); +static bool SOSCCTryUserCredentialsAndDSID_internal(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error) { sec_trace_return_bool_api(^{ - do_if_registered(soscc_TryUserCredentials, user_label, user_password, error); - - return label_and_password_to_bool_error_request(kSecXPCOpTryUserCredentials, user_label, user_password, error); + do_if_registered(soscc_TryUserCredentials, user_label, user_password, dsid, error); + + bool result = false; + __block CFStringRef account_dsid = dsid; + + require_action_quiet(user_label, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_label is nil"))); + require_action_quiet(user_password, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_password is nil"))); + + if(account_dsid == NULL){ + account_dsid = CFSTR(""); + } + + return label_and_password_and_dsid_to_bool_error_request(kSecXPCOpTryUserCredentials, user_label, user_password, account_dsid, error); + out: + return result; + }, NULL) + +} + +bool SOSCCTryUserCredentialsAndDSID(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error) +{ + secnotice("sosops", "SOSCCTryUserCredentialsAndDSID!! %@\n", user_label); + require_action_quiet(user_label, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_label is nil"))); + require_action_quiet(user_password, out, SOSErrorCreate(kSOSErrorParam, error, NULL, CFSTR("user_password is nil"))); + CFStringRef account_dsid = (dsid != NULL) ? dsid: CFSTR(""); + return SOSCCTryUserCredentialsAndDSID_internal(user_label, user_password, account_dsid, error); +out: + return false; +} + +bool SOSCCTryUserCredentials(CFStringRef user_label, CFDataRef user_password, CFErrorRef* error) { + return SOSCCTryUserCredentialsAndDSID_internal(user_label, user_password, NULL, error); } @@ -1829,18 +1861,15 @@ bool SOSCCSendToPeerIsPending(SOSPeerInfoRef peer, CFErrorRef *error) { @implementation SecSOSStatus @synthesize connection = _connection; -- (instancetype) initWithEndpoint:(xpc_endpoint_t)endpoint +- (instancetype) init { if ((self = [super init]) == NULL) return NULL; NSXPCInterface *interface = [NSXPCInterface interfaceWithProtocol:@protocol(SOSControlProtocol)]; _SOSControlSetupInterface(interface); - NSXPCListenerEndpoint *listenerEndpoint = [[NSXPCListenerEndpoint alloc] init]; - - [listenerEndpoint _setEndpoint:endpoint]; - self.connection = [[NSXPCConnection alloc] initWithListenerEndpoint:listenerEndpoint]; + self.connection = [[NSXPCConnection alloc] initWithMachServiceName:@(kSecuritydSOSServiceName) options:0]; if (self.connection == NULL) return NULL; @@ -1862,11 +1891,7 @@ SOSCCGetStatusObject(CFErrorRef *error) static SecSOSStatus *control; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - xpc_endpoint_t endpoint = _SecSecuritydCopySOSStatusEndpoint(error); - if (endpoint == NULL) - return; - - control = [[SecSOSStatus alloc] initWithEndpoint:endpoint]; + control = [[SecSOSStatus alloc] init]; }); return control.connection.remoteObjectProxy; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircleInternal.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircleInternal.h index c901d102..5a0e01f0 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircleInternal.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircleInternal.h @@ -149,8 +149,6 @@ CFDictionaryRef SOSCCCopyBackupInformation(CFErrorRef *error); bool SOSCCRequestSyncWithPeerOverKVSUsingIDOnly(CFStringRef peerID, CFErrorRef *error); bool SOSCCTestPopulateKVSWithBadKeys(CFErrorRef *error); CFDataRef SOSCCCopyInitialSyncData(CFErrorRef *error); - -char *SOSCCSysdiagnose(const char *directoryname); void SOSCCForEachEngineStateAsStringFromArray(CFArrayRef states, void (^block)(CFStringRef oneStateString)); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSControlServer.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSControlServer.h new file mode 100644 index 00000000..e1c217af --- /dev/null +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSControlServer.h @@ -0,0 +1,6 @@ +#ifndef _SOSCONTROLSERVER_H_ +#define _SOSCONTROLSERVER_H_ + +void SOSControlServerInitialize(void); + +#endif /* !_SOSCONTROLSERVER_H_ */ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSControlServer.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSControlServer.m new file mode 100644 index 00000000..237e7b13 --- /dev/null +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSControlServer.m @@ -0,0 +1,184 @@ +#import +#import +#import +#import +#import "SOSAccount.h" +#import "SOSControlHelper.h" +#import "SOSControlServer.h" + +@interface SOSControlServer : NSObject +@end + +@interface SOSClient : NSObject +@property (weak) NSXPCConnection * connection; +@property (strong) SOSAccount * account; + +- (instancetype)initWithConnection:(NSXPCConnection *)connection account:(SOSAccount *)account; +@end + +@implementation SOSControlServer + +- (BOOL)listener:(__unused NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection +{ + NSNumber *num = [newConnection valueForEntitlement:(__bridge NSString *)kSecEntitlementKeychainCloudCircle]; + if (![num isKindOfClass:[NSNumber class]] || ![num boolValue]) { + secerror("sos: Client pid: %d doesn't have entitlement: %@", + [newConnection processIdentifier], kSecEntitlementKeychainCloudCircle); + return NO; + } + + + SOSClient *sosClient = [[SOSClient alloc] initWithConnection:newConnection account:(__bridge SOSAccount *)SOSKeychainAccountGetSharedAccount()]; + + newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(SOSControlProtocol)]; + _SOSControlSetupInterface(newConnection.exportedInterface); + newConnection.exportedObject = sosClient; + + [newConnection resume]; + + return YES; +} + +@end + +@implementation SOSClient + +@synthesize account = _account; +@synthesize connection = _connection; + +- (instancetype)initWithConnection:(NSXPCConnection *)connection account:(SOSAccount *)account +{ + if ((self = [super init])) { + _connection = connection; + _account = account; + } + return self; +} + +- (bool)checkEntitlement:(NSString *)entitlement +{ + NSXPCConnection *strongConnection = _connection; + + NSNumber *num = [strongConnection valueForEntitlement:entitlement]; + if (![num isKindOfClass:[NSNumber class]] || ![num boolValue]) { + secerror("sos: Client pid: %d doesn't have entitlement: %@", + [strongConnection processIdentifier], entitlement); + return false; + } + return true; +} + +- (void)userPublicKey:(void ((^))(BOOL trusted, NSData *spki, NSError *error))reply +{ + [self.account userPublicKey:reply]; +} + +- (void)kvsPerformanceCounters:(void(^)(NSDictionary *))reply +{ + [self.account kvsPerformanceCounters:reply]; +} + +- (void)idsPerformanceCounters:(void(^)(NSDictionary *))reply +{ + [self.account idsPerformanceCounters:reply]; +} + +- (void)rateLimitingPerformanceCounters:(void(^)(NSDictionary *))reply +{ + [self.account rateLimitingPerformanceCounters:reply]; +} + +- (void)stashedCredentialPublicKey:(void(^)(NSData *, NSError *error))reply +{ + [self.account stashedCredentialPublicKey:reply]; +} + +- (void)assertStashedAccountCredential:(void(^)(BOOL result, NSError *error))reply +{ + [self.account assertStashedAccountCredential:reply]; +} + +- (void)validatedStashedAccountCredential:(void(^)(NSData *credential, NSError *error))complete +{ + [self.account validatedStashedAccountCredential:complete]; +} + +- (void)stashAccountCredential:(NSData *)credential complete:(void(^)(bool success, NSError *error))complete +{ + [self.account stashAccountCredential:credential complete:complete]; +} + +- (void)myPeerInfo:(void (^)(NSData *, NSError *))complete +{ + [self.account myPeerInfo:complete]; +} + +- (void)circleJoiningBlob:(NSData *)applicant complete:(void (^)(NSData *blob, NSError *))complete +{ + [self.account circleJoiningBlob:applicant complete:complete]; +} + +- (void)joinCircleWithBlob:(NSData *)blob version:(PiggyBackProtocolVersion)version complete:(void (^)(bool success, NSError *))complete +{ + [self.account joinCircleWithBlob:blob version:version complete:complete]; +} + +- (void)initialSyncCredentials:(uint32_t)flags complete:(void (^)(NSArray *, NSError *))complete +{ + if (![self checkEntitlement:(__bridge NSString *)kSecEntitlementKeychainInitialSync]) { + complete(@[], [NSError errorWithDomain:(__bridge NSString *)kSOSErrorDomain code:kSOSEntitlementMissing userInfo:NULL]); + return; + } + + [self.account initialSyncCredentials:flags complete:complete]; +} + +- (void)importInitialSyncCredentials:(NSArray *)items complete:(void (^)(bool success, NSError *))complete +{ + if (![self checkEntitlement:(__bridge NSString *)kSecEntitlementKeychainInitialSync]) { + complete(false, [NSError errorWithDomain:(__bridge NSString *)kSOSErrorDomain code:kSOSEntitlementMissing userInfo:NULL]); + return; + } + + [self.account importInitialSyncCredentials:items complete:complete]; +} + +- (void)triggerSync:(NSArray *)peers complete:(void(^)(bool success, NSError *))complete +{ + if (![self checkEntitlement:(__bridge NSString *)kSecEntitlementKeychainCloudCircle]) { + complete(false, [NSError errorWithDomain:(__bridge NSString *)kSOSErrorDomain code:kSOSEntitlementMissing userInfo:NULL]); + return; + } + + [self.account triggerSync:peers complete:complete]; +} + +- (void)getWatchdogParameters:(void (^)(NSDictionary* parameters, NSError* error))complete +{ + [self.account getWatchdogParameters:complete]; +} + +- (void)setWatchdogParmeters:(NSDictionary*)parameters complete:(void (^)(NSError* error))complete +{ + [self.account setWatchdogParmeters:parameters complete:complete]; +} + +@end + +void +SOSControlServerInitialize(void) +{ + static dispatch_once_t once; + static SOSControlServer *server; + static NSXPCListener *listener; + + dispatch_once(&once, ^{ + @autoreleasepool { + server = [SOSControlServer new]; + + listener = [[NSXPCListener alloc] initWithMachServiceName:@(kSecuritydSOSServiceName)]; + listener.delegate = server; + [listener resume]; + } + }); +} diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.c b/OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.c index 733795d6..0730e7f9 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.c +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.c @@ -714,6 +714,7 @@ bool TestSOSEngineLoadCoders(CFTypeRef engine, SOSTransactionRef txn, CFErrorRef static bool SOSEngineLoadCoders(SOSEngineRef engine, SOSTransactionRef txn, CFErrorRef *error) { // Read the serialized engine state from the datasource (aka keychain) and populate the in-memory engine + __block bool needPeerRegistration = false; bool ok = true; CFDataRef derCoders = NULL; CFMutableDictionaryRef codersDict = NULL; @@ -721,37 +722,59 @@ static bool SOSEngineLoadCoders(SOSEngineRef engine, SOSTransactionRef txn, CFEr require_quiet(derCoders, xit); codersDict = derStateToDictionaryCopy(derCoders, error); require_quiet(codersDict, xit); + + /* + * Make sure all peer have coders + */ CFDictionaryForEach(engine->peerMap, ^(const void *peerID, const void *peerState) { - if (peerID) { - CFTypeRef coderRef = CFDictionaryGetValue(codersDict, peerID); - if (coderRef) { - CFDataRef coderData = asData(coderRef, NULL); - if (coderData) { - CFErrorRef createError = NULL; - SOSCoderRef coder = SOSCoderCreateFromData(coderData, &createError); - if (coder) { - CFDictionaryAddValue(engine->coders, peerID, coder); - secnotice("coder", "adding coder: %@ for peerid: %@", coder, peerID); - } else { - secnotice("coder", "Coder for '%@' failed to create: %@", peerID, createError); - } - CFReleaseNull(createError); - CFReleaseNull(coder); + /* + * Skip backup peer since they will never have coders + */ + if (isString(peerID) && CFStringHasSuffix(peerID, CFSTR("-tomb"))) { + secnotice("coder", "Skipping coder check for peer: %@", peerID); + return; + } + + CFTypeRef coderRef = CFDictionaryGetValue(codersDict, peerID); + if (coderRef) { + CFDataRef coderData = asData(coderRef, NULL); + if (coderData) { + CFErrorRef createError = NULL; + SOSCoderRef coder = SOSCoderCreateFromData(coderData, &createError); + if (coder) { + CFDictionaryAddValue(engine->coders, peerID, coder); + secnotice("coder", "adding coder: %@ for peerid: %@", coder, peerID); } else { - // Needed a coder, didn't find one, notify the account to help us out. - // Next attempt to sync will fix this - secnotice("coder", "coder for %@ was not cf data: %@", peerID, coderData); - SOSCCEnsurePeerRegistration(); + secnotice("coder", "Coder for '%@' failed to create: %@", peerID, createError); } + CFReleaseNull(createError); + CFReleaseNull(coder); + } else { + // Needed a coder, didn't find one, notify the account to help us out. + // Next attempt to sync will fix this + secnotice("coder", "coder for %@ was not cf data: %@", peerID, coderData); + needPeerRegistration = true; } - else{ - secnotice("coder", "didn't find coder for peer: %@ engine dictionary: %@", peerID, codersDict); - SOSCCEnsurePeerRegistration(); - } - + } else{ + secnotice("coder", "didn't find coder for peer: %@ engine dictionary: %@", peerID, codersDict); + needPeerRegistration = true; } }); + secnotice("coder", "Will force peer registration: %s",needPeerRegistration ? "yes" : "no"); + + if (needPeerRegistration) { + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + + dispatch_async(queue, ^{ + CFErrorRef eprError = NULL; + if (!SOSCCProcessEnsurePeerRegistration_Server(&eprError)) { + secnotice("coder", "SOSCCProcessEnsurePeerRegistration failed with: %@", eprError); + } + CFReleaseNull(eprError); + }); + } + engine->haveLoadedCoders = true; xit: @@ -1954,10 +1977,17 @@ bool SOSEngineHandleMessage_locked(SOSEngineRef engine, CFStringRef peerID, SOSM #endif base = SOSPeerCopyManifestForDigest(peer, baseDigest); + + // Note that the sender digest will only exist if we receive a SOSManifestDigestMessageType (since we never receive v2 messages) confirmed = SOSPeerCopyManifestForDigest(peer, SOSMessageGetSenderDigest(message)); if (!confirmed) { if (SOSManifestGetCount(SOSMessageGetRemovals(message)) || SOSManifestGetCount(allAdditions)) { if (base || !baseDigest) { + + secnotice("engine", "SOSEngineHandleMessage_locked (%@): creating a confirmed manifest via a patch (base %zu %@, +%zu, -%zu)", SOSPeerGetID(peer), + SOSManifestGetCount(base), SOSManifestGetDigest(base, NULL), + SOSManifestGetCount(allAdditions), SOSManifestGetCount(SOSMessageGetRemovals(message))); + confirmed = SOSManifestCreateWithPatch(base, SOSMessageGetRemovals(message), allAdditions, error); } if (!confirmed) { @@ -1968,6 +1998,9 @@ bool SOSEngineHandleMessage_locked(SOSEngineRef engine, CFStringRef peerID, SOSM confirmed = CFRetainSafe(base); secerror("%@:%@ Protocol error send L00 - figure out later base: %@", engine->myID, peerID, base); } + + } else { + secnotice("engine", "SOSEngineHandleMessage_locked (%@): got a confirmed manifest by digest: (%zu, %@)", SOSPeerGetID(peer), SOSManifestGetCount(confirmed), SOSMessageGetSenderDigest(message)); } secnoticeq("engine", "%@:%@ confirmed: %@ base: %@", engine->myID, peerID, confirmed, base); if (confirmed) { @@ -1975,13 +2008,27 @@ bool SOSEngineHandleMessage_locked(SOSEngineRef engine, CFStringRef peerID, SOSM if (SOSManifestGetCount(SOSMessageGetRemovals(message))) CFAssignRetained(confirmedRemovals, SOSManifestCreateUnion(confirmedRemovals, SOSMessageGetRemovals(message), error)); } - if (SOSManifestGetCount(confirmedRemovals) || SOSManifestGetCount(confirmedAdditions) || SOSManifestGetCount(unwanted)) + if (SOSManifestGetCount(confirmedRemovals) || SOSManifestGetCount(confirmedAdditions) || SOSManifestGetCount(unwanted)) { ok &= SOSPeerDidReceiveRemovalsAndAdditions(peer, confirmedRemovals, confirmedAdditions, unwanted, localManifest, error); + } + + // TODO: We should probably remove the if below and always call SOSPeerSetConfirmedManifest, // since having a NULL confirmed will force us to send a manifest message to get in sync again. - if (confirmed) + if (confirmed) { + + SOSManifestRef previousConfirmedManifest = SOSPeerGetConfirmedManifest(peer); + if(previousConfirmedManifest) { + secnotice("engine", "SOSEngineHandleMessage_locked (%@): new confirmed manifest (%zu, %@) will replace existing confirmed manifest (%zu, %@)", SOSPeerGetID(peer), + SOSManifestGetCount(confirmed), SOSManifestGetDigest(confirmed, NULL), + SOSManifestGetCount(previousConfirmedManifest), SOSManifestGetDigest(previousConfirmedManifest, NULL)); + } else { + secnotice("engine", "SOSEngineHandleMessage_locked (%@): new confirmed manifest (%zu, %@) is first manifest for peer", SOSPeerGetID(peer), + SOSManifestGetCount(confirmed), SOSManifestGetDigest(confirmed, NULL)); + } + SOSPeerSetConfirmedManifest(peer, confirmed); - else if (SOSPeerGetConfirmedManifest(peer)) { + } else if (SOSPeerGetConfirmedManifest(peer)) { secnoticeq("engine", "%@:%@ unable to find confirmed in %@, sync protocol reset", engine->myID, peer, message); SOSPeerSetConfirmedManifest(peer, NULL); @@ -2202,7 +2249,10 @@ static __unused bool SOSEngineCheckPeerIntegrity(SOSEngineRef engine, SOSPeerRef CFReleaseSafe(AunionT); CFReleaseSafe(MunionU); + CFReleaseSafe(CunionU); + CFReleaseNull(SunionAunionT); + CFReleaseNull(SunionMunionU); CFReleaseSafe(A); CFReleaseSafe(M); @@ -2247,7 +2297,7 @@ static void SOSEngineCompletedSyncWithPeer(SOSEngineRef engine, SOSPeerRef peer) CFDataRef SOSEngineCreateMessage_locked(SOSEngineRef engine, SOSTransactionRef txn, SOSPeerRef peer, - CFMutableArrayRef *attributeList, CFErrorRef *error, SOSEnginePeerMessageSentBlock *sent) { + CFMutableArrayRef *attributeList, CFErrorRef *error, SOSEnginePeerMessageSentCallback **sent) { SOSManifestRef local = SOSEngineCopyLocalPeerManifest_locked(engine, peer, error); __block SOSMessageRef message = SOSMessageCreate(kCFAllocatorDefault, SOSPeerGetMessageVersion(peer), error); SOSManifestRef confirmed = SOSPeerGetConfirmedManifest(peer); @@ -2299,12 +2349,14 @@ CFDataRef SOSEngineCreateMessage_locked(SOSEngineRef engine, SOSTransactionRef t CFReleaseNull(allMissing); CFReleaseNull(excessUnwanted); - secnoticeq("engine", "%@:%@: send state for peer [%s%s%s][%s%s] P:%zu, E:%zu, M:%zu U:%zu", engine->myID, SOSPeerGetID(peer), + secnoticeq("engine", "%@:%@: send state for peer [%s%s%s][%s%s] local:%zu confirmed:%zu pending:%zu, extra:%zu, missing:%zu unwanted:%zu", engine->myID, SOSPeerGetID(peer), local ? "L":"l", confirmed ? "C":"0", pendingObjects ? "P":"0", SOSPeerSendObjects(peer) ? "O":"o", SOSPeerMustSendMessage(peer) ? "S":"s", + SOSManifestGetCount(local), + SOSManifestGetCount(confirmed), SOSManifestGetCount(pendingObjects), SOSManifestGetCount(extra), SOSManifestGetCount(missing), @@ -2337,8 +2389,8 @@ CFDataRef SOSEngineCreateMessage_locked(SOSEngineRef engine, SOSTransactionRef t send = true; } if (!send) { - CFReleaseSafe(local); - CFReleaseSafe(message); + CFReleaseNull(local); + CFReleaseNull(message); CFReleaseNull(extra); CFReleaseNull(missing); return CFDataCreate(kCFAllocatorDefault, NULL, 0); @@ -2401,8 +2453,9 @@ CFDataRef SOSEngineCreateMessage_locked(SOSEngineRef engine, SOSTransactionRef t *attributeList = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); CFDictionaryRef itemPlist = SOSObjectCopyPropertyList(engine->dataSource, object, &localError); if(itemPlist && !CFArrayContainsValue(*attributeList, CFRangeMake(0, CFArrayGetCount(*attributeList)), (CFStringRef)CFDictionaryGetValue(itemPlist, kSecAttrAccessGroup))){ - CFArrayAppendValue(*attributeList, (CFStringRef)CFDictionaryGetValue(itemPlist, kSecAttrAccessGroup)); - }//copy access group to array + CFArrayAppendValue(*attributeList, (CFStringRef)CFDictionaryGetValue(itemPlist, kSecAttrAccessGroup)); + }//copy access group to array + CFReleaseNull(itemPlist); } else { const uint8_t *d = CFDataGetBytePtr(digest); CFStringRef hexder = CFDataCopyHexString(der); @@ -2471,42 +2524,89 @@ CFDataRef SOSEngineCreateMessage_locked(SOSEngineRef engine, SOSTransactionRef t } if (result) { - // Capture the peer in our block (SOSEnginePeerMessageSentBlock) - CFRetainSafe(peer); - *sent = Block_copy(^(bool success) { - dispatch_async(engine->queue, ^{ - if (success) { - SOSPeerSetMustSendMessage(peer, false); - if (!confirmed && !proposed) { - SOSPeerSetSendObjects(peer, true); - secnoticeq("engine", "%@:%@ sendObjects=true L:%@", engine->myID, SOSPeerGetID(peer), local); + SOSEnginePeerMessageSentCallback* pmsc = malloc(sizeof(SOSEnginePeerMessageSentCallback)); + memset(pmsc, 0, sizeof(SOSEnginePeerMessageSentCallback)); + pmsc->engine = engine; CFRetain(pmsc->engine); + pmsc->peer = CFRetainSafe(peer); + pmsc->local = CFRetainSafe(local); + pmsc->proposed = CFRetainSafe(proposed); + pmsc->message = CFRetainSafe(message); + pmsc->confirmed = CFRetainSafe(confirmed); + + SOSEngineMessageCallbackSetCallback(pmsc, ^(bool success) { + // Have to copy pmsc so it'll still be around during the dispatch_async + SOSEnginePeerMessageSentCallback* pmsc2 = malloc(sizeof(SOSEnginePeerMessageSentCallback)); + memset(pmsc2, 0, sizeof(SOSEnginePeerMessageSentCallback)); + pmsc2->engine = pmsc->engine; CFRetain(pmsc2->engine); + pmsc2->peer = CFRetainSafe(pmsc->peer); + pmsc2->local = CFRetainSafe(pmsc->local); + pmsc2->proposed = CFRetainSafe(pmsc->proposed); + pmsc2->message = CFRetainSafe(pmsc->message); + pmsc2->confirmed = CFRetainSafe(pmsc->confirmed); + + dispatch_async(pmsc->engine->queue, ^{ + if (success) { + SOSPeerSetMustSendMessage(pmsc2->peer, false); + if (!pmsc2->confirmed && !pmsc2->proposed) { + SOSPeerSetSendObjects(pmsc2->peer, true); + secnoticeq("engine", "%@:%@ sendObjects=true L:%@", pmsc2->engine->myID, SOSPeerGetID(pmsc2->peer), pmsc2->local); + } + SOSPeerAddLocalManifest(pmsc2->peer, pmsc2->local); + SOSPeerAddProposedManifest(pmsc2->peer, pmsc2->proposed); + secnoticeq("engine", "send %@:%@ %@", pmsc2->engine->myID, SOSPeerGetID(pmsc2->peer), pmsc2->message); + //SOSEngineCheckPeerIntegrity(engine, peer, NULL); + } else { + secerror("%@:%@ failed to send %@", pmsc2->engine->myID, SOSPeerGetID(pmsc2->peer), pmsc2->message); } - SOSPeerAddLocalManifest(peer, local); - SOSPeerAddProposedManifest(peer, proposed); - secnoticeq("engine", "send %@:%@ %@", engine->myID, SOSPeerGetID(peer), message); - //SOSEngineCheckPeerIntegrity(engine, peer, NULL); - } else { - secerror("%@:%@ failed to send %@", engine->myID, SOSPeerGetID(peer), message); - } - CFReleaseSafe(peer); - CFReleaseSafe(local); - CFReleaseSafe(proposed); - CFReleaseSafe(message); + SOSEngineFreeMessageCallback(pmsc2); }); }); - } else { - CFReleaseSafe(local); - CFReleaseSafe(proposed); - CFReleaseSafe(message); + + *sent = pmsc; } + + CFReleaseNull(local); CFReleaseNull(extra); CFReleaseNull(missing); + CFReleaseNull(message); + CFReleaseNull(proposed); if (error && *error) secerror("%@:%@ error in send: %@", engine->myID, SOSPeerGetID(peer), *error); return result; } +void SOSEngineMessageCallbackSetCallback(SOSEnginePeerMessageSentCallback *sent, SOSEnginePeerMessageSentBlock block) { + if(sent) { + sent->block = Block_copy(block); + } +} + + +void SOSEngineMessageCallCallback(SOSEnginePeerMessageSentCallback *sent, bool ok) { + if (sent && sent->block) { + (sent->block)(ok); + } +} + +void SOSEngineFreeMessageCallback(SOSEnginePeerMessageSentCallback* psmc) { + if(psmc) { + CFReleaseNull(psmc->engine); + CFReleaseNull(psmc->peer); + CFReleaseNull(psmc->coder); + CFReleaseNull(psmc->local); + CFReleaseNull(psmc->proposed); + CFReleaseNull(psmc->message); + CFReleaseNull(psmc->confirmed); + + if(psmc->block) { + Block_release(psmc->block); + } + + free(psmc); + } +} + static void SOSEngineLogItemError(SOSEngineRef engine, CFStringRef peerID, CFDataRef key, CFDataRef optionalDigest, const char *where, CFErrorRef error) { if (!optionalDigest) { const uint8_t *d = CFDataGetBytePtr(key); @@ -2848,10 +2948,10 @@ bool SOSEngineWithPeerID(SOSEngineRef engine, CFStringRef peerID, CFErrorRef *er return result; } -CFDataRef SOSEngineCreateMessageToSyncToPeer(SOSEngineRef engine, CFStringRef peerID, CFMutableArrayRef *attributeList, SOSEnginePeerMessageSentBlock *sentBlock, CFErrorRef *error){ +CFDataRef SOSEngineCreateMessageToSyncToPeer(SOSEngineRef engine, CFStringRef peerID, CFMutableArrayRef *attributeList, SOSEnginePeerMessageSentCallback **sentCallback, CFErrorRef *error){ __block CFDataRef message = NULL; SOSEngineForPeerID(engine, peerID, error, ^(SOSTransactionRef txn, SOSPeerRef peer) { - message = SOSEngineCreateMessage_locked(engine, txn, peer, attributeList, error, sentBlock); + message = SOSEngineCreateMessage_locked(engine, txn, peer, attributeList, error, sentCallback); }); return message; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.h index 1325e5fb..755732be 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.h @@ -37,9 +37,24 @@ __BEGIN_DECLS -// TODO: Move this to SOSPeer.h? typedef void (^SOSEnginePeerMessageSentBlock)(bool success); +typedef struct { + __unsafe_unretained SOSEnginePeerMessageSentBlock block; + SOSEngineRef engine; + SOSPeerRef peer; + SOSCoderRef coder; + SOSManifestRef local; + SOSManifestRef proposed; + SOSManifestRef confirmed; + SOSMessageRef message; +} SOSEnginePeerMessageSentCallback; +void SOSEngineMessageCallCallback(SOSEnginePeerMessageSentCallback *sent, bool ok); + +// Must always be in C or obj-c; splitting is unwise +void SOSEngineMessageCallbackSetCallback(SOSEnginePeerMessageSentCallback *sent, SOSEnginePeerMessageSentBlock block); + + // Return a new engine instance for a given data source. SOSEngineRef SOSEngineCreate(SOSDataSourceRef dataSource, CFErrorRef *error); @@ -93,7 +108,10 @@ bool SOSEngineHandleMessage_locked(SOSEngineRef engine, CFStringRef peerID, SOSM SOSTransactionRef txn, bool *commit, bool *somethingChanged, CFErrorRef *error); CFDataRef SOSEngineCreateMessage_locked(SOSEngineRef engine, SOSTransactionRef txn, SOSPeerRef peer, - CFMutableArrayRef *attributeList, CFErrorRef *error, SOSEnginePeerMessageSentBlock *sent); + CFMutableArrayRef *attributeList, CFErrorRef *error, SOSEnginePeerMessageSentCallback **sentCallback); + +// When you're done with the *sent parameter from SOSEngineCreateMessage_locked, you must call this on the returned object +void SOSEngineFreeMessageCallback(SOSEnginePeerMessageSentCallback* sentCallback); // Return a SOSPeerRef for a given peer_id. SOSPeerRef SOSEngineCopyPeerWithID(SOSEngineRef engine, CFStringRef peer_id, CFErrorRef *error); @@ -110,7 +128,7 @@ bool SOSEngineInitializePeerCoder(SOSEngineRef engine, SOSFullPeerInfoRef myPeer // return a zero length CFDataRef if there is nothing to send. // If *ProposedManifest is set the caller is responsible for updating their // proposed manifest upon successful transmission of the message. -CFDataRef SOSEngineCreateMessageToSyncToPeer(SOSEngineRef engine, CFStringRef peerID, CFMutableArrayRef *attributeList, SOSEnginePeerMessageSentBlock *sentBlock, CFErrorRef *error); +CFDataRef SOSEngineCreateMessageToSyncToPeer(SOSEngineRef engine, CFStringRef peerID, CFMutableArrayRef *attributeList, SOSEnginePeerMessageSentCallback **sentBlock, CFErrorRef *error); CFStringRef SOSEngineGetMyID(SOSEngineRef engine); bool SOSEnginePeerDidConnect(SOSEngineRef engine, CFStringRef peerID, CFErrorRef *error); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSEnsureBackup.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSEnsureBackup.m index 710ed742..b32f3e01 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSEnsureBackup.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSEnsureBackup.m @@ -25,8 +25,9 @@ #import "SOSEnsureBackup.h" #include -#if TARGET_OS_OSX || TARGET_OS_IOS +#if OCTAGON #import "keychain/ckks/CKKSLockStateTracker.h" +#import "keychain/ckks/NSOperationCategories.h" #include #import #import "keychain/analytics/awd/AWDMetricIds_Keychain.h" @@ -50,19 +51,20 @@ void SOSEnsureBackupWhileUnlocked(void) { NSBlockOperation *backupOperation = [NSBlockOperation blockOperationWithBlock:^{ secnotice("engine", "Performing keychain backup after unlock because backing up while locked failed"); SOSAccount *account = (__bridge SOSAccount *)(SOSKeychainAccountGetSharedAccount()); - SOSAccountTransaction* transaction = [SOSAccountTransaction transactionWithAccount:account]; - CFErrorRef error = NULL; - CFSetRef set = SOSAccountCopyBackupPeersAndForceSync(transaction, &error); - if (set) { - secnotice("engine", "SOSEnsureBackup: SOS made a backup of views: %@", set); - } else { - secerror("engine: SOSEnsureBackup: encountered an error while making backup (%@)", error); - } - CFReleaseNull(error); - CFReleaseNull(set); + [account performTransaction:^(SOSAccountTransaction *transaction) { + CFErrorRef error = NULL; + NSSet* set = CFBridgingRelease(SOSAccountCopyBackupPeersAndForceSync(transaction, &error)); + if (set) { + secnotice("engine", "SOSEnsureBackup: SOS made a backup of views: %@", set); + } else { + secerror("engine: SOSEnsureBackup: encountered an error while making backup (%@)", error); + } + + CFReleaseNull(error); + }]; }]; - [backupOperation addDependency:lockStateTracker.unlockDependency]; + [backupOperation addNullableDependency:lockStateTracker.unlockDependency]; [backupOperationQueue addOperation:backupOperation]; AWDPostSimpleMetric(AWDMetricId_Keychain_SOSKeychainBackupFailed); } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSExports.exp-in b/OSX/sec/SOSCircle/SecureObjectSync/SOSExports.exp-in index 1434f14d..d55aa5a2 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSExports.exp-in +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSExports.exp-in @@ -6,6 +6,7 @@ // _SOSCCAcceptApplicants +_SOSCCAccountGetAccountPrivateCredential _SOSCCAccountGetPublicKey _SOSCCAccountGetKeyCircleGeneration _SOSCCAccountHasPublicKey @@ -84,9 +85,9 @@ _SOSCCSetLastDepartureReason _SOSCCSetUserCredentials _SOSCCSetUserCredentialsAndDSID _SOSCCSignedOut -_SOSCCSysdiagnose _SOSCCThisDeviceIsInCircle _SOSCCTryUserCredentials +_SOSCCTryUserCredentialsAndDSID _SOSCCValidateUserPublic _SOSCCView _SOSCCViewSet @@ -99,8 +100,6 @@ _kSOSCCEngineStateManifestHashKey _kSOSCCEngineStatePeerIDKey _kSOSCCEngineStateSyncSetKey -_UserParametersDescription - _kSOSCCCircleChangedNotification _kSOSCCViewMembershipChangedNotification _kSOSCCInitialSyncChangedNotification @@ -112,10 +111,6 @@ _kSOSCCCircleOctagonKeysChangedNotification _SOSCCSetLastDepartureReason _SOSCCAccountSetToNew -_SOSCCDumpCircleInformation -_SOSCCDumpCircleKVSInformation - - // // Peer Info interfaces for SPI // @@ -123,12 +118,24 @@ _SOSCCDumpCircleKVSInformation _SOSPeerInfoApplicationVerify _SOSPeerInfoCompareByID _SOSPeerInfoCopyAsApplication +_SOSPeerInfoCopyBackupKey +_SOSPeerInfoCopyDeviceID +_SOSPeerInfoCopyEnabledViews _SOSPeerInfoCopyEncodedData +_SOSPeerInfoCopyEscrowRecord +_SOSPeerInfoCopyIDSACKModelPreference +_SOSPeerInfoCopyIDSFragmentationPreference +_SOSPeerInfoCopyIDSPreference +_SOSPeerInfoCopyOctagonSigningPublicKey +_SOSPeerInfoCopyOctagonEncryptionPublicKey _SOSPeerInfoCopyPeerGestalt _SOSPeerInfoCopyPubKey +_SOSPeerInfoCopyTransportType _SOSPeerInfoCopyWithBackupKeyUpdate _SOSPeerInfoCopyWithEscrowRecordUpdate _SOSPeerInfoCopyWithGestaltUpdate +_SOSPeerInfoCopyWithPing +_SOSPeerInfoCopyWithReplacedEscrowRecords _SOSPeerInfoCopyWithSecurityPropertyChange _SOSPeerInfoCopyWithViewsChange _SOSPeerInfoCopyTransportType @@ -137,17 +144,18 @@ _SOSPeerInfoCopyOSVersion _SOSPeerInfoCreate _SOSPeerInfoCreateCloudIdentity _SOSPeerInfoCreateCopy +_SOSPeerInfoCreateCurrentCopy _SOSPeerInfoCreateFromDER _SOSPeerInfoCreateFromData _SOSPeerInfoCreateRetirementTicket +_SOSPeerInfoCreateWithTransportAndViews +_SOSPeerInfoCopyData _SOSPeerInfoEncodeToDER +_SOSPeerInfoExpandV2Data _SOSPeerInfoGetApplicationDate _SOSPeerInfoGetAutoAcceptInfo -_SOSPeerInfoCopyBackupKey +_SOSPeerInfoGetClass _SOSPeerInfoGetDEREncodedSize -_SOSPeerInfoCopyDeviceID -_SOSPeerInfoCopyEnabledViews -_SOSPeerInfoCopyIDSPreference _SOSPeerInfoGetPeerDeviceType _SOSPeerInfoGetPeerID _SOSPeerInfoGetPeerName @@ -158,22 +166,36 @@ _SOSPeerInfoGetTypeID _SOSPeerInfoGetVersion _SOSPeerInfoHasBackupKey _SOSPeerInfoHasDeviceID +_SOSPeerInfoHasOctagonEncryptionPubKey +_SOSPeerInfoHasOctagonSigningPubKey _SOSPeerInfoInspectRetirementTicket _SOSPeerInfoIsCloudIdentity +_SOSPeerInfoIsEnabledView _SOSPeerInfoIsRetirementTicket +_SOSPeerInfoKVSOnly +_SOSPeerInfoLogState _SOSPeerInfoLookupGestaltValue _SOSPeerInfoPeerIDEqual _SOSPeerInfoRetireRetirementTicket _SOSPeerInfoSecurityPropertyStatus _SOSPeerInfoSetDeviceID +_SOSPeerInfoSetIDSACKModelPreference +_SOSPeerInfoSetIDSFragmentationPreference _SOSPeerInfoSetIDSPreference +_SOSPeerInfoSetOctagonEncryptionKey +_SOSPeerInfoSetOctagonSigningKey _SOSPeerInfoSetTransportType +_SOSPeerInfoShouldUseACKModel +_SOSPeerInfoShouldUseIDSMessageFragmentation _SOSPeerInfoShouldUseIDSTransport +_SOSPeerInfoTransportTypeIs _SOSPeerInfoUpdateDigestWithDescription _SOSPeerInfoUpdateDigestWithPublicKeyBytes _SOSPeerInfoUpgradeSignatures +_SOSPeerInfoVersionHasV2Data +_SOSPeerInfoVersionIsCurrent _SOSPeerInfoViewStatus -_SOSPeerInfoExpandV2Data +_SOSPeerInfoWithEnabledViewSet _SOSFullPeerInfoCreate @@ -195,17 +217,22 @@ _SOSCCEnableRing _SOSCCIsThisDeviceLastBackup _SOSCloudKeychainSendIDSMessage +_SOSCloudKeychainRemoveKeys +_SOSCloudKeychainRetrieveCountersFromIDSProxy _CFArrayOfSOSPeerInfosSortByID _CFSetCreateMutableForSOSPeerInfosByID +_CFSetCreateMutableForSOSPeerInfosByIDWithArray _CreateArrayOfPeerInfoWithXPCObject _CreateXPCObjectWithArrayOfPeerInfo +_kSOSPeerSetCallbacks _SOSPeerInfoArrayCreateFromDER _SOSPeerInfoArrayEncodeToDER _SOSPeerInfoArrayGetDEREncodedSize _SOSPeerInfoSetContainsIdenticalPeers _SOSPeerInfoSetCreateFromArrayDER _SOSPeerInfoSetEncodeToArrayDER +_SOSPeerInfoSetFindByID _SOSPeerInfoSetGetDEREncodedArraySize _SecCreateCFErrorWithXPCObject @@ -215,23 +242,29 @@ _SecCreateXPCObjectWithCFError // Backup Key Bag SPI // +_SOSBKSBKeyIsInKeyBag +_SOSBKSBPrefixedKeyIsInKeyBag _SOSBSKBCopyAKSBag _SOSBSKBCopyEncoded -_SOSBSKBIsDirect -_SOSBSKBGetPeers _SOSBSKBCopyRecoveryKey - -_SOSBSKBLoadLocked +_SOSBSKBCountPeers +_SOSBSKBGetPeers +_SOSBSKBIsDirect +_SOSBSKBIsGoodBackupPublic _SOSBSKBLoadAndUnlockWithDirectSecret +_SOSBSKBLoadAndUnlockWithPeerIDAndSecret _SOSBSKBLoadAndUnlockWithPeerSecret _SOSBSKBLoadAndUnlockWithWrappingSecret +_SOSBSKBLoadLocked +_SOSBSKBPeerIsInKeyBag _SOSBackupSliceKeyBagCreate _SOSBackupSliceKeyBagCreateDirect _SOSBackupSliceKeyBagCreateFromData -_SOSBackupSliceKeyBagGetTypeID +_SOSBackupSliceKeyBagCreateWithAdditionalKeys _der_decode_BackupSliceKeyBag _der_encode_BackupSliceKeyBag _der_sizeof_BackupSliceKeyBag +_bskbRkbgPrefix _SOSWrapToBackupSliceKeyBagForView _SOSBSKBHasRecoveryKey @@ -245,6 +278,23 @@ _SOSViewCopyViewSet _SOSViewsGetAllCurrent +_SOSViewHintInCKKSSystem +_SOSViewHintInSOSSystem +_SOSViewInSOSSystem +_SOSViewSetDisable +_SOSViewSetEnable +_SOSViewsDisable +_SOSViewsEnable +_SOSViewsForEachDefaultEnabledViewName +_SOSViewsGetV0BackupBagViewSet +_SOSViewsGetV0BackupViewSet +_SOSViewsGetV0SubviewSet +_SOSViewsGetV0ViewSet +_SOSViewsIsV0Subview +_SOSViewsQuery +_SOSViewsSetTestViewsSet +_SOSViewsXlateAction + // // Preferred symbols for viewHints // @@ -253,6 +303,29 @@ _SOSViewsGetAllCurrent _kSecUseSyncBubbleKeychain +// +// Deprecated viewHints (but still in headers) +// +_kSOSViewAutofillPasswords_tomb +_kSOSViewBackupBagV0_tomb +_kSOSViewHintAppleTV +_kSOSViewHintHomeKit +_kSOSViewHintPCSCloudKit +_kSOSViewHintPCSEscrow +_kSOSViewHintPCSFDE +_kSOSViewHintPCSMailDrop +_kSOSViewHintPCSMasterKey +_kSOSViewHintPCSNotes +_kSOSViewHintPCSPhotos +_kSOSViewHintPCSiCloudBackup +_kSOSViewHintPCSiCloudDrive +_kSOSViewHintPCSiMessage +_kSOSViewKeychainV0_tomb +_kSOSViewOtherSyncable_tomb +_kSOSViewSafariCreditCards_tomb +_kSOSViewWiFi_tomb +_kSOSViewiCloudIdentity_tomb + // // Exported for testing/tools (?) // @@ -275,13 +348,132 @@ _SOSCircleRequestAdmission _SOSCircleAcceptRequest _SOSCircleHasPeer +_SOSGenCountCreateFromDER +_SOSGenCountEncodeToDER +_SOSGenCountGetDEREncodedSize +_SOSGenerationCopy +_SOSGenerationCountWithDescription +_SOSGenerationCreate +_SOSGenerationCreateWithBaseline +_SOSGenerationCreateWithValue +_SOSGenerationIsOlder +_SOSGetGenerationSint + +_SOSCircleAcceptRequests +_SOSCircleAppendConcurringPeers +_SOSCircleConcordanceSign +_SOSCircleConcordanceTrust +_SOSCircleCopyAllSignatures +_SOSCircleCopyApplicants +_SOSCircleCopyConcurringPeers +_SOSCircleCopyEncodedData +_SOSCircleCopyPeerWithID +_SOSCircleCopyPeers +_SOSCircleCopyRejectedApplicant +_SOSCircleCopyRejectedApplicants +_SOSCircleCopyiCloudFullPeerInfoRef +_SOSCircleCountActivePeers +_SOSCircleCountActiveValidPeers +_SOSCircleCountApplicants +_SOSCircleCountPeers +_SOSCircleCountRejectedApplicants +_SOSCircleCountRetiredPeers +_SOSCircleCountValidSyncingPeers +_SOSCircleCreateFromDER +_SOSCircleCreateIncompatibleCircleDER +_SOSCircleEncodeToDER +_SOSCircleForEachActivePeer +_SOSCircleForEachActiveValidPeer +_SOSCircleForEachApplicant +_SOSCircleForEachPeer +_SOSCircleForEachRetiredPeer +_SOSCircleForEachValidPeer +_SOSCircleForEachValidSyncingPeer +_SOSCircleForEachiCloudIdentityPeer +_SOSCircleGenerationSign +_SOSCircleGetDEREncodedSize +_SOSCircleGetName +_SOSCircleGetNameC +_SOSCircleGetSignature +_SOSCircleGetTypeID +_SOSCircleHasActivePeer +_SOSCircleHasActivePeerWithID +_SOSCircleHasActiveValidPeer +_SOSCircleHasActiveValidPeerWithID +_SOSCircleHasApplicant +_SOSCircleHasPeerWithID +_SOSCircleHasRejectedApplicant +_SOSCircleHasValidSyncingPeer +_SOSCircleIsOlderGeneration +_SOSCircleLogState +_SOSCirclePeerSigUpdate +_SOSCircleRejectRequest +_SOSCircleRemovePeer +_SOSCircleRemovePeers +_SOSCircleRemovePeersByID +_SOSCircleRemovePeersByIDUnsigned +_SOSCircleRemoveRejectedPeer +_SOSCircleRemoveRetired +_SOSCircleRequestReadmission +_SOSCircleResetToEmpty +_SOSCircleResetToEmptyWithSameGeneration +_SOSCircleResetToOffering +_SOSCircleSetGeneration +_SOSCircleSetSignature +_SOSCircleSharedTrustedPeers +_SOSCircleSign +_SOSCircleSignOldStyleResetToOfferingCircle +_SOSCircleUpdatePeerInfo +_SOSCircleVerify +_SOSCircleVerifyPeerSigned +_SOSCircleVerifySignatureExists +_SOSCircleWithdrawRequest +_debugDumpCircle + +_SOSFullPeerInfoAddEscrowRecord +_SOSFullPeerInfoCopyDeviceKey +_SOSFullPeerInfoCopyEncodedData +_SOSFullPeerInfoCopyFullPeerInfo _SOSFullPeerInfoCopyOctagonSigningKey _SOSFullPeerInfoCopyOctagonEncryptionKey _SOSFullPeerInfoCopyOctagonPublicEncryptionKey _SOSFullPeerInfoCopyOctagonPublicSigningKey - +_SOSFullPeerInfoCopyPubKey +_SOSFullPeerInfoCreateCloudIdentity +_SOSFullPeerInfoCreateFromDER +_SOSFullPeerInfoCreateFromData +_SOSFullPeerInfoCreateWithViews +_SOSFullPeerInfoEncodeToDER +_SOSFullPeerInfoGetDEREncodedSize +_SOSFullPeerInfoHaveOctagonKeys +_SOSFullPeerInfoPing +_SOSFullPeerInfoPrivKeyExists +_SOSFullPeerInfoPromoteToRetiredAndCopy +_SOSFullPeerInfoPurgePersistentKey +_SOSFullPeerInfoReplaceEscrowRecords +_SOSFullPeerInfoSecurityPropertyStatus +_SOSFullPeerInfoUpdateBackupKey +_SOSFullPeerInfoUpdateDeviceID +_SOSFullPeerInfoUpdateGestalt +_SOSFullPeerInfoUpdateOctagonEncryptionKey +_SOSFullPeerInfoUpdateOctagonSigningKey +_SOSFullPeerInfoUpdateSecurityProperty +_SOSFullPeerInfoUpdateToCurrent +_SOSFullPeerInfoUpdateToThisPeer +_SOSFullPeerInfoUpdateTransportAckModelPreference +_SOSFullPeerInfoUpdateTransportFragmentationPreference +_SOSFullPeerInfoUpdateTransportPreference +_SOSFullPeerInfoUpdateTransportType +_SOSFullPeerInfoUpdateV2Dictionary +_SOSFullPeerInfoUpdateViews +_SOSFullPeerInfoUpgradeSignatures +_SOSFullPeerInfoValidate +_SOSFullPeerInfoViewStatus + +_SOSPiggyBackBlobCreateFromDER _SOSPiggyBackBlobCreateFromData _SOSPiggyBackBlobCopyEncodedData +_SOSPiggyBackAddToKeychain _SOSCloudKeychainRetrievePendingMessageFromProxy _SOSCloudKeychainClearAll @@ -291,8 +483,71 @@ _SOSCloudKeychainPutObjectsInCloud _SOSCloudKeychainSetItemsChangedBlock _SOSCloudKeychainSynchronizeAndWait _SOSCloudKeychainUpdateKeys +_SOSCloudCopyKVSState +_SOSCloudKeychainFlush +_SOSCloudKeychainGetIDSDeviceAvailability +_SOSCloudKeychainGetIDSDeviceID +_SOSCloudKeychainHandleUpdateMessage +_SOSCloudKeychainHasPendingKey +_SOSCloudKeychainHasPendingSyncWithPeer +_SOSCloudKeychainRequestEnsurePeerRegistration +_SOSCloudKeychainRequestPerfCounters +_SOSCloudKeychainRequestSyncWithPeers +_SOSCloudKeychainSynchronize + + +_SOSCircleKeyCopyCircleName +_SOSCircleKeyCreateWithCircle +_SOSCircleKeyCreateWithName +_SOSDebugInfoKeyCreateWithTypeName +_SOSKVSKeyGetKeyTypeAndParse +_SOSKVSKeyParse +_SOSLastKeyParametersPushedKeyCreateWithAccountGestalt +_SOSLastKeyParametersPushedKeyCreateWithPeerID +_SOSMessageKeyCopyCircleName +_SOSMessageKeyCopyFromPeerName +_SOSMessageKeyCreateFromPeerToTransport +_SOSMessageKeyCreateFromTransportToPeer +_SOSMessageKeyCreateWithCircleAndPeerInfos +_SOSMessageKeyCreateWithCircleAndPeerNames +_SOSMessageKeyCreateWithCircleNameAndPeerNames +_SOSMessageKeyCreateWithCircleNameAndTransportType +_SOSRetirementKeyCreateWithCircleAndPeer +_SOSRetirementKeyCreateWithCircleNameAndPeer +_SOSRingKeyCreateWithName +_SOSRingKeyCreateWithRingName +_kSOSKVSKeyParametersKey +_sCirclePrefix +_sDebugInfoPrefix +_sLastKeyParametersPushedPrefix +_sRetirementPrefix + + + +_CFDataCreateWithDER +_GenerateECPair +_GeneratePermanentECPair +_SOSCopyDeviceBackupPublicKey +_SOSCopyECUnwrappedData +_SOSCopyECWrappedData +_SOSCopyIDOfDataBuffer +_SOSCopyIDOfDataBufferWithLength +_SOSCopyIDOfKey +_SOSCopyIDOfKeyWithLength +_SOSCreateError +_SOSCreateErrorWithFormat +_SOSCreateErrorWithFormatAndArguments +_SOSDateCreate +_SOSErrorCreate +_SOSGenerateDeviceBackupFullKey +_SOSGetBackupKeyCurveParameters +_SOSItemsChangedCopyDescription +_SOSPerformWithDeviceBackupFullKey +_SOSPerformWithUnwrappedData +_SOSTransportMessageTypeIDSV2 +_SOSTransportMessageTypeKVS +_kSOSDSIDKey -_SOSKVSKeyGetKeyType _SOSPeerGestaltGetAnswer _SOSPeerGestaltGetName @@ -300,7 +555,7 @@ _SOSPeerGetGestalt _SecCreateCFErrorWithXPCObject _SecCreateXPCObjectWithCFError -_SecOTRPacketTypeString +_CreateXPCObjectWithCFSetRef _kSOSErrorDomain _kSecIDSErrorDomain @@ -330,6 +585,10 @@ _sPreferIDS _sPreferIDSFragmentation _sPreferIDSACKModel _sDeviceID +_sRingState +_sV2DictionaryKey +_sBackupKeyKey +_sEscrowRecord _sTransportType _sSecurityPropertiesKey _kIDSOperationType @@ -339,8 +598,27 @@ _kIDSMessageRecipientPeerID _kIDSMessageRecipientDeviceID _kIDSMessageUsesAckModel _SOSGenerationCountCopyDescription +_kIDSMessageSenderDeviceID -_SOSLogSetOutputTo +_kSOSHsaCrKeyDictionary +_SOSPeerInfoCopySerialNumber +_SOSPeerInfoCopyWithV2DictionaryUpdate +_SOSPeerInfoPackV2Data +_SOSPeerInfoSerialNumberIsSet +_SOSPeerInfoSetSerialNumber +_SOSPeerInfoSetTestSerialNumber +_SOSPeerInfoUpdateToV2 +_SOSPeerInfoV2DictionaryCopyDictionary +_SOSPeerInfoV2DictionaryForEachSetValue +_SOSPeerInfoV2DictionaryHasBoolean +_SOSPeerInfoV2DictionaryHasData +_SOSPeerInfoV2DictionaryHasSet +_SOSPeerInfoV2DictionaryHasSetContaining +_SOSPeerInfoV2DictionaryHasString +_SOSPeerInfoV2DictionaryHasStringValue +_SOSPeerInfoV2DictionaryRemoveValue +_SOSPeerInfoV2DictionarySetValue +_SOSPeerInfoV2DictionaryWithSet _der_sizeof_data_or_null _der_encode_data_or_null diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.h index d969cf45..096c0128 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.h @@ -53,7 +53,10 @@ SOSFullPeerInfoRef SOSFullPeerInfoCreateCloudIdentity(CFAllocatorRef allocator, SOSPeerInfoRef SOSFullPeerInfoGetPeerInfo(SOSFullPeerInfoRef fullPeer); SecKeyRef SOSFullPeerInfoCopyDeviceKey(SOSFullPeerInfoRef fullPeer, CFErrorRef* error); -SecKeyRef SOSFullPeerInfoCopyPubKey(SOSFullPeerInfoRef fpi, CFErrorRef *error); + +CF_RETURNS_RETAINED +SecKeyRef +SOSFullPeerInfoCopyPubKey(SOSFullPeerInfoRef fpi, CFErrorRef *error); /* octagon keys */ SecKeyRef SOSFullPeerInfoCopyOctagonPublicSigningKey(SOSFullPeerInfoRef fullPeer, CFErrorRef* error); @@ -72,8 +75,6 @@ bool SOSFullPeerInfoValidate(SOSFullPeerInfoRef peer, CFErrorRef* error); bool SOSFullPeerInfoPrivKeyExists(SOSFullPeerInfoRef peer); -bool SOSFullPeerInfoOctagonPrivKeyExists(SOSFullPeerInfoRef peer); - bool SOSFullPeerInfoUpdateGestalt(SOSFullPeerInfoRef peer, CFDictionaryRef gestalt, CFErrorRef* error); bool SOSFullPeerInfoUpdateV2Dictionary(SOSFullPeerInfoRef peer, CFDictionaryRef newv2dict, CFErrorRef* error); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.m index d698f2d5..fe1416c2 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.m @@ -102,9 +102,8 @@ static bool SOSFullPeerInfoUpdate(SOSFullPeerInfoRef fullPeerInfo, CFErrorRef *e newPeer = create_modification(fullPeerInfo->peer_info, device_key, error); require_quiet(newPeer, fail); - + CFTransferRetained(fullPeerInfo->peer_info, newPeer); - result = true; fail: @@ -140,7 +139,7 @@ SOSFullPeerInfoRef SOSFullPeerInfoCreateWithViews(CFAllocatorRef allocator, SOSFullPeerInfoRef fpi = CFTypeAllocate(SOSFullPeerInfo, struct __OpaqueSOSFullPeerInfo, allocator); CFStringRef IDSID = CFSTR(""); - CFStringRef transportType = SOSTransportMessageTypeIDSV2; + CFStringRef transportType = SOSTransportMessageTypeKVS; CFBooleanRef preferIDS = kCFBooleanFalse; CFBooleanRef preferIDSFragmentation = kCFBooleanTrue; CFBooleanRef preferACKModel = kCFBooleanTrue; @@ -175,7 +174,7 @@ SOSFullPeerInfoRef SOSFullPeerInfoCopyFullPeerInfo(SOSFullPeerInfoRef toCopy) { require_quiet(fpi, errOut); fpi->peer_info = SOSPeerInfoCreateCopy(kCFAllocatorDefault, piToCopy, NULL); require_quiet(fpi->peer_info, errOut); - fpi->key_ref = toCopy->key_ref; + fpi->key_ref = CFRetainSafe(toCopy->key_ref); CFTransferRetained(retval, fpi); errOut: @@ -252,6 +251,7 @@ CFDataRef SOSPeerInfoCopyData(SOSPeerInfoRef pi, CFErrorRef *error) exit: CFReleaseNull(query); + CFReleaseNull(pubKey); secnotice("fpi","no private key found"); return (CFDataRef)vData; @@ -360,8 +360,7 @@ static CFStringRef SOSFullPeerInfoCopyFormatDescription(CFTypeRef aObj, CFDictio bool SOSFullPeerInfoUpdateGestalt(SOSFullPeerInfoRef peer, CFDictionaryRef gestalt, CFErrorRef* error) { return SOSFullPeerInfoUpdate(peer, error, ^SOSPeerInfoRef(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error) { - return SOSPeerInfoCopyWithGestaltUpdate(kCFAllocatorDefault, peer, - gestalt, key, error); + return SOSPeerInfoCopyWithGestaltUpdate(kCFAllocatorDefault, peer, gestalt, key, error); }); } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.h index e1722f56..88f754b8 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.h @@ -37,6 +37,8 @@ __BEGIN_DECLS +#define ENABLE_IDS 0 + enum { // Public errors are first (See SOSCloudCircle) @@ -85,7 +87,6 @@ typedef enum { extern const CFStringRef SOSTransportMessageTypeIDSV2; extern const CFStringRef SOSTransportMessageTypeKVS; -extern const CFStringRef SOSTransportMessageTypeIDS; extern const CFStringRef kSOSDSIDKey; // Returns false unless errorCode is 0. @@ -165,6 +166,7 @@ extern const CFStringRef kIDSMessageUniqueID; extern const CFStringRef kIDSMessageRecipientPeerID; extern const CFStringRef kIDSMessageRecipientDeviceID; extern const CFStringRef kIDSMessageUsesAckModel; +extern const CFStringRef kIDSMessageSenderDeviceID; __END_DECLS diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.m index 4aac04d1..adcf8165 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.m @@ -58,8 +58,11 @@ const CFStringRef kIDSMessageToSendKey = CFSTR("MessageToSendKey"); const CFStringRef kIDSMessageUniqueID = CFSTR("MessageID"); const CFStringRef kIDSMessageRecipientPeerID = CFSTR("RecipientPeerID"); const CFStringRef kIDSMessageRecipientDeviceID = CFSTR("RecipientDeviceID"); +const CFStringRef kIDSMessageSenderDeviceID = CFSTR("SendersDeviceID"); + const CFStringRef kIDSMessageUsesAckModel = CFSTR("UsesAckModel"); const CFStringRef kSOSErrorDomain = CFSTR("com.apple.security.sos.error"); +const CFStringRef kSOSDSIDKey = CFSTR("AccountDSID"); const CFStringRef SOSTransportMessageTypeIDSV2 = CFSTR("IDS2.0"); const CFStringRef SOSTransportMessageTypeKVS = CFSTR("KVS"); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.h index 7dd56944..079be6dc 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.h @@ -3,7 +3,7 @@ #ifndef SOSKVSKEYS_H #define SOSKVSKEYS_H -#include "SOSCircle.h" +#include #include #include // @@ -21,7 +21,6 @@ typedef enum { kRingKey, kLastCircleKey, kLastKeyParameterKey, - kOTRConfig, kUnknownKey, } SOSKVSKeyType; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.m index 2699dfd4..58f7a78e 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.m @@ -77,7 +77,6 @@ SOSKVSKeyType SOSKVSKeyGetKeyType(CFStringRef key) { else if(CFStringHasPrefix(key, kSOSKVSAccountChangedKey)) retval = kAccountChangedKey; else if(CFStringHasPrefix(key, sDebugInfoPrefix)) retval = kDebugInfoKey; else if(CFStringHasPrefix(key, sLastKeyParametersPushedPrefix)) retval = kLastKeyParameterKey; - else if(CFStringHasPrefix(key, kSOSKVSOTRConfigVersion)) retval = kOTRConfig; else retval = kMessageKey; return retval; @@ -150,7 +149,6 @@ bool SOSKVSKeyParse(SOSKVSKeyType keyType, CFStringRef key, CFStringRef *circle, case kParametersKey: case kInitialSyncKey: case kUnknownKey: - case kOTRConfig: break; case kLastKeyParameterKey: if(from) { @@ -315,6 +313,17 @@ CFStringRef SOSRetirementKeyCreateWithCircleAndPeer(SOSCircleRef circle, CFStrin return SOSRetirementKeyCreateWithCircleNameAndPeer(SOSCircleGetName(circle), retirement_peer_name); } +static CFStringRef SOSAccountCreateCompactDescription(SOSAccount* a) { + + CFStringRef gestaltDescription = CFDictionaryCopySuperCompactDescription((__bridge CFDictionaryRef)(a.gestalt)); + + CFStringRef result = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@"), gestaltDescription); + + CFReleaseNull(gestaltDescription); + + return result; +} + //should be >KeyParameters|ourPeerID CFStringRef SOSLastKeyParametersPushedKeyCreateWithPeerID(CFStringRef peerID){ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSMessage.c b/OSX/sec/SOSCircle/SecureObjectSync/SOSMessage.c index 3e98390d..4bc308db 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSMessage.c +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSMessage.c @@ -409,8 +409,12 @@ bool SOSMessageSetManifests(SOSMessageRef message, SOSManifestRef sender, // TODO: Check at v2 encoding time // if (!sender) return (SOSMessageRef)SOSErrorCreate(kSOSErrorProcessingFailure, error, NULL, CFSTR("no sender manifest specified for SOSMessage")); message->baseDigest = CFRetainSafe(SOSManifestGetDigest(base, NULL)); + secinfo("engine", "SOSMessageSetManifests: setting base digest to %@ %zu", message->baseDigest, SOSManifestGetCount(base)); message->proposedDigest = CFRetainSafe(SOSManifestGetDigest(proposed, NULL)); + secinfo("engine", "SOSMessageSetManifests: setting proposed digest to %@ %zu", message->proposedDigest, SOSManifestGetCount(proposed)); message->senderDigest = CFRetainSafe(SOSManifestGetDigest(sender, NULL)); + secinfo("engine", "SOSMessageSetManifests: setting sender digest to %@ %zu", message->senderDigest, SOSManifestGetCount(sender)); + if (includeManifestDeltas) { SOSManifestRef additions = NULL; ok = SOSManifestDiff(base, proposed, &message->removals, &additions, error); @@ -641,6 +645,7 @@ static size_t der_sizeof_manifest_digest_message(SOSMessageRef message, CFErrorR } static uint8_t *der_encode_manifest_digest_message(SOSMessageRef message, CFErrorRef *error, const uint8_t *der, uint8_t *der_end) { + secinfo("engine", "der_encode_manifest_digest_message: encoded sender digest as %@", message->senderDigest); return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der, ccder_encode_uint64(SOSManifestDigestMessageType, der, ccder_encode_raw_octet_string(SOSDigestSize, CFDataGetBytePtr(message->senderDigest), der, der_end))); @@ -658,6 +663,7 @@ static size_t der_sizeof_manifest_message(SOSMessageRef message, CFErrorRef *err } static uint8_t *der_encode_manifest_message(SOSMessageRef message, CFErrorRef *error, const uint8_t *der, uint8_t *der_end) { + secinfo("engine", "der_encode_manifest_message: encoded message additions as (%zu, %@)", SOSManifestGetCount(message->additions), SOSManifestGetDigest(message->additions, NULL)); return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der, ccder_encode_uint64(SOSManifestMessageType, der, der_encode_implicit_data(CCDER_OCTET_STRING, SOSManifestGetData(message->additions), der, der_end))); @@ -680,6 +686,7 @@ static size_t der_sizeof_manifest_and_objects_message(SOSMessageRef message, CFE } static uint8_t *der_encode_manifest_and_objects_message(SOSMessageRef message, CFErrorRef *error, const uint8_t *der, uint8_t *der_end) { + secinfo("engine", "der_encode_manifest_and_objects_message: encoded base digest as %@", message->baseDigest); return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der, ccder_encode_uint64(SOSManifestDeltaAndObjectsMessageType, der, ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der, @@ -996,8 +1003,14 @@ static const uint8_t *der_decode_message_header(SOSMessageRef message, CFErrorRe message->flags = flags[0]; der = der_decode_implicit_data(CCDER_OCTET_STRING, &message->senderDigest, der, der_end); + secinfo("engine", "der_decode_message_header: decoded sender digest as %@", message->senderDigest); + der = der_decode_optional_implicit_data(0 | CCDER_CONTEXT_SPECIFIC, &message->baseDigest, der, der_end); + secinfo("engine", "der_decode_message_header: decoded base digest as %@", message->baseDigest); + der = der_decode_optional_implicit_data(1 | CCDER_CONTEXT_SPECIFIC, &message->proposedDigest, der, der_end); + secinfo("engine", "der_decode_message_header: decoded proposed digest as %@", message->proposedDigest); + return der; } @@ -1013,6 +1026,8 @@ der_decode_manifest_and_objects_message(SOSMessageRef message, return NULL; } der = der_decode_implicit_data(CCDER_OCTET_STRING, &message->baseDigest, der, body_end); + secinfo("engine", "der_decode_manifest_and_objects_message: decoded base digest as %@", message->baseDigest); + der = der_decode_deltas_body(message, error, der, body_end); // Remember a pointer into message->der where objects starts. der = message->objectsDer = ccder_decode_tl(CCDER_CONSTRUCTED_SEQUENCE, &objects_len, der, body_end); @@ -1028,6 +1043,7 @@ static const uint8_t *der_decode_v0_message_body(SOSMessageRef message, CFErrorR case SOSManifestDigestMessageType: { der = der_decode_implicit_data(CCDER_OCTET_STRING, &message->senderDigest, der, der_end); + secinfo("engine", "der_decode_v0_message_body: received a DigestMessage with sender digest: %@", message->senderDigest); break; } case SOSManifestMessageType: @@ -1039,6 +1055,7 @@ static const uint8_t *der_decode_v0_message_body(SOSMessageRef message, CFErrorR secwarning("%td trailing bytes after deltas DER", der_end - der); } message->additions = SOSManifestCreateWithData(manifestBody, error); + secinfo("engine", "der_decode_v0_message_body: received a ManifestMessage with (%zu, %@)", SOSManifestGetCount(message->additions), SOSManifestGetDigest(message->additions, NULL)); CFReleaseSafe(manifestBody); break; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeer.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeer.m index 0251c73e..8c01228d 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeer.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeer.m @@ -649,6 +649,7 @@ static void SOSPeerDestroy(CFTypeRef cf) { CFReleaseNull(peer->localManifests); CFReleaseNull(peer->otrTimers); CFReleaseNull(peer->limiter); + CFReleaseNull(peer->_keyBag); } bool SOSPeerDidConnect(SOSPeerRef peer) { @@ -846,7 +847,7 @@ bool SOSPeerTimerForPeerExist(SOSPeerRef peer){ return timer ? true : false; } void SOSPeerSetOTRTimer(SOSPeerRef peer, dispatch_source_t timer){ - NSMutableDictionary* timers = (__bridge NSMutableDictionary*)peer->otrTimers; + NSMutableDictionary* timers = (NSMutableDictionary*)CFBridgingRelease(peer->otrTimers); if(!timers) timers = [[NSMutableDictionary alloc]init]; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerCoder.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerCoder.h index 20654ffd..302b117f 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerCoder.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerCoder.h @@ -33,12 +33,10 @@ enum SOSCoderUnwrapStatus{ SOSCoderUnwrapHandled = 2 }; -bool SOSPeerCoderSendMessageIfNeeded(SOSAccount* account, SOSEngineRef engine, SOSTransactionRef txn, SOSPeerRef peer, SOSCoderRef coder, CFDataRef *message_to_send, CFStringRef peer_id, CFMutableArrayRef *attributeList, SOSEnginePeerMessageSentBlock *sent, CFErrorRef *error); +bool SOSPeerCoderSendMessageIfNeeded(SOSAccount* account, SOSEngineRef engine, SOSTransactionRef txn, SOSPeerRef peer, SOSCoderRef coder, CFDataRef *message_to_send, CFStringRef peer_id, CFMutableArrayRef *attributeList, SOSEnginePeerMessageSentCallback **sentCallback, CFErrorRef *error); enum SOSCoderUnwrapStatus SOSPeerHandleCoderMessage(SOSPeerRef peer, SOSCoderRef coder, CFStringRef peer_id, CFDataRef codedMessage, CFDataRef *decodedMessage, bool *forceSave, CFErrorRef *error); -bool SOSPeerSendMessageIfNeeded(SOSPeerRef peer, CFDataRef *message, CFDataRef *message_to_send, SOSCoderRef *coder, CFStringRef circle_id, CFStringRef peer_id, SOSEnginePeerMessageSentBlock *sent, CFErrorRef *error); - -void SOSPeerCoderConsume(SOSEnginePeerMessageSentBlock *sent, bool ok); +bool SOSPeerSendMessageIfNeeded(SOSPeerRef peer, CFDataRef *message, CFDataRef *message_to_send, SOSCoderRef *coder, CFStringRef circle_id, CFStringRef peer_id, SOSEnginePeerMessageSentCallback **sentCallback, CFErrorRef *error); #endif diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerCoder.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerCoder.m index 421f9262..863ec788 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerCoder.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerCoder.m @@ -40,11 +40,6 @@ #include #include "SOSInternal.h" -void SOSPeerCoderConsume(SOSEnginePeerMessageSentBlock *sent, bool ok) { - if (*sent) - (*sent)(ok); -} - enum SOSCoderUnwrapStatus SOSPeerHandleCoderMessage(SOSPeerRef peer, SOSCoderRef coder, CFStringRef peer_id, CFDataRef codedMessage, CFDataRef *decodedMessage, bool *forceSave, CFErrorRef *error) { enum SOSCoderUnwrapStatus result = SOSCoderUnwrapError; @@ -112,7 +107,7 @@ enum SOSCoderUnwrapStatus SOSPeerHandleCoderMessage(SOSPeerRef peer, SOSCoderRef xit: return result; } -bool SOSPeerCoderSendMessageIfNeeded(SOSAccount* account, SOSEngineRef engine, SOSTransactionRef txn, SOSPeerRef peer, SOSCoderRef coder, CFDataRef *message_to_send, CFStringRef peer_id, CFMutableArrayRef *attributeList, SOSEnginePeerMessageSentBlock *sent, CFErrorRef *error) { +bool SOSPeerCoderSendMessageIfNeeded(SOSAccount* account, SOSEngineRef engine, SOSTransactionRef txn, SOSPeerRef peer, SOSCoderRef coder, CFDataRef *message_to_send, CFStringRef peer_id, CFMutableArrayRef *attributeList, SOSEnginePeerMessageSentCallback **sentCallback, CFErrorRef *error) { bool ok = false; secnotice("transport", "coder state: %@", coder); require_action_quiet(coder, xit, secerror("%@ getCoder: %@", peer_id, error ? *error : NULL)); @@ -120,7 +115,7 @@ bool SOSPeerCoderSendMessageIfNeeded(SOSAccount* account, SOSEngineRef engine, S if (SOSCoderCanWrap(coder)) { secinfo("transport", "%@ Coder can wrap, getting message from engine", peer_id); CFMutableDataRef codedMessage = NULL; - CFDataRef message = SOSEngineCreateMessage_locked(engine, txn, peer, attributeList, error, sent); + CFDataRef message = SOSEngineCreateMessage_locked(engine, txn, peer, attributeList, error, sentCallback); if (!message) { secnotice("transport", "%@ SOSEngineCreateMessage_locked failed: %@", peer_id, *error); } else if (CFDataGetLength(message) || SOSPeerMustSendMessage(peer)) { @@ -143,10 +138,18 @@ bool SOSPeerCoderSendMessageIfNeeded(SOSAccount* account, SOSEngineRef engine, S *message_to_send = SOSCoderCopyPendingResponse(coder); SOSEngineSetCodersNeedSaving(engine, true); secinfo("transport", "%@ negotiating, %@", peer_id, (message_to_send && *message_to_send) ? CFSTR("sending negotiation message.") : CFSTR("waiting for negotiation message.")); - *sent = ^(bool wasSent){ - if (wasSent) - SOSCoderConsumeResponse(coder); - }; + + SOSEnginePeerMessageSentCallback* pmsc = malloc(sizeof(SOSEnginePeerMessageSentCallback)); + memset(pmsc, 0, sizeof(SOSEnginePeerMessageSentCallback)); + + pmsc->coder = CFRetainSafe(coder); + SOSEngineMessageCallbackSetCallback(pmsc, ^(bool wasSent){ + if (wasSent) { + SOSCoderConsumeResponse(pmsc->coder); + } + }); + + *sentCallback = pmsc; ok = true; } /*if coder state is in awaiting for message, then set a timer and restart if failure*/ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.h index 6bb92ea0..c25d8eb3 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.h @@ -193,7 +193,7 @@ bool SOSPeerInfoIsRetirementTicket(SOSPeerInfoRef pi); bool SOSPeerInfoIsCloudIdentity(SOSPeerInfoRef pi); -SOSPeerInfoRef SOSPeerInfoUpgradeSignatures(CFAllocatorRef allocator, SecKeyRef privKey, SecKeyRef perKey, SOSPeerInfoRef peer, CFErrorRef *error); +CF_RETURNS_RETAINED SOSPeerInfoRef SOSPeerInfoUpgradeSignatures(CFAllocatorRef allocator, SecKeyRef privKey, SecKeyRef perKey, SOSPeerInfoRef peer, CFErrorRef *error); SOSViewResultCode SOSPeerInfoViewStatus(SOSPeerInfoRef pi, CFStringRef view, CFErrorRef *error); @@ -211,7 +211,7 @@ SOSPeerInfoRef SOSPeerInfoSetIDSPreference(CFAllocatorRef allocator, SOSPeerInfo CFBooleanRef SOSPeerInfoCopyIDSFragmentationPreference(SOSPeerInfoRef peer); CFBooleanRef SOSPeerInfoCopyIDSACKModelPreference(SOSPeerInfoRef peer); SOSPeerInfoRef SOSPeerInfoSetIDSFragmentationPreference(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFBooleanRef preference, SecKeyRef signingKey, CFErrorRef *error); -SOSPeerInfoRef SOSPeerInfoSetIDSACKModelPreference(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFBooleanRef preference, SecKeyRef signingKey, CFErrorRef *error); +SOSPeerInfoRef CF_RETURNS_RETAINED SOSPeerInfoSetIDSACKModelPreference(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFBooleanRef preference, SecKeyRef signingKey, CFErrorRef *error); CFStringRef SOSPeerInfoCopyTransportType(SOSPeerInfoRef peer); bool SOSPeerInfoTransportTypeIs(SOSPeerInfoRef pi, CFStringRef transportType); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.m index b1b72e75..8a2dbf3a 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.m @@ -311,11 +311,8 @@ static SOSPeerInfoRef SOSPeerInfoCreate_Internal(CFAllocatorRef allocator, description_modifier(pi->description); - pi->peerID = SOSCopyIDOfKey(publicKey, error); - CFReleaseNull(publicKey); - require_quiet(pi->peerID, exit); // ================ V2 Additions Start @@ -343,6 +340,7 @@ static SOSPeerInfoRef SOSPeerInfoCreate_Internal(CFAllocatorRef allocator, exit: CFReleaseNull(versionNumber); + CFReleaseNull(publicKey); CFReleaseNull(publicBytes); CFReleaseNull(octagonPeerSigningPublicBytes); CFReleaseNull(octagonPeerEncryptionPublicBytes); @@ -797,16 +795,28 @@ bool SOSPeerInfoUpdateDigestWithDescription(SOSPeerInfoRef peer, const struct cc ccdigest_ctx_t ctx, CFErrorRef *error) { if(SOSPeerInfoVersionHasV2Data(peer)) SOSPeerInfoPackV2Data(peer); size_t description_size = der_sizeof_plist(peer->description, error); - uint8_t data_begin[description_size]; - uint8_t *data_end = data_begin + description_size; - uint8_t *encoded = der_encode_plist(peer->description, error, data_begin, data_end); + if (description_size == 0) { + SOSCreateErrorWithFormat(kSOSErrorEncodeFailure, NULL, error, NULL, CFSTR("Description length failed")); + return false; + } + + uint8_t * data = malloc(description_size); + if (data == NULL) { + SOSCreateErrorWithFormat(kSOSErrorEncodeFailure, NULL, error, NULL, CFSTR("Description alloc failed")); + return false; + } + uint8_t *data_end = data + description_size; + uint8_t *encoded = der_encode_plist(peer->description, error, data, data_end); if(!encoded) { + free(data); SOSCreateErrorWithFormat(kSOSErrorEncodeFailure, NULL, error, NULL, CFSTR("Description encode failed")); return false; } - ccdigest_update(di, ctx, description_size, data_begin); + ccdigest_update(di, ctx, description_size, data); + + free(data); return true; } @@ -1025,7 +1035,7 @@ CFBooleanRef SOSPeerInfoCopyIDSACKModelPreference(SOSPeerInfoRef peer){ return (preference ? preference : CFRetain(kCFBooleanFalse)); } -SOSPeerInfoRef SOSPeerInfoSetIDSFragmentationPreference(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFBooleanRef preference, SecKeyRef signingKey, CFErrorRef *error){ +SOSPeerInfoRef CF_RETURNS_RETAINED SOSPeerInfoSetIDSFragmentationPreference(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFBooleanRef preference, SecKeyRef signingKey, CFErrorRef *error){ return SOSPeerInfoCopyWithModification(allocator, toCopy, signingKey, error, ^bool(SOSPeerInfoRef peerToModify, CFErrorRef *error) { SOSPeerInfoV2DictionarySetValue(peerToModify, sPreferIDSFragmentation, preference); @@ -1033,7 +1043,7 @@ SOSPeerInfoRef SOSPeerInfoSetIDSFragmentationPreference(CFAllocatorRef allocator }); } -SOSPeerInfoRef SOSPeerInfoSetIDSACKModelPreference(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFBooleanRef preference, SecKeyRef signingKey, CFErrorRef *error){ +SOSPeerInfoRef CF_RETURNS_RETAINED SOSPeerInfoSetIDSACKModelPreference(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, CFBooleanRef preference, SecKeyRef signingKey, CFErrorRef *error){ return SOSPeerInfoCopyWithModification(allocator, toCopy, signingKey, error, ^bool(SOSPeerInfoRef peerToModify, CFErrorRef *error) { SOSPeerInfoV2DictionarySetValue(peerToModify, sPreferIDSACKModel, preference); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoPriv.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoPriv.h index c5cb8390..28b34561 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoPriv.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoPriv.h @@ -27,7 +27,7 @@ struct __OpaqueSOSPeerInfo { CFMutableDictionaryRef v2Dictionary; }; -SOSPeerInfoRef SOSPeerInfoAllocate(CFAllocatorRef allocator); +CF_RETURNS_RETAINED SOSPeerInfoRef SOSPeerInfoAllocate(CFAllocatorRef allocator); bool SOSPeerInfoSign(SecKeyRef privKey, SOSPeerInfoRef peer, CFErrorRef *error); bool SOSPeerInfoVerify(SOSPeerInfoRef peer, CFErrorRef *error); void SOSPeerInfoSetVersionNumber(SOSPeerInfoRef pi, int version); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.m index 4dd77fdc..dbdf0934 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.m @@ -110,7 +110,6 @@ static CFDataRef SOSPeerInfoGetV2Data(SOSPeerInfoRef pi) { } static CFMutableDictionaryRef SOSCreateDictionaryFromDER(CFDataRef v2Data, CFErrorRef *error) { - CFMutableDictionaryRef retval = NULL; CFPropertyListRef pl = NULL; if(!v2Data) { @@ -137,26 +136,33 @@ static CFMutableDictionaryRef SOSCreateDictionaryFromDER(CFDataRef v2Data, CFErr CFStringRef description = CFCopyTypeIDDescription(CFGetTypeID(pl)); SOSCreateErrorWithFormat(kSOSErrorUnexpectedType, NULL, error, NULL, CFSTR("Expected dictionary got %@"), description); - CFReleaseSafe(description); - CFReleaseSafe(pl); + CFReleaseNull(description); + CFReleaseNull(pl); goto fail; } - retval = (CFMutableDictionaryRef) pl; - return retval; - + return (CFMutableDictionaryRef) pl; + fail: - CFReleaseNull(retval); + CFReleaseNull(pl); return NULL; } static CFDataRef SOSCreateDERFromDictionary(CFDictionaryRef di, CFErrorRef *error) { size_t size = der_sizeof_plist(di, error); - if (size == 0) return NULL; - uint8_t der[size]; - der_encode_plist(di, error, der, der+size); - return CFDataCreate(kCFAllocatorDefault, der, size); + if (size == 0) { + return NULL; + } + uint8_t *der = malloc(size); + if (der == NULL) { + return NULL; + } + if (der_encode_plist(di, error, der, der+size) == NULL) { + free(der); + return NULL; + } + return CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, der, size, kCFAllocatorMalloc); } @@ -173,7 +179,7 @@ bool SOSPeerInfoUpdateToV2(SOSPeerInfoRef pi, CFErrorRef *error) { CFDictionaryAddValue(v2Dictionary, sSecurityPropertiesKey, secproperties); CFDictionaryAddValue(v2Dictionary, sDeviceID, CFSTR("")); - CFDictionaryAddValue(v2Dictionary, sTransportType, SOSTransportMessageTypeIDSV2); + CFDictionaryAddValue(v2Dictionary, sTransportType, SOSTransportMessageTypeKVS); CFDictionaryAddValue(v2Dictionary, sPreferIDS, kCFBooleanFalse); CFDictionaryAddValue(v2Dictionary, sPreferIDSFragmentation, kCFBooleanTrue); CFDictionaryAddValue(v2Dictionary, sPreferIDSACKModel, kCFBooleanTrue); @@ -188,6 +194,7 @@ out: CFReleaseNull(views); CFReleaseNull(v2data); CFReleaseNull(v2Dictionary); + CFReleaseNull(secproperties); return retval; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerOTRTimer.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerOTRTimer.h index 8dc9a775..df65540c 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerOTRTimer.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerOTRTimer.h @@ -9,9 +9,6 @@ void SOSPeerOTRTimerFired(SOSAccount* account, SOSPeerRef peer, SOSEngineRef eng int SOSPeerOTRTimerTimeoutValue(SOSAccount* account, SOSPeerRef peer); void SOSPeerOTRTimerSetupAwaitingTimer(SOSAccount* account, SOSPeerRef peer, SOSEngineRef engine, SOSCoderRef coder); -//KVS global config -void SOSPeerOTRTimerCreateKVSConfigDict(SOSAccount* account, CFNumberRef timeout, CFStringRef peerid); - //functions to handle max retry counter void SOSPeerOTRTimerIncreaseOTRNegotiationRetryCount(SOSAccount* account, NSString* peerid); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerOTRTimer.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerOTRTimer.m index 0cbb885b..03ca8a6c 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerOTRTimer.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerOTRTimer.m @@ -25,10 +25,6 @@ //AGGD NSString* const SecSOSAggdMaxRenegotiation = @"com.apple.security.sos.otrrenegotiationmaxretries"; - -static const CFStringRef OTRTimeoutsPerPeer = CFSTR("OTRTimeoutsPerPeer"); -static const CFStringRef OTRConfigVersion = CFSTR("OTRConfigVersion"); - __unused static int initialOTRTimeoutValue = 60; //best round trip time in KVS plus extra for good measure static int maxRetryCount = 7; //max number of times to attempt restarting OTR negotiation @@ -118,240 +114,21 @@ void SOSPeerOTRTimerIncreaseOTRNegotiationRetryCount(SOSAccount* account, NSStri SOSAccountSetValue(account, kSOSAccountRenegotiationRetryCount, (__bridge CFMutableDictionaryRef)attemptsPerPeer, NULL); } -static CFNumberRef SOSPeerOTRTimerCopyConfigVersion(SOSAccount* account) -{ - uint64_t v = 0; - CFNumberRef versionFromAccount = NULL; - CFNumberRef version = (CFNumberRef)SOSAccountGetValue(account, OTRConfigVersion, NULL); - - if(!version){ - versionFromAccount = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &v); - SOSAccountSetValue(account, OTRConfigVersion, versionFromAccount, NULL); - } - else{ - versionFromAccount = CFRetainSafe(version); - } - return versionFromAccount; -} - -void SOSPeerOTRTimerCreateKVSConfigDict(SOSAccount* account, CFNumberRef timeout, CFStringRef peerid) -{ - CFMutableDictionaryRef peerToTimeout = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); - CFDictionaryAddValue(peerToTimeout, peerid, timeout); - - CFNumberRef versionFromAccount = SOSPeerOTRTimerCopyConfigVersion(account); - - CFMutableDictionaryRef peerTimeOutsAndVersion = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); - CFDictionaryAddValue(peerTimeOutsAndVersion, OTRTimeoutsPerPeer, peerToTimeout); - CFDictionaryAddValue(peerTimeOutsAndVersion, OTRConfigVersion, versionFromAccount); - - CFMutableDictionaryRef myPeerChanges = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); - CFStringRef myPeerID = (__bridge CFStringRef) account.peerID; - CFDictionaryAddValue(myPeerChanges, myPeerID, peerTimeOutsAndVersion); - - CFMutableDictionaryRef otrConfig = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); - CFDictionaryAddValue(otrConfig, kSOSKVSOTRConfigVersion, myPeerChanges); - - SOSCloudKeychainPutObjectsInCloud(otrConfig, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(CFDictionaryRef returnedValues __unused, CFErrorRef block_error) { - if (block_error) { - secerror("Error putting: %@", block_error); - } - }); - secnotice("kvsconfig", "submitting config to KVS: %@", otrConfig); - CFReleaseNull(myPeerChanges); - CFReleaseNull(peerToTimeout); - CFReleaseNull(versionFromAccount); - CFReleaseNull(otrConfig); -} - -//grab existing key from KVS -__unused __unused static CFDictionaryRef SOSPeerOTRTimerCopyConfigFromKVS() -{ - CFErrorRef error = NULL; - __block CFTypeRef object = NULL; - - dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0); - const uint64_t maxTimeToWaitInSeconds = 5ull * NSEC_PER_SEC; - - dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, maxTimeToWaitInSeconds); - - SOSCloudKeychainGetAllObjectsFromCloud(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(CFDictionaryRef returnedValues, CFErrorRef block_error) { - secnotice("otrtimer", "SOSCloudKeychainGetObjectsFromCloud returned: %@", returnedValues); - object = returnedValues; - if (object) - CFRetain(object); - if (error) - { - secerror("SOSCloudKeychainGetObjectsFromCloud returned error: %@", error); - } - secnotice("otrtimer", "SOSCloudKeychainGetObjectsFromCloud block exit: %@", object); - dispatch_semaphore_signal(waitSemaphore); - }); - - dispatch_semaphore_wait(waitSemaphore, finishTime); - if (object && (CFGetTypeID(object) == CFNullGetTypeID())) // return a NULL instead of a CFNull - { - CFRelease(object); - object = NULL; - return NULL; - } - if(isDictionary(object)) - { - return CFRetainSafe((CFDictionaryRef)object); - } - return NULL; -} - -__unused static bool SOSPeerOTRTimerShouldWriteConfig(CFDictionaryRef config, CFStringRef myID, CFStringRef peerid, CFNumberRef currentConfigVersion, CFNumberRef localTimeout) -{ - bool result = true; - secnotice("otrtimer", "grabbed config from KVS: %@", config); - CFDictionaryRef myPeerConfigSettings = NULL; - CFNumberRef versionFromKVS = NULL; - CFDictionaryRef peerToTimeouts = NULL; - CFNumberRef timeoutInKVS = NULL; - CFDictionaryRef otrConfig = NULL; - - require_action_quiet(currentConfigVersion, fail, secnotice("otrtimer","current config version is null")); - require_action_quiet(localTimeout, fail, secnotice("otrtimer", "local timeout is null")); - - otrConfig = CFDictionaryGetValue(config, kSOSKVSOTRConfigVersion); - require_action_quiet(otrConfig, fail, secnotice("otrtimer","otr config does not exist")); - - myPeerConfigSettings = CFDictionaryGetValue(otrConfig, myID); - require_action_quiet(myPeerConfigSettings, fail, secnotice("otrtimer","my peer config settings dictionary is null")); - - versionFromKVS = CFDictionaryGetValue(myPeerConfigSettings, OTRConfigVersion); - require_action_quiet(versionFromKVS, fail, secnotice("otrtimer", "version from KVS is null")); - - peerToTimeouts = CFDictionaryGetValue(myPeerConfigSettings, OTRTimeoutsPerPeer); - require_action_quiet(peerToTimeouts, fail, secnotice("otrtimer", "dictionary of peerids and timeout values is null")); - - timeoutInKVS = CFDictionaryGetValue(peerToTimeouts, peerid); - require_action_quiet(timeoutInKVS, fail, secnotice("otrtimer", "timeout value from kvs is null")); - - if(kCFCompareEqualTo == CFNumberCompare(currentConfigVersion, versionFromKVS, NULL) && - (CFNumberCompare(timeoutInKVS, localTimeout, NULL) == kCFCompareEqualTo)){ - secnotice("otrtimer", "versions match, can write new config"); - }else if(CFNumberCompare(versionFromKVS, currentConfigVersion, NULL) == kCFCompareGreaterThan){ - result = false; - secnotice("otrtimer", "versions do not match, cannot write a new config"); - }else{ - secnotice("otrtimer", "config versions match, going to write current configuration of peerids to timeouts to KVS"); - } - -fail: - return result; - -} - -__unused static CFNumberRef SOSPeerOTRTimerCopyOTRConfigVersionFromAccount(SOSAccount* account) -{ - CFNumberRef version = SOSAccountGetValue(account, OTRConfigVersion, NULL); - if(!version){ - uint64_t v = 0; - version = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &v); - SOSAccountSetValue(account, OTRConfigVersion, version, NULL); - }else{ - return CFRetainSafe(version); - } - - return version; -} - -__unused static bool SOSPeerOTRTimerShouldUseTimeoutValueFromKVS(CFDictionaryRef otrConfigFromKVS, CFStringRef myID, CFNumberRef localConfigVersion){ - bool shouldUseTimeoutFromKVS = false; - CFDictionaryRef otrConfig = NULL; - CFDictionaryRef myPeerConfigSettings = NULL; - CFNumberRef versionFromKVS = NULL; - - require_action_quiet(otrConfigFromKVS, xit, secnotice("otrtimer", "configuration file from kvs does not exist")); - - otrConfig = CFDictionaryGetValue(otrConfigFromKVS, kSOSKVSOTRConfigVersion); - require_action_quiet(otrConfig, xit, secnotice("otrtimer", "configuration file from kvs does not exist")); - - myPeerConfigSettings = CFDictionaryGetValue(otrConfig, myID); - require_action_quiet(myPeerConfigSettings, xit, secnotice("otrtimer", "configuration file from kvs does not exist")); - - versionFromKVS = CFDictionaryGetValue(myPeerConfigSettings, OTRConfigVersion); - require_action_quiet(versionFromKVS && (CFGetTypeID(versionFromKVS) != CFNullGetTypeID()), xit, secnotice("otrtimer", "configuration file from kvs does not exist")); - - if(CFNumberCompare(versionFromKVS, localConfigVersion, NULL) == kCFCompareGreaterThan){ - secnotice("otrtimer", "should use timeout from kvs"); - shouldUseTimeoutFromKVS = true; - } - -xit: - return shouldUseTimeoutFromKVS; -} - -__unused static CFNumberRef SOSPeerOTRTimerTimeoutFromKVS(CFDictionaryRef otrConfigFromKVS, CFStringRef myID, CFStringRef peerID) -{ - CFNumberRef timeout = NULL; - CFDictionaryRef otrConfig = NULL; - CFDictionaryRef myPeerConfigSettings = NULL; - CFDictionaryRef peerToTimeoutDictionary = NULL; - - require_action_quiet(otrConfigFromKVS, xit, secnotice("otrtimer", "configuration file from kvs does not exist")); - - otrConfig = CFDictionaryGetValue(otrConfigFromKVS, kSOSKVSOTRConfigVersion); - require_action_quiet(otrConfig, xit, secnotice("otrtimer", "configuration file from kvs does not exist")); - - myPeerConfigSettings = CFDictionaryGetValue(otrConfig, myID); - require_action_quiet(myPeerConfigSettings, xit, secnotice("otrtimer", "configuration file from kvs does not exist")); - - peerToTimeoutDictionary = CFDictionaryGetValue(myPeerConfigSettings, OTRTimeoutsPerPeer); - require_action_quiet(peerToTimeoutDictionary, xit, secnotice("otrtimer", "configuration file from kvs does not exist")); - - timeout = CFDictionaryGetValue(peerToTimeoutDictionary, peerID); -xit: - return timeout; -} - int SOSPeerOTRTimerTimeoutValue(SOSAccount* account, SOSPeerRef peer) { CFErrorRef error = NULL; - //bool shouldWriteConfig = true; - //bool shouldUseTimeoutFromKVS = false; int timeoutIntValue = 0; - - //CFDictionaryRef configFromKVS = SOSPeerOTRTimerCopyConfigFromKVS(); - - //CFNumberRef configVersion = SOSPeerOTRTimerCopyOTRConfigVersionFromAccount(account); - //shouldUseTimeoutFromKVS = SOSPeerOTRTimerShouldUseTimeoutValueFromKVS(configFromKVS, (__bridge CFStringRef)account.peerID,configVersion); - //CFReleaseNull(configVersion); - - //if(shouldUseTimeoutFromKVS){ - // secnotice("otrtimer", "using timeout from kvs"); - //CFNumberRef timeoutFromKVS = SOSPeerOTRTimerTimeoutFromKVS(configFromKVS, (__bridge CFStringRef)account.peerID, //SOSPeerGetID(peer)); - //CFReleaseNull(configFromKVS); - //return [(__bridge NSNumber*)timeoutFromKVS intValue]; - // } - + CFMutableDictionaryRef timeouts = (CFMutableDictionaryRef)asDictionary(SOSAccountGetValue(account, kSOSAccountPeerNegotiationTimeouts, &error), NULL); require_action_quiet(timeouts, xit, secnotice("otrtimer","deadline value not available yet")); - + CFNumberRef timeout = CFDictionaryGetValue(timeouts, SOSPeerGetID(peer)); require_action_quiet(timeout, xit, secnotice("otrtimer","deadline value not available yet")); - + secnotice("otrtimer", "decided to wait %d before restarting negotiation", [(__bridge NSNumber*)timeout intValue]); timeoutIntValue = [(__bridge NSNumber*)timeout intValue]; - - //CFNumberRef localConfigVersion = SOSPeerOTRTimerCopyOTRConfigVersionFromAccount(account); - /* - if(localConfigVersion){ - shouldWriteConfig = SOSPeerOTRTimerShouldWriteConfig(configFromKVS, (__bridge CFStringRef)account.peerID, SOSPeerGetID(peer), localConfigVersion, timeout); - } - - if(shouldWriteConfig) - SOSPeerOTRTimerCreateKVSConfigDict(account, timeout, SOSPeerGetID(peer)); - */ - + xit: - // CFReleaseNull(configVersion); - //CFReleaseNull(localConfigVersion); - //CFReleaseNull(configFromKVS); - return timeoutIntValue; } @@ -360,7 +137,7 @@ void SOSPeerOTRTimerSetupAwaitingTimer(SOSAccount* account, SOSPeerRef peer, SOS //check which timeout value to use int timeoutValue = SOSPeerOTRTimerTimeoutValue(account, peer); CFStringRef peerid = CFRetainSafe(SOSPeerGetID(peer)); - + secnotice("otrtimer", "setting timer for peer: %@", peer); __block dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, timeoutValue * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, 0); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerRateLimiter.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerRateLimiter.m index 22f4bba7..c67b3fd3 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerRateLimiter.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerRateLimiter.m @@ -54,7 +54,7 @@ property\ accessGroup\ capacity\ - 20\ + 50\ rate\ 900\ badness\ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPiggyback.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSPiggyback.m index 23377ed9..237a5224 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPiggyback.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSPiggyback.m @@ -392,9 +392,9 @@ SOSPiggyBackBlobCreateFromDER(SOSGenCountRef *retGencount, errOut: if(!res) { CFReleaseNull(gencount); - CFReleaseNull(publicBytes); CFReleaseNull(signature); } + CFReleaseNull(publicBytes); return res; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRecoveryKeyBag.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSRecoveryKeyBag.m index 6883a312..e0ceca74 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSRecoveryKeyBag.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSRecoveryKeyBag.m @@ -171,6 +171,8 @@ SOSRecoveryKeyBagRef SOSRecoveryKeyBagCreateForAccount(CFAllocatorRef allocator, require_action_quiet(account, errOut, SOSCreateError(kSOSErrorEncodeFailure, CFSTR("Null Account Object"), NULL, error)); CFStringRef dsid = NULL; dsid = asString(SOSAccountGetValue((__bridge SOSAccount*)account, kSOSDSIDKey, NULL), error); + require_action_quiet(dsid, errOut, SOSCreateError(kSOSErrorEncodeFailure, CFSTR("Couldn't get dsid for recovery keybag components"), NULL, error)); + gencount = SOSGenerationCreate(); require_action_quiet(pubData && dsid && gencount, errOut, SOSCreateError(kSOSErrorEncodeFailure, CFSTR("Couldn't get recovery keybag components"), NULL, error)); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingBasic.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSRingBasic.m index 673eddae..e92abdf9 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingBasic.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSRingBasic.m @@ -67,8 +67,8 @@ bool SOSRingApply_Basic(SOSRingRef ring, SecKeyRef user_pubkey, SOSFullPeerInfoR SOSRingAddPeerID(ring, myPeerID) && SOSRingSetLastModifier(ring, myPeerID) && SOSRingGenerationSign_Internal(ring, priv, error); - CFReleaseNull(priv); errOut: + CFReleaseNull(priv); return retval; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingUtils.c b/OSX/sec/SOSCircle/SecureObjectSync/SOSRingUtils.c index 8483a72f..a83f8c47 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingUtils.c +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSRingUtils.c @@ -219,14 +219,6 @@ bool SOSRingIsSame(SOSRingRef ring1, SOSRingRef ring2) { require_action_quiet(name1 && name2, errOut, secnotice("ring", "Cannot get both names to consider rings the same")); if(CFEqualSafe(name1, name2) != true) return false; -#if 0 - // Not considering this for now - upgraded version can still be the "same ring". - uint32_t version1 = SOSRingGetVersion(ring1); - uint32_t version2 = SOSRingGetVersion(ring2); - require_action_quiet(version1 && version2, errOut, secnotice("ring", "Cannot get both versions to consider rings the same")); - if(version1 != version2) return false; -#endif - uint32_t type1 = SOSRingGetType(ring1); uint32_t type2 = SOSRingGetVersion(ring2); require_action_quiet(type1 && type2, errOut, secnotice("ring", "Cannot get both types to consider rings the same")); @@ -579,12 +571,6 @@ bool SOSRingResetToEmpty_Internal(SOSRingRef ring, CFErrorRef *error) { // MARK: PeerIDs in Ring -#if 0 -static inline bool isHiddenPeer(SOSPeerInfoRef peer) { - return SOSPeerInfoIsRetirementTicket(peer) || SOSPeerInfoIsCloudIdentity(peer); -} -#endif - int SOSRingCountPeers(SOSRingRef ring) { SOSRingAssertStable(ring); return (int) CFSetGetCount(SOSRingGetPeerIDs(ring)); @@ -618,10 +604,17 @@ static CFDataRef SOSRingCreateHash(const struct ccdigest_info *di, SOSRingRef ri if(dersize == 0) { return false; } - uint8_t der[dersize]; - der_encode_plist(ring->signedInformation, error, der, der+dersize); + uint8_t *der = malloc(dersize); + if (der == NULL) { + return false; + } + if (der_encode_plist(ring->signedInformation, error, der, der+dersize) == NULL) { + free(der); + return false; + } ccdigest(di, dersize, der, hash_result); + free(der); return CFDataCreate(NULL, hash_result, di->output_size); } @@ -828,117 +821,6 @@ static CFStringRef SOSRingCopyFormatDescription(CFTypeRef aObj, CFDictionaryRef return description; } -// -// Peer Retirement -// - #define SIGLEN 128 -#if 0 -static CFDataRef sosSignHash(SecKeyRef privkey, const struct ccdigest_info *di, uint8_t *hbuf) { - OSStatus stat; - size_t siglen = SIGLEN; - uint8_t sig[siglen]; - if((stat = SecKeyRawSign(privkey, kSecPaddingNone, hbuf, di->output_size, sig, &siglen)) != 0) { - return NULL; - } - return CFDataCreate(NULL, sig, (CFIndex)siglen); -} -#endif -#if 0 -static void WithBufferSpace(size_t space, void (^action)(uint8_t *buffer, size_t length)) { - if (space == 0) { - action(NULL, space); - } else if (space <= 2048) { - uint8_t buffer[space]; - action(buffer, space); - } else { - uint8_t* buffer = malloc(space); - - action(buffer, space); - - free(buffer); - } -} - -static CFDataRef CFDictionaryHashCreate(CFDictionaryRef dict, CFErrorRef *error) { - - __block CFDataRef result = NULL; - - require_quiet(dict, errOut); - - WithBufferSpace(der_sizeof_dictionary(dict, error), ^(uint8_t *der, size_t len) { - if (len > 0) { - const struct ccdigest_info *di = ccsha256_di(); - uint8_t hash_result[di->output_size]; - der_encode_dictionary(dict, error, der, der+len); - - ccdigest(di, len, der, hash_result); - result = CFDataCreate(ALLOCATOR, hash_result, di->output_size); - } - }); -errOut: - return NULL; -} -#endif -/* - CFDictionary: - signatures: CFDictionary of key = hash(pubkey), value = signature(privkey, (DER(payload)) - payload: CFDictionary passed in - - - */ -#if 0 -static CFStringRef sPayload = CFSTR("payload"); -static CFStringRef sSignature = CFSTR("signature"); - -static bool SOSCFSignedDictionarySetSignature(SecKeyRef priv, CFDictionaryRef sd, CFErrorRef *error) { - CFDictionaryRef payload = CFDictionaryGetValue(sd, sPayload); - CFMutableDictionaryRef signatures = (CFMutableDictionaryRef) CFDictionaryGetValue(sd, sSignature); - CFDataRef hash = CFDictionaryHashCreate(payload, error); - CFDataRef signature = SOSHashSign(priv, hash, error); - CFReleaseNull(hash); - CFStringRef pubhash = SOSCopyIDOfKey(priv, error); - require_quiet(signature && pubhash, errOut); - CFDictionaryAddValue(signatures, pubhash, signature); - return true; -errOut: - return false; -} -#endif -#if 0 -static CFDictionaryRef SOSCFSignedDictionaryCreate(SecKeyRef priv, CFDictionaryRef payload, CFErrorRef *error) { - CFMutableDictionaryRef signatures = CFDictionaryCreateMutableForCFTypes(ALLOCATOR); - CFMutableDictionaryRef retval = CFDictionaryCreateMutableForCFTypes(ALLOCATOR); - require_quiet(signatures && retval, errOut); - - CFDictionaryAddValue(retval, sSignature, signatures); - CFDictionaryAddValue(retval, sPayload, payload); - SOSCFSignedDictionarySetSignature(priv, retval, error); - return retval; -errOut: - CFReleaseNull(signatures); - CFReleaseNull(retval); - return NULL; -} -#endif - -#if 0 -CFDictionaryRef SOSRingCreateRetirementTicket(SOSFullPeerInfoRef fpi, CFErrorRef *error) { - CFDictionaryRef retval = NULL; - CFStringRef myPeerID = SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(fpi)); - SecKeyRef priv = SOSFullPeerInfoCopyDeviceKey(fpi, error); - CFDataRef resignationDate = SOSDateCreate(); - GENCOUNT!!! - - CFDataRef sig = SOSDERAndSignStuff(priv, keys, values, 2, error); - retval = CFDictionaryCreate(ALLOCATOR, <#const void **keys#>, <#const void **values#>, <#CFIndex numValues#>, <#const CFDictionaryKeyCallBacks *keyCallBacks#>, <#const CFDictionaryValueCallBacks *valueCallBacks#>) - return pi; - -exit_stage_right: - CFReleaseNull(priv); - CFReleaseNull(resignationDate); - return retval; -} -#endif diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingUtils.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSRingUtils.h index 0b97e463..2354ed50 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingUtils.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSRingUtils.h @@ -56,7 +56,7 @@ extern CFStringRef sGenerationKey; extern CFStringRef sPeerIDsKey; extern CFStringRef sRingVersionKey; -SOSRingRef SOSRingAllocate(void); +CF_RETURNS_RETAINED SOSRingRef SOSRingAllocate(void); SOSRingRef SOSRingCreate_Internal(CFStringRef name, SOSRingType type, CFErrorRef *error); SOSRingRef SOSRingCopyRing(SOSRingRef original, CFErrorRef *error); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.h new file mode 100644 index 00000000..031a4606 --- /dev/null +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef SOSSysdiagnose_h +#define SOSSysdiagnose_h + +char *SOSCCSysdiagnose(const char *directoryname); + +#endif /* SOSSysdiagnose_h */ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.m index 780651d9..0e7b6ae3 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.m @@ -39,6 +39,7 @@ #include +#include "SOSSysdiagnose.h" #include "keychain_log.h" #include "secToolFileIO.h" #include "secViewDisplay.h" @@ -87,7 +88,10 @@ static char *assemblePath(char *dir, char *fname) { size_t length = strlen(dir) + strlen(fname) + 2; char *outputDir = malloc(length); int status = snprintf(outputDir, length, "%s/%s", dir, fname); - if(status < 0) return NULL; + if(status < 0) { + if(outputDir) free(outputDir); + return NULL; + } return outputDir; } @@ -117,7 +121,10 @@ static char *sysdiagnose_dir(const char *passedIn, const char *hostname, const c length = strlen(outputParent) + strlen(outputBase) + 2; char *outputDir = malloc(length); status = snprintf(outputDir, length, "%s/%s", outputParent, outputBase); - if(status < 0) return NULL; + if(status < 0) { + if(outputDir) free(outputDir); + return NULL; + } return outputDir; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransport.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransport.m index 127bd0a1..41787724 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransport.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransport.m @@ -154,9 +154,6 @@ void SOSUpdateKeyInterest(SOSAccount* account) secerror("Error getting debug key interests %@", localError); } - if(![tkvs kvsAppendConfigKeyInterest:alwaysKeys firstUnlock:afterFirstUnlockKeys unlocked:whenUnlockedKeys err:&localError]) { - secerror("Error getting config key interests %@", localError); - } CFReleaseNull(localError); } @@ -310,7 +307,6 @@ CFMutableArrayRef SOSTransportDispatchMessages(SOSAccountTransaction* txn, CFDic __block bool new_account = false; CFDictionaryForEach(updates, ^(const void *key, const void *value) { - CFErrorRef localError = NULL; CFStringRef circle_name = NULL; CFStringRef ring_name = NULL; CFStringRef peer_info_name = NULL; @@ -351,11 +347,6 @@ CFMutableArrayRef SOSTransportDispatchMessages(SOSAccountTransaction* txn, CFDic case kDebugInfoKey: CFDictionarySetValue(debug_info_message_table, peer_info_name, value); break; - case kOTRConfig: - if(isDictionary(value)){ - config_message_table = CFRetainSafe((CFMutableDictionaryRef)(value)); - } - break; case kLastCircleKey: case kLastKeyParameterKey: case kUnknownKey: @@ -373,10 +364,6 @@ CFMutableArrayRef SOSTransportDispatchMessages(SOSAccountTransaction* txn, CFDic if (error && *error) secerror("Peer message processing error for: %@ -> %@ (%@)", key, value, *error); - if (localError) - secerror("Peer message local processing error for: %@ -> %@ (%@)", key, value, localError); - - CFReleaseNull(localError); }); @@ -396,12 +383,7 @@ CFMutableArrayRef SOSTransportDispatchMessages(SOSAccountTransaction* txn, CFDic if(initial_sync){ CFArrayAppendValue(handledKeys, kSOSKVSInitialSyncKey); } - - if(CFDictionaryGetCount(config_message_table)){ - secnotice("otrtimer","got the config table: %@", config_message_table); - CFArrayAppendValue(handledKeys, kOTRConfigVersion); - } - + if(CFDictionaryGetCount(debug_info_message_table)) { /* check for a newly set circle debug scope */ CFTypeRef debugScope = CFDictionaryGetValue(debug_info_message_table, kSOSAccountDebugScope); @@ -509,7 +491,8 @@ CFMutableArrayRef SOSTransportDispatchMessages(SOSAccountTransaction* txn, CFDic CFReleaseNull(keyHandled); }); } - + + CFReleaseNull(handleCircleMessages); CFReleaseNull(localError); } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircle.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircle.h index efba0f77..95992173 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircle.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircle.h @@ -26,7 +26,7 @@ -(bool) postRetirement:(CFStringRef) circleName peer:(SOSPeerInfoRef) peer err:(CFErrorRef *)error; -(CFDictionaryRef) CF_RETURNS_RETAINED handleRetirementMessages:(CFMutableDictionaryRef) circle_retirement_messages_table err:(CFErrorRef *)error; --(CFArrayRef) handleCircleMessagesAndReturnHandledCopy:(CFMutableDictionaryRef) circle_circle_messages_table err:(CFErrorRef *)error; +-(CFArrayRef)CF_RETURNS_RETAINED handleCircleMessagesAndReturnHandledCopy:(CFMutableDictionaryRef) circle_circle_messages_table err:(CFErrorRef *)error; @end #endif diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleCK.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleCK.m index 99f352cb..822abcc5 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleCK.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleCK.m @@ -63,7 +63,7 @@ { return NULL; } --(CFArrayRef) handleCircleMessagesAndReturnHandledCopy:(CFMutableDictionaryRef) circle_circle_messages_table err:(CFErrorRef *)error +-(CFArrayRef)CF_RETURNS_RETAINED handleCircleMessagesAndReturnHandledCopy:(CFMutableDictionaryRef) circle_circle_messages_table err:(CFErrorRef *)error { return NULL; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleKVS.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleKVS.h index 998bd928..82f2809c 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleKVS.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleKVS.h @@ -27,7 +27,6 @@ -(bool)kvsAppendKeyInterest:(CFMutableArrayRef) alwaysKeys firstUnlock:(CFMutableArrayRef) afterFirstUnlockKeys unlocked:(CFMutableArrayRef)unlockedKeys err:(CFErrorRef *)error; -(bool)kvsAppendRingKeyInterest:(CFMutableArrayRef) alwaysKeys firstUnlock:(CFMutableArrayRef)afterFirstUnlockKeys unlocked:(CFMutableArrayRef) unlockedKeys err:(CFErrorRef *)error; -(bool)kvsAppendDebugKeyInterest:(CFMutableArrayRef) alwaysKeys firstUnlock:(CFMutableArrayRef)afterFirstUnlockKeys unlocked:(CFMutableArrayRef) unlockedKeys err:(CFErrorRef *)error; --(bool)kvsAppendConfigKeyInterest:(CFMutableArrayRef) alwaysKeys firstUnlock:(CFMutableArrayRef)afterFirstUnlockKeys unlocked:(CFMutableArrayRef) unlockedKeys err:(CFErrorRef *)error; -(bool) kvsRingFlushChanges:(CFErrorRef*) error; -(bool) kvsRingPostRing:(CFStringRef) ringName ring:(CFDataRef) ring err:(CFErrorRef *)error; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleKVS.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleKVS.m index e253420c..56aaa5af 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleKVS.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleKVS.m @@ -158,7 +158,7 @@ static bool SOSTransportCircleKVSUpdateRetirementRecords(CFDictionaryRef updates return SOSAccountHandleRetirementMessages(self.account, circle_retirement_messages_table, error); } --(CFArrayRef) handleCircleMessagesAndReturnHandledCopy:(CFMutableDictionaryRef) circle_circle_messages_table err:(CFErrorRef *)error +-(CFArrayRef)CF_RETURNS_RETAINED handleCircleMessagesAndReturnHandledCopy:(CFMutableDictionaryRef) circle_circle_messages_table err:(CFErrorRef *)error { CFMutableArrayRef handledKeys = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); CFDictionaryForEach(circle_circle_messages_table, ^(const void *key, const void *value) { @@ -238,13 +238,6 @@ fail: return true; } -//register otr config --(bool)kvsAppendConfigKeyInterest:(CFMutableArrayRef) alwaysKeys firstUnlock:(CFMutableArrayRef)afterFirstUnlockKeys unlocked:(CFMutableArrayRef) unlockedKeys err:(CFErrorRef *)error -{ - CFArrayAppendValue(alwaysKeys, kSOSKVSOTRConfigVersion); - return true; -} - //send debug info over KVS -(bool) kvssendDebugInfo:(CFStringRef) type debug:(CFTypeRef) debugInfo err:(CFErrorRef *)error { diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessage.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessage.m index f94eeca5..bbc7eac0 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessage.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessage.m @@ -15,7 +15,10 @@ #include #include // TODO: Remove this layer violation. -NSString* const SecSOSMessageRTT = @"com.apple.security.sos.messagertt"; +static const CFStringRef kSecSOSMessageRTT = CFSTR("com.apple.security.sos.messagertt"); +static const CFStringRef kSecAccessGroupSecureBackupd = CFSTR("com.apple.securebackupd"); +static const CFStringRef kSecAccessGroupSBD = CFSTR("com.apple.sbd"); +static const CFStringRef kSecAccessGroupCKKS = CFSTR("com.apple.security.ckks"); @class SOSMessage; @@ -171,7 +174,7 @@ bool SOSEngineHandleCodedMessage(SOSAccount* account, SOSEngineRef engine, CFStr secnotice("otrtimer", "rtt: %d", rtt); [self SOSTransportMessageCalculateNextTimer:account rtt:rtt peerid:peerid]; - SecADClientPushValueForDistributionKey((__bridge CFStringRef) SecSOSMessageRTT, rtt); + SecADClientPushValueForDistributionKey(kSecSOSMessageRTT, rtt); [peerToTimeLastSentDict removeObjectForKey:peerid]; //remove last sent message date SOSAccountSetValue(account, kSOSAccountPeerLastSentTimestamp, (__bridge CFMutableDictionaryRef)peerToTimeLastSentDict, NULL); } @@ -366,28 +369,38 @@ static void SOSTransportSendPendingMessage(CFArrayRef attributes, SOSMessage* tr ok &= SOSEngineWithPeerID((SOSEngineRef)transport.engine, peer_id, error, ^(SOSPeerRef peer, SOSCoderRef coder, SOSDataSourceRef dataSource, SOSTransactionRef txn, bool *forceSaveState) { // Now under engine lock do stuff CFDataRef message_to_send = NULL; - SOSEnginePeerMessageSentBlock sent = NULL; + SOSEnginePeerMessageSentCallback* sentCallback = NULL; CFMutableArrayRef attributes = NULL; - ok = SOSPeerCoderSendMessageIfNeeded([transport SOSTransportMessageGetAccount],(SOSEngineRef)transport.engine, txn, peer, coder, &message_to_send, peer_id, &attributes, &sent, error); + ok = SOSPeerCoderSendMessageIfNeeded([transport SOSTransportMessageGetAccount],(SOSEngineRef)transport.engine, txn, peer, coder, &message_to_send, peer_id, &attributes, &sentCallback, error); secnotice("ratelimit","attribute list: %@", attributes); bool shouldSend = true; - + if(attributes == NULL){ //no attribute but still should be rate limited attributes = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); CFArrayAppendValue(attributes, CFSTR("NoAttribute")); } + if(initialSync){ secnotice("ratelimit","not going to rate limit, currently in initial sync"); } if(!initialSync && message_to_send){ //need to judge the message if not in initial sync secnotice("ratelimit","not in initial sync!"); shouldSend = SOSPeerShouldSend(attributes, peer, transport, message_to_send); - secnotice("ratelimit","should send? : %d", shouldSend); + CFRange range = CFRangeMake(0, CFArrayGetCount(attributes)); + if(CFArrayContainsValue(attributes, range, kSecAccessGroupCKKS) || + CFArrayContainsValue(attributes, range, kSecAccessGroupSBD) || + CFArrayContainsValue(attributes, range, kSecAccessGroupSecureBackupd)){ + shouldSend = true; + } + + secnotice("ratelimit","should send? : %@", shouldSend ? @"YES" : @"NO"); } if (shouldSend && message_to_send) { SOSTransportSendPendingMessage(attributes, transport, peer); ok = ok && [transport SOSTransportMessageSendMessage:transport id:peer_id messageToSend:message_to_send err:error]; - SOSPeerCoderConsume(&sent, ok); + + SOSEngineMessageCallCallback(sentCallback, ok); + [transport SOSTransportMessageUpdateLastMessageSentTimetstamp:account peer:peer]; }else if(!shouldSend){ @@ -395,8 +408,11 @@ static void SOSTransportSendPendingMessage(CFArrayRef attributes, SOSMessage* tr }else{ secnotice("transport", "no message to send to peer: %@", peer_id); } - sent = NULL; + + SOSEngineFreeMessageCallback(sentCallback); + sentCallback = NULL; CFReleaseSafe(message_to_send); + CFReleaseNull(attributes); *forceSaveState = ok; }); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageIDS.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageIDS.h index 97506591..2f31a754 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageIDS.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageIDS.h @@ -27,7 +27,7 @@ extern const CFStringRef kIDSMessageUniqueID; extern const CFStringRef kIDSMessageRecipientPeerID; extern const CFStringRef kIDSMessageRecipientDeviceID; extern const CFStringRef kIDSMessageUsesAckModel; - +extern const CFStringRef kIDSMessageSenderDeviceID;; @interface SOSMessageIDS : SOSMessage { diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageIDS.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageIDS.m index baccac59..0d4425fc 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageIDS.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageIDS.m @@ -82,6 +82,7 @@ static HandleIDSMessageReason checkMessageValidity(SOSAccount* account, CFString return; } else if(CFStringCompare(fromDeviceID, deviceID, 0) != 0){ //IDSids do not match, ghost + secnotice("ids transport", "deviceIDMisMatch"); reason = kHandleIDSmessageDeviceIDMismatch; CFReleaseNull(deviceID); return; @@ -93,6 +94,9 @@ static HandleIDSMessageReason checkMessageValidity(SOSAccount* account, CFString reason = kHandleIDSMessageSuccess; return; } + else{ + secerror("?? deviceID:%@, pID: %@, fromPeerID: %@, fromDeviceID: %@", deviceID, pID, fromPeerID, fromDeviceID); + } } } CFReleaseNull(deviceID); @@ -109,6 +113,7 @@ static HandleIDSMessageReason checkMessageValidity(SOSAccount* account, CFString CFStringRef deviceIDKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeyDeviceID, kCFStringEncodingASCII); CFStringRef sendersPeerIDKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeySendersPeerID, kCFStringEncodingASCII); CFStringRef ourPeerIdKey = CFStringCreateWithCString(kCFAllocatorDefault, kMessageKeyPeerID, kCFStringEncodingASCII); + NSString *errMessage = nil; HandleIDSMessageReason result = kHandleIDSMessageSuccess; @@ -120,10 +125,10 @@ static HandleIDSMessageReason checkMessageValidity(SOSAccount* account, CFString CFStringRef peerID = NULL; SOSPeerInfoRef theirPeer = NULL; - require_action_quiet(fromDeviceID, exit, result = kHandleIDSMessageDontHandle); - require_action_quiet(fromPeerID, exit, result = kHandleIDSMessageDontHandle); - require_action_quiet(messageData && CFDataGetLength(messageData) != 0, exit, result = kHandleIDSMessageDontHandle); - require_action_quiet(SOSAccountHasFullPeerInfo(account, error), exit, result = kHandleIDSMessageNotReady); + require_action_quiet(fromDeviceID, exit, result = kHandleIDSMessageDontHandle; errMessage = @"Missing device name"); + require_action_quiet(fromPeerID, exit, result = kHandleIDSMessageDontHandle; errMessage = @"Missing from peer id"); + require_action_quiet(messageData && CFDataGetLength(messageData) != 0, exit, result = kHandleIDSMessageDontHandle; errMessage = @"no message data"); + require_action_quiet(SOSAccountHasFullPeerInfo(account, error), exit, result = kHandleIDSMessageNotReady; errMessage = @"no full perinfo"); require_action_quiet(ourPeerID && [account.peerID isEqual: (__bridge NSString*) ourPeerID], exit, result = kHandleIDSMessageDontHandle; secnotice("IDS Transport","ignoring message for: %@", ourPeerID)); require_quiet((result = checkMessageValidity( account, fromDeviceID, fromPeerID, &peerID, &theirPeer)) == kHandleIDSMessageSuccess, exit); @@ -170,6 +175,10 @@ static HandleIDSMessageReason checkMessageValidity(SOSAccount* account, CFString } exit: + + if(errMessage != nil){ + secerror("%@", errMessage); + } CFReleaseNull(ourPeerIdKey); CFReleaseNull(sendersPeerIDKey); CFReleaseNull(deviceIDKey); @@ -236,9 +245,15 @@ static bool sendToPeer(SOSMessageIDS* transport, bool shouldUseAckModel, CFStrin dispatch_semaphore_t wait_for = dispatch_semaphore_create(0); secnotice("IDS Transport", "Starting"); + SecADAddValueForScalarKey(CFSTR("com.apple.security.sos.sendids"), 1); - SOSCloudKeychainSendIDSMessage(messagetoSend, deviceID, ourPeerID, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), [transport SOSTransportMessageIDSGetFragmentationPreference:transport], ^(CFDictionaryRef returnedValues, CFErrorRef sync_error) { + CFStringRef myDeviceID = CFRetainSafe((__bridge CFStringRef)account.deviceID); + if(!myDeviceID){ + myDeviceID = SOSPeerInfoCopyDeviceID(account.peerInfo); + } + + SOSCloudKeychainSendIDSMessage(messagetoSend, deviceID, ourPeerID, myDeviceID, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), [transport SOSTransportMessageIDSGetFragmentationPreference:transport], ^(CFDictionaryRef returnedValues, CFErrorRef sync_error) { success = (sync_error == NULL); if (sync_error && error) { CFRetainAssign(*error, sync_error); @@ -260,7 +275,7 @@ static bool sendToPeer(SOSMessageIDS* transport, bool shouldUseAckModel, CFStrin else{ secnotice("IDS Transport", "Sent message to peer!"); } - + CFReleaseNull(myDeviceID); CFReleaseNull(messagetoSend); CFReleaseNull(operation); CFReleaseNull(operationData); @@ -357,7 +372,7 @@ static bool sendToPeer(SOSMessageIDS* transport, bool shouldUseAckModel, CFStrin { SOSAccountTrustClassic* trust = acct.trust; CFStringRef deviceID = SOSPeerInfoCopyDeviceID(trust.peerInfo); - bool hasDeviceID = deviceID != NULL && CFStringGetLength(deviceID) != 0; + bool hasDeviceID = (deviceID != NULL && CFStringGetLength(deviceID) != 0) || account.deviceID; CFReleaseNull(deviceID); if(!hasDeviceID){ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageKVS.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageKVS.m index 0cc26cc7..22b72d82 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageKVS.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageKVS.m @@ -28,6 +28,13 @@ return self; } +-(void)dealloc +{ + if(self) { + CFReleaseNull(self->pending_changes); + } +} + -(CFIndex) SOSTransportMessageGetTransportType { return kKVS; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTypes.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSTypes.h index a8a58b07..6c689bf5 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTypes.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSTypes.h @@ -126,7 +126,7 @@ typedef int SOSSecurityPropertyActionCode; #define SOSControlInitialSyncFlagPCSNonCurrent (1 << 2) #define SOSControlInitialSyncFlagBluetoothMigration (1 << 3) -@protocol SOSControlProtocol +@protocol SOSControlProtocol - (void)userPublicKey:(void ((^))(BOOL trusted, NSData *spki, NSError *error))complete; - (void)kvsPerformanceCounters:(void(^)(NSDictionary *))reply; - (void)idsPerformanceCounters:(void(^)(NSDictionary *))reply; @@ -147,7 +147,6 @@ typedef int SOSSecurityPropertyActionCode; - (void)getWatchdogParameters:(void (^)(NSDictionary* parameters, NSError* error))complete; - (void)setWatchdogParmeters:(NSDictionary*)parameters complete:(void (^)(NSError* error))complete; - @end #endif diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSUserKeygen.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSUserKeygen.h index a83c3756..24dc76a1 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSUserKeygen.h +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSUserKeygen.h @@ -28,7 +28,7 @@ #include CFDataRef SOSUserKeyCreateGenerateParameters(CFErrorRef *error); -SecKeyRef SOSUserKeygen(CFDataRef password, CFDataRef parameters, CFErrorRef *error); +CF_RETURNS_RETAINED SecKeyRef SOSUserKeygen(CFDataRef password, CFDataRef parameters, CFErrorRef *error); void debugDumpUserParameters(CFStringRef message, CFDataRef parameters); CF_RETURNS_RETAINED CFStringRef UserParametersDescription(CFDataRef parameters); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSUserKeygen.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSUserKeygen.m index 5734221e..b3aa9753 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSUserKeygen.m +++ b/OSX/sec/SOSCircle/SecureObjectSync/SOSUserKeygen.m @@ -213,7 +213,7 @@ CFDataRef SOSUserKeyCreateGenerateParameters(CFErrorRef *error) { CFReleaseNull(result); if (result) { - secnotice("keygen", "Created new parameters: iterations %zd, keysize %zd: %@", iterations, keysize, result); + secnotice("circleOps", "Created new parameters: iterations %zd, keysize %zd: %@", iterations, keysize, result); } return result; @@ -266,7 +266,7 @@ SecKeyRef SOSUserKeygen(CFDataRef password, CFDataRef parameters, CFErrorRef *er ccec_full_ctx_decl_cp(cp, tmpkey); - secnotice("keygen", "Generating key for: iterations %zd, keysize %zd: %@", iterations, keysize, parameters); + secnotice("circleOps", "Generating key for: iterations %zd, keysize %zd: %@", iterations, keysize, parameters); if (ccrng_pbkdf2_prng_init(&pbkdf2_prng, maxbytes, password_length, password_bytes, @@ -297,13 +297,13 @@ void debugDumpUserParameters(CFStringRef message, CFDataRef parameters) der = der_decode_pbkdf2_params(&saltlen, &salt, &iterations, &keysize, der, der_end); if (der == NULL) { - secnotice("keygen", "failed to decode pbkdf2 params"); + secnotice("circleOps", "failed to decode pbkdf2 params"); return; } BufferPerformWithHexString(salt, saltlen, ^(CFStringRef saltHex) { CFDataPerformWithHexString(parameters, ^(CFStringRef parametersHex) { - secnotice("keygen", "%@ ]", message, iterations, keysize, saltHex, parametersHex); + secnotice("circleOps", "%@ ]", message, iterations, keysize, saltHex, parametersHex); }); }); } @@ -320,7 +320,7 @@ CF_RETURNS_RETAINED CFStringRef UserParametersDescription(CFDataRef parameters){ CFDataGetBytePtr(parameters), CFDataGetPastEndPtr(parameters)); if (parse_end != CFDataGetPastEndPtr(parameters)){ - secdebug("keygen", "failed to decode cloud parameters"); + secdebug("circleOps", "failed to decode cloud parameters"); return NULL; } @@ -335,7 +335,7 @@ CF_RETURNS_RETAINED CFStringRef UserParametersDescription(CFDataRef parameters){ der = der_decode_pbkdf2_params(&saltlen, &salt, &iterations, &keysize, der, der_end); if (der == NULL) { - secdebug("keygen", "failed to decode pbkdf2 params"); + secdebug("circleOps", "failed to decode pbkdf2 params"); return NULL; } diff --git a/OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.h b/OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.h index 2a3c4362..c9955671 100644 --- a/OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.h +++ b/OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.h @@ -1,10 +1,25 @@ -// -// accountCirclesViewsPrint.h -// Security -// -// Created by Richard Murphy on 12/8/16. -// -// +/* + * Copyright (c) 2016 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ #ifndef accountCirclesViewsPrint_h #define accountCirclesViewsPrint_h @@ -13,6 +28,8 @@ #include void SOSCCDumpCircleInformation(void); +void SOSCCDumpEngineInformation(void); +void SOSCCDumpViewUnwarePeers(void); bool SOSCCDumpCircleKVSInformation(char *itemName); #endif /* accountCirclesViewsPrint_h */ diff --git a/OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.m b/OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.m index c4fe7a2e..0ca7efe4 100644 --- a/OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.m +++ b/OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.m @@ -85,6 +85,26 @@ static const char *getSOSCCStatusDescription(SOSCCStatus ccstatus) } } +static const char * +getSOSCCLastDepartureReasonDescription(enum DepartureReason reason) +{ + switch (reason) { +#define CASE_REASON(x) case kSOS##x: return #x + CASE_REASON(DepartureReasonError); + CASE_REASON(NeverLeftCircle); + CASE_REASON(WithdrewMembership); + CASE_REASON(MembershipRevoked); + CASE_REASON(LeftUntrustedCircle); + CASE_REASON(NeverAppliedToCircle); + CASE_REASON(DiscoveredRetirement); // we should all be so lucky + CASE_REASON(LostPrivateKey); + CASE_REASON(PasswordChanged); +#undef CASE_REASON + default: + return "Unknown"; + } +} + static void printPeerInfos(char *label, CFArrayRef (^getArray)(CFErrorRef *error)) { CFErrorRef error = NULL; CFArrayRef ppi = getArray(&error); @@ -104,7 +124,6 @@ static void printPeerInfos(char *label, CFArrayRef (^getArray)(CFErrorRef *error CFStringRef deviceID = CFSTR(""); CFDictionaryRef gestalt = SOSPeerInfoCopyPeerGestalt(peer); CFStringRef osVersion = CFDictionaryGetValue(gestalt, CFSTR("OSVersion")); - CFReleaseNull(gestalt); if(version >= 2){ @@ -116,24 +135,31 @@ static void printPeerInfos(char *label, CFArrayRef (^getArray)(CFErrorRef *error char *dname = CFStringToCString(devtype); char *tname = CFStringToCString(transportType); char *iname = CFStringToCString(deviceID); - char *osname = CFStringToCString(osVersion); const char *me = CFEqualSafe(mypeerID, peerID) ? "me>" : " "; - snprintf(buf, 160, "%s %s: %-16s %-16s %-16s %-16s", me, label, pname, dname, tname, iname); + snprintf(buf, 160, "%s %s: %-16s %-16s %-16s %-36s", me, label, pname, dname, tname, iname); free(pname); free(dname); + free(tname); + free(iname); + + // %s in (Core)Foundation format strings treats the string as MacRoman, need to do this to guarantee UTF8 handling + CFStringRef bufstr = CFStringCreateWithCString(NULL, buf, kCFStringEncodingUTF8); CFStringRef pid = SOSPeerInfoGetPeerID(peer); CFIndex vers = SOSPeerInfoGetVersion(peer); - printmsg(CFSTR("%s %@ V%d OS:%s\n"), buf, pid, vers, osname); - free(osname); + printmsg(CFSTR("%@ %@ V%d OS:%@\n"), bufstr, pid, vers, osVersion ?: CFSTR("")); + CFRelease(bufstr); + + CFReleaseNull(gestalt); }); } else { printmsg(CFSTR("No %s, error: %@\n"), label, error); } CFReleaseNull(ppi); CFReleaseNull(error); + CFReleaseNull(me); } void SOSCCDumpCircleInformation() @@ -145,10 +171,21 @@ void SOSCCDumpCircleInformation() SOSCCStatus ccstatus = SOSCCThisDeviceIsInCircle(&error); printmsg(CFSTR("ccstatus: %s (%d)\n"), getSOSCCStatusDescription(ccstatus), ccstatus); + if (error != NULL) { + printmsg(CFSTR("Error checking circle status: %@\n"), error); + } + CFReleaseNull(error); + enum DepartureReason departureReason = SOSCCGetLastDepartureReason(&error); + printmsg(CFSTR("LastDepartureReason: %s (%d)\n"), getSOSCCLastDepartureReasonDescription(departureReason), departureReason); + if (error != NULL) { + printmsg(CFSTR("Error checking last departure reason error: %@\n"), error); + } + CFReleaseNull(error); + is_accountKeyIsTrusted = SOSCCValidateUserPublic(&error); if(is_accountKeyIsTrusted) - printmsg(CFSTR("Account user public is trusted%@"),CFSTR("\n")); + printmsg(CFSTR("Account user public is trusted\n")); else printmsg(CFSTR("Account user public is not trusted error:(%@)\n"), error); CFReleaseNull(error); @@ -182,8 +219,25 @@ void SOSCCDumpCircleInformation() CFReleaseNull(error); } +void +SOSCCDumpEngineInformation(void) +{ + CFErrorRef error = NULL; + printmsg(CFSTR("Engine state:\n")); + if (!SOSCCForEachEngineStateAsString(&error, ^(CFStringRef oneStateString) { + printmsg(CFSTR("%@\n"), oneStateString); + })) { + printmsg(CFSTR("No engine state, got error: %@\n"), error); + } +} +// security sync -o +void +SOSCCDumpViewUnwarePeers(void) +{ + printPeerInfos("view-unaware", ^(CFErrorRef *error) { return SOSCCCopyViewUnawarePeerInfo(error); }); +} /* KVS Dumping Support for iCloud Keychain */ diff --git a/OSX/sec/SOSCircle/Tool/keychain_log.m b/OSX/sec/SOSCircle/Tool/keychain_log.m index ba5054e4..65b4419b 100644 --- a/OSX/sec/SOSCircle/Tool/keychain_log.m +++ b/OSX/sec/SOSCircle/Tool/keychain_log.m @@ -64,9 +64,11 @@ #include #include +#include "SOSSysdiagnose.h" #include "keychain_log.h" #include "secToolFileIO.h" #include "secViewDisplay.h" +#include "accountCirclesViewsPrint.h" #include @@ -75,371 +77,6 @@ #define MAXKVSKEYTYPE kUnknownKey #define DATE_LENGTH 18 - -static const char *getSOSCCStatusDescription(SOSCCStatus ccstatus) -{ - switch (ccstatus) - { - case kSOSCCInCircle: return "In Circle"; - case kSOSCCNotInCircle: return "Not in Circle"; - case kSOSCCRequestPending: return "Request pending"; - case kSOSCCCircleAbsent: return "Circle absent"; - case kSOSCCError: return "Circle error"; - - default: - return ""; - break; - } -} - -static void printPeerInfos(char *label, CFArrayRef (^getArray)(CFErrorRef *error)) { - CFErrorRef error = NULL; - CFArrayRef ppi = getArray(&error); - SOSPeerInfoRef me = SOSCCCopyMyPeerInfo(NULL); - CFStringRef mypeerID = SOSPeerInfoGetPeerID(me); - - if(ppi) { - printmsg(CFSTR("%s count: %ld\n"), label, (long)CFArrayGetCount(ppi)); - CFArrayForEach(ppi, ^(const void *value) { - char buf[160]; - SOSPeerInfoRef peer = (SOSPeerInfoRef)value; - CFIndex version = SOSPeerInfoGetVersion(peer); - CFStringRef peerName = SOSPeerInfoGetPeerName(peer); - CFStringRef devtype = SOSPeerInfoGetPeerDeviceType(peer); - CFStringRef peerID = SOSPeerInfoGetPeerID(peer); - CFStringRef transportType = CFSTR("KVS"); - CFStringRef deviceID = CFSTR(""); - CFDictionaryRef gestalt = SOSPeerInfoCopyPeerGestalt(peer); - CFStringRef osVersion = CFDictionaryGetValue(gestalt, CFSTR("OSVersion")); - CFReleaseNull(gestalt); - - - if(version >= 2){ - CFDictionaryRef v2Dictionary = peer->v2Dictionary; - transportType = CFDictionaryGetValue(v2Dictionary, sTransportType); - deviceID = CFDictionaryGetValue(v2Dictionary, sDeviceID); - } - char *pname = CFStringToCString(peerName); - char *dname = CFStringToCString(devtype); - char *tname = CFStringToCString(transportType); - char *iname = CFStringToCString(deviceID); - char *osname = CFStringToCString(osVersion); - const char *me = CFEqualSafe(mypeerID, peerID) ? "me>" : " "; - - - snprintf(buf, 160, "%s %s: %-16s %-16s %-16s %-16s", me, label, pname, dname, tname, iname); - - free(pname); - free(dname); - CFStringRef pid = SOSPeerInfoGetPeerID(peer); - CFIndex vers = SOSPeerInfoGetVersion(peer); - printmsg(CFSTR("%s %@ V%d OS:%s\n"), buf, pid, vers, osname); - free(osname); - }); - } else { - printmsg(CFSTR("No %s, error: %@\n"), label, error); - } - CFReleaseNull(ppi); - CFReleaseNull(error); -} - -static void dumpCircleInfo() -{ - CFErrorRef error = NULL; - CFArrayRef generations = NULL; - bool is_accountKeyIsTrusted = false; - __block int count = 0; - - SOSCCStatus ccstatus = SOSCCThisDeviceIsInCircle(&error); - if(ccstatus == kSOSCCError) { - printmsg(CFSTR("End of Dump - unable to proceed due to ccstatus (%s) error: %@\n"), getSOSCCStatusDescription(ccstatus), error); - return; - } - printmsg(CFSTR("ccstatus: %s (%d)\n"), getSOSCCStatusDescription(ccstatus), ccstatus, error); - - is_accountKeyIsTrusted = SOSCCValidateUserPublic(&error); - if(is_accountKeyIsTrusted) - printmsg(CFSTR("Account user public is trusted%@"),CFSTR("\n")); - else - printmsg(CFSTR("Account user public is not trusted error:(%@)\n"), error); - CFReleaseNull(error); - - generations = SOSCCCopyGenerationPeerInfo(&error); - if(generations) { - CFArrayForEach(generations, ^(const void *value) { - count++; - if(count%2 == 0) - printmsg(CFSTR("Circle name: %@, "),value); - - if(count%2 != 0) { - CFStringRef genDesc = SOSGenerationCountCopyDescription(value); - printmsg(CFSTR("Generation Count: %@"), genDesc); - CFReleaseNull(genDesc); - } - printmsg(CFSTR("%s\n"), ""); - }); - } else { - printmsg(CFSTR("No generation count: %@\n"), error); - } - CFReleaseNull(generations); - CFReleaseNull(error); - - printPeerInfos(" Peers", ^(CFErrorRef *error) { return SOSCCCopyValidPeerPeerInfo(error); }); - printPeerInfos(" Invalid", ^(CFErrorRef *error) { return SOSCCCopyNotValidPeerPeerInfo(error); }); - printPeerInfos(" Retired", ^(CFErrorRef *error) { return SOSCCCopyRetirementPeerInfo(error); }); - printPeerInfos(" Concur", ^(CFErrorRef *error) { return SOSCCCopyConcurringPeerPeerInfo(error); }); - printPeerInfos("Applicants", ^(CFErrorRef *error) { return SOSCCCopyApplicantPeerInfo(error); }); - - if (!SOSCCForEachEngineStateAsString(&error, ^(CFStringRef oneStateString) { - printmsg(CFSTR("%@\n"), oneStateString); - })) { - printmsg(CFSTR("No engine peers: %@\n"), error); - } - - CFReleaseNull(error); -} - -static CFTypeRef getObjectsFromCloud(CFArrayRef keysToGet, dispatch_queue_t processQueue, dispatch_group_t dgroup) -{ - __block CFTypeRef object = NULL; - - const uint64_t maxTimeToWaitInSeconds = 30ull * NSEC_PER_SEC; - dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0); - dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, maxTimeToWaitInSeconds); - - dispatch_group_enter(dgroup); - - CloudKeychainReplyBlock replyBlock = - ^ (CFDictionaryRef returnedValues, CFErrorRef error) - { - secinfo("sync", "SOSCloudKeychainGetObjectsFromCloud returned: %@", returnedValues); - object = returnedValues; - if (object) - CFRetain(object); - if (error) - { - secerror("SOSCloudKeychainGetObjectsFromCloud returned error: %@", error); - } - dispatch_group_leave(dgroup); - secinfo("sync", "SOSCloudKeychainGetObjectsFromCloud block exit: %@", object); - dispatch_semaphore_signal(waitSemaphore); - }; - - if (!keysToGet) - SOSCloudKeychainGetAllObjectsFromCloud(processQueue, replyBlock); - else - SOSCloudKeychainGetObjectsFromCloud(keysToGet, processQueue, replyBlock); - - dispatch_semaphore_wait(waitSemaphore, finishTime); - - if (object && (CFGetTypeID(object) == CFNullGetTypeID())) // return a NULL instead of a CFNull - { - CFRelease(object); - object = NULL; - } - secerror("returned: %@", object); - return object; -} - -static CFStringRef printFullDataString(CFDataRef data){ - __block CFStringRef fullData = NULL; - - BufferPerformWithHexString(CFDataGetBytePtr(data), CFDataGetLength(data), ^(CFStringRef dataHex) { - fullData = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@"), dataHex); - }); - - return fullData; -} - -static void displayLastKeyParameters(CFTypeRef key, CFTypeRef value) -{ - CFDataRef valueAsData = asData(value, NULL); - if(valueAsData){ - CFDataRef dateData = CFDataCreateCopyFromRange(kCFAllocatorDefault, valueAsData, CFRangeMake(0, DATE_LENGTH)); - CFDataRef keyParameterData = CFDataCreateCopyFromPositions(kCFAllocatorDefault, valueAsData, DATE_LENGTH, CFDataGetLength(valueAsData)); - CFStringRef dateString = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, dateData, kCFStringEncodingUTF8); - CFStringRef keyParameterDescription = UserParametersDescription(keyParameterData); - if(keyParameterDescription) - printmsg(CFSTR("%@: %@: %@\n"), key, dateString, keyParameterDescription); - else - printmsg(CFSTR("%@: %@\n"), key, printFullDataString(value)); - CFReleaseNull(dateString); - CFReleaseNull(keyParameterData); - CFReleaseNull(dateData); - CFReleaseNull(keyParameterDescription); - } - else{ - printmsg(CFSTR("%@: %@\n"), key, value); - } -} - -static void displayKeyParameters(CFTypeRef key, CFTypeRef value) -{ - if(isData(value)){ - CFStringRef keyParameterDescription = UserParametersDescription((CFDataRef)value); - - if(keyParameterDescription) - printmsg(CFSTR("%@: %@\n"), key, keyParameterDescription); - else - printmsg(CFSTR("%@: %@\n"), key, value); - - CFReleaseNull(keyParameterDescription); - } - else{ - printmsg(CFSTR("%@: %@\n"), key, value); - } -} - -static void displayLastCircle(CFTypeRef key, CFTypeRef value) -{ - CFDataRef valueAsData = asData(value, NULL); - if(valueAsData){ - CFErrorRef localError = NULL; - - CFDataRef dateData = CFDataCreateCopyFromRange(kCFAllocatorDefault, valueAsData, CFRangeMake(0, DATE_LENGTH)); - CFDataRef circleData = CFDataCreateCopyFromPositions(kCFAllocatorDefault, valueAsData, DATE_LENGTH, CFDataGetLength(valueAsData)); - CFStringRef dateString = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, dateData, kCFStringEncodingUTF8); - SOSCircleRef circle = SOSCircleCreateFromData(NULL, (CFDataRef) circleData, &localError); - - if(circle){ - CFIndex size = 5; - CFNumberRef idLength = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &size); - CFDictionaryRef format = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, CFSTR("SyncD"), CFSTR("SyncD"), CFSTR("idLength"), idLength, NULL); - printmsgWithFormatOptions(format, CFSTR("%@: %@: %@\n"), key, dateString, circle); - CFReleaseNull(idLength); - CFReleaseNull(format); - - } - else - printmsg(CFSTR("%@: %@\n"), key, printFullDataString(circleData)); - - CFReleaseNull(dateString); - CFReleaseNull(circleData); - CFReleaseSafe(circle); - CFReleaseNull(dateData); - CFReleaseNull(localError); - } - else{ - printmsg(CFSTR("%@: %@\n"), key, value); - } -} - -static void displayCircle(CFTypeRef key, CFTypeRef value) -{ - CFDataRef circleData = (CFDataRef)value; - - CFErrorRef localError = NULL; - if (isData(circleData)) - { - CFIndex size = 5; - CFNumberRef idLength = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &size); - CFDictionaryRef format = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, CFSTR("SyncD"), CFSTR("SyncD"), CFSTR("idLength"), idLength, NULL); - SOSCircleRef circle = SOSCircleCreateFromData(NULL, circleData, &localError); - printmsgWithFormatOptions(format, CFSTR("%@: %@\n"), key, circle); - CFReleaseSafe(circle); - CFReleaseNull(idLength); - CFReleaseNull(format); - - } - else - printmsg(CFSTR("%@: %@\n"), key, value); -} - -static void displayMessage(CFTypeRef key, CFTypeRef value) -{ - CFDataRef message = (CFDataRef)value; - if(isData(message)){ - const char* messageType = SecOTRPacketTypeString(message); - printmsg(CFSTR("%@: %s: %ld\n"), key, messageType, CFDataGetLength(message)); - } - else - printmsg(CFSTR("%@: %@\n"), key, value); -} - -static void printEverything(CFTypeRef objects) -{ - CFDictionaryForEach(objects, ^(const void *key, const void *value) { - if (isData(value)) - { - printmsg(CFSTR("%@: %@\n\n"), key, printFullDataString(value)); - } - else - printmsg(CFSTR("%@: %@\n"), key, value); - }); - -} - -static void decodeForKeyType(CFTypeRef key, CFTypeRef value, SOSKVSKeyType type){ - switch (type) { - case kCircleKey: - displayCircle(key, value); - break; - case kRetirementKey: - case kMessageKey: - displayMessage(key, value); - break; - case kParametersKey: - displayKeyParameters(key, value); - break; - case kLastKeyParameterKey: - displayLastKeyParameters(key, value); - break; - case kLastCircleKey: - displayLastCircle(key, value); - break; - case kInitialSyncKey: - case kAccountChangedKey: - case kDebugInfoKey: - case kRingKey: - default: - printmsg(CFSTR("%@: %@\n"), key, value); - break; - } -} - -static void decodeAllTheValues(CFTypeRef objects){ - SOSKVSKeyType keyType = 0; - __block bool didPrint = false; - - for (keyType = 0; keyType <= MAXKVSKEYTYPE; keyType++){ - CFDictionaryForEach(objects, ^(const void *key, const void *value) { - if(SOSKVSKeyGetKeyType(key) == keyType){ - decodeForKeyType(key, value, keyType); - didPrint = true; - } - }); - if(didPrint) - printmsg(CFSTR("%@\n"), CFSTR("")); - didPrint = false; - } -} -static bool dumpKVS(char *itemName, CFErrorRef *err) -{ - CFArrayRef keysToGet = NULL; - if (itemName) - { - CFStringRef itemStr = CFStringCreateWithCString(kCFAllocatorDefault, itemName, kCFStringEncodingUTF8); - fprintf(outFile, "Retrieving %s from KVS\n", itemName); - keysToGet = CFArrayCreateForCFTypes(kCFAllocatorDefault, itemStr, NULL); - CFReleaseSafe(itemStr); - } - dispatch_queue_t generalq = dispatch_queue_create("general", DISPATCH_QUEUE_SERIAL); - dispatch_group_t work_group = dispatch_group_create(); - CFTypeRef objects = getObjectsFromCloud(keysToGet, generalq, work_group); - CFReleaseSafe(keysToGet); - if (objects) - { - fprintf(outFile, "All keys and values straight from KVS\n"); - printEverything(objects); - fprintf(outFile, "\nAll values in decoded form...\n"); - decodeAllTheValues(objects); - } - fprintf(outFile, "\n"); - return true; -} - - - #define USE_NEW_SPI 1 #if ! USE_NEW_SPI @@ -542,12 +179,13 @@ static void sysdiagnose_dump() { SOSLogSetOutputTo(outputDir, "syncD.log"); // do sync -D - dumpKVS(optarg, NULL); + SOSCCDumpCircleKVSInformation(optarg); closeOutput(); SOSLogSetOutputTo(outputDir, "synci.log"); // do sync -i - dumpCircleInfo(); + SOSCCDumpCircleInformation(); + SOSCCDumpEngineInformation(); closeOutput(); SOSLogSetOutputTo(outputDir, "syncL.log"); @@ -603,7 +241,8 @@ keychain_log(int argc, char * const *argv) switch (ch) { case 'i': - dumpCircleInfo(); + SOSCCDumpCircleInformation(); + SOSCCDumpEngineInformation(); break; @@ -612,7 +251,7 @@ keychain_log(int argc, char * const *argv) break; case 'D': - hadError = !dumpKVS(optarg, &error); + (void)SOSCCDumpCircleKVSInformation(optarg); break; case 'L': @@ -625,7 +264,7 @@ keychain_log(int argc, char * const *argv) case '?': default: - return 2; /* Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } if (hadError) diff --git a/OSX/sec/SOSCircle/Tool/keychain_sync.m b/OSX/sec/SOSCircle/Tool/keychain_sync.m index 73f00ac7..32136f94 100644 --- a/OSX/sec/SOSCircle/Tool/keychain_sync.m +++ b/OSX/sec/SOSCircle/Tool/keychain_sync.m @@ -61,6 +61,7 @@ #include "secToolFileIO.h" #include "secViewDisplay.h" +#include "accountCirclesViewsPrint.h" #include @@ -87,131 +88,6 @@ static bool clearAllKVS(CFErrorRef *error) return result; } -static const char *getSOSCCStatusDescription(SOSCCStatus ccstatus) -{ - switch (ccstatus) - { - case kSOSCCInCircle: return "In Circle"; - case kSOSCCNotInCircle: return "Not in Circle"; - case kSOSCCRequestPending: return "Request pending"; - case kSOSCCCircleAbsent: return "Circle absent"; - case kSOSCCError: return "Circle error"; - - default: - return ""; - break; - } -} - -static void printPeerInfos(char *label, CFArrayRef (^getArray)(CFErrorRef *error)) { - CFErrorRef error = NULL; - CFArrayRef ppi = getArray(&error); - SOSPeerInfoRef me = SOSCCCopyMyPeerInfo(NULL); - CFStringRef mypeerID = SOSPeerInfoGetPeerID(me); - - if(ppi) { - printmsg(CFSTR("%s count: %ld\n"), label, (long)CFArrayGetCount(ppi)); - CFArrayForEach(ppi, ^(const void *value) { - char buf[160]; - SOSPeerInfoRef peer = (SOSPeerInfoRef)value; - CFIndex version = SOSPeerInfoGetVersion(peer); - CFStringRef peerName = SOSPeerInfoGetPeerName(peer); - CFStringRef devtype = SOSPeerInfoGetPeerDeviceType(peer); - CFStringRef peerID = SOSPeerInfoGetPeerID(peer); - CFStringRef transportType = CFSTR("KVS"); - CFStringRef deviceID = CFSTR(""); - CFDictionaryRef gestalt = SOSPeerInfoCopyPeerGestalt(peer); - CFStringRef osVersion = CFDictionaryGetValue(gestalt, CFSTR("OSVersion")); - CFReleaseNull(gestalt); - - - if(version >= 2){ - CFDictionaryRef v2Dictionary = peer->v2Dictionary; - transportType = CFDictionaryGetValue(v2Dictionary, sTransportType); - deviceID = CFDictionaryGetValue(v2Dictionary, sDeviceID); - } - char *pname = CFStringToCString(peerName); - char *dname = CFStringToCString(devtype); - char *tname = CFStringToCString(transportType); - char *iname = CFStringToCString(deviceID); - char *osname = CFStringToCString(osVersion); - const char *me = CFEqualSafe(mypeerID, peerID) ? "me>" : " "; - - - snprintf(buf, 160, "%s %s: %-16s %-16s %-16s %-16s", me, label, pname, dname, tname, iname); - - free(pname); - free(dname); - CFStringRef pid = SOSPeerInfoGetPeerID(peer); - CFIndex vers = SOSPeerInfoGetVersion(peer); - printmsg(CFSTR("%s %@ V%d OS:%s\n"), buf, pid, vers, osname); - free(osname); - }); - } else { - printmsg(CFSTR("No %s, error: %@\n"), label, error); - } - CFReleaseNull(ppi); - CFReleaseNull(error); -} - -static void dumpCircleInfo() -{ - CFErrorRef error = NULL; - CFArrayRef generations = NULL; - CFArrayRef confirmedDigests = NULL; - bool is_accountKeyIsTrusted = false; - __block int count = 0; - - SOSCCStatus ccstatus = SOSCCThisDeviceIsInCircle(&error); - if(ccstatus == kSOSCCError) { - printmsg(CFSTR("End of Dump - unable to proceed due to ccstatus (%s) error: %@\n"), getSOSCCStatusDescription(ccstatus), error); - return; - } - printmsg(CFSTR("ccstatus: %s (%d)\n"), getSOSCCStatusDescription(ccstatus), ccstatus, error); - - is_accountKeyIsTrusted = SOSCCValidateUserPublic(&error); - if(is_accountKeyIsTrusted) - printmsg(CFSTR("Account user public is trusted%@"),CFSTR("\n")); - else - printmsg(CFSTR("Account user public is not trusted error:(%@)\n"), error); - CFReleaseNull(error); - - generations = SOSCCCopyGenerationPeerInfo(&error); - if(generations) { - CFArrayForEach(generations, ^(const void *value) { - count++; - if(count%2 == 0) - printmsg(CFSTR("Circle name: %@, "),value); - - if(count%2 != 0) { - CFStringRef genDesc = SOSGenerationCountCopyDescription(value); - printmsg(CFSTR("Generation Count: %@"), genDesc); - CFReleaseNull(genDesc); - } - printmsg(CFSTR("%s\n"), ""); - }); - } else { - printmsg(CFSTR("No generation count: %@\n"), error); - } - CFReleaseNull(generations); - CFReleaseNull(error); - - printPeerInfos(" Peers", ^(CFErrorRef *error) { return SOSCCCopyValidPeerPeerInfo(error); }); - printPeerInfos(" Invalid", ^(CFErrorRef *error) { return SOSCCCopyNotValidPeerPeerInfo(error); }); - printPeerInfos(" Retired", ^(CFErrorRef *error) { return SOSCCCopyRetirementPeerInfo(error); }); - printPeerInfos(" Concur", ^(CFErrorRef *error) { return SOSCCCopyConcurringPeerPeerInfo(error); }); - printPeerInfos("Applicants", ^(CFErrorRef *error) { return SOSCCCopyApplicantPeerInfo(error); }); - - if (!SOSCCForEachEngineStateAsString(&error, ^(CFStringRef oneStateString) { - printmsg(CFSTR("%@\n"), oneStateString); - })) { - printmsg(CFSTR("No engine peers: %@\n"), error); - } - - CFReleaseNull(error); - CFReleaseNull(confirmedDigests); -} - static bool enableDefaultViews() { bool result = false; @@ -277,244 +153,6 @@ static bool tryPassword(char *labelAndPassword, CFErrorRef *err) return returned; } -static CFTypeRef getObjectsFromCloud(CFArrayRef keysToGet, dispatch_queue_t processQueue, dispatch_group_t dgroup) -{ - __block CFTypeRef object = NULL; - - const uint64_t maxTimeToWaitInSeconds = 30ull * NSEC_PER_SEC; - dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0); - dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, maxTimeToWaitInSeconds); - - dispatch_group_enter(dgroup); - - CloudKeychainReplyBlock replyBlock = - ^ (CFDictionaryRef returnedValues, CFErrorRef error) - { - secinfo("sync", "SOSCloudKeychainGetObjectsFromCloud returned: %@", returnedValues); - object = returnedValues; - if (object) - CFRetain(object); - if (error) - { - secerror("SOSCloudKeychainGetObjectsFromCloud returned error: %@", error); - } - dispatch_group_leave(dgroup); - secinfo("sync", "SOSCloudKeychainGetObjectsFromCloud block exit: %@", object); - dispatch_semaphore_signal(waitSemaphore); - }; - - if (!keysToGet) - SOSCloudKeychainGetAllObjectsFromCloud(processQueue, replyBlock); - else - SOSCloudKeychainGetObjectsFromCloud(keysToGet, processQueue, replyBlock); - - dispatch_semaphore_wait(waitSemaphore, finishTime); - if (object && (CFGetTypeID(object) == CFNullGetTypeID())) // return a NULL instead of a CFNull - { - CFRelease(object); - object = NULL; - } - secerror("returned: %@", object); - return object; -} - -static CFStringRef printFullDataString(CFDataRef data){ - __block CFStringRef fullData = NULL; - - BufferPerformWithHexString(CFDataGetBytePtr(data), CFDataGetLength(data), ^(CFStringRef dataHex) { - fullData = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@"), dataHex); - }); - - return fullData; -} - -static void displayLastKeyParameters(CFTypeRef key, CFTypeRef value) -{ - CFDataRef valueAsData = asData(value, NULL); - if(valueAsData){ - CFDataRef dateData = CFDataCreateCopyFromRange(kCFAllocatorDefault, valueAsData, CFRangeMake(0, DATE_LENGTH)); - CFDataRef keyParameterData = CFDataCreateCopyFromPositions(kCFAllocatorDefault, valueAsData, DATE_LENGTH, CFDataGetLength(valueAsData)); - CFStringRef dateString = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, dateData, kCFStringEncodingUTF8); - CFStringRef keyParameterDescription = UserParametersDescription(keyParameterData); - if(keyParameterDescription) - printmsg(CFSTR("%@: %@: %@\n"), key, dateString, keyParameterDescription); - else - printmsg(CFSTR("%@: %@\n"), key, printFullDataString(value)); - CFReleaseNull(dateString); - CFReleaseNull(keyParameterData); - CFReleaseNull(dateData); - CFReleaseNull(keyParameterDescription); - } - else{ - printmsg(CFSTR("%@: %@\n"), key, value); - } -} - -static void displayKeyParameters(CFTypeRef key, CFTypeRef value) -{ - if(isData(value)){ - CFStringRef keyParameterDescription = UserParametersDescription((CFDataRef)value); - - if(keyParameterDescription) - printmsg(CFSTR("%@: %@\n"), key, keyParameterDescription); - else - printmsg(CFSTR("%@: %@\n"), key, value); - - CFReleaseNull(keyParameterDescription); - } - else{ - printmsg(CFSTR("%@: %@\n"), key, value); - } -} - -static void displayLastCircle(CFTypeRef key, CFTypeRef value) -{ - CFDataRef valueAsData = asData(value, NULL); - if(valueAsData){ - CFErrorRef localError = NULL; - - CFDataRef dateData = CFDataCreateCopyFromRange(kCFAllocatorDefault, valueAsData, CFRangeMake(0, DATE_LENGTH)); - CFDataRef circleData = CFDataCreateCopyFromPositions(kCFAllocatorDefault, valueAsData, DATE_LENGTH, CFDataGetLength(valueAsData)); - CFStringRef dateString = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, dateData, kCFStringEncodingUTF8); - SOSCircleRef circle = SOSCircleCreateFromData(NULL, (CFDataRef) circleData, &localError); - - if(circle){ - CFIndex size = 5; - CFNumberRef idLength = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &size); - CFDictionaryRef format = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, CFSTR("SyncD"), CFSTR("SyncD"), CFSTR("idLength"), idLength, NULL); - printmsgWithFormatOptions(format, CFSTR("%@: %@: %@\n"), key, dateString, circle); - CFReleaseNull(idLength); - CFReleaseNull(format); - - } - else - printmsg(CFSTR("%@: %@\n"), key, printFullDataString(circleData)); - - CFReleaseNull(dateString); - CFReleaseNull(circleData); - CFReleaseSafe(circle); - CFReleaseNull(dateData); - CFReleaseNull(localError); - } - else{ - printmsg(CFSTR("%@: %@\n"), key, value); - } -} - -static void displayCircle(CFTypeRef key, CFTypeRef value) -{ - CFDataRef circleData = (CFDataRef)value; - - CFErrorRef localError = NULL; - if (isData(circleData)) - { - CFIndex size = 5; - CFNumberRef idLength = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &size); - CFDictionaryRef format = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, CFSTR("SyncD"), CFSTR("SyncD"), CFSTR("idLength"), idLength, NULL); - SOSCircleRef circle = SOSCircleCreateFromData(NULL, circleData, &localError); - printmsgWithFormatOptions(format, CFSTR("%@: %@\n"), key, circle); - CFReleaseSafe(circle); - CFReleaseNull(idLength); - CFReleaseNull(format); - - } - else - printmsg(CFSTR("%@: %@\n"), key, value); -} - -static void displayMessage(CFTypeRef key, CFTypeRef value) -{ - CFDataRef message = (CFDataRef)value; - if(isData(message)){ - const char* messageType = SecOTRPacketTypeString(message); - printmsg(CFSTR("%@: %s: %ld\n"), key, messageType, CFDataGetLength(message)); - } - else - printmsg(CFSTR("%@: %@\n"), key, value); -} - -static void printEverything(CFTypeRef objects) -{ - CFDictionaryForEach(objects, ^(const void *key, const void *value) { - if (isData(value)) - { - printmsg(CFSTR("%@: %@\n\n"), key, printFullDataString(value)); - } - else - printmsg(CFSTR("%@: %@\n"), key, value); - }); - -} - -static void decodeForKeyType(CFTypeRef key, CFTypeRef value, SOSKVSKeyType type){ - switch (type) { - case kCircleKey: - displayCircle(key, value); - break; - case kRetirementKey: - case kMessageKey: - displayMessage(key, value); - break; - case kParametersKey: - displayKeyParameters(key, value); - break; - case kLastKeyParameterKey: - displayLastKeyParameters(key, value); - break; - case kLastCircleKey: - displayLastCircle(key, value); - break; - case kInitialSyncKey: - case kAccountChangedKey: - case kDebugInfoKey: - case kRingKey: - default: - printmsg(CFSTR("%@: %@\n"), key, value); - break; - } -} - -static void decodeAllTheValues(CFTypeRef objects){ - SOSKVSKeyType keyType = 0; - __block bool didPrint = false; - - for (keyType = 0; keyType <= MAXKVSKEYTYPE; keyType++){ - CFDictionaryForEach(objects, ^(const void *key, const void *value) { - if(SOSKVSKeyGetKeyType(key) == keyType){ - decodeForKeyType(key, value, keyType); - didPrint = true; - } - }); - if(didPrint) - printmsg(CFSTR("%@\n"), CFSTR("")); - didPrint = false; - } -} -static bool dumpKVS(char *itemName, CFErrorRef *err) -{ - CFArrayRef keysToGet = NULL; - if (itemName) - { - CFStringRef itemStr = CFStringCreateWithCString(kCFAllocatorDefault, itemName, kCFStringEncodingUTF8); - fprintf(outFile, "Retrieving %s from KVS\n", itemName); - keysToGet = CFArrayCreateForCFTypes(kCFAllocatorDefault, itemStr, NULL); - CFReleaseSafe(itemStr); - } - dispatch_queue_t generalq = dispatch_queue_create("general", DISPATCH_QUEUE_SERIAL); - dispatch_group_t work_group = dispatch_group_create(); - CFTypeRef objects = getObjectsFromCloud(keysToGet, generalq, work_group); - CFReleaseSafe(keysToGet); - if (objects) - { - fprintf(outFile, "All keys and values straight from KVS\n"); - printEverything(objects); - fprintf(outFile, "\nAll values in decoded form...\n"); - decodeAllTheValues(objects); - } - fprintf(outFile, "\n"); - return true; -} - static bool syncAndWait(CFErrorRef *err) { __block CFTypeRef objects = NULL; @@ -540,7 +178,7 @@ static bool syncAndWait(CFErrorRef *err) dispatch_semaphore_wait(waitSemaphore, finishTime); - dumpKVS(NULL, NULL); + (void)SOSCCDumpCircleKVSInformation(NULL); fprintf(outFile, "\n"); return false; } @@ -670,7 +308,9 @@ static bool dumpMyPeer(CFErrorRef *error) { } - return myPeer != NULL; + bool ret = myPeer != NULL; + CFReleaseNull(myPeer); + return ret; } static bool setBag(char *itemName, CFErrorRef *err) @@ -961,7 +601,8 @@ keychain_sync(int argc, char * const *argv) } case 'i': - dumpCircleInfo(); + SOSCCDumpCircleInformation(); + SOSCCDumpEngineInformation(); break; case 'k': @@ -970,7 +611,7 @@ keychain_sync(int argc, char * const *argv) case 'o': { - printPeerInfos("view-unaware", ^(CFErrorRef *error) { return SOSCCCopyViewUnawarePeerInfo(error); }); + SOSCCDumpViewUnwarePeers(); break; } @@ -1205,7 +846,7 @@ keychain_sync(int argc, char * const *argv) break; case 'D': - hadError = !dumpKVS(optarg, &error); + (void)SOSCCDumpCircleKVSInformation(optarg); break; case 'W': @@ -1236,7 +877,7 @@ keychain_sync(int argc, char * const *argv) break; case '?': default: - return 2; /* Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } if (hadError) diff --git a/OSX/sec/SOSCircle/Tool/keychain_sync_test.m b/OSX/sec/SOSCircle/Tool/keychain_sync_test.m index 1f345865..3aed8f9d 100644 --- a/OSX/sec/SOSCircle/Tool/keychain_sync_test.m +++ b/OSX/sec/SOSCircle/Tool/keychain_sync_test.m @@ -77,7 +77,7 @@ keychain_sync_test(int argc, char * const *argv) case -1: break; default: - return 2; + return SHOW_USAGE_MESSAGE; } } diff --git a/OSX/sec/SOSCircle/Tool/recovery_key.m b/OSX/sec/SOSCircle/Tool/recovery_key.m index 882111cc..f836de1f 100644 --- a/OSX/sec/SOSCircle/Tool/recovery_key.m +++ b/OSX/sec/SOSCircle/Tool/recovery_key.m @@ -66,16 +66,16 @@ recovery_key(int argc, char * const *argv) NSError *nserror = NULL; NSString *testString = [NSString stringWithUTF8String:optarg]; if(testString == nil) - return 2; + return SHOW_USAGE_MESSAGE; SecRecoveryKey *rk = SecRKCreateRecoveryKeyWithError(testString, &nserror); if(rk == nil) { printmsg(CFSTR("SecRKCreateRecoveryKeyWithError: %@\n"), nserror); - return 2; + return SHOW_USAGE_MESSAGE; } NSData *publicKey = SecRKCopyBackupPublicKey(rk); if(publicKey == nil) - return 2; + return SHOW_USAGE_MESSAGE; printmsg(CFSTR("example (not registered) public recovery key: %@\n"), publicKey); break; @@ -83,7 +83,7 @@ recovery_key(int argc, char * const *argv) case 'R': { NSString *testString = SecRKCreateRecoveryKeyString(NULL); if(testString == nil) - return 2; + return SHOW_USAGE_MESSAGE; printmsg(CFSTR("public recovery string: %@\n"), testString); @@ -94,19 +94,19 @@ recovery_key(int argc, char * const *argv) NSError *nserror = NULL; NSString *testString = [NSString stringWithUTF8String:optarg]; if(testString == nil) - return 2; + return SHOW_USAGE_MESSAGE; SecRecoveryKey *rk = SecRKCreateRecoveryKeyWithError(testString, &nserror); if(rk == nil) { printmsg(CFSTR("SecRKCreateRecoveryKeyWithError: %@\n"), nserror); - return 2; + return SHOW_USAGE_MESSAGE; } CFErrorRef cferror = NULL; if(!SecRKRegisterBackupPublicKey(rk, &cferror)) { printmsg(CFSTR("Error from SecRKRegisterBackupPublicKey: %@\n"), cferror); CFReleaseNull(cferror); - return 2; + return SHOW_USAGE_MESSAGE; } break; } @@ -146,12 +146,12 @@ recovery_key(int argc, char * const *argv) NSString *testString = [NSString stringWithUTF8String:optarg]; NSString *fileName = [NSString stringWithFormat:@"%@.plist", testString]; if(testString == nil) - return 2; + return SHOW_USAGE_MESSAGE; NSDictionary *ver = SecRKCopyAccountRecoveryVerifier(testString, &localError); if(ver == nil) { printmsg(CFSTR("Failed to make verifier dictionary: %@\n"), localError); - return 2; + return SHOW_USAGE_MESSAGE; } printmsg(CFSTR("Verifier Dictionary: %@\n\n"), ver); @@ -169,7 +169,7 @@ recovery_key(int argc, char * const *argv) for (unsigned n = 0; n < sizeof(long_options)/sizeof(long_options[0]); n++) { printf("\t [-%c|--%s\n", long_options[n].val, long_options[n].name); } - return 2; + return SHOW_USAGE_MESSAGE; } } if (hadError) diff --git a/OSX/sec/SOSCircle/Tool/syncbackup.m b/OSX/sec/SOSCircle/Tool/syncbackup.m index d44a94d7..d2f13955 100644 --- a/OSX/sec/SOSCircle/Tool/syncbackup.m +++ b/OSX/sec/SOSCircle/Tool/syncbackup.m @@ -136,7 +136,7 @@ syncbackup(int argc, char * const *argv) case '?': default: - return 2; /* Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } if (hadError) diff --git a/OSX/sec/Security/Regressions/otr/otr-otrdh.c b/OSX/sec/Security/Regressions/otr/otr-otrdh.c index e852ff06..1a569976 100644 --- a/OSX/sec/Security/Regressions/otr/otr-otrdh.c +++ b/OSX/sec/Security/Regressions/otr/otr-otrdh.c @@ -80,7 +80,9 @@ int otr_otrdh(int argc, char *const * argv) ok(0 == memcmp(aliceMacKeys[0], bobMacKeys[1], sizeof(aliceMacKeys[0])), "Mac Keys don't match!!"); ok(0 == memcmp(aliceMacKeys[1], bobMacKeys[0], sizeof(aliceMacKeys[1])), "Mac Keys don't match!!"); CFReleaseNull(aliceCompactSerialized); + CFReleaseNull(aliceCompactDeserialized); CFReleaseNull(aliceSerialized); + CFReleaseNull(aliceDeserialized); CFReleaseNull(aliceFull); CFReleaseNull(alicePublic); CFReleaseNull(bobFull); diff --git a/OSX/sec/Security/Regressions/secitem/si-10-find-internet.c b/OSX/sec/Security/Regressions/secitem/si-10-find-internet.c index 65e28052..57694b9c 100644 --- a/OSX/sec/Security/Regressions/secitem/si-10-find-internet.c +++ b/OSX/sec/Security/Regressions/secitem/si-10-find-internet.c @@ -59,6 +59,7 @@ static void tests(void) ok_status(SecItemCopyMatching(query2, &results), "find internet password, return attributes"); CFReleaseNull(query2); query2 = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, results); + CFReleaseNull(results); CFDictionaryRemoveValue(query2, kSecAttrSHA1), CFDictionarySetValue(query2, kSecClass, kSecClassInternetPassword); CFDictionarySetValue(query2, kSecReturnData, kCFBooleanTrue); diff --git a/OSX/sec/Security/Regressions/secitem/si-15-certificate.c b/OSX/sec/Security/Regressions/secitem/si-15-certificate.c index 2407e3aa..bd51a64c 100644 --- a/OSX/sec/Security/Regressions/secitem/si-15-certificate.c +++ b/OSX/sec/Security/Regressions/secitem/si-15-certificate.c @@ -982,13 +982,76 @@ static void test_copy_email_addresses(void) { CFReleaseNull(array); } +static void test_copy_extension_value(void) { + SecCertificateRef cert = SecCertificateCreateWithBytes(NULL, mail_google_com, sizeof(mail_google_com)); + CFDataRef extension = NULL, expected = NULL, oid = NULL; + bool critical = false; + + /* parameter fails */ + is(extension = SecCertificateCopyExtensionValue(NULL, CFSTR("1.2.3.4"), &critical), NULL, + "NULL cert input succeeded"); + is(extension = SecCertificateCopyExtensionValue(cert, NULL, &critical), NULL, + "NULL OID input succeeded"); + + /* Extension not present */ + is(extension = SecCertificateCopyExtensionValue(cert, CFSTR("1.2.3.4"), &critical), NULL, + "Got extension value for non-present extension OID"); + + /* Using decimal OID, extension present and critical */ + isnt(extension = SecCertificateCopyExtensionValue(cert, CFSTR("2.5.29.19"), &critical), NULL, + "Failed to get extension for present extension OID"); + is(critical, true, "Got wrong criticality for critical extension"); + uint8_t basic_constraints_value[2] = { 0x30, 0x00 }; + expected = CFDataCreate(NULL, basic_constraints_value, sizeof(basic_constraints_value)); + ok(CFEqual(extension, expected), "Got wrong extension value for basic constraints"); + CFReleaseNull(extension); + CFReleaseNull(expected); + + /* Using binary OID, extension present and non critical */ + uint8_t oidExtendedKeyUsage[3] = { 0x55, 0x01d, 0x25 }; + oid = CFDataCreate(NULL, oidExtendedKeyUsage, sizeof(oidExtendedKeyUsage)); + isnt(extension = SecCertificateCopyExtensionValue(cert, oid, &critical), NULL, + "Failed to get extension for present extension OID"); + is(critical, false, "Got wrong criticality for non-critical extension"); + uint8_t eku_value[] = { + 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, + 0x01 + }; + expected = CFDataCreate(NULL, eku_value, sizeof(eku_value)); + ok(CFEqual(extension, expected), "Got wrong extension value for extended key usage"); + CFReleaseNull(oid); + CFReleaseNull(extension); + CFReleaseNull(expected); + + /* No critical output */ + isnt(extension = SecCertificateCopyExtensionValue(cert, CFSTR("2.5.29.19"), NULL), NULL, + "Failed to get extension for present extension OID"); + CFReleaseNull(extension); + + /* messed up binary OIDs */ + is(extension = SecCertificateCopyExtensionValue(cert, CFSTR("abcd"), NULL), NULL, + "letters in OID"); + is(extension = SecCertificateCopyExtensionValue(cert, CFSTR("8.1.1.2"), NULL), NULL, + "bad first arc"); + is(extension = SecCertificateCopyExtensionValue(cert, CFSTR("10.1.1.1"), NULL), NULL, + "longer bad first arc"); + is(extension = SecCertificateCopyExtensionValue(cert, CFSTR(""), NULL), NULL, + "empty string"); + is(extension = SecCertificateCopyExtensionValue(cert, CFSTR("1.2.1099511627776."), NULL), NULL, + "six byte component"); + + CFReleaseNull(cert); +} + int si_15_certificate(int argc, char *const *argv) { - plan_tests(30); + plan_tests(45); tests(); test_common_name(); test_copy_email_addresses(); + test_copy_extension_value(); return 0; } diff --git a/OSX/sec/Security/Regressions/secitem/si-18-certificate-parse.m b/OSX/sec/Security/Regressions/secitem/si-18-certificate-parse.m index 6f59d94a..bca3b341 100644 --- a/OSX/sec/Security/Regressions/secitem/si-18-certificate-parse.m +++ b/OSX/sec/Security/Regressions/secitem/si-18-certificate-parse.m @@ -142,7 +142,7 @@ static void test_path_parse_failure(void) { require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)[NSDate dateWithTimeIntervalSinceReferenceDate:507200000.0]), blockOut, fail("Unable to set verify date: %@", url)); require_noerr_action(SecTrustEvaluate(trust, &trustResult), blockOut, - fail("Failed ot evaluate trust with error: %@", url)); + fail("Failed to evaluate trust with error: %@", url)); is(trustResult, kSecTrustResultRecoverableTrustFailure, "Got wrong trust result (%d) for %@", trustResult, url); require_action(cert, blockOut, diff --git a/OSX/sec/Security/Regressions/secitem/si-20-sectrust.c b/OSX/sec/Security/Regressions/secitem/si-20-sectrust.c index fc0dd486..33cc714d 100644 --- a/OSX/sec/Security/Regressions/secitem/si-20-sectrust.c +++ b/OSX/sec/Security/Regressions/secitem/si-20-sectrust.c @@ -451,7 +451,7 @@ static bool test_chain_of_three(uint8_t *cert0, size_t cert0len, ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate chain"); is(SecTrustGetCertificateCount(trust), 3, "expected chain of 3"); - bool did_succeed = (trustResult == kSecTrustResultUnspecified); + bool did_succeed = (trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed); if (failureReason && should_succeed && !did_succeed) { *failureReason = SecTrustCopyFailureDescription(trust); @@ -647,12 +647,260 @@ errOut: CFReleaseNull(date); } +static void test_evaluate_with_error(void) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability-new" + + SecCertificateRef cert0 = NULL, cert1 = NULL, cert2 = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CFArrayRef certificates = NULL, roots = NULL; + CFDateRef date = NULL, validDate = NULL; + CFErrorRef error = NULL; + + require(cert0 = SecCertificateCreateWithBytes(NULL, _expired_badssl, sizeof(_expired_badssl)), errOut); + require(cert1 = SecCertificateCreateWithBytes(NULL, _comodo_rsa_dvss, sizeof(_comodo_rsa_dvss)), errOut); + require(cert2 = SecCertificateCreateWithBytes(NULL, _comodo_rsa_root, sizeof(_comodo_rsa_root)), errOut); + + const void *v_certs[] = { + cert0, + cert1 + }; + certificates = CFArrayCreate(NULL, v_certs, + array_size(v_certs), + &kCFTypeArrayCallBacks); + + const void *v_roots[] = { + cert2 + }; + roots = CFArrayCreate(NULL, v_roots, + array_size(v_roots), + &kCFTypeArrayCallBacks); + + require(policy = SecPolicyCreateSSL(true, CFSTR("expired.badssl.com")), errOut); + require_noerr(SecTrustCreateWithCertificates(certificates, policy, &trust), errOut); + require_noerr(SecTrustSetAnchorCertificates(trust, roots), errOut); + + /* April 10 2015 (cert expired in 2015) */ + require(validDate = CFDateCreateForGregorianZuluMoment(NULL, 2015, 4, 10, 12, 0, 0), errOut); + require_noerr(SecTrustSetVerifyDate(trust, validDate), errOut); + + is(SecTrustEvaluateWithError(trust, &error), true, "wrong result for valid cert"); + is(error, NULL, "set error for passing trust evaluation"); + CFReleaseNull(error); + + /* Mar 21 2017 (cert expired in 2015, so this will cause a validity error.) */ + require(date = CFDateCreateForGregorianZuluMoment(NULL, 2017, 3, 21, 12, 0, 0), errOut); + require_noerr(SecTrustSetVerifyDate(trust, date), errOut); + + /* expect expiration error */ + is(SecTrustEvaluateWithError(trust, &error), false, "wrong result for expired cert"); + isnt(error, NULL, "failed to set error for failing trust evaluation"); + is(CFErrorGetCode(error), errSecCertificateExpired, "Got wrong error code for evaluation"); + CFReleaseNull(error); + + CFReleaseNull(policy); + require(policy = SecPolicyCreateSSL(true, CFSTR("expired.terriblessl.com")), errOut); + require_noerr(SecTrustSetPolicies(trust, policy), errOut); + + /* expect a hostname mismatch as well as expiration; hostname mismatch must be a higher priority */ + is(SecTrustEvaluateWithError(trust, &error), false, "wrong result for expired cert with hostname mismatch"); + isnt(error, NULL, "failed to set error for failing trust evaluation"); + is(CFErrorGetCode(error), errSecHostNameMismatch, "Got wrong error code for evaluation"); + CFReleaseNull(error); + + /* expect only a hostname mismatch*/ + require_noerr(SecTrustSetVerifyDate(trust, validDate), errOut); + is(SecTrustEvaluateWithError(trust, &error), false, "wrong result for valid cert with hostname mismatch"); + isnt(error, NULL, "failed to set error for failing trust evaluation"); + is(CFErrorGetCode(error), errSecHostNameMismatch, "Got wrong error code for evaluation"); + CFReleaseNull(error); + + /* pinning failure */ + CFReleaseNull(policy); + require(policy = SecPolicyCreateAppleSSLPinned(CFSTR("test"), CFSTR("expired.badssl.com"), + NULL, CFSTR("1.2.840.113635.100.6.27.1")), errOut); + require_noerr(SecTrustSetPolicies(trust, policy), errOut); + + is(SecTrustEvaluateWithError(trust, &error), false, "wrong result for valid cert with pinning failure"); + isnt(error, NULL, "failed to set error for failing trust evaluation"); + CFIndex errorCode = CFErrorGetCode(error); + // failed checks: AnchorApple, LeafMarkerOid, or IntermediateMarkerOid + ok(errorCode == errSecMissingRequiredExtension || errorCode == errSecInvalidRoot, "Got wrong error code for evaluation"); + CFReleaseNull(error); + + /* trust nothing, trust errors higher priority than hostname mismatch */ + CFReleaseNull(policy); + require(policy = SecPolicyCreateSSL(true, CFSTR("expired.terriblessl.com")), errOut); + require_noerr(SecTrustSetPolicies(trust, policy), errOut); + + CFReleaseNull(roots); + roots = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks); + require_noerr(SecTrustSetAnchorCertificates(trust, roots), errOut); + is(SecTrustEvaluateWithError(trust, &error), false, "wrong result for expired cert with hostname mismatch"); + isnt(error, NULL, "failed to set error for failing trust evaluation"); + is(CFErrorGetCode(error), errSecNotTrusted, "Got wrong error code for evaluation"); + CFReleaseNull(error); + +errOut: + CFReleaseNull(trust); + CFReleaseNull(cert0); + CFReleaseNull(cert1); + CFReleaseNull(cert2); + CFReleaseNull(policy); + CFReleaseNull(certificates); + CFReleaseNull(roots); + CFReleaseNull(date); + CFReleaseNull(validDate); + CFReleaseNull(error); + +#pragma clang diagnostic pop +} + +static void test_optional_policy_check(void) { + SecCertificateRef cert0 = NULL, cert1 = NULL, root = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = NULL; + CFArrayRef certs = NULL, anchors = NULL; + CFDateRef date = NULL; + + require_action(cert0 = SecCertificateCreateWithBytes(NULL, _leaf384C, sizeof(_leaf384C)), errOut, + fail("unable to create cert")); + require_action(cert1 = SecCertificateCreateWithBytes(NULL, _int384B, sizeof(_int384B)), errOut, + fail("unable to create cert")); + require_action(root = SecCertificateCreateWithBytes(NULL, _root384, sizeof(_root384)), errOut, + fail("unable to create cert")); + + const void *v_certs[] = { cert0, cert1 }; + require_action(certs = CFArrayCreate(NULL, v_certs, array_size(v_certs), &kCFTypeArrayCallBacks), errOut, + fail("unable to create array")); + require_action(anchors = CFArrayCreate(NULL, (const void **)&root, 1, &kCFTypeArrayCallBacks), errOut, + fail("unable to create anchors array")); + require_action(date = CFDateCreate(NULL, 472100000.0), errOut, fail("unable to create date")); + + require_action(policy = SecPolicyCreateBasicX509(), errOut, fail("unable to create policy")); + SecPolicySetOptionsValue(policy, CFSTR("not-a-policy-check"), kCFBooleanTrue); + + ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "failed to create trust"); + require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, + fail("unable to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, date), errOut, fail("unable to set verify date")); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability-new" +#if NDEBUG + ok(SecTrustEvaluateWithError(trust, NULL), "Trust evaluation failed"); +#else + is(SecTrustEvaluateWithError(trust, NULL), false, "Expect failure in Debug config"); +#endif +#pragma clang diagnostic pop + +errOut: + CFReleaseNull(cert0); + CFReleaseNull(cert1); + CFReleaseNull(root); + CFReleaseNull(certs); + CFReleaseNull(anchors); + CFReleaseNull(date); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +static void test_serialization(void) { + SecCertificateRef cert0 = NULL, cert1 = NULL, root = NULL; + SecTrustRef trust = NULL, deserializedTrust = NULL; + SecPolicyRef policy = NULL; + CFArrayRef certs = NULL, anchors = NULL, deserializedCerts = NULL; + CFDateRef date = NULL; + CFDataRef serializedTrust = NULL; + CFErrorRef error = NULL; + + require_action(cert0 = SecCertificateCreateWithBytes(NULL, _leaf384C, sizeof(_leaf384C)), errOut, + fail("unable to create cert")); + require_action(cert1 = SecCertificateCreateWithBytes(NULL, _int384B, sizeof(_int384B)), errOut, + fail("unable to create cert")); + require_action(root = SecCertificateCreateWithBytes(NULL, _root384, sizeof(_root384)), errOut, + fail("unable to create cert")); + + const void *v_certs[] = { cert0, cert1 }; + require_action(certs = CFArrayCreate(NULL, v_certs, array_size(v_certs), &kCFTypeArrayCallBacks), errOut, + fail("unable to create array")); + require_action(anchors = CFArrayCreate(NULL, (const void **)&root, 1, &kCFTypeArrayCallBacks), errOut, + fail("unable to create anchors array")); + require_action(date = CFDateCreate(NULL, 472100000.0), errOut, fail("unable to create date")); + + require_action(policy = SecPolicyCreateBasicX509(), errOut, fail("unable to create policy")); + + ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "failed to create trust"); + require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, + fail("unable to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, date), errOut, fail("unable to set verify date")); + + ok(serializedTrust = SecTrustSerialize(trust, NULL), "failed to serialize trust"); + ok(deserializedTrust = SecTrustDeserialize(serializedTrust, NULL), "Failed to deserialize trust"); + CFReleaseNull(serializedTrust); + + require_noerr_action(SecTrustCopyCustomAnchorCertificates(deserializedTrust, &deserializedCerts), errOut, + fail("unable to get anchors from deserialized trust")); + ok(CFEqual(anchors, deserializedCerts), "Failed to get the same anchors after serialization/deserialization"); + CFReleaseNull(deserializedCerts); + + require_noerr_action(SecTrustCopyInputCertificates(trust, &deserializedCerts), errOut, + fail("unable to get input certificates from deserialized trust")); + ok(CFEqual(certs, deserializedCerts), "Failed to get same input certificates after serialization/deserialization"); + CFReleaseNull(deserializedCerts); + + /* correct API behavior */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" + is(SecTrustSerialize(NULL, &error), NULL, "serialize succeeded with null input"); + is(CFErrorGetCode(error), errSecParam, "Incorrect error code for bad serialization input"); + CFReleaseNull(error); + is(SecTrustDeserialize(NULL, &error), NULL, "deserialize succeeded with null input"); + is(CFErrorGetCode(error), errSecParam, "Incorrect error code for bad deserialization input"); + CFReleaseNull(error); +#pragma clang diagnostic pop + +errOut: + CFReleaseNull(cert0); + CFReleaseNull(cert1); + CFReleaseNull(root); + CFReleaseNull(certs); + CFReleaseNull(anchors); + CFReleaseNull(date); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(deserializedTrust); +} + +static void test_tls_analytics_report(void) +{ + xpc_object_t metric = xpc_dictionary_create(NULL, NULL, 0); + ok(metric != NULL); + + const char *TLS_METRIC_PROCESS_IDENTIFIER = "process"; + const char *TLS_METRIC_CIPHERSUITE = "cipher_name"; + const char *TLS_METRIC_PROTOCOL_VERSION = "version"; + const char *TLS_METRIC_SESSION_RESUMED = "resumed"; + + xpc_dictionary_set_string(metric, TLS_METRIC_PROCESS_IDENTIFIER, "super awesome unit tester"); + xpc_dictionary_set_uint64(metric, TLS_METRIC_CIPHERSUITE, 0x0304); + xpc_dictionary_set_uint64(metric, TLS_METRIC_PROTOCOL_VERSION, 0x0304); + xpc_dictionary_set_bool(metric, TLS_METRIC_SESSION_RESUMED, false); + // ... TLS would fill in the rest + + // Invoke the callback + CFErrorRef error = NULL; + bool reported = SecTrustReportTLSAnalytics(CFSTR("TLSConnectionEvent"), metric, &error); + ok(reported, "Failed to report analytics with error %@", error); +} + int si_20_sectrust(int argc, char *const *argv) { #if TARGET_OS_IPHONE - plan_tests(101+9+(8*13)+9+1+2); + plan_tests(101+9+(8*13)+9+1+2+17+2+9+2); #else - plan_tests(97+9+(8*13)+9+1+2+2); + plan_tests(97+9+(8*13)+9+1+2+2+17+2+9+2); #endif basic_tests(); @@ -664,6 +912,10 @@ int si_20_sectrust(int argc, char *const *argv) test_input_certificates(); test_async_trust(); test_expired_only(); + test_evaluate_with_error(); + test_optional_policy_check(); + test_serialization(); + test_tls_analytics_report(); return 0; } diff --git a/OSX/sec/Security/Regressions/secitem/si-22-sectrust-iap.c b/OSX/sec/Security/Regressions/secitem/si-22-sectrust-iap.c index e75eebb8..3f1c0bc5 100644 --- a/OSX/sec/Security/Regressions/secitem/si-22-sectrust-iap.c +++ b/OSX/sec/Security/Regressions/secitem/si-22-sectrust-iap.c @@ -1,7 +1,8 @@ /* - * Copyright (c) 2006-2016 Apple Inc. All Rights Reserved. + * Copyright (c) 2006-2017 Apple Inc. All Rights Reserved. */ +#include #include #include #include @@ -16,7 +17,7 @@ #include "si-22-sectrust-iap.h" -static void tests(void) +static void test_v1(void) { SecTrustRef trust; SecCertificateRef iAP1CA, iAP2CA, leaf0, leaf1; @@ -79,7 +80,7 @@ static void tests(void) static void test_v3(void) { SecCertificateRef v3CA = NULL, v3leaf = NULL; isnt(v3CA = SecCertificateCreateWithBytes(NULL, _v3ca, sizeof(_v3ca)), - NULL, "create v3leaf"); + NULL, "create v3 CA"); isnt(v3leaf = SecCertificateCreateWithBytes(NULL, _v3leaf, sizeof(_v3leaf)), NULL, "create v3leaf"); @@ -108,7 +109,6 @@ trustFail: CFReleaseSafe(anchors); CFReleaseSafe(date); -#if TARGET_OS_IPHONE /* Test interface for determining iAuth version */ SecCertificateRef leaf0 = NULL, leaf1 = NULL; isnt(leaf0 = SecCertificateCreateWithBytes(NULL, _leaf0, sizeof(_leaf0)), @@ -151,20 +151,15 @@ trustFail: "compare expected output"); CFReleaseNull(extensionData); CFReleaseNull(malformedV3leaf); -#endif CFReleaseSafe(v3leaf); CFReleaseSafe(v3CA); } int si_22_sectrust_iap(int argc, char *const *argv) { -#if TARGET_OS_IPHONE plan_tests(14+20); -#else - plan_tests(14+8); -#endif - tests(); + test_v1(); test_v3(); return 0; diff --git a/OSX/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.c b/OSX/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.c index d9b3ce58..df8a5cb1 100644 --- a/OSX/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.c +++ b/OSX/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.c @@ -1202,7 +1202,7 @@ static void test_forced_revocation() isnt(VerifyDate = CFDateCreate(NULL, 332900000.0), NULL, "Create verify date"); if (!VerifyDate) { goto errOut; } - // Standard evaluation should succeed for the given verify date + // Standard evaluation for the given verify date { SecTrustRef trust = NULL; SecTrustResultType trust_result; @@ -1215,7 +1215,9 @@ static void test_forced_revocation() ok_status(status = SecTrustEvaluate(trust, &trust_result), "SecTrustEvaluate"); // Check results - is_status(trust_result, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); + // %%% This is now expected to fail, since the "TC TrustCenter Class 1 L1 CA IX" CA is revoked + // and the revocation information is present in the Valid database. + is_status(trust_result, kSecTrustResultFatalTrustFailure, "trust is kSecTrustResultFatalTrustFailure"); CFReleaseNull(trust); } @@ -1234,7 +1236,9 @@ static void test_forced_revocation() ok_status(status = SecTrustEvaluate(trust, &trust_result), "SecTrustEvaluate"); // Check results - is_status(trust_result, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure"); + // %%% This is now expected to fail, since the "TC TrustCenter Class 1 L1 CA IX" CA is revoked + // and the revocation information is present in the Valid database. + is_status(trust_result, kSecTrustResultFatalTrustFailure, "trust is kSecTrustResultFatalTrustFailure"); CFReleaseNull(trust); } diff --git a/OSX/sec/Security/Regressions/secitem/si-32-sectrust-pinning-required.m b/OSX/sec/Security/Regressions/secitem/si-32-sectrust-pinning-required.m index e63c9d73..7a006405 100644 --- a/OSX/sec/Security/Regressions/secitem/si-32-sectrust-pinning-required.m +++ b/OSX/sec/Security/Regressions/secitem/si-32-sectrust-pinning-required.m @@ -86,15 +86,18 @@ static void tests(void) policy = SecPolicyCreateSSL(true, CFSTR("openmarket.ess.apple.com")); SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue); - is(test_with_policy(policy), kSecTrustResultRecoverableTrustFailure, "Unpinned connection succeeeded when pinning required"); + //%%% openmarket.ess.apple.com cert is now revoked, so expect a fatal result. + is(test_with_policy(policy), kSecTrustResultFatalTrustFailure, "Unpinned connection succeeeded when pinning required"); policy = SecPolicyCreateAppleIDSServiceContext(CFSTR("openmarket.ess.apple.com"), NULL); SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue); - is(test_with_policy(policy), kSecTrustResultUnspecified, "Policy pinned connection failed when pinning required"); + //%%% openmarket.ess.apple.com cert is now revoked, so expect a fatal result. + is(test_with_policy(policy), kSecTrustResultFatalTrustFailure, "Policy pinned connection failed when pinning required"); policy = SecPolicyCreateSSL(true, CFSTR("profile.ess.apple.com")); + //%%% profile.ess.apple.com cert is now revoked, so expect a fatal result. SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue); - is(test_with_policy(policy), kSecTrustResultUnspecified, "Systemwide hostname pinned connection failed when pinning required"); + is(test_with_policy(policy), kSecTrustResultFatalTrustFailure, "Systemwide hostname pinned connection failed when pinning required"); NSDictionary *policy_properties = @{ (__bridge NSString *)kSecPolicyName : @"openmarket.ess.apple.com", @@ -102,11 +105,13 @@ static void tests(void) }; policy = SecPolicyCreateWithProperties(kSecPolicyAppleSSL, (__bridge CFDictionaryRef)policy_properties); SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue); - is(test_with_policy(policy), kSecTrustResultUnspecified, "Systemwide policy name pinned connection failed when pinning required"); + //%%% openmarket.ess.apple.com cert is now revoked, so expect a fatal result. + is(test_with_policy(policy), kSecTrustResultFatalTrustFailure, "Systemwide policy name pinned connection failed when pinning required"); policy = SecPolicyCreateSSL(true, CFSTR("openmarket.ess.apple.com")); SecPolicySetOptionsValue(policy, kSecPolicyCheckPinningRequired, kCFBooleanTrue); - is(test_with_policy_exception(policy, true), kSecTrustResultUnspecified, "Unpinned connection failed when pinning exception set"); + //%%% openmarket.ess.apple.com cert is now revoked, so expect a fatal result. + is(test_with_policy_exception(policy, true), kSecTrustResultFatalTrustFailure, "Unpinned connection failed when pinning exception set"); /* can I write an effective test for charles?? */ } diff --git a/OSX/sec/Security/Regressions/secitem/si-60-cms.c b/OSX/sec/Security/Regressions/secitem/si-60-cms.c index 0a3ba7d6..4ebc3948 100644 --- a/OSX/sec/Security/Regressions/secitem/si-60-cms.c +++ b/OSX/sec/Security/Regressions/secitem/si-60-cms.c @@ -21,6 +21,7 @@ * @APPLE_LICENSE_HEADER_END@ */ +#include #include #include @@ -1783,6 +1784,7 @@ static void tests(void) CFDataSetLength(message_data, 0); #if TARGET_OS_IPHONE + /* macOS never supported signing with MD5 */ CFMutableDictionaryRef params = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(params, kSecCMSSignHashAlgorithm, kSecCMSHashingAlgorithmMD5); is(SecCMSCreateSignedData(identity, NULL, params, NULL, message_data), errSecParam, "signing md5 message should fail"); @@ -1850,15 +1852,100 @@ static void tests(void) CFReleaseNull(message_data); } +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Neptune */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Neptune */ +/* X509v3 Key Usage: Certificate Sign, CRL Sign */ +uint8_t _cacert[964]={ + 0x30,0x82,0x03,0xC0,0x30,0x82,0x02,0xA8,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0xCD,0xDF,0x76,0xED,0x2A,0x08,0xF1,0x74,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x7C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55, + 0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C, + 0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x12,0x30,0x10,0x06, + 0x03,0x55,0x04,0x07,0x0C,0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E,0x6F,0x31, + 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20, + 0x49,0x6E,0x63,0x2E,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x0C,0x14,0x53, + 0x65,0x63,0x75,0x72,0x69,0x74,0x79,0x20,0x45,0x6E,0x67,0x69,0x6E,0x65,0x65,0x72, + 0x69,0x6E,0x67,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x03,0x0C,0x07,0x4E,0x65, + 0x70,0x74,0x75,0x6E,0x65,0x30,0x1E,0x17,0x0D,0x31,0x38,0x30,0x32,0x32,0x37,0x31, + 0x39,0x35,0x39,0x32,0x31,0x5A,0x17,0x0D,0x32,0x38,0x30,0x32,0x32,0x35,0x31,0x39, + 0x35,0x39,0x32,0x31,0x5A,0x30,0x7C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06, + 0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C,0x0A,0x43, + 0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x12,0x30,0x10,0x06,0x03,0x55, + 0x04,0x07,0x0C,0x09,0x43,0x75,0x70,0x65,0x72,0x74,0x69,0x6E,0x6F,0x31,0x13,0x30, + 0x11,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E, + 0x63,0x2E,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x0C,0x14,0x53,0x65,0x63, + 0x75,0x72,0x69,0x74,0x79,0x20,0x45,0x6E,0x67,0x69,0x6E,0x65,0x65,0x72,0x69,0x6E, + 0x67,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x03,0x0C,0x07,0x4E,0x65,0x70,0x74, + 0x75,0x6E,0x65,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, + 0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02, + 0x82,0x01,0x01,0x00,0xD6,0xFA,0x29,0x49,0x27,0x13,0x4E,0x50,0x00,0x5E,0xEB,0x0E, + 0xD3,0x33,0x30,0xC6,0x47,0x76,0x9C,0xBA,0x81,0x38,0xB5,0x91,0x54,0xB2,0x28,0x95, + 0x5E,0xFA,0x9E,0xC3,0x7A,0xDC,0x90,0xA4,0xDD,0xB3,0xB4,0x3F,0x95,0x1A,0x3B,0x1A, + 0x17,0xC2,0xA2,0xDC,0x8E,0x67,0xBC,0x3D,0x28,0x53,0xC0,0xDE,0x8C,0xED,0x1F,0x70, + 0xC3,0x96,0x5C,0x46,0x90,0xA3,0xE4,0xC3,0xEC,0x78,0xBD,0x88,0x6B,0x3B,0xE3,0xC3, + 0x78,0xE3,0xA4,0x9F,0x6E,0xAE,0x67,0x0A,0xC8,0xAC,0xE3,0xD9,0xCB,0x2C,0xDE,0xB2, + 0x2A,0x72,0x2F,0x91,0x81,0x99,0xED,0xC1,0x60,0x82,0x1E,0xA3,0xE0,0x79,0x20,0x8B, + 0x7F,0xDC,0x89,0xAA,0x13,0x3B,0x7C,0x61,0x4E,0xA4,0xF1,0x8D,0xA3,0x07,0x45,0xAB, + 0x5E,0x1B,0xDB,0x12,0x34,0x24,0xF3,0x0C,0xC8,0x09,0x00,0xF1,0x02,0x9A,0x40,0xDF, + 0x2C,0xF3,0xB6,0x92,0x1E,0x5F,0x1B,0xAA,0x25,0x11,0x51,0x8C,0x9C,0x5F,0x14,0xD8, + 0x5F,0x3C,0xE8,0x94,0xC0,0xDF,0xF8,0xCF,0x72,0xE4,0xD6,0x80,0x0A,0xB1,0xFC,0x50, + 0x27,0xE5,0xB4,0xDC,0xE4,0xD8,0x8F,0xA2,0x2B,0x06,0xC5,0x74,0xC8,0x52,0x3A,0x3A, + 0x2D,0x21,0xC9,0x6E,0x48,0x1E,0xC8,0x90,0x82,0x54,0xB9,0x41,0x0C,0xBB,0x24,0xBB, + 0x7E,0x4A,0xCF,0x4F,0xBA,0xA1,0xA7,0xAA,0x67,0x1C,0xA2,0x3F,0x8B,0xB8,0xDE,0x68, + 0x2B,0x6E,0x5C,0xCE,0xD6,0xD0,0xC7,0xE5,0x13,0xE5,0x85,0x96,0xD1,0xCD,0xC2,0x77, + 0xC2,0x84,0xE0,0x78,0xE8,0x5C,0x81,0x33,0xA3,0xA1,0xAD,0xDE,0xBB,0x55,0xA3,0x49, + 0x89,0x55,0xC7,0x35,0x02,0x03,0x01,0x00,0x01,0xA3,0x45,0x30,0x43,0x30,0x12,0x06, + 0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01, + 0x00,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01, + 0x06,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x88,0x51,0xE5,0x13, + 0xF5,0x10,0xCF,0xA8,0x79,0xB1,0x20,0x89,0xA4,0xBF,0x95,0xD4,0xB3,0x41,0xC8,0x2B, + 0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03, + 0x82,0x01,0x01,0x00,0x44,0x82,0x0F,0x82,0x37,0x2D,0xA8,0x84,0xF1,0xC5,0x11,0x5B, + 0x42,0xCD,0x55,0xC1,0x61,0xB2,0x4B,0x63,0xCE,0x8C,0xFE,0x80,0x19,0x56,0x7B,0x7C, + 0x73,0xA4,0xE7,0xA1,0x01,0xD6,0xF7,0x0E,0x9A,0xA3,0x40,0x6F,0x12,0x78,0xCE,0x4F, + 0x94,0xE9,0xC7,0x31,0x81,0x0B,0x4B,0x67,0xFF,0x6B,0xD4,0xFE,0x51,0x86,0xA3,0xD0, + 0xA2,0xEE,0x1C,0xEB,0xED,0x72,0xF9,0x76,0x9B,0x0F,0xCC,0xF0,0x20,0xE0,0x7B,0x05, + 0x39,0xDA,0x5B,0xA4,0x1F,0xD1,0x6F,0xD9,0xB0,0x5D,0x98,0xE6,0xC5,0x2B,0x80,0x0E, + 0x6C,0x2A,0x2A,0xEE,0xD2,0x1D,0xF5,0xB8,0x9A,0x1A,0x2E,0x23,0xA8,0x1E,0xFF,0xF8, + 0x90,0x84,0x4C,0x7B,0xE1,0x64,0xFB,0xD3,0x11,0x53,0x96,0x55,0x25,0xD3,0x23,0xB5, + 0x8E,0x29,0xF4,0x16,0x60,0x64,0xD1,0x52,0xF3,0x0E,0xB8,0x43,0xE3,0x72,0xE9,0xDC, + 0x33,0xA4,0x39,0xDA,0xB9,0xD0,0x48,0x5C,0x89,0xF3,0x0C,0x7C,0x8F,0xE9,0x4A,0x73, + 0x54,0x14,0x9B,0xB4,0xCF,0x3D,0xF5,0x41,0xC0,0xD8,0x01,0xB5,0x64,0x45,0x65,0x7D, + 0x77,0xA2,0x4C,0x1A,0x97,0x29,0x1A,0xD9,0x32,0x4F,0x81,0xDD,0xF9,0x30,0xEF,0xEF, + 0xA9,0x6C,0x87,0x9E,0x6B,0x1A,0xF1,0x52,0x98,0x5B,0xAC,0xF5,0x7B,0x24,0x2D,0xFB, + 0x28,0x53,0x63,0x95,0xA2,0x66,0xE7,0xE3,0x04,0xD7,0xEB,0x95,0x91,0x5E,0x24,0xE3, + 0x28,0x60,0x43,0xBF,0x8B,0x11,0xCA,0xC1,0xA6,0xC3,0xF9,0x50,0x94,0xEE,0x2D,0xCC, + 0x0D,0xE3,0x65,0xD9,0xDD,0xD5,0xD6,0x85,0x35,0x31,0xBD,0x10,0x80,0xF9,0xEB,0xEA, + 0x2E,0xA2,0x80,0x76, +}; + +static void test_key_usage_enveloped_data(void) { + SecCertificateRef cacert = SecCertificateCreateWithBytes(NULL, _cacert, sizeof(_cacert)); + CFMutableDataRef message_data = CFDataCreateMutable(kCFAllocatorDefault, 0); + const uint8_t test[] = "hoi joh"; + CFDataRef test_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (unsigned char *)test, sizeof(test), kCFAllocatorNull); + CFArrayRef recipients = CFArrayCreate(kCFAllocatorDefault, (const void **)&cacert, 1, &kCFTypeArrayCallBacks); + require_action(cacert && message_data && test_data && recipients, out, fail("failed to create necessary data for test")); + + ok_status(SecCMSCreateEnvelopedData(recipients, NULL, test_data, message_data), "encrypt for bad key usage recip"); + +out: + CFReleaseNull(cacert); + CFReleaseNull(message_data); + CFReleaseNull(test_data); + CFReleaseNull(recipients); +} + int si_60_cms(int argc, char *const *argv) { #if TARGET_OS_IPHONE - plan_tests(42); + plan_tests(43); #else - plan_tests(41); + plan_tests(42); #endif tests(); + test_key_usage_enveloped_data(); return 0; } diff --git a/OSX/sec/Security/Regressions/secitem/si-62-csr.c b/OSX/sec/Security/Regressions/secitem/si-62-csr.c deleted file mode 100644 index 239c51b0..00000000 --- a/OSX/sec/Security/Regressions/secitem/si-62-csr.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (c) 2008-2010,2012-2014 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "shared_regressions.h" - -#include -__unused static inline void write_data(const char * path, CFDataRef data) -{ - int data_file = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0644); - write(data_file, CFDataGetBytePtr(data), CFDataGetLength(data)); - close(data_file); -} - - -static void tests(void) -{ - SecKeyRef phone_publicKey = NULL, phone_privateKey = NULL; - SecKeyRef ca_publicKey = NULL, ca_privateKey = NULL; - - int keysize = 2048; - CFNumberRef key_size_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &keysize); - const void *keygen_keys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits }; - const void *keygen_vals[] = { kSecAttrKeyTypeRSA, key_size_num }; - CFDictionaryRef parameters = CFDictionaryCreate(kCFAllocatorDefault, - keygen_keys, keygen_vals, array_size(keygen_vals), - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); - CFReleaseNull(key_size_num); - - CFMutableDictionaryRef subject_alt_names = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionarySetValue(subject_alt_names, CFSTR("dnsname"), CFSTR("xey.nl")); - - int key_usage = kSecKeyUsageDigitalSignature | kSecKeyUsageKeyEncipherment; - CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage); - - CFMutableDictionaryRef random_extensions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - - const void *key[] = { kSecCSRChallengePassword, kSecSubjectAltName, kSecCertificateKeyUsage, kSecCertificateExtensions }; - const void *val[] = { CFSTR("magic"), subject_alt_names, key_usage_num, random_extensions }; - CFDictionaryRef csr_parameters = CFDictionaryCreate(kCFAllocatorDefault, - key, val, array_size(key), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - - SecATV cn_phone[] = { { kSecOidCommonName, SecASN1PrintableString, CFSTR("My iPhone") }, {} }; - SecATV c[] = { { kSecOidCountryName, SecASN1PrintableString, CFSTR("US") }, {} }; - SecATV st[] = { { kSecOidStateProvinceName, SecASN1PrintableString, CFSTR("CA") }, {} }; - SecATV l[] = { { kSecOidLocalityName, SecASN1PrintableString, CFSTR("Cupertino") }, {} }; - SecATV o[] = { { CFSTR("2.5.4.10"), SecASN1PrintableString, CFSTR("Apple Inc.") }, {} }; - SecATV ou[] = { { kSecOidOrganizationalUnit, SecASN1PrintableString, CFSTR("iPhone") }, {} }; - - SecRDN atvs_phone[] = { cn_phone, c, st, l, o, ou, NULL }; - - ok_status(SecKeyGeneratePair(parameters, &phone_publicKey, &phone_privateKey), "generate key pair"); - ok_status(SecKeyGeneratePair(parameters, &ca_publicKey, &ca_privateKey), "generate key pair"); - - int self_key_usage = kSecKeyUsageKeyCertSign | kSecKeyUsageCRLSign; - CFNumberRef self_key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &self_key_usage); - int path_len = 0; - CFNumberRef path_len_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &path_len); - const void *self_key[] = { kSecCertificateKeyUsage, kSecCSRBasicContraintsPathLen }; - const void *self_val[] = { self_key_usage_num, path_len_num }; - CFDictionaryRef self_signed_parameters = CFDictionaryCreate(kCFAllocatorDefault, - self_key, self_val, array_size(self_key), NULL, NULL); - - const void * ca_o[] = { kSecOidOrganization, CFSTR("Apple Inc.") }; - const void * ca_cn[] = { kSecOidCommonName, CFSTR("Root CA") }; - CFArrayRef ca_o_dn = CFArrayCreate(kCFAllocatorDefault, ca_o, 2, NULL); - CFArrayRef ca_cn_dn = CFArrayCreate(kCFAllocatorDefault, ca_cn, 2, NULL); - const void *ca_dn_array[2]; - ca_dn_array[0] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_o_dn, 1, NULL); - ca_dn_array[1] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_cn_dn, 1, NULL); - CFArrayRef ca_rdns = CFArrayCreate(kCFAllocatorDefault, ca_dn_array, 2, NULL); - - SecCertificateRef ca_cert = SecGenerateSelfSignedCertificate(ca_rdns, - self_signed_parameters, ca_publicKey, ca_privateKey); - SecCertificateRef ca_cert_phone_key = - SecGenerateSelfSignedCertificate(ca_rdns, self_signed_parameters, phone_publicKey, phone_privateKey); - - CFReleaseSafe(self_signed_parameters); - CFReleaseSafe(self_key_usage_num); - CFReleaseSafe(path_len_num); - CFReleaseNull(ca_o_dn); - CFReleaseNull(ca_cn_dn); - CFReleaseNull(ca_dn_array[0]); - CFReleaseNull(ca_dn_array[1]); - CFReleaseNull(ca_rdns); - - isnt(ca_cert, NULL, "got back a cert"); - ok(SecCertificateIsSelfSignedCA(ca_cert), "cert is self-signed ca cert"); - isnt(ca_cert_phone_key, NULL, "got back a cert"); - ok(SecCertificateIsSelfSignedCA(ca_cert_phone_key), "cert is self-signed ca cert"); - CFDataRef data = SecCertificateCopyData(ca_cert); - //write_data("/tmp/ca_cert.der", data); - CFReleaseSafe(data); - - SecIdentityRef ca_identity = SecIdentityCreate(kCFAllocatorDefault, ca_cert, ca_privateKey); - SecIdentityRef ca_identity_phone_key = SecIdentityCreate(kCFAllocatorDefault, ca_cert_phone_key, phone_privateKey); - isnt(ca_identity, NULL, "got a identity"); - isnt(ca_identity_phone_key, NULL, "got a identity"); - CFDictionaryRef dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&ca_identity, 1, NULL, NULL); - ok_status(SecItemAdd(dict, NULL), "add ca identity"); - CFReleaseSafe(dict); -#if TARGET_OS_IPHONE - TODO: { - todo("Adding a cert with the same issuer/serial but a different key should return something other than errSecDuplicateItem"); -#else - { -#endif - dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&ca_identity_phone_key, 1, NULL, NULL); - is_status(errSecDuplicateItem, SecItemAdd(dict, NULL), "add ca identity"); - CFReleaseSafe(dict); - } - - CFDataRef csr = SecGenerateCertificateRequestWithParameters(atvs_phone, NULL, phone_publicKey, phone_privateKey); - isnt(csr, NULL, "got back a csr"); - CFReleaseNull(csr); - - //dict[kSecSubjectAltName, dict[ntPrincipalName, "foo@bar.org"]] - CFStringRef nt_princ_name_val = CFSTR("foo@bar.org"); - CFStringRef nt_princ_name_key = CFSTR("ntPrincipalName"); - CFDictionaryRef nt_princ = CFDictionaryCreate(NULL, (const void **)&nt_princ_name_key, (const void **)&nt_princ_name_val, 1, NULL, NULL); - CFDictionaryRef params = CFDictionaryCreate(NULL, (const void **)&kSecSubjectAltName, (const void **)&nt_princ, 1, NULL, NULL); - - csr = SecGenerateCertificateRequestWithParameters(atvs_phone, params, phone_publicKey, phone_privateKey); - isnt(csr, NULL, "got back a csr"); - //write_data("/var/tmp/csr-nt-princ", csr); - CFReleaseNull(csr); - CFReleaseNull(params); - CFReleaseNull(nt_princ); - - csr = SecGenerateCertificateRequestWithParameters(atvs_phone, csr_parameters, phone_publicKey, phone_privateKey); - isnt(csr, NULL, "csr w/ params"); - //write_data("/tmp/csr", csr); - CFDataRef subject, extensions; - CFStringRef challenge; - ok(SecVerifyCertificateRequest(csr, NULL, &challenge, &subject, &extensions), "verify csr"); - CFReleaseNull(csr); - - uint8_t serialno_byte = 42; - CFDataRef serialno = CFDataCreate(kCFAllocatorDefault, &serialno_byte, sizeof(serialno_byte)); - SecCertificateRef cert = SecIdentitySignCertificate(ca_identity, serialno, - phone_publicKey, subject, extensions); - data = SecCertificateCopyData(cert); - //write_data("/tmp/iphone_cert.der", data); - CFReleaseNull(data); - CFReleaseNull(subject); - CFReleaseNull(extensions); - CFReleaseNull(challenge); - - const void * email[] = { CFSTR("1.2.840.113549.1.9.1"), CFSTR("foo@bar.biz") }; - const void * cn[] = { CFSTR("2.5.4.3"), CFSTR("S/MIME Baby") }; - CFArrayRef email_dn = CFArrayCreate(kCFAllocatorDefault, email, 2, NULL); - CFArrayRef cn_dn = CFArrayCreate(kCFAllocatorDefault, cn, 2, NULL); - const void *dn_array[2]; - dn_array[0] = CFArrayCreate(kCFAllocatorDefault, (const void **)&email_dn, 1, NULL); - dn_array[1] = CFArrayCreate(kCFAllocatorDefault, (const void **)&cn_dn, 1, NULL); - CFArrayRef rdns = CFArrayCreate(kCFAllocatorDefault, dn_array, 2, NULL); - CFDictionarySetValue(subject_alt_names, CFSTR("rfc822name"), CFSTR("mongo@pawn.org")); - - uint8_t random_extension_data[] = { 0xde, 0xad, 0xbe, 0xef }; - CFDataRef random_extension_value = CFDataCreate(kCFAllocatorDefault, random_extension_data, sizeof(random_extension_data)); - CFDictionarySetValue(random_extensions, CFSTR("1.2.840.113635.100.6.1.2"), random_extension_value); // APPLE_FDR_ACCESS_OID - CFDictionarySetValue(random_extensions, CFSTR("1.2.840.113635.100.6.1.3"), CFSTR("that guy")); // APPLE_FDR_CLIENT_IDENTIFIER_OID - CFReleaseNull(random_extension_value); - - csr = SecGenerateCertificateRequest(rdns, csr_parameters, phone_publicKey, phone_privateKey); - isnt(csr, NULL, "csr w/ params"); - //write_data("/tmp/csr_neu", csr); - CFReleaseNull(csr); - CFReleaseNull(subject_alt_names); - CFDictionaryRemoveAllValues(random_extensions); - -#if TARGET_OS_IPHONE - CFDataRef scep_request = SecSCEPGenerateCertificateRequest(rdns, - csr_parameters, phone_publicKey, phone_privateKey, NULL, ca_cert); - isnt(scep_request, NULL, "got scep blob"); - //write_data("/tmp/scep_request.der", scep_request); -#endif - - CFReleaseNull(email_dn); - CFReleaseNull(cn_dn); - CFReleaseNull(dn_array[0]); - CFReleaseNull(dn_array[1]); - CFReleaseNull(rdns); - -#if TARGET_OS_IPHONE - CFDataRef scep_reply = SecSCEPCertifyRequest(scep_request, ca_identity, serialno, false); - isnt(scep_reply, NULL, "produced scep reply"); - //write_data("/tmp/scep_reply.der", scep_reply); - - CFArrayRef issued_certs = NULL; - ok(issued_certs = SecSCEPVerifyReply(scep_request, scep_reply, ca_cert, NULL), "verify scep reply"); - - // take the issued cert and CA cert and pretend it's a RA/CA couple - CFMutableArrayRef scep_certs = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, issued_certs); - CFArrayAppendValue(scep_certs, ca_cert); - SecCertificateRef ca_certificate = NULL, ra_signing_certificate = NULL, ra_encryption_certificate = NULL; - - ok_status(SecSCEPValidateCACertMessage(scep_certs, NULL, - &ca_certificate, &ra_signing_certificate, - &ra_encryption_certificate), "pull apart array again"); - ok(CFEqual(ca_cert, ca_certificate), "found ca"); - ok(CFArrayContainsValue(issued_certs, CFRangeMake(0, CFArrayGetCount(issued_certs)), ra_signing_certificate), "found ra"); - ok(!ra_encryption_certificate, "no separate encryption cert"); - - CFReleaseSafe(ca_certificate); - CFReleaseSafe(ra_signing_certificate); - CFReleaseSafe(scep_certs); - - CFReleaseSafe(scep_request); - CFReleaseSafe(scep_reply); - CFReleaseSafe(issued_certs); -#endif - - // cleanups - dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&ca_identity, 1, NULL, NULL); - ok_status(SecItemDelete(dict), "delete ca identity"); - CFReleaseSafe(dict); - dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&phone_privateKey, 1, NULL, NULL); - ok_status(SecItemDelete(dict), "delete phone private key"); - CFReleaseSafe(dict); - - CFReleaseSafe(serialno); - - CFReleaseSafe(cert); - CFReleaseSafe(ca_identity); - CFReleaseSafe(ca_cert); - CFReleaseSafe(ca_identity_phone_key); - CFReleaseSafe(ca_cert_phone_key); - CFReleaseSafe(csr_parameters); - CFReleaseSafe(random_extensions); - CFReleaseSafe(parameters); - CFReleaseSafe(ca_publicKey); - CFReleaseSafe(ca_privateKey); - CFReleaseSafe(phone_publicKey); - CFReleaseSafe(phone_privateKey); -} - -static void test_ec_csr(void) { - SecKeyRef ecPublicKey = NULL, ecPrivateKey = NULL; - - int keysize = 256; - CFNumberRef key_size_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &keysize); - - const void *keyParamsKeys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits }; - const void *keyParamsValues[] = { kSecAttrKeyTypeECSECPrimeRandom, key_size_num}; - CFDictionaryRef keyParameters = CFDictionaryCreate(NULL, keyParamsKeys, keyParamsValues, 2, - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - ok_status(SecKeyGeneratePair(keyParameters, &ecPublicKey, &ecPrivateKey), - "unable to generate EC key"); - - SecATV cn_phone[] = { { kSecOidCommonName, SecASN1PrintableString, CFSTR("My iPhone") }, {} }; - SecATV c[] = { { kSecOidCountryName, SecASN1PrintableString, CFSTR("US") }, {} }; - SecATV st[] = { { kSecOidStateProvinceName, SecASN1PrintableString, CFSTR("CA") }, {} }; - SecATV l[] = { { kSecOidLocalityName, SecASN1PrintableString, CFSTR("Cupertino") }, {} }; - SecATV o[] = { { CFSTR("2.5.4.10"), SecASN1PrintableString, CFSTR("Apple Inc.") }, {} }; - SecATV ou[] = { { kSecOidOrganizationalUnit, SecASN1PrintableString, CFSTR("iPhone") }, {} }; - - SecRDN atvs_phone[] = { cn_phone, c, st, l, o, ou, NULL }; - - CFMutableDictionaryRef subject_alt_names = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionarySetValue(subject_alt_names, CFSTR("dnsname"), CFSTR("xey.nl")); - - int key_usage = kSecKeyUsageDigitalSignature | kSecKeyUsageKeyEncipherment; - CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage); - - CFMutableDictionaryRef random_extensions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - - const void *key[] = { kSecCSRChallengePassword, kSecSubjectAltName, kSecCertificateKeyUsage, kSecCertificateExtensions }; - const void *val[] = { CFSTR("magic"), subject_alt_names, key_usage_num, random_extensions }; - CFDictionaryRef csr_parameters = CFDictionaryCreate(kCFAllocatorDefault, - key, val, array_size(key), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - - - CFDataRef csr = SecGenerateCertificateRequestWithParameters(atvs_phone, csr_parameters, ecPublicKey, ecPrivateKey); - isnt(csr, NULL, "csr w/ params"); - //write_data("/tmp/csr", csr); - CFDataRef subject, extensions; - CFStringRef challenge; - ok(SecVerifyCertificateRequest(csr, NULL, &challenge, &subject, &extensions), "verify csr"); - - CFReleaseNull(csr); - CFReleaseNull(key_size_num); - CFReleaseNull(keyParameters); - CFReleaseNull(ecPublicKey); - CFReleaseNull(ecPrivateKey); - CFReleaseNull(subject_alt_names); - CFReleaseNull(key_usage_num); - CFReleaseNull(random_extensions); - CFReleaseNull(csr_parameters); - CFReleaseNull(subject); - CFReleaseNull(extensions); - CFReleaseNull(challenge); -} - -int si_62_csr(int argc, char *const *argv) -{ -#if TARGET_OS_IPHONE - plan_tests(27); -#else - plan_tests(20); -#endif - - tests(); - test_ec_csr(); - - return 0; -} diff --git a/OSX/sec/Security/Regressions/secitem/si-62-csr.m b/OSX/sec/Security/Regressions/secitem/si-62-csr.m new file mode 100644 index 00000000..a6aa4b9d --- /dev/null +++ b/OSX/sec/Security/Regressions/secitem/si-62-csr.m @@ -0,0 +1,519 @@ +/* + * Copyright (c) 2008-2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import +#import + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "shared_regressions.h" + +#include +__unused static inline void write_data(const char * path, CFDataRef data) +{ + int data_file = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0644); + write(data_file, CFDataGetBytePtr(data), CFDataGetLength(data)); + close(data_file); +} + + +static void tests(void) +{ + SecKeyRef phone_publicKey = NULL, phone_privateKey = NULL; + SecKeyRef ca_publicKey = NULL, ca_privateKey = NULL; + + int keysize = 2048; + CFNumberRef key_size_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &keysize); + const void *keygen_keys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits }; + const void *keygen_vals[] = { kSecAttrKeyTypeRSA, key_size_num }; + CFDictionaryRef parameters = CFDictionaryCreate(kCFAllocatorDefault, + keygen_keys, keygen_vals, array_size(keygen_vals), + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); + CFReleaseNull(key_size_num); + + CFMutableDictionaryRef subject_alt_names = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(subject_alt_names, kSecSubjectAltNameDNSName, CFSTR("xey.nl")); + + int key_usage = kSecKeyUsageDigitalSignature | kSecKeyUsageKeyEncipherment; + CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage); + + CFMutableDictionaryRef random_extensions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + const void *key[] = { kSecCSRChallengePassword, kSecSubjectAltName, kSecCertificateKeyUsage, kSecCertificateExtensions }; + const void *val[] = { CFSTR("magic"), subject_alt_names, key_usage_num, random_extensions }; + CFDictionaryRef csr_parameters = CFDictionaryCreate(kCFAllocatorDefault, + key, val, array_size(key), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + SecATV cn_phone[] = { { kSecOidCommonName, SecASN1PrintableString, CFSTR("My iPhone") }, {} }; + SecATV c[] = { { kSecOidCountryName, SecASN1PrintableString, CFSTR("US") }, {} }; + SecATV st[] = { { kSecOidStateProvinceName, SecASN1PrintableString, CFSTR("CA") }, {} }; + SecATV l[] = { { kSecOidLocalityName, SecASN1PrintableString, CFSTR("Cupertino") }, {} }; + SecATV o[] = { { CFSTR("2.5.4.10"), SecASN1PrintableString, CFSTR("Apple Inc.") }, {} }; + SecATV ou[] = { { kSecOidOrganizationalUnit, SecASN1PrintableString, CFSTR("iPhone") }, {} }; + + SecRDN atvs_phone[] = { cn_phone, c, st, l, o, ou, NULL }; + + ok_status(SecKeyGeneratePair(parameters, &phone_publicKey, &phone_privateKey), "generate key pair"); + ok_status(SecKeyGeneratePair(parameters, &ca_publicKey, &ca_privateKey), "generate key pair"); + + int self_key_usage = kSecKeyUsageKeyCertSign | kSecKeyUsageCRLSign; + CFNumberRef self_key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &self_key_usage); + int path_len = 0; + CFNumberRef path_len_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &path_len); + const void *self_key[] = { kSecCertificateKeyUsage, kSecCSRBasicContraintsPathLen }; + const void *self_val[] = { self_key_usage_num, path_len_num }; + CFDictionaryRef self_signed_parameters = CFDictionaryCreate(kCFAllocatorDefault, + self_key, self_val, array_size(self_key), NULL, NULL); + + const void * ca_o[] = { kSecOidOrganization, CFSTR("Apple Inc.") }; + const void * ca_cn[] = { kSecOidCommonName, CFSTR("Root CA") }; + CFArrayRef ca_o_dn = CFArrayCreate(kCFAllocatorDefault, ca_o, 2, NULL); + CFArrayRef ca_cn_dn = CFArrayCreate(kCFAllocatorDefault, ca_cn, 2, NULL); + const void *ca_dn_array[2]; + ca_dn_array[0] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_o_dn, 1, NULL); + ca_dn_array[1] = CFArrayCreate(kCFAllocatorDefault, (const void **)&ca_cn_dn, 1, NULL); + CFArrayRef ca_rdns = CFArrayCreate(kCFAllocatorDefault, ca_dn_array, 2, NULL); + + SecCertificateRef ca_cert = SecGenerateSelfSignedCertificate(ca_rdns, + self_signed_parameters, ca_publicKey, ca_privateKey); + SecCertificateRef ca_cert_phone_key = + SecGenerateSelfSignedCertificate(ca_rdns, self_signed_parameters, phone_publicKey, phone_privateKey); + + CFReleaseSafe(self_signed_parameters); + CFReleaseSafe(self_key_usage_num); + CFReleaseSafe(path_len_num); + CFReleaseNull(ca_o_dn); + CFReleaseNull(ca_cn_dn); + CFReleaseNull(ca_dn_array[0]); + CFReleaseNull(ca_dn_array[1]); + CFReleaseNull(ca_rdns); + + isnt(ca_cert, NULL, "got back a cert"); + ok(SecCertificateIsSelfSignedCA(ca_cert), "cert is self-signed ca cert"); + isnt(ca_cert_phone_key, NULL, "got back a cert"); + ok(SecCertificateIsSelfSignedCA(ca_cert_phone_key), "cert is self-signed ca cert"); + CFDataRef data = SecCertificateCopyData(ca_cert); + //write_data("/tmp/ca_cert.der", data); + CFReleaseSafe(data); + + SecIdentityRef ca_identity = SecIdentityCreate(kCFAllocatorDefault, ca_cert, ca_privateKey); + SecIdentityRef ca_identity_phone_key = SecIdentityCreate(kCFAllocatorDefault, ca_cert_phone_key, phone_privateKey); + isnt(ca_identity, NULL, "got a identity"); + isnt(ca_identity_phone_key, NULL, "got a identity"); + CFDictionaryRef dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&ca_identity, 1, NULL, NULL); + ok_status(SecItemAdd(dict, NULL), "add ca identity"); + CFReleaseSafe(dict); +#if TARGET_OS_IPHONE + TODO: { + todo("Adding a cert with the same issuer/serial but a different key should return something other than errSecDuplicateItem"); +#else + { +#endif + dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&ca_identity_phone_key, 1, NULL, NULL); + is_status(errSecDuplicateItem, SecItemAdd(dict, NULL), "add ca identity"); + CFReleaseSafe(dict); + } + + CFDataRef csr = SecGenerateCertificateRequestWithParameters(atvs_phone, NULL, phone_publicKey, phone_privateKey); + isnt(csr, NULL, "got back a csr"); + CFReleaseNull(csr); + + //dict[kSecSubjectAltName, dict[ntPrincipalName, "foo@bar.org"]] + CFStringRef nt_princ_name_val = CFSTR("foo@bar.org"); + CFDictionaryRef nt_princ = CFDictionaryCreate(NULL, (const void **)&kSecSubjectAltNameNTPrincipalName, (const void **)&nt_princ_name_val, 1, NULL, NULL); + CFDictionaryRef params = CFDictionaryCreate(NULL, (const void **)&kSecSubjectAltName, (const void **)&nt_princ, 1, NULL, NULL); + + csr = SecGenerateCertificateRequestWithParameters(atvs_phone, params, phone_publicKey, phone_privateKey); + isnt(csr, NULL, "got back a csr"); + //write_data("/var/tmp/csr-nt-princ", csr); + CFReleaseNull(csr); + CFReleaseNull(params); + CFReleaseNull(nt_princ); + + csr = SecGenerateCertificateRequestWithParameters(atvs_phone, csr_parameters, phone_publicKey, phone_privateKey); + isnt(csr, NULL, "csr w/ params"); + //write_data("/tmp/csr", csr); + CFDataRef subject, extensions; + CFStringRef challenge; + ok(SecVerifyCertificateRequest(csr, NULL, &challenge, &subject, &extensions), "verify csr"); + CFReleaseNull(csr); + + uint8_t serialno_byte = 42; + CFDataRef serialno = CFDataCreate(kCFAllocatorDefault, &serialno_byte, sizeof(serialno_byte)); + SecCertificateRef cert = SecIdentitySignCertificate(ca_identity, serialno, + phone_publicKey, subject, extensions); + data = SecCertificateCopyData(cert); + //write_data("/tmp/iphone_cert.der", data); + CFReleaseNull(data); + CFReleaseNull(subject); + CFReleaseNull(extensions); + CFReleaseNull(challenge); + + const void * email[] = { CFSTR("1.2.840.113549.1.9.1"), CFSTR("foo@bar.biz") }; + const void * cn[] = { CFSTR("2.5.4.3"), CFSTR("S/MIME Baby") }; + CFArrayRef email_dn = CFArrayCreate(kCFAllocatorDefault, email, 2, NULL); + CFArrayRef cn_dn = CFArrayCreate(kCFAllocatorDefault, cn, 2, NULL); + const void *dn_array[2]; + dn_array[0] = CFArrayCreate(kCFAllocatorDefault, (const void **)&email_dn, 1, NULL); + dn_array[1] = CFArrayCreate(kCFAllocatorDefault, (const void **)&cn_dn, 1, NULL); + CFArrayRef rdns = CFArrayCreate(kCFAllocatorDefault, dn_array, 2, NULL); + CFDictionarySetValue(subject_alt_names, CFSTR("rfc822name"), CFSTR("mongo@pawn.org")); + + uint8_t random_extension_data[] = { 0xde, 0xad, 0xbe, 0xef }; + CFDataRef random_extension_value = CFDataCreate(kCFAllocatorDefault, random_extension_data, sizeof(random_extension_data)); + CFDictionarySetValue(random_extensions, CFSTR("1.2.840.113635.100.6.1.2"), random_extension_value); // APPLE_FDR_ACCESS_OID + CFDictionarySetValue(random_extensions, CFSTR("1.2.840.113635.100.6.1.3"), CFSTR("that guy")); // APPLE_FDR_CLIENT_IDENTIFIER_OID + CFReleaseNull(random_extension_value); + + csr = SecGenerateCertificateRequest(rdns, csr_parameters, phone_publicKey, phone_privateKey); + isnt(csr, NULL, "csr w/ params"); + //write_data("/tmp/csr_neu", csr); + CFReleaseNull(csr); + CFReleaseNull(subject_alt_names); + CFDictionaryRemoveAllValues(random_extensions); + +#if TARGET_OS_IPHONE + CFDataRef scep_request = SecSCEPGenerateCertificateRequest(rdns, + csr_parameters, phone_publicKey, phone_privateKey, NULL, ca_cert); + isnt(scep_request, NULL, "got scep blob"); + //write_data("/tmp/scep_request.der", scep_request); +#endif + + CFReleaseNull(email_dn); + CFReleaseNull(cn_dn); + CFReleaseNull(dn_array[0]); + CFReleaseNull(dn_array[1]); + CFReleaseNull(rdns); + +#if TARGET_OS_IPHONE + CFDataRef scep_reply = SecSCEPCertifyRequest(scep_request, ca_identity, serialno, false); + isnt(scep_reply, NULL, "produced scep reply"); + //write_data("/tmp/scep_reply.der", scep_reply); + + CFArrayRef issued_certs = NULL; + ok(issued_certs = SecSCEPVerifyReply(scep_request, scep_reply, ca_cert, NULL), "verify scep reply"); + + // take the issued cert and CA cert and pretend it's a RA/CA couple + CFMutableArrayRef scep_certs = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, issued_certs); + CFArrayAppendValue(scep_certs, ca_cert); + SecCertificateRef ca_certificate = NULL, ra_signing_certificate = NULL, ra_encryption_certificate = NULL; + + ok_status(SecSCEPValidateCACertMessage(scep_certs, NULL, + &ca_certificate, &ra_signing_certificate, + &ra_encryption_certificate), "pull apart array again"); + ok(CFEqual(ca_cert, ca_certificate), "found ca"); + ok(CFArrayContainsValue(issued_certs, CFRangeMake(0, CFArrayGetCount(issued_certs)), ra_signing_certificate), "found ra"); + ok(!ra_encryption_certificate, "no separate encryption cert"); + + CFReleaseSafe(ca_certificate); + CFReleaseSafe(ra_signing_certificate); + CFReleaseSafe(scep_certs); + + CFReleaseSafe(scep_request); + CFReleaseSafe(scep_reply); + CFReleaseSafe(issued_certs); +#endif + + // cleanups + dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&ca_identity, 1, NULL, NULL); + ok_status(SecItemDelete(dict), "delete ca identity"); + CFReleaseSafe(dict); + dict = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, (const void **)&phone_privateKey, 1, NULL, NULL); + ok_status(SecItemDelete(dict), "delete phone private key"); + CFReleaseSafe(dict); + + CFReleaseSafe(serialno); + + CFReleaseSafe(cert); + CFReleaseSafe(ca_identity); + CFReleaseSafe(ca_cert); + CFReleaseSafe(ca_identity_phone_key); + CFReleaseSafe(ca_cert_phone_key); + CFReleaseSafe(csr_parameters); + CFReleaseSafe(random_extensions); + CFReleaseSafe(parameters); + CFReleaseSafe(ca_publicKey); + CFReleaseSafe(ca_privateKey); + CFReleaseSafe(phone_publicKey); + CFReleaseSafe(phone_privateKey); +} + +static void test_ec_csr(void) { + SecKeyRef ecPublicKey = NULL, ecPrivateKey = NULL; + + int keysize = 256; + CFNumberRef key_size_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &keysize); + + const void *keyParamsKeys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits }; + const void *keyParamsValues[] = { kSecAttrKeyTypeECSECPrimeRandom, key_size_num}; + CFDictionaryRef keyParameters = CFDictionaryCreate(NULL, keyParamsKeys, keyParamsValues, 2, + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + ok_status(SecKeyGeneratePair(keyParameters, &ecPublicKey, &ecPrivateKey), + "unable to generate EC key"); + + SecATV cn_phone[] = { { kSecOidCommonName, SecASN1PrintableString, CFSTR("My iPhone") }, {} }; + SecATV c[] = { { kSecOidCountryName, SecASN1PrintableString, CFSTR("US") }, {} }; + SecATV st[] = { { kSecOidStateProvinceName, SecASN1PrintableString, CFSTR("CA") }, {} }; + SecATV l[] = { { kSecOidLocalityName, SecASN1PrintableString, CFSTR("Cupertino") }, {} }; + SecATV o[] = { { CFSTR("2.5.4.10"), SecASN1PrintableString, CFSTR("Apple Inc.") }, {} }; + SecATV ou[] = { { kSecOidOrganizationalUnit, SecASN1PrintableString, CFSTR("iPhone") }, {} }; + + SecRDN atvs_phone[] = { cn_phone, c, st, l, o, ou, NULL }; + + CFMutableDictionaryRef subject_alt_names = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(subject_alt_names, kSecSubjectAltNameDNSName, CFSTR("xey.nl")); + + int key_usage = kSecKeyUsageDigitalSignature | kSecKeyUsageKeyEncipherment; + CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage); + + CFMutableDictionaryRef random_extensions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + const void *key[] = { kSecCSRChallengePassword, kSecSubjectAltName, kSecCertificateKeyUsage, kSecCertificateExtensions }; + const void *val[] = { CFSTR("magic"), subject_alt_names, key_usage_num, random_extensions }; + CFDictionaryRef csr_parameters = CFDictionaryCreate(kCFAllocatorDefault, + key, val, array_size(key), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + + CFDataRef csr = SecGenerateCertificateRequestWithParameters(atvs_phone, csr_parameters, ecPublicKey, ecPrivateKey); + isnt(csr, NULL, "csr w/ params"); + //write_data("/tmp/csr", csr); + CFDataRef subject, extensions; + CFStringRef challenge; + ok(SecVerifyCertificateRequest(csr, NULL, &challenge, &subject, &extensions), "verify csr"); + + CFReleaseNull(csr); + CFReleaseNull(key_size_num); + CFReleaseNull(keyParameters); + CFReleaseNull(ecPublicKey); + CFReleaseNull(ecPrivateKey); + CFReleaseNull(subject_alt_names); + CFReleaseNull(key_usage_num); + CFReleaseNull(random_extensions); + CFReleaseNull(csr_parameters); + CFReleaseNull(subject); + CFReleaseNull(extensions); + CFReleaseNull(challenge); +} + +static bool test_csr_create_sign_verify(SecKeyRef ca_priv, SecKeyRef leaf_priv, + CFStringRef cert_hashing_alg, CFStringRef csr_hashing_alg) { + bool status = false; + SecCertificateRef ca_cert = NULL, leaf_cert1 = NULL, leaf_cert2 = NULL; + SecIdentityRef ca_identity = NULL; + NSArray *leaf_rdns = nil, *anchors = nil; + NSDictionary *leaf_parameters = nil; + NSData *csr = nil, *serial_no = nil; + SecKeyRef csr_pub_key = NULL; + CFDataRef csr_subject = NULL, csr_extensions = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + SecTrustResultType trustResult = kSecTrustResultInvalid; + + /* Generate a self-signed cert */ + NSString *common_name = [NSString stringWithFormat:@"CSR Test Root: %@", cert_hashing_alg]; + NSArray *ca_rdns = @[ + @[@[(__bridge NSString*)kSecOidCountryName, @"US"]], + @[@[(__bridge NSString*)kSecOidOrganization, @"Apple Inc."]], + @[@[(__bridge NSString*)kSecOidCommonName, common_name]] + ]; + NSDictionary *ca_parameters = @{ + (__bridge NSString *)kSecCMSSignHashAlgorithm: (__bridge NSString*)cert_hashing_alg, + (__bridge NSString *)kSecCSRBasicContraintsPathLen: @0, + (__bridge NSString *)kSecCertificateKeyUsage: @(kSecKeyUsageKeyCertSign | kSecKeyUsageCRLSign) + }; + ca_cert = SecGenerateSelfSignedCertificate((__bridge CFArrayRef)ca_rdns, + (__bridge CFDictionaryRef)ca_parameters, + NULL, ca_priv); + require(ca_cert, out); + ca_identity = SecIdentityCreate(NULL, ca_cert, ca_priv); + require(ca_identity, out); + + /* Generate a CSR */ + leaf_rdns = @[ + @[@[(__bridge NSString*)kSecOidCountryName, @"US"]], + @[@[(__bridge NSString*)kSecOidOrganization, @"Apple Inc"]], + @[@[(__bridge NSString*)kSecOidCommonName, @"Leaf 1"]] + ]; + leaf_parameters = @{ + (__bridge NSString*)kSecCMSSignHashAlgorithm: (__bridge NSString*)csr_hashing_alg, + (__bridge NSString*)kSecSubjectAltName: @{ + (__bridge NSString*)kSecSubjectAltNameDNSName : @[ @"valid.apple.com", + @"valid-qa.apple.com", + @"valid-uat.apple.com"] + }, + (__bridge NSString*)kSecCertificateKeyUsage : @(kSecKeyUsageDigitalSignature) + }; + csr = CFBridgingRelease(SecGenerateCertificateRequest((__bridge CFArrayRef)leaf_rdns, + (__bridge CFDictionaryRef)leaf_parameters, + NULL, leaf_priv)); + require(csr, out); + + /* Verify that CSR */ + require(SecVerifyCertificateRequest((__bridge CFDataRef)csr, &csr_pub_key, NULL, &csr_subject, &csr_extensions), out); + require(csr_pub_key && csr_extensions && csr_subject, out); + + /* Sign that CSR */ + uint8_t serial_no_bytes[] = { 0xbb, 0x01 }; + serial_no = [NSData dataWithBytes:serial_no_bytes length:sizeof(serial_no_bytes)]; + leaf_cert1 = SecIdentitySignCertificateWithAlgorithm(ca_identity, (__bridge CFDataRef)serial_no, + csr_pub_key, csr_subject, csr_extensions, cert_hashing_alg); + require(leaf_cert1, out); + + CFReleaseNull(csr_pub_key); + CFReleaseNull(csr_subject); + CFReleaseNull(csr_extensions); + + /* Generate a CSR "with parameters" SPI */ + SecATV c[] = { { kSecOidCountryName, SecASN1PrintableString, CFSTR("US") }, {} }; + SecATV o[] = { { kSecOidOrganization, SecASN1PrintableString, CFSTR("Apple Inc.") }, {} }; + SecATV cn[] = { { kSecOidCommonName, SecASN1PrintableString, CFSTR("Leaf 2") }, {} }; + + SecRDN atvs_leaf2[] = { c, o, cn, NULL }; + csr = CFBridgingRelease(SecGenerateCertificateRequestWithParameters(atvs_leaf2, (__bridge CFDictionaryRef)leaf_parameters, NULL, leaf_priv)); + require(csr, out); + + /* Verify that CSR */ + require(SecVerifyCertificateRequest((__bridge CFDataRef)csr, &csr_pub_key, NULL, &csr_subject, &csr_extensions), out); + require(csr_pub_key && csr_extensions && csr_subject, out); + + /* Sign that CSR */ + uint8_t serial_no_bytes2[] = { 0xbb, 0x02 }; + serial_no = [NSData dataWithBytes:serial_no_bytes2 length:sizeof(serial_no_bytes2)]; + leaf_cert2 = SecIdentitySignCertificateWithAlgorithm(ca_identity, (__bridge CFDataRef)serial_no, + csr_pub_key, csr_subject, csr_extensions, cert_hashing_alg); + require(leaf_cert2, out); + + /* Verify the signed leaf certs chain to the root */ + require(policy = SecPolicyCreateBasicX509(), out); + require_noerr(SecTrustCreateWithCertificates(leaf_cert1, policy, &trust), out); + anchors = @[ (__bridge id)ca_cert ]; + require_noerr(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), out); + require_noerr(SecTrustEvaluate(trust, &trustResult), out); + require(trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed, out); + CFReleaseNull(trust); + + require_noerr(SecTrustCreateWithCertificates(leaf_cert2, policy, &trust), out); + require_noerr(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), out); + require_noerr(SecTrustEvaluate(trust, &trustResult), out); + require(trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed, out); + CFReleaseNull(trust); + + status = true; +out: + CFReleaseNull(ca_cert); + CFReleaseNull(ca_identity); + CFReleaseNull(leaf_cert1); + CFReleaseNull(leaf_cert2); + CFReleaseNull(csr_pub_key); + CFReleaseNull(csr_subject); + CFReleaseNull(csr_extensions); + CFReleaseNull(policy); + CFReleaseNull(trust); + return status; +} + +static void test_algs(void) { + SecKeyRef ca_rsa_key = NULL, ca_ec_key = NULL; + SecKeyRef leaf_rsa_key = NULL, leaf_ec_key = NULL; + SecKeyRef publicKey = NULL; + NSDictionary *rsa_parameters = nil, *ec_parameters = nil; + + rsa_parameters = @{ + (__bridge NSString*)kSecAttrKeyType: (__bridge NSString*)kSecAttrKeyTypeRSA, + (__bridge NSString*)kSecAttrKeySizeInBits : @2048, + }; + ok_status(SecKeyGeneratePair((__bridge CFDictionaryRef)rsa_parameters, &publicKey, &ca_rsa_key), + "Failed to generate CA RSA key"); + CFReleaseNull(publicKey); + ok_status(SecKeyGeneratePair((__bridge CFDictionaryRef)rsa_parameters, &publicKey, &leaf_rsa_key), + "Failed to generate leaf RSA key"); + CFReleaseNull(publicKey); + + ec_parameters = @{ + (__bridge NSString*)kSecAttrKeyType: (__bridge NSString*)kSecAttrKeyTypeECSECPrimeRandom, + (__bridge NSString*)kSecAttrKeySizeInBits : @384, + }; + ok_status(SecKeyGeneratePair((__bridge CFDictionaryRef)ec_parameters, &publicKey, &ca_ec_key), + "Failed to generate CA EC key"); + CFReleaseNull(publicKey); + ok_status(SecKeyGeneratePair((__bridge CFDictionaryRef)ec_parameters, &publicKey, &leaf_ec_key), + "Failed to generate leaf EC key"); + CFReleaseNull(publicKey); + + /* Single algorithm tests */ + ok(test_csr_create_sign_verify(ca_rsa_key, leaf_rsa_key, kSecCMSHashingAlgorithmSHA1, kSecCMSHashingAlgorithmSHA1), + "Failed to run csr test with RSA SHA-1"); + ok(test_csr_create_sign_verify(ca_rsa_key, leaf_rsa_key, kSecCMSHashingAlgorithmSHA256, kSecCMSHashingAlgorithmSHA256), + "Failed to run csr test with RSA SHA-256"); + ok(test_csr_create_sign_verify(ca_rsa_key, leaf_rsa_key, kSecCMSHashingAlgorithmSHA384, kSecCMSHashingAlgorithmSHA384), + "Failed to run csr test with RSA SHA-384"); + ok(test_csr_create_sign_verify(ca_rsa_key, leaf_rsa_key, kSecCMSHashingAlgorithmSHA512, kSecCMSHashingAlgorithmSHA512), + "Failed to run csr test with RSA SHA-512"); + ok(test_csr_create_sign_verify(ca_ec_key, leaf_ec_key, kSecCMSHashingAlgorithmSHA256, kSecCMSHashingAlgorithmSHA256), + "Failed to run csr test with EC SHA-256"); + ok(test_csr_create_sign_verify(ca_ec_key, leaf_ec_key, kSecCMSHashingAlgorithmSHA384, kSecCMSHashingAlgorithmSHA384), + "Failed to run csr test with EC SHA-384"); + ok(test_csr_create_sign_verify(ca_ec_key, leaf_ec_key, kSecCMSHashingAlgorithmSHA512, kSecCMSHashingAlgorithmSHA512), + "Failed to run csr test with EC SHA-512"); + + /* Mix and match */ + ok(test_csr_create_sign_verify(ca_rsa_key, leaf_ec_key, kSecCMSHashingAlgorithmSHA256, kSecCMSHashingAlgorithmSHA384), + "Failed to run csr test with RSA CA, EC leaf, SHA256 certs, SHA384 csrs"); + ok(test_csr_create_sign_verify(ca_rsa_key, leaf_rsa_key, kSecCMSHashingAlgorithmSHA256, kSecCMSHashingAlgorithmSHA1), + "Failed to run csr test with RSA keys, SHA256 certs, SHA1 csrs"); + ok(test_csr_create_sign_verify(ca_ec_key, leaf_ec_key, kSecCMSHashingAlgorithmSHA384, kSecCMSHashingAlgorithmSHA256), + "Failed to run csr test with EC keys, SHA384 certs, SHA256 csrs"); + + CFReleaseNull(ca_rsa_key); + CFReleaseNull(ca_ec_key); + CFReleaseNull(leaf_rsa_key); + CFReleaseNull(leaf_ec_key); +} + +int si_62_csr(int argc, char *const *argv) +{ +#if TARGET_OS_IPHONE + plan_tests(41); +#else + plan_tests(34); +#endif + + tests(); + test_ec_csr(); + test_algs(); + + return 0; +} diff --git a/OSX/sec/Security/Regressions/secitem/si-63-scep.c b/OSX/sec/Security/Regressions/secitem/si-63-scep.c deleted file mode 100644 index aa2f543f..00000000 --- a/OSX/sec/Security/Regressions/secitem/si-63-scep.c +++ /dev/null @@ -1,1216 +0,0 @@ -/* - * Copyright (c) 2008,2012-2014 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "Security_regressions.h" -#include - -static uint8_t msscep_getcacert[] = { - 0x30, 0x82, 0x10, 0x8d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x07, 0x02, 0xa0, 0x82, 0x10, 0x7e, 0x30, 0x82, 0x10, 0x7a, 0x02, - 0x01, 0x01, 0x31, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x10, 0x62, 0x30, 0x82, 0x05, - 0xcc, 0x30, 0x82, 0x04, 0xb4, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, - 0x61, 0x0c, 0x81, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x30, 0x4e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, - 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f, 0x6d, - 0x31, 0x18, 0x30, 0x16, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, - 0x2c, 0x64, 0x01, 0x19, 0x16, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, - 0x73, 0x74, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, - 0x14, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, - 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, - 0x0d, 0x30, 0x39, 0x30, 0x32, 0x31, 0x37, 0x32, 0x32, 0x33, 0x35, 0x35, - 0x35, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x32, 0x31, 0x37, 0x32, 0x32, - 0x33, 0x35, 0x35, 0x35, 0x5a, 0x30, 0x81, 0x8a, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x63, 0x61, 0x31, 0x12, - 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x63, 0x75, 0x70, - 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x13, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, - 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x02, - 0x71, 0x61, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, - 0x0c, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, - 0x6d, 0x31, 0x23, 0x30, 0x21, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x09, 0x01, 0x16, 0x14, 0x71, 0x61, 0x61, 0x64, 0x6d, 0x69, - 0x6e, 0x40, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, - 0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, - 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0x93, 0x67, 0x34, 0x15, 0xe9, - 0x97, 0x97, 0x74, 0xbf, 0x0e, 0x1c, 0xd8, 0x44, 0x00, 0x0d, 0x42, 0x7a, - 0x3d, 0xd1, 0xea, 0xc8, 0x95, 0xc0, 0x6b, 0x93, 0x6c, 0x6d, 0x87, 0x4a, - 0x21, 0xf5, 0xbf, 0x16, 0x10, 0x19, 0x44, 0x2f, 0xd2, 0xd6, 0x87, 0x55, - 0x52, 0x04, 0xb0, 0x0b, 0x3e, 0x49, 0xb7, 0x9c, 0x2b, 0x01, 0xc8, 0x6c, - 0x3e, 0x56, 0xb5, 0xd2, 0x20, 0x29, 0x0f, 0x25, 0x04, 0xcb, 0x59, 0xce, - 0x37, 0x69, 0xcf, 0x4e, 0x05, 0x06, 0x2d, 0xac, 0xaf, 0x33, 0xee, 0x4e, - 0xce, 0xe1, 0x55, 0x46, 0xc6, 0x5c, 0x68, 0x56, 0xda, 0xd6, 0x0a, 0x6e, - 0xeb, 0xdb, 0x4d, 0xf6, 0xef, 0x0d, 0xcf, 0x1e, 0x43, 0xfa, 0xc2, 0xe2, - 0xfa, 0x87, 0xe0, 0x31, 0x16, 0x46, 0x97, 0x12, 0x26, 0xdc, 0x94, 0x16, - 0x73, 0xb0, 0xcf, 0xad, 0x7d, 0x7d, 0x8b, 0xb8, 0xf5, 0xd1, 0x89, 0x50, - 0x12, 0x1d, 0x49, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x02, 0xf1, - 0x30, 0x82, 0x02, 0xed, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, - 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x15, 0x06, 0x03, 0x55, 0x1d, 0x25, - 0x04, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, - 0x37, 0x14, 0x02, 0x01, 0x30, 0x3b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, - 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x2e, 0x1e, 0x2c, 0x00, 0x45, 0x00, - 0x6e, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6d, 0x00, - 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x41, 0x00, 0x67, 0x00, 0x65, 0x00, - 0x6e, 0x00, 0x74, 0x00, 0x4f, 0x00, 0x66, 0x00, 0x66, 0x00, 0x6c, 0x00, - 0x69, 0x00, 0x6e, 0x00, 0x65, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, - 0x04, 0x16, 0x04, 0x14, 0xb3, 0xd0, 0xef, 0xb6, 0xe0, 0x3b, 0x3b, 0x39, - 0xf8, 0x5a, 0x33, 0x07, 0x2f, 0x19, 0xd9, 0xcd, 0xdd, 0xe3, 0xf9, 0x1e, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, - 0x14, 0x40, 0xb5, 0x54, 0x10, 0x88, 0x09, 0xeb, 0x3e, 0x2e, 0x69, 0x82, - 0xa6, 0xa0, 0xd8, 0xe4, 0xb0, 0x98, 0xc1, 0x69, 0x3d, 0x30, 0x82, 0x01, - 0x19, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, 0x10, 0x30, 0x82, - 0x01, 0x0c, 0x30, 0x82, 0x01, 0x08, 0xa0, 0x82, 0x01, 0x04, 0xa0, 0x82, - 0x01, 0x00, 0x86, 0x81, 0xbc, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, - 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, - 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, - 0x2c, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2c, - 0x43, 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, - 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, - 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, - 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, - 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x6d, 0x3f, 0x63, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x76, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x3f, - 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, - 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44, 0x69, 0x73, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x69, 0x6e, - 0x74, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x71, 0x61, - 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, - 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x65, 0x72, 0x74, 0x45, - 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, - 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, - 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x82, 0x01, 0x2b, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x82, 0x01, 0x1d, - 0x30, 0x82, 0x01, 0x19, 0x30, 0x81, 0xb4, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0xa7, 0x6c, 0x64, 0x61, 0x70, - 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, - 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, - 0x63, 0x6f, 0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x49, 0x41, 0x2c, 0x43, - 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, - 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76, - 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, - 0x6d, 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x60, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x54, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, - 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, - 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, - 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x5f, 0x71, 0x61, 0x73, - 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, - 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, - 0x03, 0x82, 0x01, 0x01, 0x00, 0x7e, 0x74, 0xff, 0x77, 0xd7, 0x2e, 0x43, - 0x11, 0xcf, 0xef, 0xb3, 0xdd, 0x98, 0xae, 0x9a, 0xa3, 0x13, 0xc3, 0x07, - 0x37, 0x0e, 0xe5, 0x2c, 0x50, 0xa1, 0x5e, 0xe2, 0xa6, 0x94, 0x45, 0x2a, - 0x00, 0x9d, 0xee, 0x53, 0x67, 0x10, 0x6b, 0x13, 0xc5, 0xf9, 0x1c, 0x88, - 0x70, 0x3c, 0x73, 0x5f, 0x98, 0x2b, 0x05, 0x51, 0xf7, 0x67, 0xf6, 0xa6, - 0x5b, 0xcb, 0xb6, 0x1c, 0xc2, 0x85, 0xef, 0x1e, 0xcd, 0x25, 0x5f, 0xfa, - 0xba, 0xcd, 0x89, 0xf7, 0x93, 0xfe, 0x9f, 0xd6, 0xdd, 0x2c, 0x4c, 0xd5, - 0x33, 0xec, 0xd7, 0xef, 0x6e, 0xc8, 0x0b, 0x9b, 0x8b, 0x4e, 0x75, 0x91, - 0x0b, 0x4e, 0x96, 0x81, 0x4d, 0xee, 0x06, 0x55, 0x41, 0xfc, 0xc5, 0x2a, - 0xa6, 0x53, 0x97, 0xb6, 0xce, 0x61, 0x22, 0x93, 0xa8, 0x71, 0x04, 0x51, - 0xa7, 0xa8, 0x87, 0xee, 0x72, 0xb7, 0x0f, 0xa4, 0x5e, 0x6e, 0xc2, 0xcd, - 0xfa, 0x00, 0xf8, 0x9c, 0xe5, 0xcc, 0x61, 0xce, 0x88, 0xf0, 0x55, 0xb6, - 0xff, 0xac, 0xdb, 0xeb, 0xe6, 0xcc, 0x89, 0x7e, 0xea, 0x29, 0x7f, 0x9f, - 0x01, 0x54, 0x8a, 0x65, 0x60, 0x31, 0xe3, 0xaa, 0xa1, 0x68, 0x16, 0x50, - 0x7e, 0xe1, 0x9b, 0x04, 0x7f, 0xc5, 0x15, 0x77, 0xfe, 0xbd, 0xfa, 0xac, - 0x92, 0xcb, 0x0a, 0xc2, 0x3a, 0xbc, 0xec, 0x4e, 0xc4, 0x3a, 0x9f, 0x4d, - 0xdd, 0x2a, 0x03, 0xe3, 0x22, 0xc0, 0x66, 0x5a, 0x5c, 0x7f, 0x4c, 0x8a, - 0x58, 0x3e, 0x90, 0x79, 0x96, 0x16, 0x1d, 0x6f, 0x53, 0x43, 0x69, 0xfe, - 0xb6, 0x0a, 0x18, 0x8f, 0xbf, 0xb4, 0xb8, 0x99, 0xc5, 0x09, 0x20, 0x97, - 0x10, 0x18, 0xde, 0x57, 0x54, 0x24, 0x95, 0xeb, 0xce, 0x99, 0x01, 0xdd, - 0x42, 0xc0, 0x67, 0x0b, 0x8c, 0xdb, 0x1c, 0x77, 0x86, 0x63, 0x9d, 0x87, - 0xf6, 0xff, 0xcf, 0xc5, 0x38, 0xff, 0x6e, 0xb6, 0x05, 0x30, 0x82, 0x05, - 0xf2, 0x30, 0x82, 0x04, 0xda, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, - 0x61, 0x0c, 0x83, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x30, 0x4e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, - 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f, 0x6d, - 0x31, 0x18, 0x30, 0x16, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, - 0x2c, 0x64, 0x01, 0x19, 0x16, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, - 0x73, 0x74, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, - 0x14, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, - 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, - 0x0d, 0x30, 0x39, 0x30, 0x32, 0x31, 0x37, 0x32, 0x32, 0x33, 0x35, 0x35, - 0x36, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x32, 0x31, 0x37, 0x32, 0x32, - 0x33, 0x35, 0x35, 0x36, 0x5a, 0x30, 0x81, 0x8a, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x63, 0x61, 0x31, 0x12, - 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x63, 0x75, 0x70, - 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x13, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, - 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x02, - 0x71, 0x61, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, - 0x0c, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, - 0x6d, 0x31, 0x23, 0x30, 0x21, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x09, 0x01, 0x16, 0x14, 0x71, 0x61, 0x61, 0x64, 0x6d, 0x69, - 0x6e, 0x40, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, - 0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, - 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xa6, 0xf2, 0x65, 0xbe, 0xc6, - 0xb3, 0x53, 0xc2, 0x94, 0x89, 0xef, 0xca, 0x3a, 0x1d, 0x08, 0x64, 0x19, - 0x96, 0x5c, 0x8d, 0xc3, 0x15, 0x9b, 0xe5, 0x68, 0x86, 0x7d, 0xff, 0xf9, - 0xa1, 0xa5, 0x7b, 0x85, 0x8c, 0x14, 0x41, 0xf3, 0xe1, 0x6a, 0x17, 0xff, - 0xaf, 0x01, 0xb0, 0xbb, 0x64, 0x5d, 0xf0, 0xb8, 0x34, 0x10, 0x41, 0x3e, - 0xee, 0x43, 0x87, 0x47, 0x4a, 0x5e, 0xc2, 0x2c, 0xe8, 0xcb, 0x23, 0x14, - 0x9d, 0x92, 0xad, 0xe2, 0xaa, 0x53, 0xbd, 0xfa, 0xaf, 0x7a, 0x11, 0x64, - 0xeb, 0xb2, 0xf2, 0xd6, 0xdb, 0xd2, 0x77, 0xef, 0x74, 0xb2, 0x67, 0x1b, - 0xc7, 0xa4, 0x2e, 0x97, 0x80, 0x46, 0x92, 0xaf, 0x32, 0x18, 0x90, 0x46, - 0x57, 0x86, 0x2d, 0x97, 0x4d, 0x11, 0x48, 0xc5, 0x43, 0x23, 0x3e, 0x6b, - 0x0d, 0x32, 0x3e, 0xd0, 0xba, 0xf0, 0x20, 0x60, 0x0e, 0x02, 0x47, 0xae, - 0x58, 0xb4, 0x5b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x03, 0x17, - 0x30, 0x82, 0x03, 0x13, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, - 0x04, 0x03, 0x02, 0x05, 0x20, 0x30, 0x36, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0f, 0x04, 0x29, 0x30, 0x27, 0x30, 0x0d, - 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02, 0x01, - 0x38, 0x30, 0x0d, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, - 0x04, 0x02, 0x01, 0x38, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, - 0x07, 0x30, 0x15, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0e, 0x30, 0x0c, - 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x01, - 0x30, 0x29, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, - 0x02, 0x04, 0x1c, 0x1e, 0x1a, 0x00, 0x43, 0x00, 0x45, 0x00, 0x50, 0x00, - 0x45, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x72, 0x00, 0x79, 0x00, 0x70, 0x00, - 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xe0, 0xfc, 0xd6, 0xa7, 0xca, 0xab, - 0x38, 0x38, 0x6b, 0x79, 0x6f, 0x63, 0xb7, 0xfd, 0xc4, 0xbd, 0xb2, 0xc3, - 0x68, 0x03, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, - 0x16, 0x80, 0x14, 0x40, 0xb5, 0x54, 0x10, 0x88, 0x09, 0xeb, 0x3e, 0x2e, - 0x69, 0x82, 0xa6, 0xa0, 0xd8, 0xe4, 0xb0, 0x98, 0xc1, 0x69, 0x3d, 0x30, - 0x82, 0x01, 0x19, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, 0x10, - 0x30, 0x82, 0x01, 0x0c, 0x30, 0x82, 0x01, 0x08, 0xa0, 0x82, 0x01, 0x04, - 0xa0, 0x82, 0x01, 0x00, 0x86, 0x81, 0xbc, 0x6c, 0x64, 0x61, 0x70, 0x3a, - 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, - 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, - 0x6f, 0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, - 0x30, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, 0x3d, - 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79, - 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, - 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, - 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76, 0x70, 0x6e, - 0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x6d, 0x3f, - 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, - 0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44, 0x69, - 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, - 0x69, 0x6e, 0x74, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, - 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x65, 0x72, - 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x71, 0x61, 0x73, 0x72, - 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, - 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x82, 0x01, 0x2b, - 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x82, - 0x01, 0x1d, 0x30, 0x82, 0x01, 0x19, 0x30, 0x81, 0xb4, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0xa7, 0x6c, 0x64, - 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, - 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, - 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x49, 0x41, - 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, - 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, - 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, - 0x63, 0x6f, 0x6d, 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x65, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x60, 0x06, - 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x54, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, - 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, - 0x6c, 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, - 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x5f, 0x71, - 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, - 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x74, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, - 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x83, 0x54, 0x4e, 0x01, 0x42, - 0x95, 0x42, 0xa4, 0x56, 0x78, 0xf6, 0xa9, 0x41, 0xd8, 0xc3, 0xf2, 0xa4, - 0xdc, 0xa3, 0xb2, 0xaa, 0x72, 0x63, 0x2c, 0xab, 0x14, 0x40, 0x8c, 0xd9, - 0xdf, 0x61, 0xdf, 0xee, 0x8b, 0x50, 0x3b, 0xc7, 0xe1, 0x6f, 0xe5, 0x98, - 0x4d, 0xbd, 0x3c, 0x16, 0xc3, 0xcc, 0x3a, 0xb4, 0x11, 0x87, 0xb6, 0x93, - 0x63, 0xc6, 0x3d, 0xa2, 0xf3, 0x8c, 0xde, 0xc3, 0xcb, 0x44, 0x25, 0x7a, - 0x75, 0xc8, 0x5c, 0x9f, 0xeb, 0x43, 0xd2, 0xb1, 0x11, 0x8d, 0x9e, 0x29, - 0x7a, 0xf1, 0x9e, 0x59, 0xb2, 0x8b, 0xfa, 0x31, 0x2e, 0x4c, 0x8f, 0x6a, - 0x72, 0x0c, 0x42, 0x63, 0xf1, 0xca, 0x76, 0x8e, 0x33, 0x5e, 0x69, 0x9e, - 0x3b, 0x15, 0xba, 0xfb, 0xf8, 0x0e, 0x9d, 0x1b, 0xb1, 0x52, 0xc9, 0xc3, - 0x3e, 0x4f, 0xa4, 0x56, 0x1f, 0x71, 0x24, 0x0a, 0x61, 0x25, 0x87, 0x75, - 0x07, 0xc7, 0xf0, 0x6f, 0xb3, 0xd7, 0xe9, 0x20, 0x7a, 0xc1, 0x98, 0x48, - 0x25, 0xd0, 0x17, 0x27, 0xed, 0x21, 0xe8, 0x2b, 0xb6, 0xa7, 0xa5, 0x7b, - 0x53, 0x20, 0x27, 0x3d, 0x5d, 0xbb, 0xcd, 0x61, 0x84, 0xed, 0x66, 0x4c, - 0xcd, 0x65, 0x6d, 0xe9, 0x2d, 0xf5, 0xe5, 0x63, 0xaf, 0xd0, 0xde, 0xa0, - 0x89, 0x5b, 0x01, 0x05, 0x05, 0x63, 0x7e, 0x5b, 0xdb, 0xdc, 0x5a, 0xab, - 0xa5, 0xa4, 0x62, 0x3a, 0xe7, 0xdf, 0xae, 0x55, 0x9b, 0xf8, 0x93, 0x82, - 0x1b, 0xec, 0x00, 0x27, 0x2e, 0x73, 0x7d, 0xd8, 0xe2, 0xde, 0x76, 0xf3, - 0x70, 0xbe, 0xc5, 0x12, 0x00, 0x79, 0x62, 0x83, 0x6b, 0x04, 0x23, 0xc9, - 0x19, 0xa6, 0x23, 0x77, 0x45, 0xd6, 0x14, 0x01, 0xf7, 0x9c, 0x0f, 0x51, - 0x92, 0x98, 0x5a, 0x2a, 0x57, 0xc9, 0x5a, 0xb4, 0xe3, 0x98, 0x5f, 0x7e, - 0x07, 0x99, 0x66, 0x20, 0x17, 0x0d, 0x85, 0x2c, 0x3c, 0x98, 0x70, 0x30, - 0x82, 0x04, 0x98, 0x30, 0x82, 0x03, 0x80, 0xa0, 0x03, 0x02, 0x01, 0x02, - 0x02, 0x10, 0x7a, 0xdb, 0x4e, 0x56, 0x1a, 0xb8, 0x90, 0xae, 0x46, 0x6f, - 0x06, 0x74, 0x44, 0x09, 0x68, 0x87, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4e, 0x31, - 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, - 0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f, 0x6d, 0x31, 0x18, 0x30, 0x16, - 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, - 0x16, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x31, 0x1d, - 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x71, 0x61, 0x73, - 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, - 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30, - 0x31, 0x32, 0x38, 0x30, 0x32, 0x34, 0x33, 0x33, 0x30, 0x5a, 0x17, 0x0d, - 0x31, 0x34, 0x30, 0x31, 0x32, 0x38, 0x30, 0x32, 0x35, 0x32, 0x34, 0x33, - 0x5a, 0x30, 0x4e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, - 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f, 0x6d, - 0x31, 0x18, 0x30, 0x16, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, - 0x2c, 0x64, 0x01, 0x19, 0x16, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, - 0x73, 0x74, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, - 0x14, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, - 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, - 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, - 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbe, 0xf8, 0xff, 0x61, 0xca, 0x9d, - 0xcf, 0x07, 0x4d, 0x06, 0xf4, 0x52, 0x4b, 0x3f, 0x84, 0xc5, 0x0b, 0x71, - 0xef, 0x7f, 0x7d, 0x35, 0xac, 0x68, 0xce, 0x84, 0xe6, 0x7c, 0x0a, 0xba, - 0x02, 0x71, 0xcf, 0x81, 0x40, 0xcb, 0x25, 0xdb, 0x41, 0x23, 0x84, 0x88, - 0x4d, 0x16, 0xa2, 0x41, 0xa5, 0x2a, 0x98, 0xa3, 0xb7, 0x02, 0xff, 0x54, - 0xb6, 0xd5, 0x55, 0x75, 0x17, 0xbc, 0xd5, 0x04, 0x24, 0x35, 0x63, 0xfa, - 0xcb, 0x98, 0x38, 0x98, 0x18, 0xd3, 0x13, 0xc1, 0xef, 0x1a, 0xfe, 0xb7, - 0xcd, 0x2e, 0xc2, 0xb8, 0x0d, 0x3e, 0x62, 0x38, 0xc0, 0x05, 0xf9, 0x5b, - 0xc5, 0xd5, 0xf6, 0xc4, 0x9d, 0x8e, 0xc3, 0x90, 0x32, 0xa2, 0xb1, 0x88, - 0xa8, 0xf9, 0xd3, 0x0d, 0x02, 0x8d, 0xbe, 0x8f, 0x41, 0xe7, 0x92, 0x85, - 0xe7, 0x4c, 0x11, 0x9a, 0x4b, 0xfb, 0x00, 0xa9, 0x9f, 0xf5, 0xfb, 0x23, - 0xda, 0xf1, 0xfd, 0x95, 0x89, 0xd5, 0x2b, 0xc5, 0xbf, 0x9c, 0xc3, 0x93, - 0xd0, 0xc2, 0xf8, 0x12, 0xbe, 0x26, 0x24, 0x41, 0x80, 0x64, 0x2f, 0xc0, - 0x7b, 0x31, 0x85, 0x06, 0x3c, 0xe4, 0xc6, 0x7e, 0xbc, 0x61, 0xa7, 0xa2, - 0xf4, 0xa7, 0xd7, 0xd7, 0xcb, 0xeb, 0xea, 0xb0, 0xc6, 0xd7, 0x13, 0xd6, - 0x09, 0xfa, 0x45, 0xc6, 0x25, 0x6f, 0x34, 0xdc, 0x78, 0x70, 0xa0, 0xa5, - 0xea, 0xd7, 0xe7, 0xda, 0xe2, 0x5a, 0x7a, 0xc3, 0xe3, 0x7a, 0x8d, 0xf3, - 0x5a, 0x78, 0xfa, 0x57, 0xe1, 0xf1, 0xae, 0x6b, 0xea, 0x83, 0xd0, 0xd7, - 0xa9, 0x43, 0x2d, 0x5d, 0x8b, 0xac, 0xbb, 0x92, 0x5b, 0x2a, 0xd7, 0x27, - 0xbe, 0xe7, 0xa0, 0xd2, 0xc5, 0x9b, 0xd7, 0xa4, 0xc1, 0x6a, 0xf8, 0xec, - 0xfc, 0xa6, 0x96, 0xfc, 0x09, 0x11, 0x95, 0xca, 0x75, 0xab, 0x8a, 0x5b, - 0xd2, 0xb2, 0xb4, 0x11, 0xf1, 0x88, 0x34, 0xe3, 0xb7, 0x21, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x70, 0x30, 0x82, 0x01, 0x6c, 0x30, - 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, - 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, - 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, - 0x04, 0x16, 0x04, 0x14, 0x40, 0xb5, 0x54, 0x10, 0x88, 0x09, 0xeb, 0x3e, - 0x2e, 0x69, 0x82, 0xa6, 0xa0, 0xd8, 0xe4, 0xb0, 0x98, 0xc1, 0x69, 0x3d, - 0x30, 0x82, 0x01, 0x19, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, - 0x10, 0x30, 0x82, 0x01, 0x0c, 0x30, 0x82, 0x01, 0x08, 0xa0, 0x82, 0x01, - 0x04, 0xa0, 0x82, 0x01, 0x00, 0x86, 0x81, 0xbc, 0x6c, 0x64, 0x61, 0x70, - 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, - 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, - 0x63, 0x6f, 0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, - 0x31, 0x30, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, - 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, - 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76, 0x70, - 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x6d, - 0x3f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, - 0x73, 0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44, - 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, - 0x6f, 0x69, 0x6e, 0x74, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, - 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x65, - 0x72, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x71, 0x61, 0x73, - 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, - 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x10, 0x06, - 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x01, 0x04, 0x03, - 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x07, - 0x74, 0x27, 0x8c, 0xdd, 0x75, 0xa1, 0x0d, 0x97, 0xd1, 0x9d, 0x0d, 0xae, - 0x3b, 0xf3, 0x14, 0x0f, 0xa1, 0x1c, 0x51, 0xd8, 0x68, 0xe7, 0xfd, 0xd0, - 0xaf, 0xe7, 0x66, 0x62, 0xf8, 0x73, 0x75, 0x88, 0x6c, 0xb9, 0xb3, 0x1e, - 0xf5, 0x82, 0x3a, 0x1d, 0x82, 0x7b, 0xa3, 0x18, 0xd9, 0x1a, 0x40, 0xf2, - 0xcd, 0xb3, 0x83, 0xae, 0x12, 0x5b, 0xb4, 0x45, 0xd9, 0xbe, 0x51, 0x3e, - 0x11, 0x64, 0xaf, 0x95, 0x06, 0xb6, 0xbd, 0xd1, 0xa1, 0xfd, 0xbb, 0xdb, - 0xa4, 0xbb, 0xba, 0x3e, 0xd5, 0xd6, 0x1d, 0x37, 0x80, 0x17, 0xe8, 0x08, - 0x75, 0x5f, 0x5d, 0x49, 0x5f, 0x70, 0xdd, 0x67, 0xde, 0x9a, 0x34, 0x95, - 0x2e, 0x54, 0x58, 0x42, 0xaf, 0x8a, 0x57, 0xf2, 0xb4, 0x1f, 0xfb, 0x40, - 0x9c, 0x05, 0xa0, 0x6a, 0x9a, 0x91, 0x0e, 0x27, 0xaa, 0x9e, 0xdb, 0xbf, - 0x50, 0xc9, 0xa4, 0x2f, 0xc8, 0x71, 0x00, 0x11, 0xf8, 0x2f, 0xda, 0x98, - 0xf4, 0x1d, 0x98, 0x2a, 0xe9, 0x29, 0xc7, 0xea, 0x74, 0x65, 0xf1, 0x6d, - 0x06, 0x9f, 0x59, 0xa3, 0x50, 0x7e, 0x1b, 0x52, 0x5a, 0xb9, 0x5e, 0xce, - 0xa0, 0x03, 0x53, 0xe8, 0xba, 0x36, 0x4a, 0xc2, 0x95, 0xdb, 0x34, 0x61, - 0xc8, 0xf4, 0xa5, 0x7c, 0xd6, 0x9d, 0x64, 0x91, 0xfb, 0x23, 0xfd, 0x8b, - 0x3a, 0xd2, 0x67, 0xb0, 0x64, 0xa7, 0x80, 0x82, 0x74, 0x85, 0x45, 0xa7, - 0x78, 0x57, 0xb6, 0xf0, 0x0a, 0xf9, 0xa2, 0xb5, 0x7f, 0x7e, 0x88, 0x21, - 0xd7, 0x67, 0xd2, 0xc4, 0x9c, 0x98, 0x51, 0x9b, 0x71, 0xfb, 0x39, 0xf2, - 0xb3, 0xfd, 0x3f, 0x0b, 0x61, 0x59, 0xa0, 0x15, 0x40, 0x53, 0x71, 0xac, - 0xf5, 0xf7, 0xee, 0x03, 0x6b, 0x1f, 0x5d, 0x29, 0x0a, 0xf7, 0x4f, 0x1a, - 0xea, 0xa4, 0xb8, 0x02, 0x63, 0x7c, 0x37, 0x37, 0xdd, 0x46, 0x42, 0xe3, - 0xe1, 0x82, 0x94, 0x31, 0x00 -}; -static unsigned int msscep_getcacert_len = 4241; - - -static uint8_t getcacert[] = { - 0x30, 0x82, 0x04, 0x6a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x07, 0x02, 0xa0, 0x82, 0x04, 0x5b, 0x30, 0x82, 0x04, 0x57, 0x02, - 0x01, 0x01, 0x31, 0x00, 0x30, 0x03, 0x06, 0x01, 0x00, 0xa0, 0x82, 0x04, - 0x47, 0x30, 0x82, 0x02, 0x33, 0x30, 0x82, 0x01, 0x9c, 0xa0, 0x03, 0x02, - 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4d, 0x31, 0x0d, - 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x04, 0x4e, 0x6f, 0x6e, - 0x65, 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x33, - 0x41, 0x43, 0x4d, 0x45, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, - 0x20, 0x28, 0x35, 0x36, 0x32, 0x66, 0x30, 0x64, 0x30, 0x35, 0x2d, 0x32, - 0x35, 0x36, 0x61, 0x2d, 0x34, 0x32, 0x65, 0x65, 0x2d, 0x39, 0x66, 0x35, - 0x38, 0x2d, 0x38, 0x30, 0x62, 0x30, 0x61, 0x35, 0x35, 0x37, 0x38, 0x62, - 0x66, 0x30, 0x29, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30, 0x39, 0x31, - 0x37, 0x30, 0x30, 0x33, 0x39, 0x32, 0x33, 0x5a, 0x17, 0x0d, 0x31, 0x30, - 0x30, 0x39, 0x31, 0x37, 0x30, 0x30, 0x33, 0x39, 0x32, 0x33, 0x5a, 0x30, - 0x4d, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x04, - 0x4e, 0x6f, 0x6e, 0x65, 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x0c, 0x33, 0x41, 0x43, 0x4d, 0x45, 0x20, 0x52, 0x6f, 0x6f, 0x74, - 0x20, 0x43, 0x41, 0x20, 0x28, 0x35, 0x36, 0x32, 0x66, 0x30, 0x64, 0x30, - 0x35, 0x2d, 0x32, 0x35, 0x36, 0x61, 0x2d, 0x34, 0x32, 0x65, 0x65, 0x2d, - 0x39, 0x66, 0x35, 0x38, 0x2d, 0x38, 0x30, 0x62, 0x30, 0x61, 0x35, 0x35, - 0x37, 0x38, 0x62, 0x66, 0x30, 0x29, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, - 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd4, - 0x1c, 0xaa, 0x58, 0x8a, 0xda, 0xfc, 0x24, 0x21, 0x35, 0xc2, 0xb0, 0x2b, - 0x08, 0x5d, 0xe2, 0xf5, 0xb5, 0xf0, 0xdc, 0xca, 0x04, 0xaa, 0x8e, 0x86, - 0xff, 0xfe, 0x9b, 0x35, 0xed, 0x61, 0x3a, 0xe5, 0xbf, 0xf7, 0xbf, 0xab, - 0xa4, 0xa8, 0x6e, 0xf5, 0xba, 0x5b, 0x0e, 0xdc, 0x28, 0x07, 0x24, 0x01, - 0xda, 0x9e, 0x1f, 0x92, 0xa5, 0x4b, 0x51, 0xcd, 0xd9, 0x6e, 0x27, 0xfa, - 0xda, 0x9b, 0x9c, 0x17, 0x3e, 0x1b, 0x36, 0xaf, 0xf5, 0x5d, 0x11, 0x02, - 0xe9, 0x2e, 0xf1, 0x6e, 0xb6, 0x7f, 0xe8, 0x91, 0xbd, 0x66, 0x73, 0xdf, - 0xb9, 0x27, 0xb7, 0x5b, 0x04, 0xb1, 0x9f, 0x52, 0x38, 0xea, 0xd0, 0x1c, - 0x97, 0x2d, 0x4b, 0x1b, 0x03, 0xcb, 0xe6, 0xa4, 0x92, 0x2c, 0x0f, 0x5d, - 0x34, 0x06, 0x52, 0x07, 0x35, 0x97, 0x13, 0x2f, 0x27, 0x62, 0x5a, 0x4b, - 0xc3, 0xac, 0x5f, 0x0a, 0x40, 0x98, 0x29, 0x02, 0x03, 0x01, 0x00, 0x01, - 0xa3, 0x23, 0x30, 0x21, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, - 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, - 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, - 0x86, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x35, 0xa8, 0x47, 0x69, - 0x01, 0x12, 0x43, 0x34, 0x73, 0xe4, 0xd8, 0xa4, 0x95, 0x00, 0xea, 0xd7, - 0x33, 0xf2, 0x7b, 0x49, 0xea, 0xa7, 0xc6, 0xe1, 0x7d, 0x06, 0xb8, 0xb4, - 0x4f, 0x3f, 0x08, 0x97, 0xa8, 0x47, 0x82, 0x1e, 0x0a, 0x4b, 0xdb, 0x19, - 0x9d, 0x21, 0x30, 0x2c, 0x37, 0xa0, 0x3f, 0x92, 0xf7, 0xc2, 0x39, 0x57, - 0x2b, 0x43, 0x33, 0xf9, 0x6e, 0x40, 0x8c, 0x64, 0x2b, 0xf5, 0xb6, 0xb6, - 0x6c, 0x2e, 0x59, 0xc4, 0xe6, 0x01, 0x87, 0xd4, 0x1c, 0x32, 0xf1, 0x68, - 0x72, 0xeb, 0xda, 0x35, 0x69, 0x3c, 0x7d, 0x6f, 0x4c, 0xba, 0x8b, 0x4d, - 0xaa, 0x1c, 0x11, 0x05, 0x76, 0x9e, 0x73, 0x2a, 0x20, 0xcb, 0x31, 0x9c, - 0x74, 0x20, 0x99, 0x4c, 0xbc, 0x17, 0xd0, 0xb5, 0x6e, 0x1e, 0xad, 0x87, - 0x83, 0xa6, 0xda, 0x15, 0x85, 0x7a, 0x8f, 0x76, 0x37, 0xa7, 0x11, 0x53, - 0x7f, 0x12, 0xb1, 0x05, 0x30, 0x82, 0x02, 0x0c, 0x30, 0x82, 0x01, 0x75, - 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x64, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, - 0x4d, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x04, - 0x4e, 0x6f, 0x6e, 0x65, 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x0c, 0x33, 0x41, 0x43, 0x4d, 0x45, 0x20, 0x52, 0x6f, 0x6f, 0x74, - 0x20, 0x43, 0x41, 0x20, 0x28, 0x35, 0x36, 0x32, 0x66, 0x30, 0x64, 0x30, - 0x35, 0x2d, 0x32, 0x35, 0x36, 0x61, 0x2d, 0x34, 0x32, 0x65, 0x65, 0x2d, - 0x39, 0x66, 0x35, 0x38, 0x2d, 0x38, 0x30, 0x62, 0x30, 0x61, 0x35, 0x35, - 0x37, 0x38, 0x62, 0x66, 0x30, 0x29, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, - 0x30, 0x39, 0x31, 0x37, 0x30, 0x30, 0x33, 0x39, 0x32, 0x33, 0x5a, 0x17, - 0x0d, 0x31, 0x30, 0x30, 0x39, 0x31, 0x37, 0x30, 0x30, 0x33, 0x39, 0x32, - 0x33, 0x5a, 0x30, 0x26, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x0c, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x31, 0x15, 0x30, 0x13, 0x06, - 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0c, 0x41, 0x43, 0x4d, 0x45, 0x20, 0x53, - 0x43, 0x45, 0x50, 0x20, 0x52, 0x41, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, - 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd1, - 0x6e, 0x98, 0x93, 0x0e, 0x0a, 0x27, 0x5f, 0xd9, 0x3e, 0x95, 0xe3, 0x24, - 0xae, 0x96, 0xd2, 0x62, 0x40, 0x05, 0xb6, 0x2d, 0x4d, 0xe2, 0x8f, 0x35, - 0x26, 0x14, 0x72, 0x04, 0xb0, 0x34, 0xaf, 0xf3, 0x61, 0x7c, 0xa0, 0x72, - 0xe6, 0x29, 0xf3, 0xdf, 0xc2, 0x2a, 0x8c, 0x84, 0xde, 0xea, 0x7c, 0x01, - 0x64, 0x08, 0x8c, 0xaa, 0x0b, 0x96, 0x9b, 0xb5, 0xb8, 0x86, 0x49, 0xad, - 0x68, 0x1d, 0x7c, 0xf0, 0x1a, 0xe9, 0xf6, 0x56, 0x97, 0xe4, 0xb8, 0x20, - 0xa6, 0x1f, 0x1a, 0x9d, 0xcc, 0x5f, 0xe8, 0xc9, 0x05, 0xab, 0x85, 0xab, - 0xce, 0x5c, 0xcd, 0x20, 0xb7, 0x01, 0x8d, 0xda, 0x10, 0x54, 0x22, 0xbd, - 0x93, 0xf9, 0xac, 0x12, 0x39, 0x08, 0x9d, 0x27, 0xa1, 0x92, 0xb6, 0x94, - 0xde, 0x15, 0xcc, 0x0f, 0x9e, 0x1f, 0xe0, 0x44, 0x90, 0x57, 0x87, 0x04, - 0x9b, 0xfb, 0xb0, 0x63, 0x9d, 0xc0, 0x4d, 0x02, 0x03, 0x01, 0x00, 0x01, - 0xa3, 0x23, 0x30, 0x21, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, - 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, - 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, - 0xa0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0xbb, 0xb7, 0xa1, 0xd6, - 0x0c, 0xdd, 0xa8, 0xfe, 0x4a, 0x3b, 0x90, 0x42, 0x9b, 0x4f, 0xfc, 0xa4, - 0x75, 0xf2, 0x04, 0x09, 0xd6, 0x9e, 0xfb, 0x4f, 0x99, 0xf8, 0xcb, 0x5c, - 0xcc, 0xb0, 0xb3, 0xce, 0xd7, 0x83, 0xed, 0x4d, 0xa7, 0x93, 0xdb, 0x87, - 0x7b, 0x09, 0x2f, 0x07, 0xb3, 0xd2, 0xa3, 0x08, 0x17, 0x53, 0xb4, 0x61, - 0xd7, 0x58, 0x86, 0x79, 0x2c, 0x2e, 0x09, 0x75, 0xda, 0x61, 0xa8, 0x90, - 0x1f, 0xea, 0x2f, 0x0f, 0x2a, 0xcb, 0xf5, 0x01, 0x54, 0xee, 0x23, 0x80, - 0xbb, 0xaa, 0xb5, 0x61, 0x66, 0x23, 0xb3, 0xd2, 0xff, 0x7f, 0xb8, 0x74, - 0xc9, 0x55, 0xb5, 0x84, 0x57, 0x5a, 0x2e, 0x81, 0x0d, 0xe5, 0x0d, 0x45, - 0x4f, 0x37, 0xc4, 0x2d, 0xec, 0xf8, 0xf1, 0x15, 0x59, 0xc4, 0x7a, 0x49, - 0xd0, 0x12, 0x16, 0x18, 0x6a, 0x3e, 0x74, 0xe5, 0x4e, 0x65, 0xdc, 0xcc, - 0xba, 0x9e, 0x77, 0x7c, 0x31, 0x00 -}; -static unsigned int getcacert_len = 1134; - -static uint8_t msscep_md5_hash[] = {0x13, 0x7f, 0x4d, 0xaa, 0x5d, 0xa0, 0x65, 0x1b, 0xbd, 0x54, 0x8c, 0xc2, 0xd3, 0xd4, 0xce, 0xd0 }; -static uint8_t ruby_sha1_hash[] = { 0xf3, 0x5f, 0x6b, 0xd1, 0x64, 0x0b, 0xc1, 0x81, 0x98, 0xb9, 0x30, 0xd1, 0x97, 0x10, 0x3b, 0x45, 0xf0, 0x6e, 0x53, 0xdb }; - - -static unsigned char bmw_scep_pkt[] = { - 0x30, 0x82, 0x16, 0x19, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x07, 0x02, 0xa0, 0x82, 0x16, 0x0a, 0x30, 0x82, 0x16, 0x06, 0x02, - 0x01, 0x01, 0x31, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x15, 0xee, 0x30, 0x82, 0x06, - 0x26, 0x30, 0x82, 0x05, 0x0e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, - 0x3c, 0xec, 0x7e, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x30, 0x64, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x09, 0x92, 0x26, - 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x04, 0x63, 0x6f, 0x72, - 0x70, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, - 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x62, 0x6d, 0x77, 0x31, 0x16, - 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, - 0x01, 0x19, 0x16, 0x06, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x31, 0x1f, - 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x42, 0x4d, 0x57, - 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x49, 0x73, 0x73, 0x75, 0x69, - 0x6e, 0x67, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x31, - 0x30, 0x30, 0x33, 0x30, 0x34, 0x31, 0x33, 0x35, 0x33, 0x31, 0x30, 0x5a, - 0x17, 0x0d, 0x31, 0x32, 0x30, 0x33, 0x30, 0x33, 0x31, 0x33, 0x35, 0x33, - 0x31, 0x30, 0x5a, 0x30, 0x81, 0x83, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x45, 0x31, 0x10, 0x30, 0x0e, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x42, 0x61, 0x76, 0x61, 0x72, 0x69, - 0x61, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x06, - 0x4d, 0x75, 0x6e, 0x69, 0x63, 0x68, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x13, 0x09, 0x42, 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, - 0x11, 0x53, 0x43, 0x45, 0x50, 0x20, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, - 0x67, 0x20, 0x43, 0x41, 0x20, 0x32, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x40, 0x62, - 0x6d, 0x77, 0x2e, 0x64, 0x65, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, - 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xad, 0x57, - 0x88, 0x2c, 0x2c, 0xda, 0x45, 0x32, 0x32, 0xb1, 0xba, 0xce, 0x1b, 0x0b, - 0x5d, 0xc8, 0x5d, 0x76, 0xd2, 0x63, 0xf6, 0xc7, 0xe6, 0x45, 0xff, 0x37, - 0xf3, 0x85, 0xbf, 0xbb, 0xa1, 0x83, 0xd1, 0xea, 0xe0, 0x3f, 0xc9, 0x05, - 0x79, 0xe3, 0x15, 0xc3, 0x97, 0x2a, 0x81, 0x38, 0x4f, 0x33, 0xc1, 0xc9, - 0xf5, 0xb0, 0x1b, 0xbd, 0xad, 0x52, 0x15, 0x80, 0x52, 0x7d, 0x1b, 0x68, - 0x8f, 0xb5, 0x27, 0xda, 0xcf, 0x20, 0x7d, 0x53, 0x6e, 0xb0, 0xe8, 0x4b, - 0x8e, 0x6b, 0xb2, 0x63, 0xe3, 0xd5, 0x2c, 0x67, 0x55, 0x73, 0x0f, 0xda, - 0x41, 0x04, 0x56, 0xdc, 0xb3, 0x9a, 0x6b, 0xbb, 0x62, 0xf8, 0x8f, 0xe2, - 0x91, 0x7a, 0xe8, 0xa7, 0xa9, 0xc4, 0x8b, 0x75, 0x7b, 0xb5, 0x5f, 0x4e, - 0xe1, 0x4d, 0x80, 0x4d, 0xc9, 0xee, 0x23, 0xbc, 0xf7, 0x4f, 0x8d, 0xc0, - 0x02, 0x20, 0x23, 0x82, 0x80, 0xf7, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, - 0x82, 0x03, 0x3c, 0x30, 0x82, 0x03, 0x38, 0x30, 0x0b, 0x06, 0x03, 0x55, - 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x15, 0x06, 0x03, - 0x55, 0x1d, 0x25, 0x04, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, - 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x01, 0x30, 0x3b, 0x06, 0x09, 0x2b, - 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x2e, 0x1e, 0x2c, - 0x00, 0x45, 0x00, 0x6e, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x6c, - 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x41, 0x00, 0x67, - 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x4f, 0x00, 0x66, 0x00, 0x66, - 0x00, 0x6c, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x65, 0x30, 0x1d, 0x06, 0x03, - 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd8, 0xeb, 0x70, 0x8b, 0x4e, - 0xda, 0xfb, 0x52, 0x03, 0x0c, 0xa5, 0xc5, 0xfd, 0xf3, 0x29, 0x54, 0xfd, - 0x2e, 0x8f, 0x3e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, - 0x30, 0x16, 0x80, 0x14, 0x61, 0x0a, 0xef, 0x1a, 0x3d, 0xfe, 0x9a, 0x68, - 0x81, 0xcb, 0xb2, 0x62, 0xe5, 0xc0, 0x21, 0x8e, 0xdd, 0xec, 0x61, 0x95, - 0x30, 0x82, 0x01, 0x71, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, - 0x68, 0x30, 0x82, 0x01, 0x64, 0x30, 0x82, 0x01, 0x60, 0xa0, 0x82, 0x01, - 0x5c, 0xa0, 0x82, 0x01, 0x58, 0x86, 0x81, 0xc3, 0x6c, 0x64, 0x61, 0x70, - 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x42, 0x4d, 0x57, 0x25, 0x32, - 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, - 0x75, 0x69, 0x6e, 0x67, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, - 0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x4d, 0x55, 0x43, 0x31, 0x39, 0x32, - 0x33, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, 0x3d, - 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79, - 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, - 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, - 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x62, 0x6d, 0x77, 0x2c, - 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x72, 0x70, 0x3f, 0x63, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x3f, 0x62, 0x61, - 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, - 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x86, - 0x4d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x6d, 0x75, 0x63, - 0x31, 0x39, 0x32, 0x33, 0x2e, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2e, - 0x62, 0x6d, 0x77, 0x2e, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x43, 0x65, 0x72, - 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x42, 0x4d, 0x57, 0x25, - 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, - 0x73, 0x75, 0x69, 0x6e, 0x67, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, - 0x30, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x86, 0x41, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x73, 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d, - 0x77, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, - 0x6b, 0x69, 0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, - 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2e, 0x63, 0x72, - 0x6c, 0x30, 0x82, 0x01, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x01, 0x01, 0x04, 0x82, 0x01, 0x10, 0x30, 0x82, 0x01, 0x0c, 0x30, - 0x81, 0xba, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, - 0x86, 0x81, 0xad, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, - 0x4e, 0x3d, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x25, - 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2c, 0x43, 0x4e, 0x3d, - 0x41, 0x49, 0x41, 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, - 0x44, 0x43, 0x3d, 0x62, 0x6d, 0x77, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, - 0x72, 0x70, 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x4d, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x41, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, - 0x62, 0x6d, 0x77, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, - 0x6e, 0x67, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2e, - 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x46, - 0x9e, 0x81, 0xb2, 0xec, 0xa9, 0xe4, 0x3c, 0xf3, 0x9b, 0x61, 0xdf, 0x6f, - 0xec, 0x28, 0xe9, 0x2b, 0xd4, 0xc1, 0xb2, 0x05, 0x03, 0xbd, 0x53, 0x49, - 0xa2, 0x94, 0x3a, 0xd6, 0x23, 0xa3, 0xe8, 0x52, 0xa4, 0xe6, 0x44, 0x5e, - 0x15, 0x89, 0xde, 0x32, 0x12, 0xba, 0x97, 0x3a, 0xd3, 0x1d, 0xa1, 0xda, - 0x2a, 0x70, 0x3e, 0x10, 0xea, 0x2c, 0xb5, 0x19, 0xc2, 0x71, 0xcd, 0x1c, - 0x10, 0x07, 0x4b, 0x58, 0x10, 0x61, 0x03, 0x72, 0x4f, 0x65, 0xf7, 0x38, - 0x9d, 0xa9, 0x35, 0x0c, 0xc9, 0xdf, 0x7f, 0x91, 0xa0, 0xd4, 0x08, 0xf2, - 0xf9, 0x1b, 0x0f, 0xaa, 0xb4, 0xb6, 0xe0, 0x3c, 0x9d, 0x0c, 0x64, 0xee, - 0x2f, 0x47, 0xdd, 0xdb, 0x3a, 0x6f, 0x69, 0x19, 0x1f, 0xa1, 0xdd, 0x1d, - 0xd7, 0x45, 0x04, 0x56, 0x16, 0x43, 0x22, 0x18, 0xba, 0x22, 0xd6, 0x70, - 0xd0, 0x67, 0xb0, 0x06, 0x6a, 0x16, 0x57, 0x61, 0x83, 0x47, 0xd9, 0x40, - 0xc9, 0x92, 0xdd, 0x74, 0xbe, 0xb9, 0xe8, 0x07, 0x40, 0xa8, 0x23, 0xc5, - 0xd6, 0x3e, 0x26, 0xec, 0x17, 0x6c, 0x61, 0x76, 0x47, 0x42, 0x0a, 0x82, - 0x5e, 0xdb, 0x41, 0xba, 0x42, 0x1f, 0xec, 0xb7, 0xc2, 0xe0, 0xf8, 0x3a, - 0x39, 0x5f, 0xb2, 0x45, 0x92, 0xdc, 0xe2, 0x5e, 0x5d, 0x81, 0x14, 0xa3, - 0x10, 0x68, 0x5a, 0xed, 0x28, 0x9f, 0xad, 0xa6, 0xc9, 0xd9, 0x61, 0xc2, - 0x62, 0xec, 0x1b, 0x61, 0x2a, 0x67, 0xef, 0xac, 0x79, 0xc1, 0x6e, 0x35, - 0xc4, 0xd2, 0x69, 0x05, 0x3f, 0xf2, 0x6f, 0x5a, 0x66, 0x0c, 0xea, 0xd2, - 0x70, 0x2e, 0xbe, 0x5f, 0xd8, 0x31, 0x6c, 0x1f, 0xec, 0x62, 0xf6, 0xa7, - 0x98, 0x1c, 0xd4, 0xf6, 0xc1, 0x28, 0x71, 0xf5, 0x63, 0xab, 0x59, 0x4b, - 0x34, 0xb4, 0x30, 0x12, 0x91, 0x71, 0xf8, 0x50, 0x9a, 0x26, 0x4a, 0xd9, - 0xf1, 0x30, 0x04, 0x30, 0x82, 0x06, 0x4c, 0x30, 0x82, 0x05, 0x34, 0xa0, - 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, 0x3c, 0xec, 0x82, 0xf8, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0e, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x64, 0x31, 0x14, 0x30, - 0x12, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, - 0x19, 0x16, 0x04, 0x63, 0x6f, 0x72, 0x70, 0x31, 0x13, 0x30, 0x11, 0x06, - 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, - 0x03, 0x62, 0x6d, 0x77, 0x31, 0x16, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, - 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x65, 0x75, - 0x72, 0x6f, 0x70, 0x65, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x16, 0x42, 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x20, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x41, 0x20, - 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x33, 0x30, 0x34, 0x31, - 0x33, 0x35, 0x33, 0x31, 0x31, 0x5a, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x33, - 0x30, 0x33, 0x31, 0x33, 0x35, 0x33, 0x31, 0x31, 0x5a, 0x30, 0x81, 0x83, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x44, - 0x45, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, - 0x42, 0x61, 0x76, 0x61, 0x72, 0x69, 0x61, 0x31, 0x0f, 0x30, 0x0d, 0x06, - 0x03, 0x55, 0x04, 0x07, 0x13, 0x06, 0x4d, 0x75, 0x6e, 0x69, 0x63, 0x68, - 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x42, - 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x1a, 0x30, 0x18, - 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x43, 0x45, 0x50, 0x20, - 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x41, 0x20, 0x32, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x09, 0x01, 0x16, 0x12, 0x74, 0x72, 0x75, 0x73, 0x74, 0x63, 0x65, - 0x6e, 0x74, 0x65, 0x72, 0x40, 0x62, 0x6d, 0x77, 0x2e, 0x64, 0x65, 0x30, - 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, - 0x02, 0x81, 0x81, 0x00, 0xa4, 0x78, 0xc8, 0x9b, 0xd9, 0x08, 0x24, 0xab, - 0x07, 0x33, 0x89, 0x62, 0xcd, 0x20, 0xcb, 0x16, 0xfa, 0x1d, 0x9b, 0x8a, - 0xcf, 0x9d, 0x61, 0xea, 0x10, 0xbd, 0xa0, 0x02, 0xf5, 0x97, 0x53, 0x96, - 0x86, 0xb3, 0x02, 0x88, 0xf7, 0x52, 0xd8, 0x67, 0xcd, 0xe4, 0xba, 0xa7, - 0x36, 0xfd, 0x6e, 0xd3, 0x51, 0x9a, 0xa2, 0xfb, 0xcc, 0x2c, 0xd1, 0xaa, - 0x9c, 0x49, 0x2e, 0x36, 0xe0, 0xa2, 0x21, 0xc8, 0xfd, 0x05, 0xa9, 0x54, - 0x16, 0x9f, 0xd3, 0x8e, 0x6a, 0xbe, 0x3e, 0x7f, 0xc8, 0xc6, 0x2d, 0x8d, - 0xda, 0xe9, 0x73, 0x97, 0x5e, 0x80, 0xdd, 0x8c, 0xc4, 0x9b, 0x3a, 0x77, - 0xc7, 0x6a, 0x8d, 0xe2, 0xe1, 0x54, 0x6f, 0x5e, 0xde, 0x3f, 0x71, 0x9c, - 0x14, 0x2d, 0x15, 0x6d, 0xf1, 0x7c, 0x43, 0x97, 0xb7, 0xdf, 0x5a, 0x1a, - 0xb8, 0xb7, 0x9c, 0x05, 0x4d, 0xf5, 0x45, 0x45, 0x59, 0xbe, 0x73, 0xbd, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x03, 0x62, 0x30, 0x82, 0x03, - 0x5e, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, - 0x05, 0x20, 0x30, 0x36, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x09, 0x0f, 0x04, 0x29, 0x30, 0x27, 0x30, 0x0d, 0x06, 0x08, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02, 0x01, 0x38, 0x30, 0x0d, - 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x04, 0x02, 0x01, - 0x38, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x07, 0x30, 0x15, - 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, - 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x01, 0x30, 0x29, 0x06, - 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x1c, - 0x1e, 0x1a, 0x00, 0x43, 0x00, 0x45, 0x00, 0x50, 0x00, 0x45, 0x00, 0x6e, - 0x00, 0x63, 0x00, 0x72, 0x00, 0x79, 0x00, 0x70, 0x00, 0x74, 0x00, 0x69, - 0x00, 0x6f, 0x00, 0x6e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, - 0x16, 0x04, 0x14, 0x11, 0xe1, 0x07, 0x5e, 0xd5, 0x49, 0xed, 0x64, 0x11, - 0xc4, 0x33, 0xbb, 0x2a, 0x99, 0x7c, 0xb0, 0xc8, 0xd8, 0x85, 0x8d, 0x30, - 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, - 0x61, 0x0a, 0xef, 0x1a, 0x3d, 0xfe, 0x9a, 0x68, 0x81, 0xcb, 0xb2, 0x62, - 0xe5, 0xc0, 0x21, 0x8e, 0xdd, 0xec, 0x61, 0x95, 0x30, 0x82, 0x01, 0x71, - 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, 0x68, 0x30, 0x82, 0x01, - 0x64, 0x30, 0x82, 0x01, 0x60, 0xa0, 0x82, 0x01, 0x5c, 0xa0, 0x82, 0x01, - 0x58, 0x86, 0x81, 0xc3, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, - 0x43, 0x4e, 0x3d, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, - 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2c, 0x43, 0x4e, - 0x3d, 0x53, 0x4d, 0x55, 0x43, 0x31, 0x39, 0x32, 0x33, 0x2c, 0x43, 0x4e, - 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2c, 0x44, 0x43, 0x3d, 0x62, 0x6d, 0x77, 0x2c, 0x44, 0x43, 0x3d, 0x63, - 0x6f, 0x72, 0x70, 0x3f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, - 0x52, 0x4c, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, - 0x6f, 0x6e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x86, 0x4d, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x6d, 0x75, 0x63, 0x31, 0x39, 0x32, 0x33, - 0x2e, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2e, 0x62, 0x6d, 0x77, 0x2e, - 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x72, - 0x6f, 0x6c, 0x6c, 0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, - 0x67, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2e, 0x63, - 0x72, 0x6c, 0x86, 0x41, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, - 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d, 0x77, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x42, - 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, - 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x25, 0x32, 0x30, 0x43, - 0x41, 0x25, 0x32, 0x30, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x82, 0x01, - 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, - 0x82, 0x01, 0x10, 0x30, 0x82, 0x01, 0x0c, 0x30, 0x81, 0xba, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0xad, 0x6c, - 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x42, 0x4d, - 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, - 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x25, 0x32, 0x30, 0x43, 0x41, - 0x25, 0x32, 0x30, 0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x49, 0x41, 0x2c, - 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, - 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x62, - 0x6d, 0x77, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x72, 0x70, 0x3f, 0x63, - 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x74, 0x79, 0x30, 0x4d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x30, 0x02, 0x86, 0x41, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x73, 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d, 0x77, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, - 0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x25, 0x32, - 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2e, 0x63, 0x72, 0x74, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, - 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xa6, 0xdb, 0xab, 0x42, 0x93, - 0x90, 0xb9, 0x6a, 0xc1, 0x92, 0xb7, 0x3c, 0xaf, 0xf2, 0x9b, 0xed, 0x2b, - 0x14, 0xdb, 0xd8, 0x9f, 0x6b, 0xb8, 0x8e, 0x08, 0xf0, 0x0e, 0x1a, 0xfe, - 0xb3, 0x9a, 0x6f, 0x3d, 0x28, 0x79, 0xd4, 0x88, 0xbe, 0x1c, 0x17, 0xaa, - 0x6a, 0xa4, 0xe9, 0xf0, 0xe0, 0xee, 0x9d, 0x74, 0x25, 0xbb, 0x48, 0x16, - 0xb1, 0x00, 0xca, 0xfa, 0x6a, 0x0c, 0x16, 0x98, 0xef, 0xf9, 0x42, 0xd6, - 0x81, 0xb4, 0xf7, 0xa2, 0x15, 0xb6, 0xdc, 0xe8, 0x25, 0xe8, 0xdd, 0x92, - 0x1d, 0x0c, 0x96, 0xea, 0x80, 0x41, 0x3f, 0xd7, 0xff, 0xeb, 0x53, 0xe9, - 0x13, 0xf8, 0xdc, 0x8b, 0xe2, 0x45, 0xb8, 0xbb, 0x22, 0x81, 0xea, 0x46, - 0xee, 0x19, 0x14, 0xe3, 0xd5, 0xb0, 0xaa, 0x2a, 0xd2, 0x52, 0xa5, 0x3f, - 0x7e, 0xa5, 0x7d, 0x5c, 0xb0, 0x84, 0x4e, 0x77, 0x01, 0x35, 0x76, 0x31, - 0xa3, 0x6e, 0x3f, 0x51, 0x20, 0x3f, 0x98, 0xac, 0x68, 0x28, 0x0f, 0xc6, - 0x5a, 0xc1, 0xcf, 0x58, 0xd7, 0x75, 0xaa, 0xe2, 0x9b, 0xc3, 0xfa, 0x3c, - 0xd6, 0x61, 0x98, 0x2b, 0xf1, 0x73, 0x78, 0x2a, 0xb2, 0x54, 0x78, 0xba, - 0xff, 0x36, 0x15, 0x17, 0xe7, 0xe6, 0x6e, 0x82, 0xee, 0x64, 0x87, 0x81, - 0xd9, 0x08, 0x68, 0xa4, 0xc7, 0x9b, 0xa4, 0xa9, 0xf3, 0x1e, 0xe9, 0x82, - 0xc1, 0x3d, 0xfd, 0xe9, 0x75, 0x77, 0x81, 0x73, 0x05, 0x2e, 0x36, 0x0e, - 0x17, 0x13, 0x48, 0x20, 0x9c, 0x24, 0xce, 0xe2, 0x22, 0x68, 0x3f, 0x37, - 0x3d, 0xf5, 0x01, 0x0e, 0x13, 0xec, 0x3d, 0xba, 0x0d, 0x71, 0xd2, 0xe2, - 0x67, 0x65, 0x19, 0x24, 0xa4, 0x5d, 0xae, 0x35, 0x1e, 0x39, 0x4c, 0xe4, - 0x19, 0x48, 0x91, 0x03, 0x9e, 0xe9, 0x42, 0xfd, 0x1f, 0x1d, 0x2a, 0x98, - 0x40, 0xd0, 0xb6, 0x92, 0xb3, 0x38, 0x0f, 0xf5, 0x7f, 0xf0, 0xc1, 0x30, - 0x82, 0x03, 0x70, 0x30, 0x82, 0x02, 0x58, 0xa0, 0x03, 0x02, 0x01, 0x02, - 0x02, 0x10, 0x13, 0xaa, 0xab, 0xff, 0x7f, 0x25, 0x31, 0xae, 0x49, 0x9b, - 0x17, 0x9b, 0xef, 0xee, 0xe2, 0x97, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x40, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x45, - 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x42, - 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x1d, 0x30, 0x1b, - 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x42, 0x4d, 0x57, 0x20, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, - 0x20, 0x56, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x31, 0x32, 0x31, - 0x30, 0x31, 0x30, 0x32, 0x36, 0x35, 0x31, 0x5a, 0x17, 0x0d, 0x33, 0x34, - 0x31, 0x32, 0x31, 0x30, 0x31, 0x30, 0x33, 0x35, 0x34, 0x30, 0x5a, 0x30, - 0x40, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x44, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x09, 0x42, 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x1d, - 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x42, 0x4d, 0x57, - 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, - 0x43, 0x41, 0x20, 0x56, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, - 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, - 0x01, 0x00, 0xd0, 0x27, 0x3b, 0xb7, 0xfe, 0x8d, 0x0c, 0xd6, 0xed, 0xf0, - 0xa2, 0x49, 0x1f, 0x83, 0xed, 0x11, 0xcf, 0x56, 0x96, 0xe2, 0xe2, 0x1a, - 0xac, 0x59, 0x4c, 0xef, 0x27, 0xf7, 0xda, 0xf8, 0x6a, 0x0d, 0xea, 0x78, - 0x27, 0x69, 0x84, 0xd0, 0x4d, 0x94, 0xd8, 0x78, 0xc6, 0x14, 0x25, 0x98, - 0x68, 0x69, 0xd5, 0x3a, 0xfd, 0x84, 0x39, 0xf3, 0x4a, 0xb8, 0x47, 0x51, - 0x59, 0x8c, 0xa4, 0x24, 0x97, 0x10, 0xb5, 0x3b, 0x28, 0x4f, 0x26, 0x91, - 0xad, 0xb2, 0x39, 0xc7, 0x8b, 0x96, 0x99, 0x62, 0x53, 0xe3, 0xee, 0xba, - 0x1d, 0x55, 0x49, 0x98, 0x32, 0x60, 0xb3, 0x8d, 0x1a, 0x53, 0x29, 0x7b, - 0xf1, 0xd3, 0xf4, 0xbc, 0x7d, 0xf1, 0x47, 0x78, 0x88, 0xe4, 0x14, 0x9c, - 0x60, 0xdc, 0x8b, 0x65, 0xfd, 0x95, 0x39, 0xc0, 0x8b, 0x59, 0xcb, 0x66, - 0xd2, 0x6a, 0x19, 0x67, 0x0e, 0xcd, 0x56, 0xf6, 0x7a, 0x2a, 0x8f, 0x2a, - 0x4f, 0x1e, 0x15, 0x4d, 0xbe, 0xb5, 0x3e, 0xca, 0x3a, 0xc3, 0x93, 0x8a, - 0xac, 0x28, 0x4c, 0x2d, 0xbd, 0x1f, 0x2b, 0x92, 0x43, 0x32, 0xdd, 0x97, - 0xef, 0xb7, 0x09, 0xf3, 0x6b, 0x3d, 0x1e, 0x36, 0x16, 0x8b, 0x78, 0xce, - 0x96, 0x45, 0x36, 0x9d, 0x3a, 0x90, 0x5e, 0x20, 0x3f, 0xb2, 0x39, 0x8b, - 0x2f, 0x76, 0xd1, 0x2f, 0xe9, 0x2a, 0xb0, 0xd8, 0x40, 0x0b, 0xd9, 0x62, - 0xd0, 0xe0, 0x6b, 0xa6, 0xf7, 0x00, 0xa8, 0x50, 0xac, 0xb0, 0x17, 0x20, - 0x6c, 0x89, 0x1b, 0x32, 0x0a, 0x91, 0x8f, 0x94, 0xcf, 0x24, 0x72, 0xdb, - 0x4f, 0xf9, 0x4c, 0x9e, 0x88, 0x49, 0xd9, 0x01, 0x03, 0xd0, 0xc7, 0xf4, - 0xd1, 0xf8, 0xd5, 0x6b, 0x76, 0xea, 0x14, 0xa3, 0xb5, 0x24, 0x4c, 0xa5, - 0xd2, 0xa8, 0x12, 0x79, 0xd3, 0x27, 0xb4, 0x9a, 0x47, 0xaa, 0x7b, 0x74, - 0x90, 0xbb, 0xb5, 0x74, 0x29, 0x53, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, - 0x66, 0x30, 0x64, 0x30, 0x13, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, - 0x82, 0x37, 0x14, 0x02, 0x04, 0x06, 0x1e, 0x04, 0x00, 0x43, 0x00, 0x41, - 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, - 0x86, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, - 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, - 0x0e, 0x04, 0x16, 0x04, 0x14, 0x17, 0xd0, 0xa6, 0x81, 0xc4, 0xba, 0xb6, - 0x59, 0xe8, 0xac, 0xa5, 0x5f, 0xa3, 0x07, 0xad, 0xfd, 0x8b, 0x56, 0x2b, - 0xbb, 0x30, 0x10, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, - 0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, - 0x01, 0x01, 0x00, 0x6c, 0x1b, 0xf2, 0x9b, 0xa7, 0x29, 0xc3, 0x7c, 0x90, - 0xf0, 0xd2, 0x88, 0xc1, 0x5a, 0xdf, 0xea, 0x1d, 0x48, 0xeb, 0xe5, 0x83, - 0x64, 0x31, 0xb4, 0x61, 0xa8, 0x3c, 0xfe, 0x1b, 0xf9, 0x0e, 0xc1, 0xdd, - 0xd2, 0x81, 0xcb, 0x57, 0xcf, 0x12, 0xe0, 0x97, 0xee, 0xfe, 0x7c, 0x9e, - 0x4d, 0xf2, 0x53, 0x68, 0x30, 0xab, 0xa7, 0x6b, 0xcd, 0xac, 0xef, 0x98, - 0x93, 0x6e, 0x96, 0x93, 0x49, 0x0d, 0x51, 0x61, 0xb2, 0x85, 0x71, 0x7e, - 0x3d, 0x3d, 0x90, 0x4d, 0xd6, 0x46, 0x85, 0xf8, 0x67, 0x8c, 0x53, 0x10, - 0x0c, 0x36, 0xd4, 0xe9, 0xfb, 0x29, 0x19, 0x27, 0xfb, 0xcd, 0x87, 0xd3, - 0x2b, 0xd3, 0xfd, 0x2e, 0xac, 0xf9, 0xeb, 0x1d, 0x82, 0xa7, 0x4f, 0x22, - 0xba, 0x73, 0x22, 0x26, 0x64, 0x73, 0x5c, 0xaa, 0x44, 0x23, 0x9e, 0x5d, - 0xb6, 0xd0, 0x79, 0xd8, 0x7f, 0x2e, 0xd6, 0xdb, 0x73, 0x3a, 0x09, 0xdf, - 0x44, 0xff, 0xba, 0xa6, 0xcc, 0xcc, 0x61, 0x76, 0x8c, 0x18, 0x8c, 0x89, - 0xa9, 0x10, 0xab, 0xda, 0x21, 0x22, 0xfb, 0x3f, 0x65, 0x0b, 0xa9, 0xd3, - 0x0a, 0x70, 0x85, 0x8a, 0x81, 0xb7, 0x60, 0x9a, 0x6d, 0x3a, 0x42, 0xfa, - 0xc8, 0x0b, 0x58, 0x8d, 0x47, 0x34, 0x78, 0x51, 0x66, 0xc3, 0x11, 0xa6, - 0x22, 0x99, 0x2b, 0x64, 0x64, 0xda, 0xe3, 0xa1, 0x46, 0x81, 0xb7, 0x52, - 0xdc, 0xd0, 0x17, 0x19, 0xf1, 0xae, 0xe0, 0x05, 0x92, 0x07, 0x92, 0x98, - 0x0f, 0x2a, 0xf7, 0x1d, 0xe2, 0x42, 0x7f, 0x97, 0xd1, 0xea, 0x27, 0x8e, - 0x65, 0xef, 0x00, 0x0b, 0xce, 0xbb, 0xd7, 0xa7, 0x7d, 0xf9, 0x31, 0x92, - 0x44, 0x1c, 0x9e, 0x84, 0xc6, 0x8f, 0xed, 0x37, 0x51, 0x79, 0xaa, 0x7b, - 0x9a, 0x9d, 0xac, 0xe2, 0xa0, 0xae, 0x4d, 0xf0, 0x91, 0x83, 0x5d, 0x85, - 0xca, 0xfa, 0xea, 0x26, 0x0b, 0x48, 0x16, 0x30, 0x82, 0x05, 0xfc, 0x30, - 0x82, 0x04, 0xe4, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, 0x1e, 0x30, - 0xc3, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, - 0x40, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x44, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x09, 0x42, 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x1d, - 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x42, 0x4d, 0x57, - 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, - 0x43, 0x41, 0x20, 0x56, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x31, - 0x32, 0x31, 0x37, 0x30, 0x39, 0x31, 0x37, 0x31, 0x39, 0x5a, 0x17, 0x0d, - 0x32, 0x32, 0x31, 0x32, 0x31, 0x37, 0x30, 0x39, 0x32, 0x37, 0x31, 0x39, - 0x5a, 0x30, 0x64, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x09, 0x92, 0x26, - 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x04, 0x63, 0x6f, 0x72, - 0x70, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, - 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x62, 0x6d, 0x77, 0x31, 0x16, - 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, - 0x01, 0x19, 0x16, 0x06, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x31, 0x1f, - 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x42, 0x4d, 0x57, - 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x49, 0x73, 0x73, 0x75, 0x69, - 0x6e, 0x67, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, - 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, - 0x82, 0x01, 0x01, 0x00, 0xb3, 0xab, 0xd3, 0x53, 0x73, 0x45, 0x6c, 0x37, - 0xc4, 0x79, 0x7c, 0xe9, 0xfb, 0x0d, 0x6b, 0xb5, 0x9d, 0xcc, 0x95, 0xa5, - 0xf7, 0x02, 0x04, 0x94, 0x8a, 0x2f, 0xb2, 0xea, 0x9f, 0x27, 0xe4, 0xef, - 0x95, 0x02, 0x2f, 0x8c, 0x2f, 0x23, 0x4a, 0xd9, 0x53, 0xc8, 0x81, 0xb7, - 0xe9, 0xb8, 0xb1, 0x52, 0x5c, 0x02, 0x7a, 0x2b, 0x4c, 0xe1, 0xeb, 0x25, - 0xa4, 0x8b, 0x53, 0xa4, 0x45, 0x74, 0xbb, 0x20, 0xa6, 0x2e, 0x8b, 0x5b, - 0xf0, 0x05, 0x86, 0x06, 0x79, 0x24, 0x55, 0x27, 0x10, 0x71, 0x9b, 0xf7, - 0xac, 0x71, 0x8c, 0xa0, 0x4c, 0xe7, 0x9f, 0x1a, 0xb4, 0xa2, 0xd7, 0x5b, - 0x17, 0xa3, 0x9f, 0xb3, 0x5b, 0x28, 0x16, 0xbe, 0x28, 0x48, 0x58, 0x6f, - 0x19, 0x7e, 0x7c, 0x7b, 0x0d, 0x69, 0x59, 0xa1, 0x97, 0x13, 0x1a, 0x1f, - 0x9c, 0xf3, 0x47, 0x36, 0xf2, 0xfa, 0xda, 0xad, 0xbd, 0xd2, 0xda, 0xdd, - 0xb9, 0xcb, 0x9e, 0xef, 0xe4, 0x63, 0x1e, 0xdb, 0xf6, 0xd6, 0x4c, 0x85, - 0xf1, 0x7f, 0x04, 0xe4, 0xf7, 0x07, 0xc4, 0x6e, 0x77, 0x36, 0xd7, 0x4e, - 0x62, 0xb9, 0x71, 0x5b, 0x46, 0x58, 0x99, 0x81, 0xa9, 0x71, 0x43, 0x36, - 0x4b, 0x06, 0xc2, 0x9c, 0xd9, 0x91, 0xb5, 0x5c, 0xcf, 0x95, 0x94, 0xa1, - 0x37, 0x44, 0xce, 0x59, 0xc4, 0x1f, 0x99, 0x1e, 0x2d, 0x18, 0xb8, 0x6a, - 0xf8, 0x13, 0x0e, 0x71, 0x4b, 0x67, 0xd7, 0x1e, 0xc8, 0x4d, 0x1f, 0x54, - 0xd6, 0xc5, 0x94, 0x39, 0x52, 0x32, 0xca, 0x47, 0xa2, 0x01, 0x83, 0x03, - 0x1b, 0xa8, 0xe1, 0xd4, 0x7d, 0x30, 0x1f, 0x20, 0x58, 0xb0, 0xd4, 0x6b, - 0xeb, 0x13, 0x37, 0x10, 0x98, 0x3f, 0x89, 0x0d, 0x94, 0xa3, 0x24, 0xfd, - 0xcf, 0x20, 0x79, 0xc2, 0x2e, 0x25, 0xcb, 0x0b, 0x47, 0x25, 0xe5, 0x79, - 0xbe, 0x4e, 0x92, 0xd7, 0x24, 0xea, 0xc6, 0x1b, 0x02, 0x03, 0x01, 0x00, - 0x01, 0xa3, 0x82, 0x02, 0xd2, 0x30, 0x82, 0x02, 0xce, 0x30, 0x0f, 0x06, - 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, - 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, - 0x14, 0x61, 0x0a, 0xef, 0x1a, 0x3d, 0xfe, 0x9a, 0x68, 0x81, 0xcb, 0xb2, - 0x62, 0xe5, 0xc0, 0x21, 0x8e, 0xdd, 0xec, 0x61, 0x95, 0x30, 0x0e, 0x06, - 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, - 0x06, 0x30, 0x10, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, - 0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x19, 0x06, 0x09, 0x2b, - 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x0c, 0x1e, 0x0a, - 0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, 0x41, 0x30, 0x1f, - 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x17, - 0xd0, 0xa6, 0x81, 0xc4, 0xba, 0xb6, 0x59, 0xe8, 0xac, 0xa5, 0x5f, 0xa3, - 0x07, 0xad, 0xfd, 0x8b, 0x56, 0x2b, 0xbb, 0x30, 0x82, 0x01, 0x1e, 0x06, - 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, 0x15, 0x30, 0x82, 0x01, 0x11, - 0x30, 0x82, 0x01, 0x0d, 0xa0, 0x82, 0x01, 0x09, 0xa0, 0x82, 0x01, 0x05, - 0x86, 0x81, 0xc1, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, - 0x4e, 0x3d, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x25, 0x32, 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, - 0x41, 0x25, 0x32, 0x30, 0x56, 0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x73, 0x6d, - 0x75, 0x63, 0x31, 0x38, 0x39, 0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x44, - 0x50, 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, - 0x32, 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, - 0x3d, 0x62, 0x6d, 0x77, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x72, 0x70, - 0x3f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, - 0x73, 0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44, - 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, - 0x6f, 0x69, 0x6e, 0x74, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x73, 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d, 0x77, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, - 0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x25, 0x32, 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x41, - 0x25, 0x32, 0x30, 0x56, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x82, 0x01, - 0x1a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, - 0x82, 0x01, 0x0c, 0x30, 0x82, 0x01, 0x08, 0x30, 0x81, 0xb8, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0xab, 0x6c, - 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x42, 0x4d, - 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, - 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, - 0x56, 0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x49, 0x41, 0x2c, 0x43, 0x4e, - 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, - 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x62, 0x6d, 0x77, - 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x72, 0x70, 0x3f, 0x63, 0x41, 0x43, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x3f, 0x62, - 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, - 0x61, 0x73, 0x73, 0x3d, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x74, 0x79, 0x30, 0x4b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x30, 0x02, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, - 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d, 0x77, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x42, - 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, - 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, - 0x30, 0x56, 0x32, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, - 0x01, 0x01, 0x00, 0x68, 0x8c, 0xe9, 0xec, 0x52, 0x47, 0xe5, 0x9a, 0xac, - 0x02, 0x1e, 0x1f, 0x49, 0x12, 0x24, 0x4a, 0xd6, 0x76, 0x41, 0xa7, 0xe6, - 0x32, 0xf5, 0xc3, 0x96, 0xad, 0x22, 0x34, 0xd6, 0xf7, 0xce, 0xcc, 0xf5, - 0x20, 0xcf, 0xf9, 0x81, 0x55, 0xff, 0x7a, 0xfb, 0x77, 0xe0, 0x5e, 0x37, - 0x56, 0x55, 0x17, 0xd7, 0x1a, 0x09, 0x52, 0x2c, 0xda, 0x84, 0xed, 0x1e, - 0xa3, 0xb3, 0x26, 0xfe, 0x93, 0xff, 0x45, 0x6a, 0x87, 0x91, 0xf9, 0x05, - 0xe3, 0xa6, 0xcf, 0x33, 0xbc, 0xd6, 0x4a, 0x58, 0x70, 0xfa, 0x9e, 0x54, - 0x7a, 0x79, 0x16, 0xd7, 0xea, 0xd4, 0x04, 0xaf, 0x87, 0x9a, 0x54, 0xe5, - 0x80, 0x13, 0xfd, 0xdf, 0x83, 0xc4, 0x60, 0x12, 0x33, 0x49, 0x7b, 0x90, - 0xd7, 0x1e, 0x09, 0x11, 0x4b, 0xd8, 0xbe, 0x06, 0xd4, 0xf0, 0x8e, 0x84, - 0x06, 0x2a, 0xe3, 0x0b, 0xf4, 0xac, 0x9d, 0x31, 0xa1, 0x9f, 0x03, 0x91, - 0xbe, 0xf8, 0x93, 0x6d, 0xc1, 0x9d, 0x8f, 0x18, 0xd3, 0xb9, 0x29, 0xaa, - 0x19, 0x51, 0x15, 0xf7, 0x99, 0x3f, 0x42, 0x69, 0xfd, 0xec, 0xfb, 0xf0, - 0x8a, 0x3f, 0x35, 0x65, 0x17, 0x1c, 0x52, 0xf4, 0xd1, 0x31, 0xc8, 0x14, - 0x51, 0x42, 0x1b, 0xb8, 0xea, 0x7c, 0x4f, 0xbf, 0xd5, 0x78, 0x72, 0xdf, - 0x18, 0x86, 0xc6, 0x2f, 0x2c, 0xb4, 0x45, 0x1b, 0x0b, 0x00, 0x16, 0x0e, - 0xd6, 0x41, 0xd9, 0x4d, 0xa0, 0x9e, 0xb3, 0x56, 0x8d, 0xf8, 0x6b, 0xa0, - 0x20, 0x4c, 0x1c, 0x6e, 0x3a, 0x80, 0xec, 0xd7, 0x85, 0x8c, 0xbb, 0xc1, - 0x51, 0x73, 0x66, 0x47, 0x01, 0x44, 0x9a, 0x87, 0xc9, 0xed, 0x49, 0x04, - 0xc2, 0x41, 0xea, 0x65, 0x16, 0xda, 0xd0, 0xb7, 0xe6, 0x03, 0x73, 0x74, - 0x11, 0x3b, 0x94, 0x1b, 0x9f, 0x06, 0xb9, 0x71, 0x02, 0x70, 0x66, 0xa0, - 0x12, 0xb5, 0x5a, 0xe8, 0x2c, 0xf9, 0x63, 0x31, 0x00 -}; -static unsigned int bmw_scep_pkt_len = 5661; - -#include "si-63-scep/getcacert-mdes.h" -#include "si-63-scep/getcacert-mdesqa.h" - -#include -__unused static inline void write_data(const char * path, CFDataRef data) -{ - int data_file = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0644); - write(data_file, CFDataGetBytePtr(data), CFDataGetLength(data)); - close(data_file); -} - - -__unused static inline CFMutableArrayRef maa(CFMutableArrayRef array, CFTypeRef a) { - CFMutableArrayRef ma = array; - if (!ma) - CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - if (ma) { - CFArrayAppendValue(ma, a); - CFRelease(a); - } - return ma; -} - -/* Test basic add delete update copy matching stuff. */ -static void tests(void) -{ - CFDataRef getcacert_blob = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, - getcacert, getcacert_len, kCFAllocatorNull); - CFArrayRef certificates = NULL; - SecCertificateRef ca_certificate, ra_signing_certificate, ra_encryption_certificate; - ca_certificate = ra_signing_certificate = ra_encryption_certificate = NULL; - certificates = SecCMSCertificatesOnlyMessageCopyCertificates(getcacert_blob); - isnt(certificates, NULL, "decode cert-only pkcs#7"); - CFDataRef sha1_fingerprint = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, - ruby_sha1_hash, sizeof(ruby_sha1_hash), kCFAllocatorNull); - - ok_status(SecSCEPValidateCACertMessage(certificates, sha1_fingerprint, - &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate), - "parse CA/RAse getcacert message"); - CFReleaseNull(sha1_fingerprint); - isnt(ca_certificate, NULL, "got ca cert"); - isnt(ra_signing_certificate, NULL, "got ra signing cert"); - is(ra_encryption_certificate, NULL, "no separate ra encryption cert"); - - /* these are always going to be true, but ensure replacement payloads are equivalent */ - ok(SecCertificateIsSelfSignedCA(ca_certificate), "self-signed ca cert"); - ok(SecCertificateGetKeyUsage(ra_signing_certificate) & kSecKeyUsageDigitalSignature, "can sign"); - - CFReleaseNull(ca_certificate); - CFReleaseNull(ra_signing_certificate); - CFReleaseNull(ra_encryption_certificate); - CFReleaseNull(getcacert_blob); - CFReleaseNull(certificates); - - ca_certificate = ra_signing_certificate = ra_encryption_certificate = NULL; - getcacert_blob = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, getcacert_mdes, getcacert_mdes_len, kCFAllocatorNull); - certificates = SecCMSCertificatesOnlyMessageCopyCertificates(getcacert_blob); - ok_status(SecSCEPValidateCACertMessage(certificates, NULL, &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate), "parse WF MDES getcacert message"); - ok(ca_certificate && ra_signing_certificate && ra_encryption_certificate, "identify all 3 certs"); - - CFReleaseNull(ca_certificate); - CFReleaseNull(ra_signing_certificate); - CFReleaseNull(ra_encryption_certificate); - CFReleaseNull(getcacert_blob); - CFReleaseNull(certificates); - - ca_certificate = ra_signing_certificate = ra_encryption_certificate = NULL; - getcacert_blob = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, getcacert_mdesqa, getcacert_mdesqa_len, kCFAllocatorNull); - certificates = SecCMSCertificatesOnlyMessageCopyCertificates(getcacert_blob); - ok_status(SecSCEPValidateCACertMessage(certificates, NULL, &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate), "parse WF MDESQA getcacert message"); - ok(ca_certificate && ra_signing_certificate && ra_encryption_certificate, "identify all 3 certs"); - - CFReleaseNull(ca_certificate); - CFReleaseNull(ra_signing_certificate); - CFReleaseNull(ra_encryption_certificate); - CFReleaseNull(getcacert_blob); - CFReleaseNull(certificates); - - sha1_fingerprint = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, - msscep_md5_hash, sizeof(msscep_md5_hash), kCFAllocatorNull); - CFDataRef msscep_getcacert_blob = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, - msscep_getcacert, msscep_getcacert_len, kCFAllocatorNull); - CFReleaseNull(sha1_fingerprint); - ca_certificate = ra_signing_certificate = ra_encryption_certificate = NULL; - certificates = SecCMSCertificatesOnlyMessageCopyCertificates(msscep_getcacert_blob); - ok_status(SecSCEPValidateCACertMessage(certificates, sha1_fingerprint, - &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate), - "parse CA/RAs/RAe msscep getcacert message"); - isnt(ca_certificate, NULL, "got ca cert"); - isnt(ra_signing_certificate, NULL, "got ra signing cert"); - isnt(ra_encryption_certificate, NULL, "got ra encryption cert"); - - /* these are always going to be true, but ensure replacement payloads are equivalent */ - ok(SecCertificateIsSelfSignedCA(ca_certificate), "self-signed ca cert"); - ok(SecCertificateGetKeyUsage(ra_encryption_certificate) & kSecKeyUsageKeyEncipherment, "can sign"); - - /* - int ix; - uint8_t md5_hash[CC_MD5_DIGEST_LENGTH]; - CFDataRef cert_data = SecCertificateCopyData(ca_certificate); - CC_MD5(CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data), md5_hash); - for(ix = 0; ix < CC_MD5_DIGEST_LENGTH; ix++) fprintf(stdout, "0x%.02x, ", md5_hash[ix]); fprintf(stdout, "\n"); - uint8_t sha1_hash[CC_SHA1_DIGEST_LENGTH]; - CCDigest(kCCDigestSHA1, CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data), sha1_hash); - for(ix = 0; ix < CC_SHA1_DIGEST_LENGTH; ix++) fprintf(stdout, "0x%.02x, ", sha1_hash[ix]); fprintf(stdout, "\n"); - CFRelease(cert_data); - */ - - CFReleaseNull(ca_certificate); - CFReleaseNull(ra_signing_certificate); - CFReleaseNull(ra_encryption_certificate); - CFRelease(certificates); - CFRelease(msscep_getcacert_blob); - - - - - CFDataRef bmw_getcacert_blob = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, - bmw_scep_pkt, bmw_scep_pkt_len, kCFAllocatorNull); - ca_certificate = ra_signing_certificate = ra_encryption_certificate = NULL; - certificates = SecCMSCertificatesOnlyMessageCopyCertificates(bmw_getcacert_blob); - CFMutableArrayRef certificates_mod = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, certificates); - CFArrayRemoveValueAtIndex(certificates_mod, 2); - ok_status(SecSCEPValidateCACertMessage(certificates_mod, NULL, - &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate), - "parse CA/RAs/RAe msscep getcacert message"); - CFRelease(certificates_mod); - CFRelease(ca_certificate); - CFRelease(ra_signing_certificate); - CFRelease(ra_encryption_certificate); - certificates_mod = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, certificates); - CFArrayInsertValueAtIndex(certificates_mod, 0, CFArrayGetValueAtIndex(certificates_mod, 3)); - CFArrayRemoveValueAtIndex(certificates_mod, 4); - ok_status(SecSCEPValidateCACertMessage(certificates_mod, NULL, - &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate), - "parse CA/RAs/RAe msscep getcacert message"); - CFRelease(certificates_mod); - CFRelease(ca_certificate); - CFRelease(ra_signing_certificate); - CFRelease(ra_encryption_certificate); - - ok_status(SecSCEPValidateCACertMessage(certificates, NULL, - &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate), - "parse CA/RAs/RAe msscep getcacert message"); - isnt(ca_certificate, NULL, "got ca cert"); - isnt(ra_signing_certificate, NULL, "got ra signing cert"); - isnt(ra_encryption_certificate, NULL, "got ra encryption cert"); - - /* these are always going to be true, but ensure replacement payloads are equivalent */ - ok(SecCertificateIsSelfSignedCA(ca_certificate), "self-signed ca cert"); - ok(SecCertificateGetKeyUsage(ra_encryption_certificate) & kSecKeyUsageKeyEncipherment, "can sign"); - - CFReleaseSafe(ca_certificate); - CFReleaseSafe(ra_signing_certificate); - CFReleaseSafe(ra_encryption_certificate); - CFReleaseSafe(certificates); - CFReleaseSafe(bmw_getcacert_blob); - - uint32_t key_size_in_bits = 512; - CFNumberRef key_size = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_size_in_bits); - const void *keygen_keys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits }; - const void *keygen_vals[] = { kSecAttrKeyTypeRSA, key_size }; - CFDictionaryRef parameters = CFDictionaryCreate(kCFAllocatorDefault, - keygen_keys, keygen_vals, array_size(keygen_vals), - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFRelease(key_size); - - SecKeyRef ca_publicKey = NULL, ca_privateKey = NULL; - ok_status(SecKeyGeneratePair(parameters, &ca_publicKey, &ca_privateKey), "gen key"); - SecIdentityRef ca_identity = test_cert_create_root_certificate(CFSTR("O=Foo Bar Inc.,CN=Root CA"), ca_publicKey, ca_privateKey); - CFRelease(ca_publicKey); - CFRelease(ca_privateKey); - - SecKeyRef scep_ra_publicKey = NULL, scep_ra_privateKey = NULL; - ok_status(SecKeyGeneratePair(parameters, &scep_ra_publicKey, &scep_ra_privateKey), "generate ra key pair"); - SecCertificateRef scep_ra_certificate = - test_cert_issue_certificate(ca_identity, scep_ra_publicKey, - CFSTR("O=Foo Bar Inc.,CN=SCEP RA"), 42, - kSecKeyUsageKeyEncipherment|kSecKeyUsageDigitalSignature); - ok(scep_ra_certificate, "got a ra cert"); - SecIdentityRef ra_identity = SecIdentityCreate(kCFAllocatorDefault, scep_ra_certificate, scep_ra_privateKey); - CFRelease(scep_ra_publicKey); - CFRelease(scep_ra_privateKey); - - // store encryption identity in the keychain because the decrypt function looks in there only - CFDictionaryRef identity_add = CFDictionaryCreate(NULL, - (const void **)&kSecValueRef, (const void **)&ra_identity, 1, NULL, NULL); - ok_status(SecItemAdd(identity_add, NULL), "add encryption identity to keychain"); - - SecKeyRef phone_publicKey = NULL, phone_privateKey = NULL; - ok_status(SecKeyGeneratePair(parameters, &phone_publicKey, &phone_privateKey), "generate phone key pair"); - CFArrayRef subject = test_cert_string_to_subject(CFSTR("O=Foo Bar Inc.,CN=Shoes")); - SecIdentityRef self_signed_identity = SecSCEPCreateTemporaryIdentity(phone_publicKey, phone_privateKey); - CFStringRef magic = CFSTR("magic"); - CFDictionaryRef csr_params = CFDictionaryCreate(kCFAllocatorDefault, - (const void **)&kSecCSRChallengePassword, (const void **)&magic, 1, NULL, NULL); - CFDataRef request = SecSCEPGenerateCertificateRequest(NULL, csr_params, phone_publicKey, phone_privateKey, self_signed_identity, scep_ra_certificate); - CFRelease(csr_params); - CFRelease(phone_publicKey); - CFRelease(phone_privateKey); - isnt(request, NULL, "got a request"); - CFDataRef serialno = CFDataCreate(kCFAllocatorDefault, (uint8_t*)"\001", 1); - CFDataRef pended_request = SecSCEPCertifyRequest(request, ra_identity, serialno, true); - CFRelease(serialno); - isnt(pended_request, NULL, "got a pended request (not failed)"); - CFErrorRef server_error = NULL; - CFArrayRef issued_certs = NULL; - issued_certs = SecSCEPVerifyReply(request, pended_request, scep_ra_certificate, &server_error); - CFReleaseSafe(request); - is(issued_certs, NULL, "no certs if pended"); - CFDataRef retry_get_cert_initial = NULL; - isnt(server_error, NULL, "Should have gotten PENDING error"); - CFDictionaryRef error_dict = CFErrorCopyUserInfo(server_error); - retry_get_cert_initial = SecSCEPGetCertInitial(scep_ra_certificate, subject, NULL, error_dict, self_signed_identity, scep_ra_certificate); - isnt(retry_get_cert_initial, NULL, "got retry request"); - //write_data("/var/tmp/get_cert_initial", retry_get_cert_initial); - CFRelease(subject); - - ok_status(SecItemDelete(identity_add), "delete encryption identity from keychain"); - CFReleaseSafe(identity_add); - - CFReleaseSafe(self_signed_identity); - CFReleaseSafe(retry_get_cert_initial); - CFReleaseSafe(server_error); - CFReleaseSafe(pended_request); - CFReleaseSafe(issued_certs); - CFReleaseSafe(error_dict); -} - -int si_63_scep(int argc, char *const *argv) -{ - plan_tests(36); - - - tests(); - - return 0; -} diff --git a/OSX/sec/Security/Regressions/secitem/si-63-scep.m b/OSX/sec/Security/Regressions/secitem/si-63-scep.m new file mode 100644 index 00000000..f9773ca8 --- /dev/null +++ b/OSX/sec/Security/Regressions/secitem/si-63-scep.m @@ -0,0 +1,1358 @@ +/* + * Copyright (c) 2008,2012-2014 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "Security_regressions.h" +#include + +static uint8_t msscep_getcacert[] = { + 0x30, 0x82, 0x10, 0x8d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x07, 0x02, 0xa0, 0x82, 0x10, 0x7e, 0x30, 0x82, 0x10, 0x7a, 0x02, + 0x01, 0x01, 0x31, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x10, 0x62, 0x30, 0x82, 0x05, + 0xcc, 0x30, 0x82, 0x04, 0xb4, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, + 0x61, 0x0c, 0x81, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, + 0x00, 0x30, 0x4e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, + 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f, 0x6d, + 0x31, 0x18, 0x30, 0x16, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, + 0x2c, 0x64, 0x01, 0x19, 0x16, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, + 0x73, 0x74, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x14, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, + 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, + 0x0d, 0x30, 0x39, 0x30, 0x32, 0x31, 0x37, 0x32, 0x32, 0x33, 0x35, 0x35, + 0x35, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x32, 0x31, 0x37, 0x32, 0x32, + 0x33, 0x35, 0x35, 0x35, 0x5a, 0x30, 0x81, 0x8a, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x63, 0x61, 0x31, 0x12, + 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x63, 0x75, 0x70, + 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x13, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, + 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x02, + 0x71, 0x61, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x0c, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, + 0x6d, 0x31, 0x23, 0x30, 0x21, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x01, 0x16, 0x14, 0x71, 0x61, 0x61, 0x64, 0x6d, 0x69, + 0x6e, 0x40, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, + 0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, + 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0x93, 0x67, 0x34, 0x15, 0xe9, + 0x97, 0x97, 0x74, 0xbf, 0x0e, 0x1c, 0xd8, 0x44, 0x00, 0x0d, 0x42, 0x7a, + 0x3d, 0xd1, 0xea, 0xc8, 0x95, 0xc0, 0x6b, 0x93, 0x6c, 0x6d, 0x87, 0x4a, + 0x21, 0xf5, 0xbf, 0x16, 0x10, 0x19, 0x44, 0x2f, 0xd2, 0xd6, 0x87, 0x55, + 0x52, 0x04, 0xb0, 0x0b, 0x3e, 0x49, 0xb7, 0x9c, 0x2b, 0x01, 0xc8, 0x6c, + 0x3e, 0x56, 0xb5, 0xd2, 0x20, 0x29, 0x0f, 0x25, 0x04, 0xcb, 0x59, 0xce, + 0x37, 0x69, 0xcf, 0x4e, 0x05, 0x06, 0x2d, 0xac, 0xaf, 0x33, 0xee, 0x4e, + 0xce, 0xe1, 0x55, 0x46, 0xc6, 0x5c, 0x68, 0x56, 0xda, 0xd6, 0x0a, 0x6e, + 0xeb, 0xdb, 0x4d, 0xf6, 0xef, 0x0d, 0xcf, 0x1e, 0x43, 0xfa, 0xc2, 0xe2, + 0xfa, 0x87, 0xe0, 0x31, 0x16, 0x46, 0x97, 0x12, 0x26, 0xdc, 0x94, 0x16, + 0x73, 0xb0, 0xcf, 0xad, 0x7d, 0x7d, 0x8b, 0xb8, 0xf5, 0xd1, 0x89, 0x50, + 0x12, 0x1d, 0x49, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x02, 0xf1, + 0x30, 0x82, 0x02, 0xed, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, + 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x15, 0x06, 0x03, 0x55, 0x1d, 0x25, + 0x04, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, + 0x37, 0x14, 0x02, 0x01, 0x30, 0x3b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, + 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x2e, 0x1e, 0x2c, 0x00, 0x45, 0x00, + 0x6e, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6d, 0x00, + 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x41, 0x00, 0x67, 0x00, 0x65, 0x00, + 0x6e, 0x00, 0x74, 0x00, 0x4f, 0x00, 0x66, 0x00, 0x66, 0x00, 0x6c, 0x00, + 0x69, 0x00, 0x6e, 0x00, 0x65, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0xb3, 0xd0, 0xef, 0xb6, 0xe0, 0x3b, 0x3b, 0x39, + 0xf8, 0x5a, 0x33, 0x07, 0x2f, 0x19, 0xd9, 0xcd, 0xdd, 0xe3, 0xf9, 0x1e, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, + 0x14, 0x40, 0xb5, 0x54, 0x10, 0x88, 0x09, 0xeb, 0x3e, 0x2e, 0x69, 0x82, + 0xa6, 0xa0, 0xd8, 0xe4, 0xb0, 0x98, 0xc1, 0x69, 0x3d, 0x30, 0x82, 0x01, + 0x19, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, 0x10, 0x30, 0x82, + 0x01, 0x0c, 0x30, 0x82, 0x01, 0x08, 0xa0, 0x82, 0x01, 0x04, 0xa0, 0x82, + 0x01, 0x00, 0x86, 0x81, 0xbc, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, + 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, + 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, + 0x2c, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2c, + 0x43, 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, + 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, + 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, + 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, + 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x6d, 0x3f, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x76, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x3f, + 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44, 0x69, 0x73, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x69, 0x6e, + 0x74, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x71, 0x61, + 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, + 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x65, 0x72, 0x74, 0x45, + 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, + 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, + 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x82, 0x01, 0x2b, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x82, 0x01, 0x1d, + 0x30, 0x82, 0x01, 0x19, 0x30, 0x81, 0xb4, 0x06, 0x08, 0x2b, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0xa7, 0x6c, 0x64, 0x61, 0x70, + 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, + 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, + 0x63, 0x6f, 0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x49, 0x41, 0x2c, 0x43, + 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, + 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76, + 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, + 0x6d, 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x60, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x54, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, + 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, + 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, + 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x5f, 0x71, 0x61, 0x73, + 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, + 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x01, 0x00, 0x7e, 0x74, 0xff, 0x77, 0xd7, 0x2e, 0x43, + 0x11, 0xcf, 0xef, 0xb3, 0xdd, 0x98, 0xae, 0x9a, 0xa3, 0x13, 0xc3, 0x07, + 0x37, 0x0e, 0xe5, 0x2c, 0x50, 0xa1, 0x5e, 0xe2, 0xa6, 0x94, 0x45, 0x2a, + 0x00, 0x9d, 0xee, 0x53, 0x67, 0x10, 0x6b, 0x13, 0xc5, 0xf9, 0x1c, 0x88, + 0x70, 0x3c, 0x73, 0x5f, 0x98, 0x2b, 0x05, 0x51, 0xf7, 0x67, 0xf6, 0xa6, + 0x5b, 0xcb, 0xb6, 0x1c, 0xc2, 0x85, 0xef, 0x1e, 0xcd, 0x25, 0x5f, 0xfa, + 0xba, 0xcd, 0x89, 0xf7, 0x93, 0xfe, 0x9f, 0xd6, 0xdd, 0x2c, 0x4c, 0xd5, + 0x33, 0xec, 0xd7, 0xef, 0x6e, 0xc8, 0x0b, 0x9b, 0x8b, 0x4e, 0x75, 0x91, + 0x0b, 0x4e, 0x96, 0x81, 0x4d, 0xee, 0x06, 0x55, 0x41, 0xfc, 0xc5, 0x2a, + 0xa6, 0x53, 0x97, 0xb6, 0xce, 0x61, 0x22, 0x93, 0xa8, 0x71, 0x04, 0x51, + 0xa7, 0xa8, 0x87, 0xee, 0x72, 0xb7, 0x0f, 0xa4, 0x5e, 0x6e, 0xc2, 0xcd, + 0xfa, 0x00, 0xf8, 0x9c, 0xe5, 0xcc, 0x61, 0xce, 0x88, 0xf0, 0x55, 0xb6, + 0xff, 0xac, 0xdb, 0xeb, 0xe6, 0xcc, 0x89, 0x7e, 0xea, 0x29, 0x7f, 0x9f, + 0x01, 0x54, 0x8a, 0x65, 0x60, 0x31, 0xe3, 0xaa, 0xa1, 0x68, 0x16, 0x50, + 0x7e, 0xe1, 0x9b, 0x04, 0x7f, 0xc5, 0x15, 0x77, 0xfe, 0xbd, 0xfa, 0xac, + 0x92, 0xcb, 0x0a, 0xc2, 0x3a, 0xbc, 0xec, 0x4e, 0xc4, 0x3a, 0x9f, 0x4d, + 0xdd, 0x2a, 0x03, 0xe3, 0x22, 0xc0, 0x66, 0x5a, 0x5c, 0x7f, 0x4c, 0x8a, + 0x58, 0x3e, 0x90, 0x79, 0x96, 0x16, 0x1d, 0x6f, 0x53, 0x43, 0x69, 0xfe, + 0xb6, 0x0a, 0x18, 0x8f, 0xbf, 0xb4, 0xb8, 0x99, 0xc5, 0x09, 0x20, 0x97, + 0x10, 0x18, 0xde, 0x57, 0x54, 0x24, 0x95, 0xeb, 0xce, 0x99, 0x01, 0xdd, + 0x42, 0xc0, 0x67, 0x0b, 0x8c, 0xdb, 0x1c, 0x77, 0x86, 0x63, 0x9d, 0x87, + 0xf6, 0xff, 0xcf, 0xc5, 0x38, 0xff, 0x6e, 0xb6, 0x05, 0x30, 0x82, 0x05, + 0xf2, 0x30, 0x82, 0x04, 0xda, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, + 0x61, 0x0c, 0x83, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, + 0x00, 0x30, 0x4e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, + 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f, 0x6d, + 0x31, 0x18, 0x30, 0x16, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, + 0x2c, 0x64, 0x01, 0x19, 0x16, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, + 0x73, 0x74, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x14, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, + 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, + 0x0d, 0x30, 0x39, 0x30, 0x32, 0x31, 0x37, 0x32, 0x32, 0x33, 0x35, 0x35, + 0x36, 0x5a, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x32, 0x31, 0x37, 0x32, 0x32, + 0x33, 0x35, 0x35, 0x36, 0x5a, 0x30, 0x81, 0x8a, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, 0x63, 0x61, 0x31, 0x12, + 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x63, 0x75, 0x70, + 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x13, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, + 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x02, + 0x71, 0x61, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x0c, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, + 0x6d, 0x31, 0x23, 0x30, 0x21, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x01, 0x16, 0x14, 0x71, 0x61, 0x61, 0x64, 0x6d, 0x69, + 0x6e, 0x40, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, + 0x6f, 0x6d, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, + 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xa6, 0xf2, 0x65, 0xbe, 0xc6, + 0xb3, 0x53, 0xc2, 0x94, 0x89, 0xef, 0xca, 0x3a, 0x1d, 0x08, 0x64, 0x19, + 0x96, 0x5c, 0x8d, 0xc3, 0x15, 0x9b, 0xe5, 0x68, 0x86, 0x7d, 0xff, 0xf9, + 0xa1, 0xa5, 0x7b, 0x85, 0x8c, 0x14, 0x41, 0xf3, 0xe1, 0x6a, 0x17, 0xff, + 0xaf, 0x01, 0xb0, 0xbb, 0x64, 0x5d, 0xf0, 0xb8, 0x34, 0x10, 0x41, 0x3e, + 0xee, 0x43, 0x87, 0x47, 0x4a, 0x5e, 0xc2, 0x2c, 0xe8, 0xcb, 0x23, 0x14, + 0x9d, 0x92, 0xad, 0xe2, 0xaa, 0x53, 0xbd, 0xfa, 0xaf, 0x7a, 0x11, 0x64, + 0xeb, 0xb2, 0xf2, 0xd6, 0xdb, 0xd2, 0x77, 0xef, 0x74, 0xb2, 0x67, 0x1b, + 0xc7, 0xa4, 0x2e, 0x97, 0x80, 0x46, 0x92, 0xaf, 0x32, 0x18, 0x90, 0x46, + 0x57, 0x86, 0x2d, 0x97, 0x4d, 0x11, 0x48, 0xc5, 0x43, 0x23, 0x3e, 0x6b, + 0x0d, 0x32, 0x3e, 0xd0, 0xba, 0xf0, 0x20, 0x60, 0x0e, 0x02, 0x47, 0xae, + 0x58, 0xb4, 0x5b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x03, 0x17, + 0x30, 0x82, 0x03, 0x13, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, + 0x04, 0x03, 0x02, 0x05, 0x20, 0x30, 0x36, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0f, 0x04, 0x29, 0x30, 0x27, 0x30, 0x0d, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02, 0x01, + 0x38, 0x30, 0x0d, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, + 0x04, 0x02, 0x01, 0x38, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, + 0x07, 0x30, 0x15, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0e, 0x30, 0x0c, + 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x01, + 0x30, 0x29, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, + 0x02, 0x04, 0x1c, 0x1e, 0x1a, 0x00, 0x43, 0x00, 0x45, 0x00, 0x50, 0x00, + 0x45, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x72, 0x00, 0x79, 0x00, 0x70, 0x00, + 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xe0, 0xfc, 0xd6, 0xa7, 0xca, 0xab, + 0x38, 0x38, 0x6b, 0x79, 0x6f, 0x63, 0xb7, 0xfd, 0xc4, 0xbd, 0xb2, 0xc3, + 0x68, 0x03, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, + 0x16, 0x80, 0x14, 0x40, 0xb5, 0x54, 0x10, 0x88, 0x09, 0xeb, 0x3e, 0x2e, + 0x69, 0x82, 0xa6, 0xa0, 0xd8, 0xe4, 0xb0, 0x98, 0xc1, 0x69, 0x3d, 0x30, + 0x82, 0x01, 0x19, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, 0x10, + 0x30, 0x82, 0x01, 0x0c, 0x30, 0x82, 0x01, 0x08, 0xa0, 0x82, 0x01, 0x04, + 0xa0, 0x82, 0x01, 0x00, 0x86, 0x81, 0xbc, 0x6c, 0x64, 0x61, 0x70, 0x3a, + 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, + 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, + 0x6f, 0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, + 0x30, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, 0x3d, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79, + 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, + 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, + 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76, 0x70, 0x6e, + 0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x6d, 0x3f, + 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, + 0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44, 0x69, + 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, + 0x69, 0x6e, 0x74, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, + 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x65, 0x72, + 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x71, 0x61, 0x73, 0x72, + 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, + 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x82, 0x01, 0x2b, + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x82, + 0x01, 0x1d, 0x30, 0x82, 0x01, 0x19, 0x30, 0x81, 0xb4, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0xa7, 0x6c, 0x64, + 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, + 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, + 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x49, 0x41, + 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, + 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, + 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, + 0x63, 0x6f, 0x6d, 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x60, 0x06, + 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x54, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, + 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, + 0x6c, 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, + 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x5f, 0x71, + 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, + 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x74, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x83, 0x54, 0x4e, 0x01, 0x42, + 0x95, 0x42, 0xa4, 0x56, 0x78, 0xf6, 0xa9, 0x41, 0xd8, 0xc3, 0xf2, 0xa4, + 0xdc, 0xa3, 0xb2, 0xaa, 0x72, 0x63, 0x2c, 0xab, 0x14, 0x40, 0x8c, 0xd9, + 0xdf, 0x61, 0xdf, 0xee, 0x8b, 0x50, 0x3b, 0xc7, 0xe1, 0x6f, 0xe5, 0x98, + 0x4d, 0xbd, 0x3c, 0x16, 0xc3, 0xcc, 0x3a, 0xb4, 0x11, 0x87, 0xb6, 0x93, + 0x63, 0xc6, 0x3d, 0xa2, 0xf3, 0x8c, 0xde, 0xc3, 0xcb, 0x44, 0x25, 0x7a, + 0x75, 0xc8, 0x5c, 0x9f, 0xeb, 0x43, 0xd2, 0xb1, 0x11, 0x8d, 0x9e, 0x29, + 0x7a, 0xf1, 0x9e, 0x59, 0xb2, 0x8b, 0xfa, 0x31, 0x2e, 0x4c, 0x8f, 0x6a, + 0x72, 0x0c, 0x42, 0x63, 0xf1, 0xca, 0x76, 0x8e, 0x33, 0x5e, 0x69, 0x9e, + 0x3b, 0x15, 0xba, 0xfb, 0xf8, 0x0e, 0x9d, 0x1b, 0xb1, 0x52, 0xc9, 0xc3, + 0x3e, 0x4f, 0xa4, 0x56, 0x1f, 0x71, 0x24, 0x0a, 0x61, 0x25, 0x87, 0x75, + 0x07, 0xc7, 0xf0, 0x6f, 0xb3, 0xd7, 0xe9, 0x20, 0x7a, 0xc1, 0x98, 0x48, + 0x25, 0xd0, 0x17, 0x27, 0xed, 0x21, 0xe8, 0x2b, 0xb6, 0xa7, 0xa5, 0x7b, + 0x53, 0x20, 0x27, 0x3d, 0x5d, 0xbb, 0xcd, 0x61, 0x84, 0xed, 0x66, 0x4c, + 0xcd, 0x65, 0x6d, 0xe9, 0x2d, 0xf5, 0xe5, 0x63, 0xaf, 0xd0, 0xde, 0xa0, + 0x89, 0x5b, 0x01, 0x05, 0x05, 0x63, 0x7e, 0x5b, 0xdb, 0xdc, 0x5a, 0xab, + 0xa5, 0xa4, 0x62, 0x3a, 0xe7, 0xdf, 0xae, 0x55, 0x9b, 0xf8, 0x93, 0x82, + 0x1b, 0xec, 0x00, 0x27, 0x2e, 0x73, 0x7d, 0xd8, 0xe2, 0xde, 0x76, 0xf3, + 0x70, 0xbe, 0xc5, 0x12, 0x00, 0x79, 0x62, 0x83, 0x6b, 0x04, 0x23, 0xc9, + 0x19, 0xa6, 0x23, 0x77, 0x45, 0xd6, 0x14, 0x01, 0xf7, 0x9c, 0x0f, 0x51, + 0x92, 0x98, 0x5a, 0x2a, 0x57, 0xc9, 0x5a, 0xb4, 0xe3, 0x98, 0x5f, 0x7e, + 0x07, 0x99, 0x66, 0x20, 0x17, 0x0d, 0x85, 0x2c, 0x3c, 0x98, 0x70, 0x30, + 0x82, 0x04, 0x98, 0x30, 0x82, 0x03, 0x80, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x10, 0x7a, 0xdb, 0x4e, 0x56, 0x1a, 0xb8, 0x90, 0xae, 0x46, 0x6f, + 0x06, 0x74, 0x44, 0x09, 0x68, 0x87, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4e, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, + 0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f, 0x6d, 0x31, 0x18, 0x30, 0x16, + 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, + 0x16, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x31, 0x1d, + 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x71, 0x61, 0x73, + 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, + 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30, + 0x31, 0x32, 0x38, 0x30, 0x32, 0x34, 0x33, 0x33, 0x30, 0x5a, 0x17, 0x0d, + 0x31, 0x34, 0x30, 0x31, 0x32, 0x38, 0x30, 0x32, 0x35, 0x32, 0x34, 0x33, + 0x5a, 0x30, 0x4e, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, + 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f, 0x6d, + 0x31, 0x18, 0x30, 0x16, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, + 0x2c, 0x64, 0x01, 0x19, 0x16, 0x08, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, + 0x73, 0x74, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x14, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, + 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, + 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, + 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbe, 0xf8, 0xff, 0x61, 0xca, 0x9d, + 0xcf, 0x07, 0x4d, 0x06, 0xf4, 0x52, 0x4b, 0x3f, 0x84, 0xc5, 0x0b, 0x71, + 0xef, 0x7f, 0x7d, 0x35, 0xac, 0x68, 0xce, 0x84, 0xe6, 0x7c, 0x0a, 0xba, + 0x02, 0x71, 0xcf, 0x81, 0x40, 0xcb, 0x25, 0xdb, 0x41, 0x23, 0x84, 0x88, + 0x4d, 0x16, 0xa2, 0x41, 0xa5, 0x2a, 0x98, 0xa3, 0xb7, 0x02, 0xff, 0x54, + 0xb6, 0xd5, 0x55, 0x75, 0x17, 0xbc, 0xd5, 0x04, 0x24, 0x35, 0x63, 0xfa, + 0xcb, 0x98, 0x38, 0x98, 0x18, 0xd3, 0x13, 0xc1, 0xef, 0x1a, 0xfe, 0xb7, + 0xcd, 0x2e, 0xc2, 0xb8, 0x0d, 0x3e, 0x62, 0x38, 0xc0, 0x05, 0xf9, 0x5b, + 0xc5, 0xd5, 0xf6, 0xc4, 0x9d, 0x8e, 0xc3, 0x90, 0x32, 0xa2, 0xb1, 0x88, + 0xa8, 0xf9, 0xd3, 0x0d, 0x02, 0x8d, 0xbe, 0x8f, 0x41, 0xe7, 0x92, 0x85, + 0xe7, 0x4c, 0x11, 0x9a, 0x4b, 0xfb, 0x00, 0xa9, 0x9f, 0xf5, 0xfb, 0x23, + 0xda, 0xf1, 0xfd, 0x95, 0x89, 0xd5, 0x2b, 0xc5, 0xbf, 0x9c, 0xc3, 0x93, + 0xd0, 0xc2, 0xf8, 0x12, 0xbe, 0x26, 0x24, 0x41, 0x80, 0x64, 0x2f, 0xc0, + 0x7b, 0x31, 0x85, 0x06, 0x3c, 0xe4, 0xc6, 0x7e, 0xbc, 0x61, 0xa7, 0xa2, + 0xf4, 0xa7, 0xd7, 0xd7, 0xcb, 0xeb, 0xea, 0xb0, 0xc6, 0xd7, 0x13, 0xd6, + 0x09, 0xfa, 0x45, 0xc6, 0x25, 0x6f, 0x34, 0xdc, 0x78, 0x70, 0xa0, 0xa5, + 0xea, 0xd7, 0xe7, 0xda, 0xe2, 0x5a, 0x7a, 0xc3, 0xe3, 0x7a, 0x8d, 0xf3, + 0x5a, 0x78, 0xfa, 0x57, 0xe1, 0xf1, 0xae, 0x6b, 0xea, 0x83, 0xd0, 0xd7, + 0xa9, 0x43, 0x2d, 0x5d, 0x8b, 0xac, 0xbb, 0x92, 0x5b, 0x2a, 0xd7, 0x27, + 0xbe, 0xe7, 0xa0, 0xd2, 0xc5, 0x9b, 0xd7, 0xa4, 0xc1, 0x6a, 0xf8, 0xec, + 0xfc, 0xa6, 0x96, 0xfc, 0x09, 0x11, 0x95, 0xca, 0x75, 0xab, 0x8a, 0x5b, + 0xd2, 0xb2, 0xb4, 0x11, 0xf1, 0x88, 0x34, 0xe3, 0xb7, 0x21, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x70, 0x30, 0x82, 0x01, 0x6c, 0x30, + 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, + 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0x40, 0xb5, 0x54, 0x10, 0x88, 0x09, 0xeb, 0x3e, + 0x2e, 0x69, 0x82, 0xa6, 0xa0, 0xd8, 0xe4, 0xb0, 0x98, 0xc1, 0x69, 0x3d, + 0x30, 0x82, 0x01, 0x19, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, + 0x10, 0x30, 0x82, 0x01, 0x0c, 0x30, 0x82, 0x01, 0x08, 0xa0, 0x82, 0x01, + 0x04, 0xa0, 0x82, 0x01, 0x00, 0x86, 0x81, 0xbc, 0x6c, 0x64, 0x61, 0x70, + 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, + 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, + 0x63, 0x6f, 0x6d, 0x2c, 0x43, 0x4e, 0x3d, 0x71, 0x61, 0x73, 0x72, 0x76, + 0x31, 0x30, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, + 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, + 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x69, 0x76, 0x70, + 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x6d, + 0x3f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, + 0x73, 0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44, + 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, + 0x6f, 0x69, 0x6e, 0x74, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x71, 0x61, 0x73, 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, + 0x6e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x65, + 0x72, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x71, 0x61, 0x73, + 0x72, 0x76, 0x31, 0x30, 0x2e, 0x69, 0x76, 0x70, 0x6e, 0x74, 0x65, 0x73, + 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x10, 0x06, + 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x01, 0x04, 0x03, + 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x07, + 0x74, 0x27, 0x8c, 0xdd, 0x75, 0xa1, 0x0d, 0x97, 0xd1, 0x9d, 0x0d, 0xae, + 0x3b, 0xf3, 0x14, 0x0f, 0xa1, 0x1c, 0x51, 0xd8, 0x68, 0xe7, 0xfd, 0xd0, + 0xaf, 0xe7, 0x66, 0x62, 0xf8, 0x73, 0x75, 0x88, 0x6c, 0xb9, 0xb3, 0x1e, + 0xf5, 0x82, 0x3a, 0x1d, 0x82, 0x7b, 0xa3, 0x18, 0xd9, 0x1a, 0x40, 0xf2, + 0xcd, 0xb3, 0x83, 0xae, 0x12, 0x5b, 0xb4, 0x45, 0xd9, 0xbe, 0x51, 0x3e, + 0x11, 0x64, 0xaf, 0x95, 0x06, 0xb6, 0xbd, 0xd1, 0xa1, 0xfd, 0xbb, 0xdb, + 0xa4, 0xbb, 0xba, 0x3e, 0xd5, 0xd6, 0x1d, 0x37, 0x80, 0x17, 0xe8, 0x08, + 0x75, 0x5f, 0x5d, 0x49, 0x5f, 0x70, 0xdd, 0x67, 0xde, 0x9a, 0x34, 0x95, + 0x2e, 0x54, 0x58, 0x42, 0xaf, 0x8a, 0x57, 0xf2, 0xb4, 0x1f, 0xfb, 0x40, + 0x9c, 0x05, 0xa0, 0x6a, 0x9a, 0x91, 0x0e, 0x27, 0xaa, 0x9e, 0xdb, 0xbf, + 0x50, 0xc9, 0xa4, 0x2f, 0xc8, 0x71, 0x00, 0x11, 0xf8, 0x2f, 0xda, 0x98, + 0xf4, 0x1d, 0x98, 0x2a, 0xe9, 0x29, 0xc7, 0xea, 0x74, 0x65, 0xf1, 0x6d, + 0x06, 0x9f, 0x59, 0xa3, 0x50, 0x7e, 0x1b, 0x52, 0x5a, 0xb9, 0x5e, 0xce, + 0xa0, 0x03, 0x53, 0xe8, 0xba, 0x36, 0x4a, 0xc2, 0x95, 0xdb, 0x34, 0x61, + 0xc8, 0xf4, 0xa5, 0x7c, 0xd6, 0x9d, 0x64, 0x91, 0xfb, 0x23, 0xfd, 0x8b, + 0x3a, 0xd2, 0x67, 0xb0, 0x64, 0xa7, 0x80, 0x82, 0x74, 0x85, 0x45, 0xa7, + 0x78, 0x57, 0xb6, 0xf0, 0x0a, 0xf9, 0xa2, 0xb5, 0x7f, 0x7e, 0x88, 0x21, + 0xd7, 0x67, 0xd2, 0xc4, 0x9c, 0x98, 0x51, 0x9b, 0x71, 0xfb, 0x39, 0xf2, + 0xb3, 0xfd, 0x3f, 0x0b, 0x61, 0x59, 0xa0, 0x15, 0x40, 0x53, 0x71, 0xac, + 0xf5, 0xf7, 0xee, 0x03, 0x6b, 0x1f, 0x5d, 0x29, 0x0a, 0xf7, 0x4f, 0x1a, + 0xea, 0xa4, 0xb8, 0x02, 0x63, 0x7c, 0x37, 0x37, 0xdd, 0x46, 0x42, 0xe3, + 0xe1, 0x82, 0x94, 0x31, 0x00 +}; +static unsigned int msscep_getcacert_len = 4241; + + +static uint8_t getcacert[] = { + 0x30, 0x82, 0x04, 0x6a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x07, 0x02, 0xa0, 0x82, 0x04, 0x5b, 0x30, 0x82, 0x04, 0x57, 0x02, + 0x01, 0x01, 0x31, 0x00, 0x30, 0x03, 0x06, 0x01, 0x00, 0xa0, 0x82, 0x04, + 0x47, 0x30, 0x82, 0x02, 0x33, 0x30, 0x82, 0x01, 0x9c, 0xa0, 0x03, 0x02, + 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4d, 0x31, 0x0d, + 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x04, 0x4e, 0x6f, 0x6e, + 0x65, 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x33, + 0x41, 0x43, 0x4d, 0x45, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, + 0x20, 0x28, 0x35, 0x36, 0x32, 0x66, 0x30, 0x64, 0x30, 0x35, 0x2d, 0x32, + 0x35, 0x36, 0x61, 0x2d, 0x34, 0x32, 0x65, 0x65, 0x2d, 0x39, 0x66, 0x35, + 0x38, 0x2d, 0x38, 0x30, 0x62, 0x30, 0x61, 0x35, 0x35, 0x37, 0x38, 0x62, + 0x66, 0x30, 0x29, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30, 0x39, 0x31, + 0x37, 0x30, 0x30, 0x33, 0x39, 0x32, 0x33, 0x5a, 0x17, 0x0d, 0x31, 0x30, + 0x30, 0x39, 0x31, 0x37, 0x30, 0x30, 0x33, 0x39, 0x32, 0x33, 0x5a, 0x30, + 0x4d, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x04, + 0x4e, 0x6f, 0x6e, 0x65, 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0c, 0x33, 0x41, 0x43, 0x4d, 0x45, 0x20, 0x52, 0x6f, 0x6f, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x28, 0x35, 0x36, 0x32, 0x66, 0x30, 0x64, 0x30, + 0x35, 0x2d, 0x32, 0x35, 0x36, 0x61, 0x2d, 0x34, 0x32, 0x65, 0x65, 0x2d, + 0x39, 0x66, 0x35, 0x38, 0x2d, 0x38, 0x30, 0x62, 0x30, 0x61, 0x35, 0x35, + 0x37, 0x38, 0x62, 0x66, 0x30, 0x29, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, + 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd4, + 0x1c, 0xaa, 0x58, 0x8a, 0xda, 0xfc, 0x24, 0x21, 0x35, 0xc2, 0xb0, 0x2b, + 0x08, 0x5d, 0xe2, 0xf5, 0xb5, 0xf0, 0xdc, 0xca, 0x04, 0xaa, 0x8e, 0x86, + 0xff, 0xfe, 0x9b, 0x35, 0xed, 0x61, 0x3a, 0xe5, 0xbf, 0xf7, 0xbf, 0xab, + 0xa4, 0xa8, 0x6e, 0xf5, 0xba, 0x5b, 0x0e, 0xdc, 0x28, 0x07, 0x24, 0x01, + 0xda, 0x9e, 0x1f, 0x92, 0xa5, 0x4b, 0x51, 0xcd, 0xd9, 0x6e, 0x27, 0xfa, + 0xda, 0x9b, 0x9c, 0x17, 0x3e, 0x1b, 0x36, 0xaf, 0xf5, 0x5d, 0x11, 0x02, + 0xe9, 0x2e, 0xf1, 0x6e, 0xb6, 0x7f, 0xe8, 0x91, 0xbd, 0x66, 0x73, 0xdf, + 0xb9, 0x27, 0xb7, 0x5b, 0x04, 0xb1, 0x9f, 0x52, 0x38, 0xea, 0xd0, 0x1c, + 0x97, 0x2d, 0x4b, 0x1b, 0x03, 0xcb, 0xe6, 0xa4, 0x92, 0x2c, 0x0f, 0x5d, + 0x34, 0x06, 0x52, 0x07, 0x35, 0x97, 0x13, 0x2f, 0x27, 0x62, 0x5a, 0x4b, + 0xc3, 0xac, 0x5f, 0x0a, 0x40, 0x98, 0x29, 0x02, 0x03, 0x01, 0x00, 0x01, + 0xa3, 0x23, 0x30, 0x21, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, + 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, + 0x86, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x35, 0xa8, 0x47, 0x69, + 0x01, 0x12, 0x43, 0x34, 0x73, 0xe4, 0xd8, 0xa4, 0x95, 0x00, 0xea, 0xd7, + 0x33, 0xf2, 0x7b, 0x49, 0xea, 0xa7, 0xc6, 0xe1, 0x7d, 0x06, 0xb8, 0xb4, + 0x4f, 0x3f, 0x08, 0x97, 0xa8, 0x47, 0x82, 0x1e, 0x0a, 0x4b, 0xdb, 0x19, + 0x9d, 0x21, 0x30, 0x2c, 0x37, 0xa0, 0x3f, 0x92, 0xf7, 0xc2, 0x39, 0x57, + 0x2b, 0x43, 0x33, 0xf9, 0x6e, 0x40, 0x8c, 0x64, 0x2b, 0xf5, 0xb6, 0xb6, + 0x6c, 0x2e, 0x59, 0xc4, 0xe6, 0x01, 0x87, 0xd4, 0x1c, 0x32, 0xf1, 0x68, + 0x72, 0xeb, 0xda, 0x35, 0x69, 0x3c, 0x7d, 0x6f, 0x4c, 0xba, 0x8b, 0x4d, + 0xaa, 0x1c, 0x11, 0x05, 0x76, 0x9e, 0x73, 0x2a, 0x20, 0xcb, 0x31, 0x9c, + 0x74, 0x20, 0x99, 0x4c, 0xbc, 0x17, 0xd0, 0xb5, 0x6e, 0x1e, 0xad, 0x87, + 0x83, 0xa6, 0xda, 0x15, 0x85, 0x7a, 0x8f, 0x76, 0x37, 0xa7, 0x11, 0x53, + 0x7f, 0x12, 0xb1, 0x05, 0x30, 0x82, 0x02, 0x0c, 0x30, 0x82, 0x01, 0x75, + 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x64, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, + 0x4d, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x04, + 0x4e, 0x6f, 0x6e, 0x65, 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0c, 0x33, 0x41, 0x43, 0x4d, 0x45, 0x20, 0x52, 0x6f, 0x6f, 0x74, + 0x20, 0x43, 0x41, 0x20, 0x28, 0x35, 0x36, 0x32, 0x66, 0x30, 0x64, 0x30, + 0x35, 0x2d, 0x32, 0x35, 0x36, 0x61, 0x2d, 0x34, 0x32, 0x65, 0x65, 0x2d, + 0x39, 0x66, 0x35, 0x38, 0x2d, 0x38, 0x30, 0x62, 0x30, 0x61, 0x35, 0x35, + 0x37, 0x38, 0x62, 0x66, 0x30, 0x29, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, + 0x30, 0x39, 0x31, 0x37, 0x30, 0x30, 0x33, 0x39, 0x32, 0x33, 0x5a, 0x17, + 0x0d, 0x31, 0x30, 0x30, 0x39, 0x31, 0x37, 0x30, 0x30, 0x33, 0x39, 0x32, + 0x33, 0x5a, 0x30, 0x26, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x0c, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x31, 0x15, 0x30, 0x13, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0c, 0x41, 0x43, 0x4d, 0x45, 0x20, 0x53, + 0x43, 0x45, 0x50, 0x20, 0x52, 0x41, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, + 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd1, + 0x6e, 0x98, 0x93, 0x0e, 0x0a, 0x27, 0x5f, 0xd9, 0x3e, 0x95, 0xe3, 0x24, + 0xae, 0x96, 0xd2, 0x62, 0x40, 0x05, 0xb6, 0x2d, 0x4d, 0xe2, 0x8f, 0x35, + 0x26, 0x14, 0x72, 0x04, 0xb0, 0x34, 0xaf, 0xf3, 0x61, 0x7c, 0xa0, 0x72, + 0xe6, 0x29, 0xf3, 0xdf, 0xc2, 0x2a, 0x8c, 0x84, 0xde, 0xea, 0x7c, 0x01, + 0x64, 0x08, 0x8c, 0xaa, 0x0b, 0x96, 0x9b, 0xb5, 0xb8, 0x86, 0x49, 0xad, + 0x68, 0x1d, 0x7c, 0xf0, 0x1a, 0xe9, 0xf6, 0x56, 0x97, 0xe4, 0xb8, 0x20, + 0xa6, 0x1f, 0x1a, 0x9d, 0xcc, 0x5f, 0xe8, 0xc9, 0x05, 0xab, 0x85, 0xab, + 0xce, 0x5c, 0xcd, 0x20, 0xb7, 0x01, 0x8d, 0xda, 0x10, 0x54, 0x22, 0xbd, + 0x93, 0xf9, 0xac, 0x12, 0x39, 0x08, 0x9d, 0x27, 0xa1, 0x92, 0xb6, 0x94, + 0xde, 0x15, 0xcc, 0x0f, 0x9e, 0x1f, 0xe0, 0x44, 0x90, 0x57, 0x87, 0x04, + 0x9b, 0xfb, 0xb0, 0x63, 0x9d, 0xc0, 0x4d, 0x02, 0x03, 0x01, 0x00, 0x01, + 0xa3, 0x23, 0x30, 0x21, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, + 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x05, + 0xa0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0xbb, 0xb7, 0xa1, 0xd6, + 0x0c, 0xdd, 0xa8, 0xfe, 0x4a, 0x3b, 0x90, 0x42, 0x9b, 0x4f, 0xfc, 0xa4, + 0x75, 0xf2, 0x04, 0x09, 0xd6, 0x9e, 0xfb, 0x4f, 0x99, 0xf8, 0xcb, 0x5c, + 0xcc, 0xb0, 0xb3, 0xce, 0xd7, 0x83, 0xed, 0x4d, 0xa7, 0x93, 0xdb, 0x87, + 0x7b, 0x09, 0x2f, 0x07, 0xb3, 0xd2, 0xa3, 0x08, 0x17, 0x53, 0xb4, 0x61, + 0xd7, 0x58, 0x86, 0x79, 0x2c, 0x2e, 0x09, 0x75, 0xda, 0x61, 0xa8, 0x90, + 0x1f, 0xea, 0x2f, 0x0f, 0x2a, 0xcb, 0xf5, 0x01, 0x54, 0xee, 0x23, 0x80, + 0xbb, 0xaa, 0xb5, 0x61, 0x66, 0x23, 0xb3, 0xd2, 0xff, 0x7f, 0xb8, 0x74, + 0xc9, 0x55, 0xb5, 0x84, 0x57, 0x5a, 0x2e, 0x81, 0x0d, 0xe5, 0x0d, 0x45, + 0x4f, 0x37, 0xc4, 0x2d, 0xec, 0xf8, 0xf1, 0x15, 0x59, 0xc4, 0x7a, 0x49, + 0xd0, 0x12, 0x16, 0x18, 0x6a, 0x3e, 0x74, 0xe5, 0x4e, 0x65, 0xdc, 0xcc, + 0xba, 0x9e, 0x77, 0x7c, 0x31, 0x00 +}; +static unsigned int getcacert_len = 1134; + +static uint8_t msscep_md5_hash[] = {0x13, 0x7f, 0x4d, 0xaa, 0x5d, 0xa0, 0x65, 0x1b, 0xbd, 0x54, 0x8c, 0xc2, 0xd3, 0xd4, 0xce, 0xd0 }; +static uint8_t ruby_sha1_hash[] = { 0xf3, 0x5f, 0x6b, 0xd1, 0x64, 0x0b, 0xc1, 0x81, 0x98, 0xb9, 0x30, 0xd1, 0x97, 0x10, 0x3b, 0x45, 0xf0, 0x6e, 0x53, 0xdb }; + + +static unsigned char bmw_scep_pkt[] = { + 0x30, 0x82, 0x16, 0x19, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x07, 0x02, 0xa0, 0x82, 0x16, 0x0a, 0x30, 0x82, 0x16, 0x06, 0x02, + 0x01, 0x01, 0x31, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x15, 0xee, 0x30, 0x82, 0x06, + 0x26, 0x30, 0x82, 0x05, 0x0e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, + 0x3c, 0xec, 0x7e, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, + 0x00, 0x30, 0x64, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x09, 0x92, 0x26, + 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x04, 0x63, 0x6f, 0x72, + 0x70, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, + 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x62, 0x6d, 0x77, 0x31, 0x16, + 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, + 0x01, 0x19, 0x16, 0x06, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x31, 0x1f, + 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x42, 0x4d, 0x57, + 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x49, 0x73, 0x73, 0x75, 0x69, + 0x6e, 0x67, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x31, + 0x30, 0x30, 0x33, 0x30, 0x34, 0x31, 0x33, 0x35, 0x33, 0x31, 0x30, 0x5a, + 0x17, 0x0d, 0x31, 0x32, 0x30, 0x33, 0x30, 0x33, 0x31, 0x33, 0x35, 0x33, + 0x31, 0x30, 0x5a, 0x30, 0x81, 0x83, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x45, 0x31, 0x10, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x42, 0x61, 0x76, 0x61, 0x72, 0x69, + 0x61, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x06, + 0x4d, 0x75, 0x6e, 0x69, 0x63, 0x68, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x13, 0x09, 0x42, 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x11, 0x53, 0x43, 0x45, 0x50, 0x20, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, + 0x67, 0x20, 0x43, 0x41, 0x20, 0x32, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x40, 0x62, + 0x6d, 0x77, 0x2e, 0x64, 0x65, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, + 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xad, 0x57, + 0x88, 0x2c, 0x2c, 0xda, 0x45, 0x32, 0x32, 0xb1, 0xba, 0xce, 0x1b, 0x0b, + 0x5d, 0xc8, 0x5d, 0x76, 0xd2, 0x63, 0xf6, 0xc7, 0xe6, 0x45, 0xff, 0x37, + 0xf3, 0x85, 0xbf, 0xbb, 0xa1, 0x83, 0xd1, 0xea, 0xe0, 0x3f, 0xc9, 0x05, + 0x79, 0xe3, 0x15, 0xc3, 0x97, 0x2a, 0x81, 0x38, 0x4f, 0x33, 0xc1, 0xc9, + 0xf5, 0xb0, 0x1b, 0xbd, 0xad, 0x52, 0x15, 0x80, 0x52, 0x7d, 0x1b, 0x68, + 0x8f, 0xb5, 0x27, 0xda, 0xcf, 0x20, 0x7d, 0x53, 0x6e, 0xb0, 0xe8, 0x4b, + 0x8e, 0x6b, 0xb2, 0x63, 0xe3, 0xd5, 0x2c, 0x67, 0x55, 0x73, 0x0f, 0xda, + 0x41, 0x04, 0x56, 0xdc, 0xb3, 0x9a, 0x6b, 0xbb, 0x62, 0xf8, 0x8f, 0xe2, + 0x91, 0x7a, 0xe8, 0xa7, 0xa9, 0xc4, 0x8b, 0x75, 0x7b, 0xb5, 0x5f, 0x4e, + 0xe1, 0x4d, 0x80, 0x4d, 0xc9, 0xee, 0x23, 0xbc, 0xf7, 0x4f, 0x8d, 0xc0, + 0x02, 0x20, 0x23, 0x82, 0x80, 0xf7, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, + 0x82, 0x03, 0x3c, 0x30, 0x82, 0x03, 0x38, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x15, 0x06, 0x03, + 0x55, 0x1d, 0x25, 0x04, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, + 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x01, 0x30, 0x3b, 0x06, 0x09, 0x2b, + 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x2e, 0x1e, 0x2c, + 0x00, 0x45, 0x00, 0x6e, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x6c, + 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x41, 0x00, 0x67, + 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x4f, 0x00, 0x66, 0x00, 0x66, + 0x00, 0x6c, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x65, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd8, 0xeb, 0x70, 0x8b, 0x4e, + 0xda, 0xfb, 0x52, 0x03, 0x0c, 0xa5, 0xc5, 0xfd, 0xf3, 0x29, 0x54, 0xfd, + 0x2e, 0x8f, 0x3e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, + 0x30, 0x16, 0x80, 0x14, 0x61, 0x0a, 0xef, 0x1a, 0x3d, 0xfe, 0x9a, 0x68, + 0x81, 0xcb, 0xb2, 0x62, 0xe5, 0xc0, 0x21, 0x8e, 0xdd, 0xec, 0x61, 0x95, + 0x30, 0x82, 0x01, 0x71, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, + 0x68, 0x30, 0x82, 0x01, 0x64, 0x30, 0x82, 0x01, 0x60, 0xa0, 0x82, 0x01, + 0x5c, 0xa0, 0x82, 0x01, 0x58, 0x86, 0x81, 0xc3, 0x6c, 0x64, 0x61, 0x70, + 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x42, 0x4d, 0x57, 0x25, 0x32, + 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, + 0x75, 0x69, 0x6e, 0x67, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, + 0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x4d, 0x55, 0x43, 0x31, 0x39, 0x32, + 0x33, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, 0x3d, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79, + 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, + 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, + 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x62, 0x6d, 0x77, 0x2c, + 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x72, 0x70, 0x3f, 0x63, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x3f, 0x62, 0x61, + 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x86, + 0x4d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x6d, 0x75, 0x63, + 0x31, 0x39, 0x32, 0x33, 0x2e, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2e, + 0x62, 0x6d, 0x77, 0x2e, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x43, 0x65, 0x72, + 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x42, 0x4d, 0x57, 0x25, + 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, + 0x73, 0x75, 0x69, 0x6e, 0x67, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, + 0x30, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x86, 0x41, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x73, 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d, + 0x77, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, + 0x6b, 0x69, 0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, + 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2e, 0x63, 0x72, + 0x6c, 0x30, 0x82, 0x01, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x01, 0x01, 0x04, 0x82, 0x01, 0x10, 0x30, 0x82, 0x01, 0x0c, 0x30, + 0x81, 0xba, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, + 0x86, 0x81, 0xad, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, + 0x4e, 0x3d, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x25, + 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2c, 0x43, 0x4e, 0x3d, + 0x41, 0x49, 0x41, 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, + 0x44, 0x43, 0x3d, 0x62, 0x6d, 0x77, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, + 0x72, 0x70, 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x4d, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x41, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, + 0x62, 0x6d, 0x77, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, + 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, + 0x6e, 0x67, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2e, + 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x46, + 0x9e, 0x81, 0xb2, 0xec, 0xa9, 0xe4, 0x3c, 0xf3, 0x9b, 0x61, 0xdf, 0x6f, + 0xec, 0x28, 0xe9, 0x2b, 0xd4, 0xc1, 0xb2, 0x05, 0x03, 0xbd, 0x53, 0x49, + 0xa2, 0x94, 0x3a, 0xd6, 0x23, 0xa3, 0xe8, 0x52, 0xa4, 0xe6, 0x44, 0x5e, + 0x15, 0x89, 0xde, 0x32, 0x12, 0xba, 0x97, 0x3a, 0xd3, 0x1d, 0xa1, 0xda, + 0x2a, 0x70, 0x3e, 0x10, 0xea, 0x2c, 0xb5, 0x19, 0xc2, 0x71, 0xcd, 0x1c, + 0x10, 0x07, 0x4b, 0x58, 0x10, 0x61, 0x03, 0x72, 0x4f, 0x65, 0xf7, 0x38, + 0x9d, 0xa9, 0x35, 0x0c, 0xc9, 0xdf, 0x7f, 0x91, 0xa0, 0xd4, 0x08, 0xf2, + 0xf9, 0x1b, 0x0f, 0xaa, 0xb4, 0xb6, 0xe0, 0x3c, 0x9d, 0x0c, 0x64, 0xee, + 0x2f, 0x47, 0xdd, 0xdb, 0x3a, 0x6f, 0x69, 0x19, 0x1f, 0xa1, 0xdd, 0x1d, + 0xd7, 0x45, 0x04, 0x56, 0x16, 0x43, 0x22, 0x18, 0xba, 0x22, 0xd6, 0x70, + 0xd0, 0x67, 0xb0, 0x06, 0x6a, 0x16, 0x57, 0x61, 0x83, 0x47, 0xd9, 0x40, + 0xc9, 0x92, 0xdd, 0x74, 0xbe, 0xb9, 0xe8, 0x07, 0x40, 0xa8, 0x23, 0xc5, + 0xd6, 0x3e, 0x26, 0xec, 0x17, 0x6c, 0x61, 0x76, 0x47, 0x42, 0x0a, 0x82, + 0x5e, 0xdb, 0x41, 0xba, 0x42, 0x1f, 0xec, 0xb7, 0xc2, 0xe0, 0xf8, 0x3a, + 0x39, 0x5f, 0xb2, 0x45, 0x92, 0xdc, 0xe2, 0x5e, 0x5d, 0x81, 0x14, 0xa3, + 0x10, 0x68, 0x5a, 0xed, 0x28, 0x9f, 0xad, 0xa6, 0xc9, 0xd9, 0x61, 0xc2, + 0x62, 0xec, 0x1b, 0x61, 0x2a, 0x67, 0xef, 0xac, 0x79, 0xc1, 0x6e, 0x35, + 0xc4, 0xd2, 0x69, 0x05, 0x3f, 0xf2, 0x6f, 0x5a, 0x66, 0x0c, 0xea, 0xd2, + 0x70, 0x2e, 0xbe, 0x5f, 0xd8, 0x31, 0x6c, 0x1f, 0xec, 0x62, 0xf6, 0xa7, + 0x98, 0x1c, 0xd4, 0xf6, 0xc1, 0x28, 0x71, 0xf5, 0x63, 0xab, 0x59, 0x4b, + 0x34, 0xb4, 0x30, 0x12, 0x91, 0x71, 0xf8, 0x50, 0x9a, 0x26, 0x4a, 0xd9, + 0xf1, 0x30, 0x04, 0x30, 0x82, 0x06, 0x4c, 0x30, 0x82, 0x05, 0x34, 0xa0, + 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, 0x3c, 0xec, 0x82, 0xf8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0e, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x64, 0x31, 0x14, 0x30, + 0x12, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, + 0x19, 0x16, 0x04, 0x63, 0x6f, 0x72, 0x70, 0x31, 0x13, 0x30, 0x11, 0x06, + 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, + 0x03, 0x62, 0x6d, 0x77, 0x31, 0x16, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, + 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x65, 0x75, + 0x72, 0x6f, 0x70, 0x65, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x16, 0x42, 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x20, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x41, 0x20, + 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x33, 0x30, 0x34, 0x31, + 0x33, 0x35, 0x33, 0x31, 0x31, 0x5a, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x33, + 0x30, 0x33, 0x31, 0x33, 0x35, 0x33, 0x31, 0x31, 0x5a, 0x30, 0x81, 0x83, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x44, + 0x45, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, + 0x42, 0x61, 0x76, 0x61, 0x72, 0x69, 0x61, 0x31, 0x0f, 0x30, 0x0d, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x13, 0x06, 0x4d, 0x75, 0x6e, 0x69, 0x63, 0x68, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x42, + 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x1a, 0x30, 0x18, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x43, 0x45, 0x50, 0x20, + 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x20, 0x43, 0x41, 0x20, 0x32, + 0x31, 0x21, 0x30, 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x09, 0x01, 0x16, 0x12, 0x74, 0x72, 0x75, 0x73, 0x74, 0x63, 0x65, + 0x6e, 0x74, 0x65, 0x72, 0x40, 0x62, 0x6d, 0x77, 0x2e, 0x64, 0x65, 0x30, + 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, + 0x02, 0x81, 0x81, 0x00, 0xa4, 0x78, 0xc8, 0x9b, 0xd9, 0x08, 0x24, 0xab, + 0x07, 0x33, 0x89, 0x62, 0xcd, 0x20, 0xcb, 0x16, 0xfa, 0x1d, 0x9b, 0x8a, + 0xcf, 0x9d, 0x61, 0xea, 0x10, 0xbd, 0xa0, 0x02, 0xf5, 0x97, 0x53, 0x96, + 0x86, 0xb3, 0x02, 0x88, 0xf7, 0x52, 0xd8, 0x67, 0xcd, 0xe4, 0xba, 0xa7, + 0x36, 0xfd, 0x6e, 0xd3, 0x51, 0x9a, 0xa2, 0xfb, 0xcc, 0x2c, 0xd1, 0xaa, + 0x9c, 0x49, 0x2e, 0x36, 0xe0, 0xa2, 0x21, 0xc8, 0xfd, 0x05, 0xa9, 0x54, + 0x16, 0x9f, 0xd3, 0x8e, 0x6a, 0xbe, 0x3e, 0x7f, 0xc8, 0xc6, 0x2d, 0x8d, + 0xda, 0xe9, 0x73, 0x97, 0x5e, 0x80, 0xdd, 0x8c, 0xc4, 0x9b, 0x3a, 0x77, + 0xc7, 0x6a, 0x8d, 0xe2, 0xe1, 0x54, 0x6f, 0x5e, 0xde, 0x3f, 0x71, 0x9c, + 0x14, 0x2d, 0x15, 0x6d, 0xf1, 0x7c, 0x43, 0x97, 0xb7, 0xdf, 0x5a, 0x1a, + 0xb8, 0xb7, 0x9c, 0x05, 0x4d, 0xf5, 0x45, 0x45, 0x59, 0xbe, 0x73, 0xbd, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x03, 0x62, 0x30, 0x82, 0x03, + 0x5e, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, + 0x05, 0x20, 0x30, 0x36, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x09, 0x0f, 0x04, 0x29, 0x30, 0x27, 0x30, 0x0d, 0x06, 0x08, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, 0x02, 0x01, 0x38, 0x30, 0x0d, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x04, 0x02, 0x01, + 0x38, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x07, 0x30, 0x15, + 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, + 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x01, 0x30, 0x29, 0x06, + 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x1c, + 0x1e, 0x1a, 0x00, 0x43, 0x00, 0x45, 0x00, 0x50, 0x00, 0x45, 0x00, 0x6e, + 0x00, 0x63, 0x00, 0x72, 0x00, 0x79, 0x00, 0x70, 0x00, 0x74, 0x00, 0x69, + 0x00, 0x6f, 0x00, 0x6e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, + 0x16, 0x04, 0x14, 0x11, 0xe1, 0x07, 0x5e, 0xd5, 0x49, 0xed, 0x64, 0x11, + 0xc4, 0x33, 0xbb, 0x2a, 0x99, 0x7c, 0xb0, 0xc8, 0xd8, 0x85, 0x8d, 0x30, + 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, + 0x61, 0x0a, 0xef, 0x1a, 0x3d, 0xfe, 0x9a, 0x68, 0x81, 0xcb, 0xb2, 0x62, + 0xe5, 0xc0, 0x21, 0x8e, 0xdd, 0xec, 0x61, 0x95, 0x30, 0x82, 0x01, 0x71, + 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, 0x68, 0x30, 0x82, 0x01, + 0x64, 0x30, 0x82, 0x01, 0x60, 0xa0, 0x82, 0x01, 0x5c, 0xa0, 0x82, 0x01, + 0x58, 0x86, 0x81, 0xc3, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, + 0x43, 0x4e, 0x3d, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, + 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2c, 0x43, 0x4e, + 0x3d, 0x53, 0x4d, 0x55, 0x43, 0x31, 0x39, 0x32, 0x33, 0x2c, 0x43, 0x4e, + 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2c, 0x44, 0x43, 0x3d, 0x62, 0x6d, 0x77, 0x2c, 0x44, 0x43, 0x3d, 0x63, + 0x6f, 0x72, 0x70, 0x3f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, + 0x52, 0x4c, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x86, 0x4d, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x6d, 0x75, 0x63, 0x31, 0x39, 0x32, 0x33, + 0x2e, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2e, 0x62, 0x6d, 0x77, 0x2e, + 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x72, + 0x6f, 0x6c, 0x6c, 0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, + 0x67, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2e, 0x63, + 0x72, 0x6c, 0x86, 0x41, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, + 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d, 0x77, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x42, + 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, + 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x25, 0x32, 0x30, 0x43, + 0x41, 0x25, 0x32, 0x30, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x82, 0x01, + 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, + 0x82, 0x01, 0x10, 0x30, 0x82, 0x01, 0x0c, 0x30, 0x81, 0xba, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0xad, 0x6c, + 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x42, 0x4d, + 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, + 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x25, 0x32, 0x30, 0x43, 0x41, + 0x25, 0x32, 0x30, 0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x49, 0x41, 0x2c, + 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, + 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x62, + 0x6d, 0x77, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x72, 0x70, 0x3f, 0x63, + 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x30, 0x4d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x30, 0x02, 0x86, 0x41, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x73, 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d, 0x77, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, + 0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x25, 0x32, 0x30, 0x49, 0x73, 0x73, 0x75, 0x69, 0x6e, 0x67, 0x25, 0x32, + 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, 0x2e, 0x63, 0x72, 0x74, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xa6, 0xdb, 0xab, 0x42, 0x93, + 0x90, 0xb9, 0x6a, 0xc1, 0x92, 0xb7, 0x3c, 0xaf, 0xf2, 0x9b, 0xed, 0x2b, + 0x14, 0xdb, 0xd8, 0x9f, 0x6b, 0xb8, 0x8e, 0x08, 0xf0, 0x0e, 0x1a, 0xfe, + 0xb3, 0x9a, 0x6f, 0x3d, 0x28, 0x79, 0xd4, 0x88, 0xbe, 0x1c, 0x17, 0xaa, + 0x6a, 0xa4, 0xe9, 0xf0, 0xe0, 0xee, 0x9d, 0x74, 0x25, 0xbb, 0x48, 0x16, + 0xb1, 0x00, 0xca, 0xfa, 0x6a, 0x0c, 0x16, 0x98, 0xef, 0xf9, 0x42, 0xd6, + 0x81, 0xb4, 0xf7, 0xa2, 0x15, 0xb6, 0xdc, 0xe8, 0x25, 0xe8, 0xdd, 0x92, + 0x1d, 0x0c, 0x96, 0xea, 0x80, 0x41, 0x3f, 0xd7, 0xff, 0xeb, 0x53, 0xe9, + 0x13, 0xf8, 0xdc, 0x8b, 0xe2, 0x45, 0xb8, 0xbb, 0x22, 0x81, 0xea, 0x46, + 0xee, 0x19, 0x14, 0xe3, 0xd5, 0xb0, 0xaa, 0x2a, 0xd2, 0x52, 0xa5, 0x3f, + 0x7e, 0xa5, 0x7d, 0x5c, 0xb0, 0x84, 0x4e, 0x77, 0x01, 0x35, 0x76, 0x31, + 0xa3, 0x6e, 0x3f, 0x51, 0x20, 0x3f, 0x98, 0xac, 0x68, 0x28, 0x0f, 0xc6, + 0x5a, 0xc1, 0xcf, 0x58, 0xd7, 0x75, 0xaa, 0xe2, 0x9b, 0xc3, 0xfa, 0x3c, + 0xd6, 0x61, 0x98, 0x2b, 0xf1, 0x73, 0x78, 0x2a, 0xb2, 0x54, 0x78, 0xba, + 0xff, 0x36, 0x15, 0x17, 0xe7, 0xe6, 0x6e, 0x82, 0xee, 0x64, 0x87, 0x81, + 0xd9, 0x08, 0x68, 0xa4, 0xc7, 0x9b, 0xa4, 0xa9, 0xf3, 0x1e, 0xe9, 0x82, + 0xc1, 0x3d, 0xfd, 0xe9, 0x75, 0x77, 0x81, 0x73, 0x05, 0x2e, 0x36, 0x0e, + 0x17, 0x13, 0x48, 0x20, 0x9c, 0x24, 0xce, 0xe2, 0x22, 0x68, 0x3f, 0x37, + 0x3d, 0xf5, 0x01, 0x0e, 0x13, 0xec, 0x3d, 0xba, 0x0d, 0x71, 0xd2, 0xe2, + 0x67, 0x65, 0x19, 0x24, 0xa4, 0x5d, 0xae, 0x35, 0x1e, 0x39, 0x4c, 0xe4, + 0x19, 0x48, 0x91, 0x03, 0x9e, 0xe9, 0x42, 0xfd, 0x1f, 0x1d, 0x2a, 0x98, + 0x40, 0xd0, 0xb6, 0x92, 0xb3, 0x38, 0x0f, 0xf5, 0x7f, 0xf0, 0xc1, 0x30, + 0x82, 0x03, 0x70, 0x30, 0x82, 0x02, 0x58, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x10, 0x13, 0xaa, 0xab, 0xff, 0x7f, 0x25, 0x31, 0xae, 0x49, 0x9b, + 0x17, 0x9b, 0xef, 0xee, 0xe2, 0x97, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x40, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x45, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x42, + 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x1d, 0x30, 0x1b, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x42, 0x4d, 0x57, 0x20, 0x47, + 0x72, 0x6f, 0x75, 0x70, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, + 0x20, 0x56, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x31, 0x32, 0x31, + 0x30, 0x31, 0x30, 0x32, 0x36, 0x35, 0x31, 0x5a, 0x17, 0x0d, 0x33, 0x34, + 0x31, 0x32, 0x31, 0x30, 0x31, 0x30, 0x33, 0x35, 0x34, 0x30, 0x5a, 0x30, + 0x40, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x44, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x09, 0x42, 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x1d, + 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x42, 0x4d, 0x57, + 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x56, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, + 0x01, 0x00, 0xd0, 0x27, 0x3b, 0xb7, 0xfe, 0x8d, 0x0c, 0xd6, 0xed, 0xf0, + 0xa2, 0x49, 0x1f, 0x83, 0xed, 0x11, 0xcf, 0x56, 0x96, 0xe2, 0xe2, 0x1a, + 0xac, 0x59, 0x4c, 0xef, 0x27, 0xf7, 0xda, 0xf8, 0x6a, 0x0d, 0xea, 0x78, + 0x27, 0x69, 0x84, 0xd0, 0x4d, 0x94, 0xd8, 0x78, 0xc6, 0x14, 0x25, 0x98, + 0x68, 0x69, 0xd5, 0x3a, 0xfd, 0x84, 0x39, 0xf3, 0x4a, 0xb8, 0x47, 0x51, + 0x59, 0x8c, 0xa4, 0x24, 0x97, 0x10, 0xb5, 0x3b, 0x28, 0x4f, 0x26, 0x91, + 0xad, 0xb2, 0x39, 0xc7, 0x8b, 0x96, 0x99, 0x62, 0x53, 0xe3, 0xee, 0xba, + 0x1d, 0x55, 0x49, 0x98, 0x32, 0x60, 0xb3, 0x8d, 0x1a, 0x53, 0x29, 0x7b, + 0xf1, 0xd3, 0xf4, 0xbc, 0x7d, 0xf1, 0x47, 0x78, 0x88, 0xe4, 0x14, 0x9c, + 0x60, 0xdc, 0x8b, 0x65, 0xfd, 0x95, 0x39, 0xc0, 0x8b, 0x59, 0xcb, 0x66, + 0xd2, 0x6a, 0x19, 0x67, 0x0e, 0xcd, 0x56, 0xf6, 0x7a, 0x2a, 0x8f, 0x2a, + 0x4f, 0x1e, 0x15, 0x4d, 0xbe, 0xb5, 0x3e, 0xca, 0x3a, 0xc3, 0x93, 0x8a, + 0xac, 0x28, 0x4c, 0x2d, 0xbd, 0x1f, 0x2b, 0x92, 0x43, 0x32, 0xdd, 0x97, + 0xef, 0xb7, 0x09, 0xf3, 0x6b, 0x3d, 0x1e, 0x36, 0x16, 0x8b, 0x78, 0xce, + 0x96, 0x45, 0x36, 0x9d, 0x3a, 0x90, 0x5e, 0x20, 0x3f, 0xb2, 0x39, 0x8b, + 0x2f, 0x76, 0xd1, 0x2f, 0xe9, 0x2a, 0xb0, 0xd8, 0x40, 0x0b, 0xd9, 0x62, + 0xd0, 0xe0, 0x6b, 0xa6, 0xf7, 0x00, 0xa8, 0x50, 0xac, 0xb0, 0x17, 0x20, + 0x6c, 0x89, 0x1b, 0x32, 0x0a, 0x91, 0x8f, 0x94, 0xcf, 0x24, 0x72, 0xdb, + 0x4f, 0xf9, 0x4c, 0x9e, 0x88, 0x49, 0xd9, 0x01, 0x03, 0xd0, 0xc7, 0xf4, + 0xd1, 0xf8, 0xd5, 0x6b, 0x76, 0xea, 0x14, 0xa3, 0xb5, 0x24, 0x4c, 0xa5, + 0xd2, 0xa8, 0x12, 0x79, 0xd3, 0x27, 0xb4, 0x9a, 0x47, 0xaa, 0x7b, 0x74, + 0x90, 0xbb, 0xb5, 0x74, 0x29, 0x53, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, + 0x66, 0x30, 0x64, 0x30, 0x13, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, + 0x82, 0x37, 0x14, 0x02, 0x04, 0x06, 0x1e, 0x04, 0x00, 0x43, 0x00, 0x41, + 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, + 0x86, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, + 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, + 0x0e, 0x04, 0x16, 0x04, 0x14, 0x17, 0xd0, 0xa6, 0x81, 0xc4, 0xba, 0xb6, + 0x59, 0xe8, 0xac, 0xa5, 0x5f, 0xa3, 0x07, 0xad, 0xfd, 0x8b, 0x56, 0x2b, + 0xbb, 0x30, 0x10, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, + 0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, + 0x01, 0x01, 0x00, 0x6c, 0x1b, 0xf2, 0x9b, 0xa7, 0x29, 0xc3, 0x7c, 0x90, + 0xf0, 0xd2, 0x88, 0xc1, 0x5a, 0xdf, 0xea, 0x1d, 0x48, 0xeb, 0xe5, 0x83, + 0x64, 0x31, 0xb4, 0x61, 0xa8, 0x3c, 0xfe, 0x1b, 0xf9, 0x0e, 0xc1, 0xdd, + 0xd2, 0x81, 0xcb, 0x57, 0xcf, 0x12, 0xe0, 0x97, 0xee, 0xfe, 0x7c, 0x9e, + 0x4d, 0xf2, 0x53, 0x68, 0x30, 0xab, 0xa7, 0x6b, 0xcd, 0xac, 0xef, 0x98, + 0x93, 0x6e, 0x96, 0x93, 0x49, 0x0d, 0x51, 0x61, 0xb2, 0x85, 0x71, 0x7e, + 0x3d, 0x3d, 0x90, 0x4d, 0xd6, 0x46, 0x85, 0xf8, 0x67, 0x8c, 0x53, 0x10, + 0x0c, 0x36, 0xd4, 0xe9, 0xfb, 0x29, 0x19, 0x27, 0xfb, 0xcd, 0x87, 0xd3, + 0x2b, 0xd3, 0xfd, 0x2e, 0xac, 0xf9, 0xeb, 0x1d, 0x82, 0xa7, 0x4f, 0x22, + 0xba, 0x73, 0x22, 0x26, 0x64, 0x73, 0x5c, 0xaa, 0x44, 0x23, 0x9e, 0x5d, + 0xb6, 0xd0, 0x79, 0xd8, 0x7f, 0x2e, 0xd6, 0xdb, 0x73, 0x3a, 0x09, 0xdf, + 0x44, 0xff, 0xba, 0xa6, 0xcc, 0xcc, 0x61, 0x76, 0x8c, 0x18, 0x8c, 0x89, + 0xa9, 0x10, 0xab, 0xda, 0x21, 0x22, 0xfb, 0x3f, 0x65, 0x0b, 0xa9, 0xd3, + 0x0a, 0x70, 0x85, 0x8a, 0x81, 0xb7, 0x60, 0x9a, 0x6d, 0x3a, 0x42, 0xfa, + 0xc8, 0x0b, 0x58, 0x8d, 0x47, 0x34, 0x78, 0x51, 0x66, 0xc3, 0x11, 0xa6, + 0x22, 0x99, 0x2b, 0x64, 0x64, 0xda, 0xe3, 0xa1, 0x46, 0x81, 0xb7, 0x52, + 0xdc, 0xd0, 0x17, 0x19, 0xf1, 0xae, 0xe0, 0x05, 0x92, 0x07, 0x92, 0x98, + 0x0f, 0x2a, 0xf7, 0x1d, 0xe2, 0x42, 0x7f, 0x97, 0xd1, 0xea, 0x27, 0x8e, + 0x65, 0xef, 0x00, 0x0b, 0xce, 0xbb, 0xd7, 0xa7, 0x7d, 0xf9, 0x31, 0x92, + 0x44, 0x1c, 0x9e, 0x84, 0xc6, 0x8f, 0xed, 0x37, 0x51, 0x79, 0xaa, 0x7b, + 0x9a, 0x9d, 0xac, 0xe2, 0xa0, 0xae, 0x4d, 0xf0, 0x91, 0x83, 0x5d, 0x85, + 0xca, 0xfa, 0xea, 0x26, 0x0b, 0x48, 0x16, 0x30, 0x82, 0x05, 0xfc, 0x30, + 0x82, 0x04, 0xe4, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, 0x1e, 0x30, + 0xc3, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, + 0x40, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x44, 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x09, 0x42, 0x4d, 0x57, 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x1d, + 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x42, 0x4d, 0x57, + 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x56, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x31, + 0x32, 0x31, 0x37, 0x30, 0x39, 0x31, 0x37, 0x31, 0x39, 0x5a, 0x17, 0x0d, + 0x32, 0x32, 0x31, 0x32, 0x31, 0x37, 0x30, 0x39, 0x32, 0x37, 0x31, 0x39, + 0x5a, 0x30, 0x64, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x09, 0x92, 0x26, + 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x04, 0x63, 0x6f, 0x72, + 0x70, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, + 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x62, 0x6d, 0x77, 0x31, 0x16, + 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, + 0x01, 0x19, 0x16, 0x06, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x31, 0x1f, + 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x42, 0x4d, 0x57, + 0x20, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x49, 0x73, 0x73, 0x75, 0x69, + 0x6e, 0x67, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, + 0x82, 0x01, 0x01, 0x00, 0xb3, 0xab, 0xd3, 0x53, 0x73, 0x45, 0x6c, 0x37, + 0xc4, 0x79, 0x7c, 0xe9, 0xfb, 0x0d, 0x6b, 0xb5, 0x9d, 0xcc, 0x95, 0xa5, + 0xf7, 0x02, 0x04, 0x94, 0x8a, 0x2f, 0xb2, 0xea, 0x9f, 0x27, 0xe4, 0xef, + 0x95, 0x02, 0x2f, 0x8c, 0x2f, 0x23, 0x4a, 0xd9, 0x53, 0xc8, 0x81, 0xb7, + 0xe9, 0xb8, 0xb1, 0x52, 0x5c, 0x02, 0x7a, 0x2b, 0x4c, 0xe1, 0xeb, 0x25, + 0xa4, 0x8b, 0x53, 0xa4, 0x45, 0x74, 0xbb, 0x20, 0xa6, 0x2e, 0x8b, 0x5b, + 0xf0, 0x05, 0x86, 0x06, 0x79, 0x24, 0x55, 0x27, 0x10, 0x71, 0x9b, 0xf7, + 0xac, 0x71, 0x8c, 0xa0, 0x4c, 0xe7, 0x9f, 0x1a, 0xb4, 0xa2, 0xd7, 0x5b, + 0x17, 0xa3, 0x9f, 0xb3, 0x5b, 0x28, 0x16, 0xbe, 0x28, 0x48, 0x58, 0x6f, + 0x19, 0x7e, 0x7c, 0x7b, 0x0d, 0x69, 0x59, 0xa1, 0x97, 0x13, 0x1a, 0x1f, + 0x9c, 0xf3, 0x47, 0x36, 0xf2, 0xfa, 0xda, 0xad, 0xbd, 0xd2, 0xda, 0xdd, + 0xb9, 0xcb, 0x9e, 0xef, 0xe4, 0x63, 0x1e, 0xdb, 0xf6, 0xd6, 0x4c, 0x85, + 0xf1, 0x7f, 0x04, 0xe4, 0xf7, 0x07, 0xc4, 0x6e, 0x77, 0x36, 0xd7, 0x4e, + 0x62, 0xb9, 0x71, 0x5b, 0x46, 0x58, 0x99, 0x81, 0xa9, 0x71, 0x43, 0x36, + 0x4b, 0x06, 0xc2, 0x9c, 0xd9, 0x91, 0xb5, 0x5c, 0xcf, 0x95, 0x94, 0xa1, + 0x37, 0x44, 0xce, 0x59, 0xc4, 0x1f, 0x99, 0x1e, 0x2d, 0x18, 0xb8, 0x6a, + 0xf8, 0x13, 0x0e, 0x71, 0x4b, 0x67, 0xd7, 0x1e, 0xc8, 0x4d, 0x1f, 0x54, + 0xd6, 0xc5, 0x94, 0x39, 0x52, 0x32, 0xca, 0x47, 0xa2, 0x01, 0x83, 0x03, + 0x1b, 0xa8, 0xe1, 0xd4, 0x7d, 0x30, 0x1f, 0x20, 0x58, 0xb0, 0xd4, 0x6b, + 0xeb, 0x13, 0x37, 0x10, 0x98, 0x3f, 0x89, 0x0d, 0x94, 0xa3, 0x24, 0xfd, + 0xcf, 0x20, 0x79, 0xc2, 0x2e, 0x25, 0xcb, 0x0b, 0x47, 0x25, 0xe5, 0x79, + 0xbe, 0x4e, 0x92, 0xd7, 0x24, 0xea, 0xc6, 0x1b, 0x02, 0x03, 0x01, 0x00, + 0x01, 0xa3, 0x82, 0x02, 0xd2, 0x30, 0x82, 0x02, 0xce, 0x30, 0x0f, 0x06, + 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, + 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, + 0x14, 0x61, 0x0a, 0xef, 0x1a, 0x3d, 0xfe, 0x9a, 0x68, 0x81, 0xcb, 0xb2, + 0x62, 0xe5, 0xc0, 0x21, 0x8e, 0xdd, 0xec, 0x61, 0x95, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, + 0x06, 0x30, 0x10, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, + 0x15, 0x01, 0x04, 0x03, 0x02, 0x01, 0x00, 0x30, 0x19, 0x06, 0x09, 0x2b, + 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x0c, 0x1e, 0x0a, + 0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, 0x41, 0x30, 0x1f, + 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x17, + 0xd0, 0xa6, 0x81, 0xc4, 0xba, 0xb6, 0x59, 0xe8, 0xac, 0xa5, 0x5f, 0xa3, + 0x07, 0xad, 0xfd, 0x8b, 0x56, 0x2b, 0xbb, 0x30, 0x82, 0x01, 0x1e, 0x06, + 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, 0x15, 0x30, 0x82, 0x01, 0x11, + 0x30, 0x82, 0x01, 0x0d, 0xa0, 0x82, 0x01, 0x09, 0xa0, 0x82, 0x01, 0x05, + 0x86, 0x81, 0xc1, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, + 0x4e, 0x3d, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x25, 0x32, 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, + 0x41, 0x25, 0x32, 0x30, 0x56, 0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x73, 0x6d, + 0x75, 0x63, 0x31, 0x38, 0x39, 0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x44, + 0x50, 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, + 0x32, 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, + 0x3d, 0x62, 0x6d, 0x77, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x72, 0x70, + 0x3f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, + 0x73, 0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44, + 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, + 0x6f, 0x69, 0x6e, 0x74, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x73, 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d, 0x77, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, + 0x2f, 0x42, 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x25, 0x32, 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x41, + 0x25, 0x32, 0x30, 0x56, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x82, 0x01, + 0x1a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, + 0x82, 0x01, 0x0c, 0x30, 0x82, 0x01, 0x08, 0x30, 0x81, 0xb8, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x81, 0xab, 0x6c, + 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e, 0x3d, 0x42, 0x4d, + 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, 0x30, + 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, + 0x56, 0x32, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x49, 0x41, 0x2c, 0x43, 0x4e, + 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, + 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x62, 0x6d, 0x77, + 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x72, 0x70, 0x3f, 0x63, 0x41, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x3f, 0x62, + 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x74, 0x79, 0x30, 0x4b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x30, 0x02, 0x86, 0x3f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, + 0x73, 0x6c, 0x63, 0x72, 0x6c, 0x2e, 0x62, 0x6d, 0x77, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x42, + 0x4d, 0x57, 0x25, 0x32, 0x30, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x25, 0x32, + 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, + 0x30, 0x56, 0x32, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, + 0x01, 0x01, 0x00, 0x68, 0x8c, 0xe9, 0xec, 0x52, 0x47, 0xe5, 0x9a, 0xac, + 0x02, 0x1e, 0x1f, 0x49, 0x12, 0x24, 0x4a, 0xd6, 0x76, 0x41, 0xa7, 0xe6, + 0x32, 0xf5, 0xc3, 0x96, 0xad, 0x22, 0x34, 0xd6, 0xf7, 0xce, 0xcc, 0xf5, + 0x20, 0xcf, 0xf9, 0x81, 0x55, 0xff, 0x7a, 0xfb, 0x77, 0xe0, 0x5e, 0x37, + 0x56, 0x55, 0x17, 0xd7, 0x1a, 0x09, 0x52, 0x2c, 0xda, 0x84, 0xed, 0x1e, + 0xa3, 0xb3, 0x26, 0xfe, 0x93, 0xff, 0x45, 0x6a, 0x87, 0x91, 0xf9, 0x05, + 0xe3, 0xa6, 0xcf, 0x33, 0xbc, 0xd6, 0x4a, 0x58, 0x70, 0xfa, 0x9e, 0x54, + 0x7a, 0x79, 0x16, 0xd7, 0xea, 0xd4, 0x04, 0xaf, 0x87, 0x9a, 0x54, 0xe5, + 0x80, 0x13, 0xfd, 0xdf, 0x83, 0xc4, 0x60, 0x12, 0x33, 0x49, 0x7b, 0x90, + 0xd7, 0x1e, 0x09, 0x11, 0x4b, 0xd8, 0xbe, 0x06, 0xd4, 0xf0, 0x8e, 0x84, + 0x06, 0x2a, 0xe3, 0x0b, 0xf4, 0xac, 0x9d, 0x31, 0xa1, 0x9f, 0x03, 0x91, + 0xbe, 0xf8, 0x93, 0x6d, 0xc1, 0x9d, 0x8f, 0x18, 0xd3, 0xb9, 0x29, 0xaa, + 0x19, 0x51, 0x15, 0xf7, 0x99, 0x3f, 0x42, 0x69, 0xfd, 0xec, 0xfb, 0xf0, + 0x8a, 0x3f, 0x35, 0x65, 0x17, 0x1c, 0x52, 0xf4, 0xd1, 0x31, 0xc8, 0x14, + 0x51, 0x42, 0x1b, 0xb8, 0xea, 0x7c, 0x4f, 0xbf, 0xd5, 0x78, 0x72, 0xdf, + 0x18, 0x86, 0xc6, 0x2f, 0x2c, 0xb4, 0x45, 0x1b, 0x0b, 0x00, 0x16, 0x0e, + 0xd6, 0x41, 0xd9, 0x4d, 0xa0, 0x9e, 0xb3, 0x56, 0x8d, 0xf8, 0x6b, 0xa0, + 0x20, 0x4c, 0x1c, 0x6e, 0x3a, 0x80, 0xec, 0xd7, 0x85, 0x8c, 0xbb, 0xc1, + 0x51, 0x73, 0x66, 0x47, 0x01, 0x44, 0x9a, 0x87, 0xc9, 0xed, 0x49, 0x04, + 0xc2, 0x41, 0xea, 0x65, 0x16, 0xda, 0xd0, 0xb7, 0xe6, 0x03, 0x73, 0x74, + 0x11, 0x3b, 0x94, 0x1b, 0x9f, 0x06, 0xb9, 0x71, 0x02, 0x70, 0x66, 0xa0, + 0x12, 0xb5, 0x5a, 0xe8, 0x2c, 0xf9, 0x63, 0x31, 0x00 +}; +static unsigned int bmw_scep_pkt_len = 5661; + +#include "si-63-scep/getcacert-mdes.h" +#include "si-63-scep/getcacert-mdesqa.h" + +#include +__unused static inline void write_data(const char * path, CFDataRef data) +{ + int data_file = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0644); + write(data_file, CFDataGetBytePtr(data), CFDataGetLength(data)); + close(data_file); +} + + +__unused static inline CFMutableArrayRef maa(CFMutableArrayRef array, CFTypeRef a) { + CFMutableArrayRef ma = array; + if (!ma) + CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); + if (ma) { + CFArrayAppendValue(ma, a); + CFRelease(a); + } + return ma; +} + +/* Test basic add delete update copy matching stuff. */ +static void tests(void) +{ + CFDataRef getcacert_blob = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + getcacert, getcacert_len, kCFAllocatorNull); + CFArrayRef certificates = NULL; + SecCertificateRef ca_certificate, ra_signing_certificate, ra_encryption_certificate; + ca_certificate = ra_signing_certificate = ra_encryption_certificate = NULL; + certificates = SecCMSCertificatesOnlyMessageCopyCertificates(getcacert_blob); + isnt(certificates, NULL, "decode cert-only pkcs#7"); + CFDataRef sha1_fingerprint = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + ruby_sha1_hash, sizeof(ruby_sha1_hash), kCFAllocatorNull); + + ok_status(SecSCEPValidateCACertMessage(certificates, sha1_fingerprint, + &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate), + "parse CA/RAse getcacert message"); + CFReleaseNull(sha1_fingerprint); + isnt(ca_certificate, NULL, "got ca cert"); + isnt(ra_signing_certificate, NULL, "got ra signing cert"); + is(ra_encryption_certificate, NULL, "no separate ra encryption cert"); + + /* these are always going to be true, but ensure replacement payloads are equivalent */ + ok(SecCertificateIsSelfSignedCA(ca_certificate), "self-signed ca cert"); + ok(SecCertificateGetKeyUsage(ra_signing_certificate) & kSecKeyUsageDigitalSignature, "can sign"); + + CFReleaseNull(ca_certificate); + CFReleaseNull(ra_signing_certificate); + CFReleaseNull(ra_encryption_certificate); + CFReleaseNull(getcacert_blob); + CFReleaseNull(certificates); + + ca_certificate = ra_signing_certificate = ra_encryption_certificate = NULL; + getcacert_blob = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, getcacert_mdes, getcacert_mdes_len, kCFAllocatorNull); + certificates = SecCMSCertificatesOnlyMessageCopyCertificates(getcacert_blob); + ok_status(SecSCEPValidateCACertMessage(certificates, NULL, &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate), "parse WF MDES getcacert message"); + ok(ca_certificate && ra_signing_certificate && ra_encryption_certificate, "identify all 3 certs"); + + CFReleaseNull(ca_certificate); + CFReleaseNull(ra_signing_certificate); + CFReleaseNull(ra_encryption_certificate); + CFReleaseNull(getcacert_blob); + CFReleaseNull(certificates); + + ca_certificate = ra_signing_certificate = ra_encryption_certificate = NULL; + getcacert_blob = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, getcacert_mdesqa, getcacert_mdesqa_len, kCFAllocatorNull); + certificates = SecCMSCertificatesOnlyMessageCopyCertificates(getcacert_blob); + ok_status(SecSCEPValidateCACertMessage(certificates, NULL, &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate), "parse WF MDESQA getcacert message"); + ok(ca_certificate && ra_signing_certificate && ra_encryption_certificate, "identify all 3 certs"); + + CFReleaseNull(ca_certificate); + CFReleaseNull(ra_signing_certificate); + CFReleaseNull(ra_encryption_certificate); + CFReleaseNull(getcacert_blob); + CFReleaseNull(certificates); + + sha1_fingerprint = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + msscep_md5_hash, sizeof(msscep_md5_hash), kCFAllocatorNull); + CFDataRef msscep_getcacert_blob = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + msscep_getcacert, msscep_getcacert_len, kCFAllocatorNull); + CFReleaseNull(sha1_fingerprint); + ca_certificate = ra_signing_certificate = ra_encryption_certificate = NULL; + certificates = SecCMSCertificatesOnlyMessageCopyCertificates(msscep_getcacert_blob); + ok_status(SecSCEPValidateCACertMessage(certificates, sha1_fingerprint, + &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate), + "parse CA/RAs/RAe msscep getcacert message"); + isnt(ca_certificate, NULL, "got ca cert"); + isnt(ra_signing_certificate, NULL, "got ra signing cert"); + isnt(ra_encryption_certificate, NULL, "got ra encryption cert"); + + /* these are always going to be true, but ensure replacement payloads are equivalent */ + ok(SecCertificateIsSelfSignedCA(ca_certificate), "self-signed ca cert"); + ok(SecCertificateGetKeyUsage(ra_encryption_certificate) & kSecKeyUsageKeyEncipherment, "can sign"); + + /* + int ix; + uint8_t md5_hash[CC_MD5_DIGEST_LENGTH]; + CFDataRef cert_data = SecCertificateCopyData(ca_certificate); + CC_MD5(CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data), md5_hash); + for(ix = 0; ix < CC_MD5_DIGEST_LENGTH; ix++) fprintf(stdout, "0x%.02x, ", md5_hash[ix]); fprintf(stdout, "\n"); + uint8_t sha1_hash[CC_SHA1_DIGEST_LENGTH]; + CCDigest(kCCDigestSHA1, CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data), sha1_hash); + for(ix = 0; ix < CC_SHA1_DIGEST_LENGTH; ix++) fprintf(stdout, "0x%.02x, ", sha1_hash[ix]); fprintf(stdout, "\n"); + CFRelease(cert_data); + */ + + CFReleaseNull(ca_certificate); + CFReleaseNull(ra_signing_certificate); + CFReleaseNull(ra_encryption_certificate); + CFRelease(certificates); + CFRelease(msscep_getcacert_blob); + + + + + CFDataRef bmw_getcacert_blob = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + bmw_scep_pkt, bmw_scep_pkt_len, kCFAllocatorNull); + ca_certificate = ra_signing_certificate = ra_encryption_certificate = NULL; + certificates = SecCMSCertificatesOnlyMessageCopyCertificates(bmw_getcacert_blob); + CFMutableArrayRef certificates_mod = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, certificates); + CFArrayRemoveValueAtIndex(certificates_mod, 2); + ok_status(SecSCEPValidateCACertMessage(certificates_mod, NULL, + &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate), + "parse CA/RAs/RAe msscep getcacert message"); + CFRelease(certificates_mod); + CFRelease(ca_certificate); + CFRelease(ra_signing_certificate); + CFRelease(ra_encryption_certificate); + certificates_mod = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, certificates); + CFArrayInsertValueAtIndex(certificates_mod, 0, CFArrayGetValueAtIndex(certificates_mod, 3)); + CFArrayRemoveValueAtIndex(certificates_mod, 4); + ok_status(SecSCEPValidateCACertMessage(certificates_mod, NULL, + &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate), + "parse CA/RAs/RAe msscep getcacert message"); + CFRelease(certificates_mod); + CFRelease(ca_certificate); + CFRelease(ra_signing_certificate); + CFRelease(ra_encryption_certificate); + + ok_status(SecSCEPValidateCACertMessage(certificates, NULL, + &ca_certificate, &ra_signing_certificate, &ra_encryption_certificate), + "parse CA/RAs/RAe msscep getcacert message"); + isnt(ca_certificate, NULL, "got ca cert"); + isnt(ra_signing_certificate, NULL, "got ra signing cert"); + isnt(ra_encryption_certificate, NULL, "got ra encryption cert"); + + /* these are always going to be true, but ensure replacement payloads are equivalent */ + ok(SecCertificateIsSelfSignedCA(ca_certificate), "self-signed ca cert"); + ok(SecCertificateGetKeyUsage(ra_encryption_certificate) & kSecKeyUsageKeyEncipherment, "can sign"); + + CFReleaseSafe(ca_certificate); + CFReleaseSafe(ra_signing_certificate); + CFReleaseSafe(ra_encryption_certificate); + CFReleaseSafe(certificates); + CFReleaseSafe(bmw_getcacert_blob); + + uint32_t key_size_in_bits = 512; + CFNumberRef key_size = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_size_in_bits); + const void *keygen_keys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits }; + const void *keygen_vals[] = { kSecAttrKeyTypeRSA, key_size }; + CFDictionaryRef parameters = CFDictionaryCreate(kCFAllocatorDefault, + keygen_keys, keygen_vals, array_size(keygen_vals), + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFRelease(key_size); + + SecKeyRef ca_publicKey = NULL, ca_privateKey = NULL; + ok_status(SecKeyGeneratePair(parameters, &ca_publicKey, &ca_privateKey), "gen key"); + SecIdentityRef ca_identity = test_cert_create_root_certificate(CFSTR("O=Foo Bar Inc.,CN=Root CA"), ca_publicKey, ca_privateKey); + CFRelease(ca_publicKey); + CFRelease(ca_privateKey); + + SecKeyRef scep_ra_publicKey = NULL, scep_ra_privateKey = NULL; + ok_status(SecKeyGeneratePair(parameters, &scep_ra_publicKey, &scep_ra_privateKey), "generate ra key pair"); + SecCertificateRef scep_ra_certificate = + test_cert_issue_certificate(ca_identity, scep_ra_publicKey, + CFSTR("O=Foo Bar Inc.,CN=SCEP RA"), 42, + kSecKeyUsageKeyEncipherment|kSecKeyUsageDigitalSignature); + ok(scep_ra_certificate, "got a ra cert"); + SecIdentityRef ra_identity = SecIdentityCreate(kCFAllocatorDefault, scep_ra_certificate, scep_ra_privateKey); + CFRelease(scep_ra_publicKey); + CFRelease(scep_ra_privateKey); + + // store encryption identity in the keychain because the decrypt function looks in there only + CFDictionaryRef identity_add = CFDictionaryCreate(NULL, + (const void **)&kSecValueRef, (const void **)&ra_identity, 1, NULL, NULL); + ok_status(SecItemAdd(identity_add, NULL), "add encryption identity to keychain"); + + SecKeyRef phone_publicKey = NULL, phone_privateKey = NULL; + ok_status(SecKeyGeneratePair(parameters, &phone_publicKey, &phone_privateKey), "generate phone key pair"); + CFArrayRef subject = test_cert_string_to_subject(CFSTR("O=Foo Bar Inc.,CN=Shoes")); + SecIdentityRef self_signed_identity = SecSCEPCreateTemporaryIdentity(phone_publicKey, phone_privateKey); + CFStringRef magic = CFSTR("magic"); + CFDictionaryRef csr_params = CFDictionaryCreate(kCFAllocatorDefault, + (const void **)&kSecCSRChallengePassword, (const void **)&magic, 1, NULL, NULL); + CFDataRef request = SecSCEPGenerateCertificateRequest(NULL, csr_params, phone_publicKey, phone_privateKey, self_signed_identity, scep_ra_certificate); + CFRelease(csr_params); + CFRelease(phone_publicKey); + CFRelease(phone_privateKey); + isnt(request, NULL, "got a request"); + CFDataRef serialno = CFDataCreate(kCFAllocatorDefault, (uint8_t*)"\001", 1); + CFDataRef pended_request = SecSCEPCertifyRequest(request, ra_identity, serialno, true); + CFRelease(serialno); + isnt(pended_request, NULL, "got a pended request (not failed)"); + CFErrorRef server_error = NULL; + CFArrayRef issued_certs = NULL; + issued_certs = SecSCEPVerifyReply(request, pended_request, scep_ra_certificate, &server_error); + CFReleaseSafe(request); + is(issued_certs, NULL, "no certs if pended"); + CFDataRef retry_get_cert_initial = NULL; + isnt(server_error, NULL, "Should have gotten PENDING error"); + CFDictionaryRef error_dict = CFErrorCopyUserInfo(server_error); + retry_get_cert_initial = SecSCEPGetCertInitial(scep_ra_certificate, subject, NULL, error_dict, self_signed_identity, scep_ra_certificate); + isnt(retry_get_cert_initial, NULL, "got retry request"); + //write_data("/var/tmp/get_cert_initial", retry_get_cert_initial); + CFRelease(subject); + + ok_status(SecItemDelete(identity_add), "delete encryption identity from keychain"); + CFReleaseSafe(identity_add); + + CFReleaseNull(parameters); + CFReleaseNull(scep_ra_certificate); + CFReleaseSafe(self_signed_identity); + CFReleaseSafe(retry_get_cert_initial); + CFReleaseSafe(server_error); + CFReleaseSafe(pended_request); + CFReleaseSafe(issued_certs); + CFReleaseSafe(error_dict); +} + +static bool test_scep_with_keys_algorithms(SecKeyRef ca_key, SecKeyRef leaf_key, CFStringRef hash_alg) { + SecCertificateRef ca_cert = NULL; + SecIdentityRef ca_identity = NULL; + NSArray *ca_rdns = nil, *leaf_rdns = nil, *issued_certs = nil; + NSDictionary *ca_parameters = nil, *leaf_parameters = nil, *ca_item_dict = nil, *leaf_item_dict = nil; + NSData *scep_request = nil, *scep_reply = nil, *serial_no = nil; + bool status = false; + + /* Generate CA cert */ + NSString *common_name = [NSString stringWithFormat:@"SCEP Test Root: %@", hash_alg]; + ca_rdns = @[ + @[@[(__bridge NSString*)kSecOidCountryName, @"US"]], + @[@[(__bridge NSString*)kSecOidOrganization, @"Apple Inc."]], + @[@[(__bridge NSString*)kSecOidCommonName, common_name]] + ]; + ca_parameters = @{ + (__bridge NSString *)kSecCMSSignHashAlgorithm: (__bridge NSString*)hash_alg, + (__bridge NSString *)kSecCSRBasicContraintsPathLen: @0, + (__bridge NSString *)kSecCertificateKeyUsage: @(kSecKeyUsageKeyCertSign | kSecKeyUsageCRLSign) + }; + ca_cert = SecGenerateSelfSignedCertificate((__bridge CFArrayRef)ca_rdns, + (__bridge CFDictionaryRef)ca_parameters, + NULL, ca_key); + require(ca_cert, out); + ca_identity = SecIdentityCreate(NULL, ca_cert, ca_key); + require(ca_identity, out); + + /* Generate leaf request - SHA-256 csr, SHA-256 CMS */ + leaf_rdns = @[ + @[@[(__bridge NSString*)kSecOidCountryName, @"US"]], + @[@[(__bridge NSString*)kSecOidOrganization, @"Apple Inc."]], + @[@[(__bridge NSString*)kSecOidCommonName, @"SCEP SHA-2 leaf"]] + ]; + leaf_parameters = @{ + (__bridge NSString*)kSecCSRChallengePassword: @"magic", + (__bridge NSString*)kSecCMSSignHashAlgorithm: (__bridge NSString*)hash_alg, + (__bridge NSString*)kSecSubjectAltName: @{ + (__bridge NSString*)kSecSubjectAltNameEmailAddress : @"test@apple.com" + }, + (__bridge NSString*)kSecCertificateKeyUsage: @(kSecKeyUsageDigitalSignature), + (__bridge NSString*)kSecCMSBulkEncryptionAlgorithm : (__bridge NSString*)kSecCMSEncryptionAlgorithmAESCBC, + }; + scep_request = CFBridgingRelease(SecSCEPGenerateCertificateRequest((__bridge CFArrayRef)leaf_rdns, + (__bridge CFDictionaryRef)leaf_parameters, + NULL, leaf_key, NULL, ca_cert)); + require(scep_request, out); + + /* Add CA identity to keychain so CMS can decrypt */ + ca_item_dict = @{ + (__bridge NSString*)kSecValueRef : (__bridge id)ca_identity, + (__bridge NSString*)kSecAttrLabel : @"SCEP CA Identity" + }; + require_noerr(SecItemAdd((__bridge CFDictionaryRef)ca_item_dict, NULL), out); + + /* Certify the request with SHA256, AES */ + uint8_t serial_no_bytes[] = { 0x12, 0x34 }; + serial_no = [NSData dataWithBytes:serial_no_bytes length:sizeof(serial_no_bytes)]; + scep_reply = CFBridgingRelease(SecSCEPCertifyRequestWithAlgorithms((__bridge CFDataRef)scep_request, ca_identity, + (__bridge CFDataRef)serial_no, false, + hash_alg, + kSecCMSEncryptionAlgorithmAESCBC)); + require(scep_reply, out); + + /* Add leaf private key to keychain so CMS can decrypt */ + leaf_item_dict = @{ + (__bridge NSString*)kSecClass : (__bridge NSString*)kSecClassKey, + (__bridge NSString*)kSecValueRef : (__bridge id)leaf_key, + (__bridge NSString*)kSecAttrApplicationLabel : @"SCEP Leaf Key" + }; + require_noerr(SecItemAdd((__bridge CFDictionaryRef)leaf_item_dict, NULL), out); + + /* Verify the reply */ + issued_certs = CFBridgingRelease(SecSCEPVerifyReply((__bridge CFDataRef)scep_request, (__bridge CFDataRef)scep_reply, ca_cert, nil)); + require(issued_certs, out); + require([issued_certs count] == 1, out); + + status = true; + +out: + /* Remove from keychain */ + if (ca_item_dict) { SecItemDelete((__bridge CFDictionaryRef)ca_item_dict); } + if (leaf_item_dict) { SecItemDelete((__bridge CFDictionaryRef)leaf_item_dict); } + CFReleaseNull(ca_cert); + CFReleaseNull(ca_identity); + return status; +} + +static void test_SCEP_algs(void) { + SecKeyRef ca_rsa_key = NULL, ca_ec_key = NULL; + SecKeyRef leaf_rsa_key = NULL, leaf_ec_key = NULL; + SecKeyRef publicKey = NULL; + NSDictionary *rsa_parameters = nil, *ec_parameters = nil; + + rsa_parameters = @{ + (__bridge NSString*)kSecAttrKeyType: (__bridge NSString*)kSecAttrKeyTypeRSA, + (__bridge NSString*)kSecAttrKeySizeInBits : @2048, + }; + ok_status(SecKeyGeneratePair((__bridge CFDictionaryRef)rsa_parameters, &publicKey, &ca_rsa_key), + "Failed to generate CA RSA key"); + CFReleaseNull(publicKey); + ok_status(SecKeyGeneratePair((__bridge CFDictionaryRef)rsa_parameters, &publicKey, &leaf_rsa_key), + "Failed to generate leaf RSA key"); + CFReleaseNull(publicKey); + + ec_parameters = @{ + (__bridge NSString*)kSecAttrKeyType: (__bridge NSString*)kSecAttrKeyTypeECSECPrimeRandom, + (__bridge NSString*)kSecAttrKeySizeInBits : @384, + }; + ok_status(SecKeyGeneratePair((__bridge CFDictionaryRef)ec_parameters, &publicKey, &ca_ec_key), + "Failed to generate CA EC key"); + CFReleaseNull(publicKey); + ok_status(SecKeyGeneratePair((__bridge CFDictionaryRef)ec_parameters, &publicKey, &leaf_ec_key), + "Failed to generate leaf EC key"); + CFReleaseNull(publicKey); + + /* Hash algorithms */ + ok(test_scep_with_keys_algorithms(ca_rsa_key, leaf_rsa_key, kSecCMSHashingAlgorithmSHA1), + "Failed to run scep test with RSA SHA-1"); + ok(test_scep_with_keys_algorithms(ca_rsa_key, leaf_rsa_key, kSecCMSHashingAlgorithmSHA256), + "Failed to run scep test with RSA SHA-256"); + ok(test_scep_with_keys_algorithms(ca_rsa_key, leaf_rsa_key, kSecCMSHashingAlgorithmSHA384), + "Failed to run scep test with RSA SHA-256"); + ok(test_scep_with_keys_algorithms(ca_rsa_key, leaf_rsa_key, kSecCMSHashingAlgorithmSHA512), + "Failed to run scep test with RSA SHA-256"); + + /* Unsupported key algorithms */ + is(test_scep_with_keys_algorithms(ca_ec_key, leaf_ec_key, kSecCMSHashingAlgorithmSHA256), false, + "Performed scep with EC ca and leaf"); + is(test_scep_with_keys_algorithms(ca_ec_key, leaf_rsa_key, kSecCMSHashingAlgorithmSHA256), false, + "Performed scep with EC ca"); + is(test_scep_with_keys_algorithms(ca_rsa_key, leaf_ec_key, kSecCMSHashingAlgorithmSHA256), false, + "Performed scep with EC leaf"); + + CFReleaseNull(ca_rsa_key); + CFReleaseNull(ca_ec_key); + CFReleaseNull(leaf_rsa_key); + CFReleaseNull(leaf_ec_key); +} + +int si_63_scep(int argc, char *const *argv) +{ + plan_tests(47); + + tests(); + test_SCEP_algs(); + + return 0; +} diff --git a/OSX/sec/Security/Regressions/secitem/si-66-smime.c b/OSX/sec/Security/Regressions/secitem/si-66-smime.c index b052146e..799b1ccb 100644 --- a/OSX/sec/Security/Regressions/secitem/si-66-smime.c +++ b/OSX/sec/Security/Regressions/secitem/si-66-smime.c @@ -2484,7 +2484,7 @@ static void tests(void) CFRelease(anchor_array); ok_status(SecTrustEvaluate(trust, &result), "evaluate trust"); - ok(result == kSecTrustResultUnspecified, "private root"); + ok(result == kSecTrustResultRecoverableTrustFailure, "private root"); #if DUMP_CERTS // debug code to save a cert chain retrieved from a SecTrustRef (written to /tmp/c[0-9].cer) @@ -2496,7 +2496,7 @@ static void tests(void) if (d) { char f[12] = { '/', 't', 'm', 'p', '/', 'c', 'n', '.', 'c', 'e', 'r', 0 }; f[6] = '0' + (idx % 10); - writeFile(f, CFDataGetBytePtr(d), CFDataGetLength(d)); + writeFile(f, CFDataGetBytePtr(d), (int)CFDataGetLength(d)); CFRelease(d); } } @@ -2523,7 +2523,7 @@ static void tests(void) CFReleaseNull(parameters); CFMutableDictionaryRef subject_alt_names = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionarySetValue(subject_alt_names, CFSTR("rfc822name"), CFSTR("xey@nl")); + CFDictionarySetValue(subject_alt_names, kSecSubjectAltNameEmailAddress, CFSTR("xey@nl")); int key_usage = kSecKeyUsageDigitalSignature | kSecKeyUsageKeyEncipherment; CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage); const void *self_key[] = { kSecCertificateKeyUsage, kSecSubjectAltName }; @@ -2819,7 +2819,7 @@ static void test_sign_no_priv(void) { CFReleaseNull(parameters); CFMutableDictionaryRef subject_alt_names = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionarySetValue(subject_alt_names, CFSTR("rfc822name"), CFSTR("xey@nl")); + CFDictionarySetValue(subject_alt_names, kSecSubjectAltNameEmailAddress, CFSTR("xey@nl")); int key_usage = kSecKeyUsageDigitalSignature | kSecKeyUsageKeyEncipherment; CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage); const void *self_key[] = { kSecCertificateKeyUsage, kSecSubjectAltName }; diff --git a/OSX/sec/Security/Regressions/secitem/si-72-syncableitems.c b/OSX/sec/Security/Regressions/secitem/si-72-syncableitems.c index f8067051..ec5cabbd 100644 --- a/OSX/sec/Security/Regressions/secitem/si-72-syncableitems.c +++ b/OSX/sec/Security/Regressions/secitem/si-72-syncableitems.c @@ -187,6 +187,9 @@ static void tests(void) CFReleaseSafe(query); } + + CFReleaseSafe(account); + CFReleaseSafe(passwordData); } int si_72_syncableitems(int argc, char * const *argv) diff --git a/OSX/sec/Security/Regressions/secitem/si-87-sectrust-name-constraints.m b/OSX/sec/Security/Regressions/secitem/si-87-sectrust-name-constraints.m index c1423458..651ea37d 100644 --- a/OSX/sec/Security/Regressions/secitem/si-87-sectrust-name-constraints.m +++ b/OSX/sec/Security/Regressions/secitem/si-87-sectrust-name-constraints.m @@ -5,6 +5,9 @@ #include #import +#import +#import + #include #include #include @@ -72,9 +75,288 @@ errOut: CFReleaseNull(trust); } +/* MARK: BetterTLS tests */ +NSString *kSecTrustTestNameConstraintsResources = @"si-87-sectrust-name-constraints"; +NSString *kSecTrustTestCertificates = @"TestCertificates"; +NSString *kSecTrustTestIPAddress = @"52.20.118.238"; +NSString *kSecTrustTestDNSAddress = @"test.nameconstraints.bettertls.com"; +NSString *kSecTrustTestID = @"id"; +NSString *kSecTrustTestDNSResult = @"dns"; +NSString *kSecTrustTestIPResult = @"ip"; +NSString *kSecTrustTestExpect = @"expect"; +NSString *kSecTrustTestExpectFailure = @"ERROR"; +NSString *kSecTrustTestExpectSuccess = @"OK"; +NSString *kSecTrustTestExpectMaybeSuccess = @"WEAK-OK"; + +static NSArray *anchors = nil; +static NSURL *tmpCertsDir = nil; + +static NSArray *getTestsArray(void) { + NSURL *testPlist = nil; + NSDictionary *testsDict = nil; + NSArray *testsArray = nil; + + testPlist = [[NSBundle mainBundle] URLForResource:@"debugging" withExtension:@"plist" + subdirectory:kSecTrustTestNameConstraintsResources]; + if (!testPlist) { + testPlist = [[NSBundle mainBundle] URLForResource:@"expects" withExtension:@"plist" + subdirectory:kSecTrustTestNameConstraintsResources]; + } + require_action_quiet(testPlist, exit, + fail("Failed to get tests plist from %@", kSecTrustTestNameConstraintsResources)); + testsDict = [NSDictionary dictionaryWithContentsOfURL:testPlist]; + require_action_quiet(testsDict, exit, fail("Failed to decode tests plist into dictionary")); + + testsArray = testsDict[@"expects"]; + require_action_quiet(testsArray, exit, fail("Failed to get expects array from test dictionary")); + require_action_quiet([testsArray isKindOfClass:[NSArray class]], exit, fail("expected array of tests")); + +exit: + return testsArray; +} + +static NSFileHandle *openFileForWriting(const char *filename) { + NSFileHandle *fileHandle = NULL; + NSURL *file = [NSURL URLWithString:[NSString stringWithCString:filename encoding:NSUTF8StringEncoding] relativeToURL:tmpCertsDir]; + int fd; + off_t off; + fd = open([file fileSystemRepresentation], O_RDWR | O_CREAT | O_TRUNC, 0644); + if (fd < 0 || (off = lseek(fd, 0, SEEK_SET)) < 0) { + fail("unable to open file for archive"); + } + if (fd >= 0) { + close(fd); + } + + NSError *error; + fileHandle = [NSFileHandle fileHandleForWritingToURL:file error:&error]; + if (!fileHandle) { + fail("unable to get file handle for %@\n\terror:%@", file, error); + } + + return fileHandle; +} + +static BOOL +extract(NSURL *archive) { + BOOL result = NO; + int r; + struct archive_entry *entry; + + struct archive *a = archive_read_new(); + archive_read_support_compression_all(a); + archive_read_support_format_tar(a); + r = archive_read_open_filename(a, [archive fileSystemRepresentation], 16384); + if (r != ARCHIVE_OK) { + fail("unable to open archive"); + goto exit; + } + + while((r = archive_read_next_header(a, &entry)) == ARCHIVE_OK) { + @autoreleasepool { + const char *filename = archive_entry_pathname(entry); + NSFileHandle *fh = openFileForWriting(filename); + ssize_t size = 0; + size_t bufsize = 4192; + uint8_t *buf = calloc(bufsize, 1); + for (;;) { + size = archive_read_data(a, buf, bufsize); + if (size < 0) { + fail("failed to read %s from archive", filename); + [fh closeFile]; + goto exit; + } + if (size == 0) { + break; + } + [fh writeData:[NSData dataWithBytes:buf length:size]]; + } + free(buf); + [fh closeFile]; + } + } + if (r != ARCHIVE_EOF) { + fail("unable to read archive header"); + } else { + result = YES; + } + +exit: + archive_read_finish(a); + return result; +} + +static BOOL untar_test_certs(void) { + NSError *error = nil; + tmpCertsDir = [[NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES] URLByAppendingPathComponent:kSecTrustTestNameConstraintsResources isDirectory:YES]; + + if (![[NSFileManager defaultManager] createDirectoryAtURL:tmpCertsDir + withIntermediateDirectories:NO + attributes:NULL + error:&error]) { + fail("unable to create temporary cert directory: %@", error); + return NO; + } + + NSURL *certs_tar = [[NSBundle mainBundle] URLForResource:kSecTrustTestCertificates withExtension:nil + subdirectory:kSecTrustTestNameConstraintsResources]; + if(!extract(certs_tar)) { + return NO; + } + + return YES; +} + +static BOOL extractLeaf(NSString *filename, NSMutableArray *certs) { + NSString *fullFilename = [NSString stringWithFormat:@"%@.cer", filename]; + NSURL *leafURL = [tmpCertsDir URLByAppendingPathComponent:fullFilename]; + if (!leafURL) { + fail("Failed to get leaf certificate for test id %@", filename); + return NO; + } + NSData *leafData = [NSData dataWithContentsOfURL:leafURL]; + if (!leafData) { + fail("Failed to get leaf certificate data for URL %@", leafURL); + return NO; + } + SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)leafData); + if (!leafData) { + fail("Failed to create leaf cert for %@", leafURL); + return NO; + } + [certs addObject:(__bridge id)cert]; + CFReleaseNull(cert); + return YES; +} + +static BOOL extractChain(NSString *filename, NSMutableArray *certs) { + NSString *fullFilename = [NSString stringWithFormat:@"%@.chain", filename]; + NSURL *chainURL = [tmpCertsDir URLByAppendingPathComponent:fullFilename]; + if (!chainURL) { + fail("Failed to get chain URL for %@", filename); + return NO; + } + NSString *chain = [NSString stringWithContentsOfURL:chainURL encoding:NSUTF8StringEncoding error:nil]; + if (!chain) { + fail("Failed to get chain for %@", chainURL); + return NO; + } + + NSString *pattern = @"-----BEGIN CERTIFICATE-----.+?-----END CERTIFICATE-----\n"; + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern + options:NSRegularExpressionDotMatchesLineSeparators|NSRegularExpressionUseUnixLineSeparators + error:nil]; + [regex enumerateMatchesInString:chain options:0 range:NSMakeRange(0, [chain length]) + usingBlock:^(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL * _Nonnull stop) { + NSString *certPEMString = [chain substringWithRange:[result range]]; + NSData *certPEMData = [certPEMString dataUsingEncoding:NSUTF8StringEncoding]; + SecCertificateRef cert = SecCertificateCreateWithPEM(NULL, (__bridge CFDataRef)certPEMData); + [certs addObject:(__bridge id)cert]; + CFReleaseNull(cert); + }]; + return YES; +} + +static BOOL getAnchor(void) { + NSURL *rootURL = [[NSBundle mainBundle] URLForResource:@"root" withExtension:@"cer" + subdirectory:kSecTrustTestNameConstraintsResources]; + if (!rootURL) { + fail("Failed to get root cert"); + return NO; + } + NSData *rootData = [NSData dataWithContentsOfURL:rootURL]; + SecCertificateRef root = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)rootData); + if (!root) { + fail("failed to create root cert"); + return NO; + } + anchors = [NSArray arrayWithObject:(__bridge id)root]; + CFReleaseNull(root); + return YES; +} + +static BOOL testTrust(NSArray *certs, NSString *hostname) { + if (!anchors && !getAnchor()) { + return NO; + } + BOOL result = NO; + SecPolicyRef policy = SecPolicyCreateSSL(true, (__bridge CFStringRef)hostname); + SecTrustRef trust = NULL; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:531900000.0]; /* November 8, 2017 at 10:00:00 PM PST */ + require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), exit, + fail("Failed to create trust ref")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), exit, + fail("Failed to add anchor")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), exit, + fail("Failed to set verify date")); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability-new" + result = SecTrustEvaluateWithError(trust, nil); +#pragma clang diagnostic pop + +exit: + CFReleaseNull(policy); + CFReleaseNull(trust); + return result; +} + +void (^runNameConstraintsTestForObject)(id, NSUInteger, BOOL *) = +^(NSDictionary *testDict, NSUInteger idx, BOOL *stop) { + @autoreleasepool { + /* Get the certificates */ + NSNumber *testNum = testDict[kSecTrustTestID]; + NSString *fileName = [NSString stringWithFormat:@"%@",testNum]; + NSMutableArray *certificates = [NSMutableArray array]; + if (!extractLeaf(fileName, certificates) || !extractChain(fileName, certificates)) { + return; + } + + /* Test DNS address */ + NSDictionary *dnsDict = testDict[kSecTrustTestDNSResult]; + BOOL result = testTrust(certificates, kSecTrustTestDNSAddress); + NSString *dnsExpectedResult = dnsDict[kSecTrustTestExpect]; + if ([dnsExpectedResult isEqualToString:kSecTrustTestExpectFailure]) { + is(result, NO, + "Test DNS id: %@. Expected %@. Got %d", testNum, dnsExpectedResult, result); + } else if ([dnsExpectedResult isEqualToString:kSecTrustTestExpectSuccess]) { + is(result, YES, + "Test DNS id: %@. Expected %@. Got %d", testNum, dnsExpectedResult, result); + } else if ([dnsExpectedResult isEqualToString:kSecTrustTestExpectMaybeSuccess]) { + /* These are "OK" but it's acceptable to reject them */ + pass(); + } + + /* Test IP address */ + NSDictionary *ipDict = testDict[kSecTrustTestIPResult]; + result = testTrust(certificates, kSecTrustTestIPAddress); + NSString *ipExpectedResult = ipDict[kSecTrustTestExpect]; + if ([ipExpectedResult isEqualToString:kSecTrustTestExpectFailure]) { + is(result, NO, + "Test IP id: %@. Expected %@. Got %d", testNum, ipExpectedResult, result); + } else if ([ipExpectedResult isEqualToString:kSecTrustTestExpectSuccess]) { + is(result, YES, + "Test IP id: %@. Expected %@. Got %d", testNum, ipExpectedResult, result); + } else if ([ipExpectedResult isEqualToString:kSecTrustTestExpectMaybeSuccess]) { + /* These are "OK" but it's acceptable to reject them */ + pass(); + } + } +}; + +static void cleanup(NSURL *tmpDir) { + [[NSFileManager defaultManager] removeItemAtURL:tmpDir error:nil]; +} + int si_87_sectrust_name_constraints(int argc, char *const *argv) { - plan_tests(2); + NSArray *testsArray = getTestsArray(); + plan_tests(2 + (int)(2 * [testsArray count])); tests(); + + if(untar_test_certs()) { + [testsArray enumerateObjectsUsingBlock:runNameConstraintsTestForObject]; + } + cleanup(tmpCertsDir); + return 0; } diff --git a/OSX/sec/Security/Regressions/secitem/si-89-cms-hash-agility.c b/OSX/sec/Security/Regressions/secitem/si-89-cms-hash-agility.c deleted file mode 100644 index 1133ca2d..00000000 --- a/OSX/sec/Security/Regressions/secitem/si-89-cms-hash-agility.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (c) 2015 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include - -#include "Security_regressions.h" - -#include "si-89-cms-hash-agility.h" - -static void ios_shim_tests(void) -{ - CFDataRef message = NULL, contentData = NULL, hashAgilityOid = NULL, hashAgilityValue = NULL; - SecPolicyRef policy = NULL; - SecTrustRef trust = NULL; - CFDictionaryRef attrs = NULL; - CFArrayRef attrValues = NULL; - CFDateRef signingTime = NULL, expectedTime = NULL; - - ok(message = CFDataCreate(NULL, valid_message, sizeof(valid_message)), "Create valid message"); - ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); - ok(policy = SecPolicyCreateBasicX509(), "Create policy"); - - /* verify the valid message and copy out attributes */ - is(SecCMSVerifyCopyDataAndAttributes(message, contentData, policy, &trust, NULL, &attrs), - errSecSuccess, "Verify valid CMS message and get attributes"); - isnt(attrs, NULL, "Copy CMS attributes"); - - /* verify we can get the parsed attribute */ - uint8_t appleHashAgilityOid[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x9, 0x1 }; - ok(hashAgilityOid = CFDataCreate(NULL, appleHashAgilityOid, sizeof(appleHashAgilityOid)), - "Create oid data"); - ok(attrValues = (CFArrayRef) CFDictionaryGetValue(attrs, hashAgilityOid), - "Get hash agility value array"); - is(CFArrayGetCount(attrValues), 1, "One attribute value"); - ok(hashAgilityValue = CFArrayGetValueAtIndex(attrValues, 0), "Get hash agility value"); - is((size_t)CFDataGetLength(hashAgilityValue), sizeof(attribute), "Verify size of parsed hash agility value"); - is(memcmp(attribute, CFDataGetBytePtr(hashAgilityValue), sizeof(attribute)), 0, - "Verify correct hash agility value"); - - attrValues = NULL; - - /*verify we can get the signing time attribute */ - ok(signingTime = (CFDateRef) CFDictionaryGetValue(attrs, kSecCMSSignDate), "Get signing time"); - ok(expectedTime = CFDateCreate(NULL, 468295000.0), "Set expected signing time"); - is(CFDateCompare(signingTime, expectedTime, NULL), 0, "Verify signing time"); - - CFReleaseNull(message); - - /* verify the invalid message */ - ok(message = CFDataCreate(NULL, invalid_message, sizeof(invalid_message)), "Create invalid message"); - is(SecCMSVerify(message, contentData, policy, &trust, NULL), errSecAuthFailed, - "Verify invalid CMS message"); - - CFReleaseNull(message); - - /* verify the valid message with no hash agility attribute */ - ok(message = CFDataCreate(NULL, valid_no_attr, sizeof(valid_no_attr)), - "Create valid message with no hash agility value"); - is(SecCMSVerifyCopyDataAndAttributes(message, contentData, policy, &trust, NULL, &attrs), - errSecSuccess, "Verify 2nd valid CMS message and get attributes"); - isnt(attrs, NULL, "Copy 2nd CMS attributes"); - - /* verify we can't get the hash agility attribute */ - is((CFArrayRef) CFDictionaryGetValue(attrs, hashAgilityOid), NULL, - "Get hash agility value array"); - - - CFReleaseNull(message); - CFReleaseNull(contentData); - CFReleaseNull(hashAgilityOid); - CFReleaseNull(expectedTime); - CFReleaseNull(policy); - CFReleaseNull(trust); - CFReleaseNull(attrs); -} - -/* MARK: macOS Shim tests */ -#include -#include - -/* encode test */ -static void encode_test(void) -{ - CMSEncoderRef encoder = NULL; - CFDataRef attributeData = NULL, message = NULL, p12Data = NULL; - CFArrayRef imported_items = NULL; - SecIdentityRef identity = NULL; - CFStringRef password = CFSTR("password"); - CFDictionaryRef options = CFDictionaryCreate(NULL, - (const void **)&kSecImportExportPassphrase, - (const void **)&password, 1, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CFDictionaryRef itemDict = NULL; - - - /* Create encoder */ - ok_status(CMSEncoderCreate(&encoder), "Create CMS encoder"); - ok_status(CMSEncoderSetSignerAlgorithm(encoder, kCMSEncoderDigestAlgorithmSHA256), - "Set digest algorithm to SHA256"); - - /* Load identity and set as signer */ - ok(p12Data = CFDataCreate(NULL, signing_identity_p12, sizeof(signing_identity_p12)), - "Create p12 data"); - ok_status(SecPKCS12Import(p12Data, options, &imported_items), - "Import identity"); - is(CFArrayGetCount(imported_items),1,"Imported 1 items"); - is(CFGetTypeID(CFArrayGetValueAtIndex(imported_items, 0)), CFDictionaryGetTypeID(), - "Got back a dictionary"); - ok(itemDict = CFArrayGetValueAtIndex(imported_items, 0), "Retreive item dictionary"); - is(CFGetTypeID(CFDictionaryGetValue(itemDict, kSecImportItemIdentity)), SecIdentityGetTypeID(), - "Got back an identity"); - ok(identity = (SecIdentityRef) CFRetainSafe(CFDictionaryGetValue(itemDict, kSecImportItemIdentity)), - "Retrieve identity"); - ok_status(CMSEncoderAddSigners(encoder, identity), "Set Signer identity"); - - /* Add signing time attribute for 3 November 2015 */ - ok_status(CMSEncoderAddSignedAttributes(encoder, kCMSAttrSigningTime), - "Set signing time flag"); - ok_status(CMSEncoderSetSigningTime(encoder, 468295000.0), "Set Signing time"); - - /* Add hash agility attribute */ - ok_status(CMSEncoderAddSignedAttributes(encoder, kCMSAttrAppleCodesigningHashAgility), - "Set hash agility flag"); - ok(attributeData = CFDataCreate(NULL, attribute, sizeof(attribute)), - "Create atttribute object"); - ok_status(CMSEncoderSetAppleCodesigningHashAgility(encoder, attributeData), - "Set hash agility data"); - - /* Load content */ - ok_status(CMSEncoderSetHasDetachedContent(encoder, true), "Set detached content"); - ok_status(CMSEncoderUpdateContent(encoder, content, sizeof(content)), "Set content"); - - /* output cms message */ - ok_status(CMSEncoderCopyEncodedContent(encoder, &message), "Finish encoding and output message"); - - /* decode message */ - CMSDecoderRef decoder = NULL; - CFDataRef contentData = NULL; - isnt(message, NULL, "Encoded message exists"); - ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); - ok_status(CMSDecoderUpdateMessage(decoder, CFDataGetBytePtr(message), CFDataGetLength(message)), - "Update decoder with CMS message"); - ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); - ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); - ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); - - - CFReleaseNull(encoder); - CFReleaseNull(p12Data); - CFReleaseNull(imported_items); - CFReleaseNull(identity); - CFReleaseNull(attributeData); - CFReleaseNull(message); - CFReleaseNull(decoder); - CFReleaseNull(contentData); -} - -static void decode_positive_test(void) -{ - CMSDecoderRef decoder = NULL; - CFDataRef contentData = NULL, attrValue = NULL; - SecPolicyRef policy = NULL; - SecTrustRef trust = NULL; - CMSSignerStatus signerStatus; - CFAbsoluteTime signingTime = 0.0; - - /* Create decoder and decode */ - ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); - ok_status(CMSDecoderUpdateMessage(decoder, valid_message, sizeof(valid_message)), - "Update decoder with CMS message"); - ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); - ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); - ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); - - /* Get signer status */ - ok(policy = SecPolicyCreateBasicX509(), "Create policy"); - ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), - "Copy Signer status"); - is(signerStatus, kCMSSignerValid, "Valid signature"); - - /* Get Hash Agility Attribute value */ - ok_status(CMSDecoderCopySignerAppleCodesigningHashAgility(decoder, 0, &attrValue), - "Copy hash agility attribute value"); - is((size_t)CFDataGetLength(attrValue), sizeof(attribute), "Decoded attribute size"); - is(memcmp(attribute, CFDataGetBytePtr(attrValue), sizeof(attribute)), 0, - "Decoded value same as input value"); - - /* Get Signing Time Attribute value */ - ok_status(CMSDecoderCopySignerSigningTime(decoder, 0, &signingTime), - "Copy signing time attribute value"); - is(signingTime, 468295000.0, "Decoded date same as input date"); - - CFReleaseNull(decoder); - CFReleaseNull(contentData); - CFReleaseNull(policy); - CFReleaseNull(trust); - CFReleaseNull(attrValue); -} - -static void decode_negative_test(void) -{ - CMSDecoderRef decoder = NULL; - CFDataRef contentData = NULL; - SecPolicyRef policy = NULL; - SecTrustRef trust = NULL; - CMSSignerStatus signerStatus; - - /* Create decoder and decode */ - ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); - ok_status(CMSDecoderUpdateMessage(decoder, invalid_message, sizeof(invalid_message)), - "Update decoder with CMS message"); - ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); - ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); - ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); - - /* Get signer status */ - ok(policy = SecPolicyCreateBasicX509(), "Create policy"); - ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), - "Copy Signer status"); - is(signerStatus, kCMSSignerInvalidSignature, "Invalid signature"); - - CFReleaseNull(decoder); - CFReleaseNull(contentData); - CFReleaseNull(policy); - CFReleaseNull(trust); -} - -static void decode_no_attr_test(void) -{ - CMSDecoderRef decoder = NULL; - CFDataRef contentData = NULL, attrValue = NULL; - SecPolicyRef policy = NULL; - SecTrustRef trust = NULL; - CMSSignerStatus signerStatus; - - /* Create decoder and decode */ - ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); - ok_status(CMSDecoderUpdateMessage(decoder, valid_no_attr, sizeof(valid_no_attr)), - "Update decoder with CMS message"); - ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); - ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); - ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); - - /* Get signer status */ - ok(policy = SecPolicyCreateBasicX509(), "Create policy"); - ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), - "Copy Signer status"); - is(signerStatus, kCMSSignerValid, "Valid signature"); - - /* Get Hash Agility Attribute value */ - ok_status(CMSDecoderCopySignerAppleCodesigningHashAgility(decoder, 0, &attrValue), - "Copy empty hash agility attribute value"); - is(attrValue, NULL, "NULL attribute value"); - - CFReleaseNull(decoder); - CFReleaseNull(contentData); - CFReleaseNull(policy); - CFReleaseNull(trust); - CFReleaseNull(attrValue); -} - -static void macos_shim_tests(void) { - encode_test(); - decode_positive_test(); - decode_negative_test(); - decode_no_attr_test(); -} - -int si_89_cms_hash_agility(int argc, char *const *argv) -{ - plan_tests(20+24+13+8+10); - - ios_shim_tests(); - macos_shim_tests(); - - return 0; -} diff --git a/OSX/sec/Security/Regressions/secitem/si-89-cms-hash-agility.h b/OSX/sec/Security/Regressions/secitem/si-89-cms-hash-agility.h index 3b245171..a52b5fb5 100644 --- a/OSX/sec/Security/Regressions/secitem/si-89-cms-hash-agility.h +++ b/OSX/sec/Security/Regressions/secitem/si-89-cms-hash-agility.h @@ -88,6 +88,14 @@ unsigned char attribute[32] = { 0x87, 0xa0, 0x4e, 0x80, 0xf4, 0xf3, 0x5d, 0xd2, 0x68, 0x08, 0x58, 0xe6 }; +/* Random data for hash agility V2 attribute */ +unsigned char _attributev2[64] = { + 0x28, 0x4f, 0x7f, 0xf5, 0xf8, 0x14, 0x80, 0xa6, 0x6b, 0x37, 0x44, 0xeb, 0xed, 0x1e, 0xf1, 0x3d, + 0x35, 0x4e, 0x02, 0x21, 0xdc, 0x26, 0x61, 0x33, 0x71, 0x57, 0x18, 0xc7, 0xdd, 0xc2, 0x50, 0xbf, + 0xfc, 0x9d, 0x6f, 0x8e, 0x8b, 0xe2, 0x3d, 0x1d, 0x41, 0xbf, 0xe6, 0xd1, 0x7a, 0xc9, 0x3f, 0xc9, + 0x4d, 0xdd, 0x38, 0x35, 0xbd, 0xdf, 0x98, 0x95, 0x0a, 0x00, 0xc6, 0x6d, 0x30, 0xe2, 0x37, 0x3b +}; + /* Valid CMS message on content with hash agility attribute */ uint8_t valid_message[] = { 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, @@ -834,4 +842,176 @@ unsigned char signing_identity_p12[4477] = { 0xfe, 0x15, 0xb1, 0x04, 0x08, 0xdd, 0xee, 0x2c, 0x8a, 0x3d, 0x65, 0x41, 0x94, 0x02, 0x02, 0x08, 0x00 }; +unsigned char _V2_valid_message[] = { + 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x80, 0x30, + 0x80, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x80, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x07, 0x01, 0x00, 0x00, 0xa0, 0x82, 0x06, 0xb4, 0x30, 0x82, 0x06, 0xb0, 0x30, 0x82, 0x04, 0x98, + 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00, 0xdd, 0x3f, 0x19, 0x90, 0xd8, 0x99, 0xba, 0x86, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, + 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, + 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, + 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, + 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x25, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x18, + 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, + 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, + 0x32, 0x39, 0x32, 0x31, 0x35, 0x35, 0x35, 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x30, 0x32, + 0x38, 0x32, 0x31, 0x35, 0x35, 0x35, 0x38, 0x5a, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, + 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, + 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x70, 0x70, 0x6c, + 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x13, 0x25, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x41, 0x72, 0x63, 0x68, 0x69, + 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x0f, 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, + 0x72, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, + 0x01, 0x00, 0xc4, 0x2a, 0x38, 0x4b, 0xdd, 0x1c, 0xc7, 0x39, 0x47, 0xba, 0xbc, 0x5d, 0xd2, 0xcc, + 0x6e, 0x9e, 0x2c, 0x81, 0x26, 0x18, 0x59, 0x18, 0xb8, 0x45, 0x0c, 0xde, 0x5b, 0xbc, 0x25, 0xa4, + 0x78, 0x0b, 0x16, 0x3d, 0x3d, 0x10, 0x34, 0x48, 0xcf, 0x1f, 0x40, 0xaa, 0x4b, 0xb5, 0xbc, 0xf0, + 0x81, 0x5e, 0xa8, 0x72, 0xed, 0x6a, 0x8c, 0xf0, 0x4a, 0x9a, 0x80, 0x09, 0x3b, 0x89, 0xed, 0xad, + 0x2b, 0xb5, 0x5b, 0x0f, 0xe4, 0x3f, 0x6b, 0xc5, 0x15, 0x33, 0x5e, 0xdd, 0xa4, 0xac, 0x2f, 0xa5, + 0x13, 0x0f, 0x3c, 0xfc, 0xd8, 0xca, 0xb8, 0x88, 0x67, 0x75, 0xc4, 0x9a, 0x4c, 0x18, 0x9a, 0x38, + 0x68, 0xaa, 0x4c, 0x94, 0x35, 0xed, 0xa4, 0x0b, 0x80, 0x2b, 0xa9, 0x4d, 0xa4, 0x57, 0x22, 0xfc, + 0xd2, 0xc3, 0x12, 0x0b, 0x8a, 0x3c, 0xd7, 0x6d, 0x8b, 0x47, 0x4f, 0x24, 0xe5, 0xea, 0x1b, 0x03, + 0x78, 0xa2, 0x12, 0x36, 0x3f, 0x92, 0x16, 0x36, 0xff, 0xc5, 0xaf, 0xc3, 0xec, 0x4b, 0x6c, 0x23, + 0x04, 0x1b, 0xa9, 0xce, 0x3a, 0xa1, 0xa5, 0xe0, 0x54, 0x13, 0x43, 0x13, 0x29, 0x95, 0x5b, 0xcb, + 0x97, 0x74, 0x01, 0xbc, 0x3c, 0xb8, 0xa1, 0xb0, 0xf3, 0x3c, 0xfa, 0x21, 0x7a, 0x89, 0x90, 0x2b, + 0x1f, 0x20, 0x3f, 0xc1, 0x22, 0xda, 0x8d, 0xa5, 0x30, 0x57, 0x6d, 0xd4, 0x40, 0x99, 0x08, 0x0d, + 0xef, 0x36, 0x16, 0xa6, 0xec, 0xcf, 0x26, 0x78, 0x7c, 0x77, 0x7e, 0x50, 0x2a, 0xe3, 0xdf, 0x28, + 0xff, 0xd0, 0xc7, 0x0e, 0x8b, 0x6b, 0x56, 0x62, 0x53, 0x37, 0x5a, 0x1a, 0x85, 0x50, 0xec, 0x6a, + 0x6b, 0x2e, 0xd1, 0x35, 0x6e, 0x5d, 0x92, 0x30, 0x39, 0x82, 0x40, 0x7b, 0x6d, 0x89, 0x5b, 0x4d, + 0x30, 0x6d, 0x2e, 0x68, 0x16, 0x24, 0x63, 0x32, 0x24, 0xdc, 0x3e, 0x5b, 0x4a, 0xc4, 0x41, 0xfc, + 0x76, 0x07, 0xe6, 0xa3, 0x1b, 0x18, 0xec, 0x59, 0xed, 0x13, 0x0b, 0x2d, 0xe9, 0x86, 0x89, 0x2c, + 0x0a, 0xb0, 0x19, 0x97, 0x4d, 0x1b, 0xfb, 0xd4, 0xef, 0x54, 0xcd, 0xe5, 0xb2, 0x22, 0x70, 0x3a, + 0x50, 0x03, 0xaa, 0xc0, 0xf8, 0xb4, 0x8e, 0x16, 0xd8, 0x2a, 0xc1, 0xd1, 0x2d, 0xa0, 0x27, 0x59, + 0x63, 0x70, 0xc3, 0x74, 0x14, 0xee, 0xde, 0xa9, 0xd9, 0x73, 0xdb, 0x16, 0x6d, 0xef, 0x7f, 0x50, + 0xb6, 0xd2, 0x54, 0x0d, 0x4d, 0x31, 0x5f, 0x23, 0x2c, 0xfd, 0x8f, 0x67, 0x7c, 0xe9, 0xaa, 0x1c, + 0x29, 0xf5, 0x83, 0x1b, 0x2b, 0x0e, 0x66, 0x0e, 0x5c, 0xfe, 0xc9, 0x38, 0xb0, 0x90, 0xfa, 0x31, + 0x4c, 0xb1, 0xef, 0xea, 0xd0, 0x47, 0x17, 0xde, 0x45, 0xc1, 0x93, 0xef, 0xba, 0xde, 0x9f, 0x69, + 0xc7, 0xa6, 0x14, 0x23, 0xb1, 0x8b, 0xaa, 0xbf, 0x61, 0x37, 0x57, 0x11, 0x6a, 0xb2, 0xf7, 0xec, + 0x52, 0x7e, 0x65, 0x80, 0xff, 0xa1, 0xa8, 0x20, 0x7e, 0x0b, 0xae, 0x21, 0xfa, 0xe8, 0x20, 0x52, + 0x93, 0xc5, 0xe9, 0x39, 0x5b, 0x8e, 0xab, 0xef, 0x86, 0xa6, 0xd8, 0x43, 0x7e, 0xa9, 0x5c, 0x6d, + 0x91, 0xd8, 0x5c, 0xa4, 0x2a, 0xed, 0x26, 0xa8, 0x1b, 0xaa, 0x3b, 0xfa, 0x86, 0x75, 0x37, 0xc6, + 0x70, 0x12, 0x2b, 0x8c, 0x55, 0x96, 0x76, 0x04, 0xf6, 0xe3, 0xf9, 0xe2, 0x0d, 0x2e, 0xe0, 0x23, + 0xdf, 0xfa, 0xe0, 0x9c, 0x11, 0xf9, 0xd4, 0x51, 0x05, 0xed, 0x2b, 0x3f, 0xa3, 0x3f, 0xa2, 0xe6, + 0x30, 0x81, 0x17, 0x00, 0x8f, 0x15, 0x91, 0xfb, 0x21, 0x62, 0xf4, 0xff, 0x93, 0x1a, 0x2e, 0xfe, + 0x1a, 0xcb, 0x93, 0x3d, 0xd4, 0x6e, 0x3a, 0xb8, 0x70, 0xdf, 0x93, 0xb4, 0x02, 0xc4, 0x8c, 0x54, + 0x92, 0xde, 0xa7, 0x32, 0x65, 0x1c, 0x85, 0x95, 0x34, 0xf8, 0x8d, 0x06, 0x5b, 0x7d, 0x72, 0x00, + 0xd8, 0x31, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xfe, 0x30, 0x81, 0xfb, 0x30, 0x1d, 0x06, + 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xee, 0x16, 0xde, 0xfd, 0x11, 0xd3, 0x88, 0xfb, + 0xef, 0xfb, 0x19, 0x23, 0x8a, 0x23, 0x85, 0x7b, 0xe8, 0x41, 0x26, 0xa1, 0x30, 0x81, 0xcb, 0x06, + 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xc3, 0x30, 0x81, 0xc0, 0x80, 0x14, 0xee, 0x16, 0xde, 0xfd, + 0x11, 0xd3, 0x88, 0xfb, 0xef, 0xfb, 0x19, 0x23, 0x8a, 0x23, 0x85, 0x7b, 0xe8, 0x41, 0x26, 0xa1, + 0xa1, 0x81, 0x9c, 0xa4, 0x81, 0x99, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, + 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x12, 0x30, 0x10, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x31, + 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, + 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x25, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x65, + 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x41, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, + 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, + 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x82, + 0x09, 0x00, 0xdd, 0x3f, 0x19, 0x90, 0xd8, 0x99, 0xba, 0x86, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, + 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x0c, 0x0f, 0x08, 0x79, + 0x6f, 0x56, 0x21, 0xdf, 0xdd, 0xf5, 0x97, 0x8d, 0xdc, 0x97, 0x06, 0xfb, 0x2e, 0xe0, 0x21, 0x60, + 0xc3, 0x02, 0xf4, 0x41, 0x79, 0x79, 0xc2, 0x23, 0x9a, 0x8a, 0x54, 0x2e, 0x66, 0xab, 0xc0, 0x21, + 0xf6, 0x9f, 0xc5, 0x2e, 0x41, 0xb8, 0xa3, 0x32, 0x9f, 0x3d, 0x4e, 0xf4, 0x83, 0xee, 0xcc, 0x60, + 0xf6, 0x82, 0x3d, 0xb4, 0xa9, 0x9d, 0xcd, 0xa0, 0x02, 0x89, 0xb0, 0x32, 0x1b, 0xb5, 0x7c, 0xf4, + 0x8f, 0xbc, 0x9b, 0x24, 0xc2, 0xe2, 0x81, 0xd6, 0x6f, 0x0e, 0x22, 0x5e, 0x50, 0xd9, 0x5b, 0x2e, + 0x89, 0xbf, 0xa4, 0xfe, 0xa8, 0xc2, 0x9a, 0xf4, 0xec, 0x70, 0x66, 0x01, 0x4b, 0x50, 0x30, 0x97, + 0x0a, 0xcc, 0x9f, 0xac, 0xe4, 0x89, 0x1c, 0x8d, 0x88, 0x0d, 0xdb, 0x21, 0xbd, 0x2f, 0x24, 0x8e, + 0x83, 0xf9, 0xe6, 0x71, 0xed, 0x71, 0x26, 0x31, 0x99, 0x9d, 0x04, 0xeb, 0x34, 0xea, 0x6d, 0x65, + 0xb8, 0x02, 0x83, 0x57, 0x78, 0x36, 0x3a, 0x0b, 0xc7, 0x41, 0x63, 0xb5, 0xf6, 0x1c, 0xd2, 0x01, + 0x86, 0x04, 0x58, 0x40, 0x3e, 0x91, 0x98, 0x39, 0x72, 0x75, 0x11, 0xca, 0x14, 0x73, 0x90, 0x34, + 0x8b, 0x21, 0xa4, 0xd0, 0xba, 0xe7, 0x33, 0x03, 0x22, 0x0f, 0x1a, 0xf7, 0x10, 0x2b, 0x69, 0x4c, + 0x73, 0xef, 0x04, 0x18, 0xf9, 0xe1, 0x11, 0xa8, 0xb8, 0x1b, 0x57, 0x0b, 0x03, 0x10, 0x1c, 0xce, + 0x13, 0xca, 0xe4, 0xde, 0x8c, 0xf4, 0xcf, 0xf5, 0xb7, 0x80, 0x3e, 0xbc, 0x1f, 0x51, 0x9b, 0x20, + 0x8c, 0xb0, 0x2d, 0x67, 0x1c, 0x84, 0x25, 0x4c, 0x8b, 0xd3, 0xa7, 0x09, 0x8e, 0x60, 0xe2, 0x99, + 0x0d, 0x10, 0x12, 0x14, 0xfc, 0x17, 0x62, 0x69, 0xcd, 0xa4, 0x64, 0xf0, 0x7e, 0xba, 0xe0, 0xc9, + 0x51, 0x78, 0xf8, 0xb4, 0x0d, 0x7d, 0xb8, 0xa0, 0xee, 0x9c, 0x9e, 0x84, 0xd5, 0xa4, 0x02, 0xe5, + 0x7a, 0x1c, 0x65, 0xe1, 0x20, 0xfb, 0x4d, 0x61, 0x7a, 0x47, 0x25, 0x06, 0x95, 0x17, 0x62, 0x60, + 0x4b, 0x0b, 0xc6, 0xca, 0xa7, 0x35, 0x8f, 0xd4, 0x63, 0x3e, 0x5e, 0x92, 0x1a, 0x08, 0x7c, 0x6b, + 0x15, 0x41, 0x95, 0x76, 0x7d, 0x39, 0x28, 0xec, 0x3e, 0x1f, 0x49, 0xd5, 0xd5, 0x89, 0xf9, 0x5f, + 0x14, 0x02, 0x2f, 0x27, 0xb0, 0x39, 0xba, 0xf7, 0x91, 0x53, 0x75, 0x77, 0xab, 0x88, 0x40, 0x1d, + 0x77, 0xaf, 0x79, 0xfd, 0xdc, 0xac, 0x99, 0x82, 0xf2, 0x46, 0x05, 0x97, 0x60, 0xef, 0x7b, 0xf5, + 0x34, 0x38, 0xbf, 0xd7, 0x42, 0x3e, 0x8b, 0x5a, 0x4a, 0x0c, 0x22, 0x7e, 0x4d, 0x4e, 0xf6, 0xf7, + 0xcc, 0x6e, 0x31, 0x33, 0x1a, 0x84, 0xbe, 0x07, 0xf7, 0xe8, 0xe2, 0x43, 0x00, 0x54, 0x4a, 0x38, + 0xda, 0x98, 0xe3, 0x84, 0xb2, 0xd0, 0x76, 0x79, 0x94, 0x11, 0x7e, 0xa8, 0xca, 0x56, 0xa0, 0xfd, + 0x4b, 0xba, 0x7c, 0x0a, 0xa4, 0x34, 0x01, 0xad, 0xf4, 0x37, 0x4f, 0x38, 0x33, 0x9f, 0x71, 0xdc, + 0xc4, 0x4c, 0x96, 0xb0, 0x8a, 0x86, 0xe5, 0x8d, 0xd2, 0x44, 0xe3, 0x18, 0xcb, 0x81, 0xa6, 0x7c, + 0xaf, 0x8e, 0xfb, 0x41, 0x6e, 0xc5, 0x82, 0xf0, 0x51, 0xb7, 0x0f, 0x23, 0x9b, 0x77, 0xed, 0x9a, + 0x06, 0x6b, 0x77, 0x7c, 0x8e, 0xc4, 0xdf, 0x50, 0xa0, 0xd2, 0x81, 0x3e, 0x65, 0xbe, 0xe5, 0x51, + 0x79, 0x93, 0x24, 0x8e, 0xb3, 0xb5, 0x25, 0x48, 0x76, 0x0e, 0x75, 0x94, 0xef, 0x9a, 0x9d, 0xc7, + 0x95, 0x08, 0xca, 0x35, 0x6b, 0x73, 0xbc, 0x4b, 0x93, 0x7a, 0x93, 0x55, 0x2d, 0xe4, 0x5f, 0xcf, + 0x11, 0x31, 0x94, 0xb2, 0x5a, 0x05, 0x80, 0xd7, 0x59, 0x79, 0x14, 0x8a, 0x2a, 0xb9, 0xd7, 0x3d, + 0x33, 0x69, 0xa9, 0xab, 0xaa, 0xb8, 0x4c, 0x73, 0xb6, 0x71, 0x2c, 0x6f, 0x31, 0x82, 0x03, 0x99, + 0x30, 0x82, 0x03, 0x95, 0x02, 0x01, 0x01, 0x30, 0x81, 0xa4, 0x30, 0x81, 0x96, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x13, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x43, 0x75, 0x70, 0x65, 0x72, 0x74, + 0x69, 0x6e, 0x6f, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, 0x41, 0x70, + 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x13, 0x25, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x45, 0x6e, 0x67, + 0x69, 0x6e, 0x65, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x41, 0x72, 0x63, + 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x0f, 0x43, 0x4d, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, + 0x6e, 0x65, 0x72, 0x02, 0x09, 0x00, 0xdd, 0x3f, 0x19, 0x90, 0xd8, 0x99, 0xba, 0x86, 0x30, 0x0d, + 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa0, 0x81, 0xc6, + 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, 0x31, 0x0b, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, 0x31, 0x0f, 0x17, 0x0d, 0x31, 0x37, 0x31, 0x30, 0x32, + 0x36, 0x30, 0x38, 0x34, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x09, 0x04, 0x31, 0x22, 0x04, 0x20, 0x30, 0x9e, 0x11, 0x91, 0x83, 0x14, 0xd8, + 0xb9, 0xd6, 0x24, 0x8e, 0x04, 0x7e, 0x31, 0xa7, 0x66, 0xf7, 0x3c, 0x96, 0xc6, 0x23, 0x60, 0x2e, + 0xec, 0x9e, 0x0c, 0xda, 0xab, 0x25, 0x58, 0x02, 0xf2, 0x30, 0x5b, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x63, 0x64, 0x09, 0x02, 0x31, 0x4e, 0x30, 0x2d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, + 0x65, 0x03, 0x04, 0x02, 0x01, 0x04, 0x20, 0xfc, 0x9d, 0x6f, 0x8e, 0x8b, 0xe2, 0x3d, 0x1d, 0x41, + 0xbf, 0xe6, 0xd1, 0x7a, 0xc9, 0x3f, 0xc9, 0x4d, 0xdd, 0x38, 0x35, 0xbd, 0xdf, 0x98, 0x95, 0x0a, + 0x00, 0xc6, 0x6d, 0x30, 0xe2, 0x37, 0x3b, 0x30, 0x1d, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, + 0x04, 0x14, 0x28, 0x4f, 0x7f, 0xf5, 0xf8, 0x14, 0x80, 0xa6, 0x6b, 0x37, 0x44, 0xeb, 0xed, 0x1e, + 0xf1, 0x3d, 0x35, 0x4e, 0x02, 0x21, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0x7c, 0x31, 0x1c, 0x96, 0xbd, 0x0a, 0xe5, + 0x47, 0xab, 0xa0, 0xb4, 0x29, 0x0f, 0x3e, 0xe7, 0x7a, 0x81, 0x87, 0x7e, 0x04, 0x30, 0xf3, 0x95, + 0xe7, 0x54, 0x68, 0xe9, 0x97, 0xae, 0xdc, 0x5a, 0x5d, 0x52, 0xc8, 0x82, 0x27, 0x3b, 0x0a, 0x7c, + 0xe1, 0x69, 0x2f, 0x46, 0x8d, 0xca, 0x77, 0xf3, 0xbf, 0x68, 0xd3, 0xda, 0xcb, 0xb3, 0x11, 0x93, + 0x81, 0x37, 0x22, 0x42, 0xbd, 0x6a, 0x55, 0x02, 0xe7, 0x85, 0x4c, 0x09, 0x5a, 0x02, 0x73, 0x98, + 0xdd, 0x7c, 0x03, 0x00, 0x53, 0xd2, 0x2e, 0x0a, 0x6f, 0x51, 0x8e, 0x95, 0x24, 0xdd, 0x32, 0x9c, + 0x4a, 0x22, 0x38, 0x7f, 0x65, 0x49, 0x17, 0xeb, 0x43, 0x0b, 0xbe, 0x8d, 0x14, 0xdc, 0xde, 0x48, + 0x74, 0x16, 0xbf, 0xe8, 0xed, 0x34, 0x67, 0x62, 0xca, 0x64, 0x57, 0xc4, 0x61, 0xf7, 0xf7, 0xfb, + 0xf2, 0xd0, 0xd1, 0xfd, 0x2e, 0x05, 0xe7, 0xd7, 0x99, 0x75, 0xa8, 0x76, 0x4e, 0xd4, 0x22, 0x67, + 0x2d, 0x34, 0xf6, 0x71, 0x48, 0x4f, 0x78, 0x8e, 0xe1, 0xb9, 0x55, 0x4d, 0x55, 0x87, 0x08, 0xc9, + 0xab, 0xbd, 0xb8, 0x87, 0x2c, 0x27, 0xef, 0x89, 0x93, 0x9c, 0xc0, 0xc1, 0xec, 0x89, 0x0f, 0xc2, + 0xe3, 0x55, 0x6a, 0x1d, 0xd9, 0x96, 0x1d, 0xa4, 0xdf, 0x50, 0x3d, 0x36, 0x25, 0x3e, 0xd4, 0x3e, + 0x1f, 0x44, 0x97, 0xe0, 0x46, 0xe7, 0xb7, 0x81, 0x7d, 0xc3, 0xd5, 0x36, 0xe7, 0x04, 0x34, 0xab, + 0x60, 0x27, 0xc9, 0x00, 0xdd, 0xfa, 0x7c, 0x32, 0x90, 0xa1, 0x62, 0xe4, 0x51, 0x8f, 0x54, 0x81, + 0xa6, 0x5c, 0xcd, 0xaf, 0x3b, 0xb7, 0x12, 0xa6, 0x87, 0x0a, 0x36, 0x5d, 0xc9, 0x77, 0xc3, 0x50, + 0xc6, 0x97, 0x14, 0x43, 0x36, 0x20, 0x6f, 0x40, 0xb3, 0x1f, 0x50, 0x87, 0x24, 0x47, 0x79, 0x93, + 0x9a, 0xc1, 0x61, 0x83, 0xae, 0xc8, 0x00, 0x56, 0x3c, 0x5b, 0x5f, 0xbb, 0x9b, 0xdf, 0x75, 0xea, + 0xc2, 0x3d, 0xf1, 0xd7, 0x26, 0xe5, 0x6b, 0xa1, 0x75, 0x01, 0x0a, 0x3f, 0xae, 0x43, 0x37, 0xdd, + 0xbf, 0x7a, 0x83, 0xa1, 0xb6, 0xc2, 0xb7, 0x2b, 0xda, 0x99, 0xa6, 0x75, 0xb8, 0xc6, 0xf0, 0xc4, + 0x6b, 0x6a, 0xe4, 0xda, 0xac, 0xab, 0x7c, 0xef, 0x6f, 0x7c, 0x73, 0xca, 0x22, 0x33, 0xdd, 0xee, + 0x05, 0xfc, 0x05, 0x90, 0xc5, 0x3f, 0xdd, 0xa6, 0x6f, 0x5b, 0x2d, 0xaf, 0x99, 0x89, 0x93, 0xf0, + 0xfa, 0xb0, 0x8e, 0xcf, 0x39, 0xf1, 0x03, 0xfe, 0x0c, 0x8a, 0x6d, 0x30, 0x6c, 0x2b, 0x67, 0x84, + 0x60, 0x2d, 0x98, 0x80, 0x6c, 0xa7, 0x3e, 0x44, 0xda, 0x44, 0x42, 0x22, 0x7d, 0xcc, 0x43, 0x1c, + 0x7a, 0x89, 0x8c, 0xa0, 0x07, 0xd0, 0x08, 0x45, 0xe0, 0x18, 0x6b, 0x58, 0xb1, 0x66, 0x49, 0x97, + 0xdd, 0xde, 0xa2, 0x73, 0xaf, 0x55, 0xdc, 0x9f, 0xe6, 0x82, 0x67, 0xdf, 0x14, 0x29, 0x90, 0x1a, + 0x00, 0xa8, 0x0a, 0x59, 0xa0, 0xef, 0x97, 0x3d, 0x09, 0x54, 0x0c, 0xe4, 0xa8, 0x3b, 0xdd, 0x08, + 0xb0, 0x9e, 0x48, 0x93, 0xa7, 0xea, 0xaa, 0xe2, 0x55, 0xca, 0x1b, 0xe8, 0xb0, 0x25, 0xa4, 0xf4, + 0x79, 0xad, 0x03, 0xe1, 0xa3, 0xb9, 0x9a, 0x27, 0x12, 0xe5, 0xe8, 0x08, 0x28, 0x36, 0xb2, 0x93, + 0x3a, 0xf8, 0x45, 0x38, 0xea, 0xd7, 0x2f, 0xa7, 0x37, 0xd1, 0xcf, 0x35, 0xef, 0xaf, 0x51, 0x76, + 0xc3, 0xf9, 0x9a, 0xc8, 0x7c, 0x17, 0x00, 0x48, 0xa0, 0x16, 0x10, 0x1c, 0x3f, 0xeb, 0xca, 0xa0, + 0xb5, 0xb7, 0x0b, 0xc1, 0xb8, 0xcf, 0x3a, 0xbd, 0xeb, 0xab, 0x1a, 0xf7, 0x00, 0x78, 0x34, 0xbd, + 0xe0, 0xfd, 0xc4, 0x8e, 0x51, 0x2e, 0x2e, 0x45, 0x18, 0x5e, 0x87, 0x33, 0xbb, 0x26, 0x71, 0x3f, + 0xad, 0x79, 0xc5, 0x60, 0x9c, 0xda, 0xc3, 0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + #endif /* si_89_cms_hash_agility_h */ diff --git a/OSX/sec/Security/Regressions/secitem/si-89-cms-hash-agility.m b/OSX/sec/Security/Regressions/secitem/si-89-cms-hash-agility.m new file mode 100644 index 00000000..dbb98096 --- /dev/null +++ b/OSX/sec/Security/Regressions/secitem/si-89-cms-hash-agility.m @@ -0,0 +1,565 @@ +/* + * Copyright (c) 2015-2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import +#include +#include +#include +#include +#include +#include + +#include "Security_regressions.h" + +#include "si-89-cms-hash-agility.h" + +static void ios_shim_tests(void) +{ + CFDataRef message = NULL, contentData = NULL, hashAgilityOid = NULL, hashAgilityValue = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CFDictionaryRef attrs = NULL; + CFArrayRef attrValues = NULL; + CFDateRef signingTime = NULL, expectedTime = NULL; + + ok(message = CFDataCreate(NULL, valid_message, sizeof(valid_message)), "Create valid message"); + ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); + ok(policy = SecPolicyCreateBasicX509(), "Create policy"); + + /* verify the valid message and copy out attributes */ + is(SecCMSVerifyCopyDataAndAttributes(message, contentData, policy, &trust, NULL, &attrs), + errSecSuccess, "Verify valid CMS message and get attributes"); + isnt(attrs, NULL, "Copy CMS attributes"); + + /* verify we can get the parsed attribute */ + uint8_t appleHashAgilityOid[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x9, 0x1 }; + ok(hashAgilityOid = CFDataCreate(NULL, appleHashAgilityOid, sizeof(appleHashAgilityOid)), + "Create oid data"); + ok(attrValues = (CFArrayRef) CFDictionaryGetValue(attrs, hashAgilityOid), + "Get hash agility value array"); + is(CFArrayGetCount(attrValues), 1, "One attribute value"); + ok(hashAgilityValue = CFArrayGetValueAtIndex(attrValues, 0), "Get hash agility value"); + is((size_t)CFDataGetLength(hashAgilityValue), sizeof(attribute), "Verify size of parsed hash agility value"); + is(memcmp(attribute, CFDataGetBytePtr(hashAgilityValue), sizeof(attribute)), 0, + "Verify correct hash agility value"); + + /* verify we can get the "cooked" parsed attribute */ + ok(hashAgilityValue = (CFDataRef)CFDictionaryGetValue(attrs, kSecCMSHashAgility), "Get cooked hash agility value"); + is((size_t)CFDataGetLength(hashAgilityValue), sizeof(attribute), "Verify size of parsed hash agility value"); + is(memcmp(attribute, CFDataGetBytePtr(hashAgilityValue), sizeof(attribute)), 0, + "Verify correct hash agility value"); + + attrValues = NULL; + + /*verify we can get the signing time attribute */ + ok(signingTime = (CFDateRef) CFDictionaryGetValue(attrs, kSecCMSSignDate), "Get signing time"); + ok(expectedTime = CFDateCreate(NULL, 468295000.0), "Set expected signing time"); + is(CFDateCompare(signingTime, expectedTime, NULL), 0, "Verify signing time"); + + CFReleaseNull(message); + + /* verify the invalid message */ + ok(message = CFDataCreate(NULL, invalid_message, sizeof(invalid_message)), "Create invalid message"); + is(SecCMSVerify(message, contentData, policy, &trust, NULL), errSecAuthFailed, + "Verify invalid CMS message"); + + CFReleaseNull(message); + + /* verify the valid message with no hash agility attribute */ + ok(message = CFDataCreate(NULL, valid_no_attr, sizeof(valid_no_attr)), + "Create valid message with no hash agility value"); + is(SecCMSVerifyCopyDataAndAttributes(message, contentData, policy, &trust, NULL, &attrs), + errSecSuccess, "Verify 2nd valid CMS message and get attributes"); + isnt(attrs, NULL, "Copy 2nd CMS attributes"); + + /* verify we can't get the hash agility attribute */ + is((CFArrayRef) CFDictionaryGetValue(attrs, hashAgilityOid), NULL, + "Get hash agility value array"); + is((CFDataRef) CFDictionaryGetValue(attrs, kSecCMSHashAgility), NULL, + "Get cooked hash agility value"); + + + CFReleaseNull(message); + CFReleaseNull(contentData); + CFReleaseNull(hashAgilityOid); + CFReleaseNull(expectedTime); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(attrs); +} + +/* MARK: macOS Shim tests */ +#include +#include + +/* encode test */ +static void encode_test(void) +{ + CMSEncoderRef encoder = NULL; + CFDataRef attributeData = NULL, message = NULL, p12Data = NULL; + CFArrayRef imported_items = NULL; + SecIdentityRef identity = NULL; + CFStringRef password = CFSTR("password"); + CFDictionaryRef options = CFDictionaryCreate(NULL, + (const void **)&kSecImportExportPassphrase, + (const void **)&password, 1, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFDictionaryRef itemDict = NULL; + + + /* Create encoder */ + ok_status(CMSEncoderCreate(&encoder), "Create CMS encoder"); + ok_status(CMSEncoderSetSignerAlgorithm(encoder, kCMSEncoderDigestAlgorithmSHA256), + "Set digest algorithm to SHA256"); + + /* Load identity and set as signer */ + ok(p12Data = CFDataCreate(NULL, signing_identity_p12, sizeof(signing_identity_p12)), + "Create p12 data"); + ok_status(SecPKCS12Import(p12Data, options, &imported_items), + "Import identity"); + is(CFArrayGetCount(imported_items),1,"Imported 1 items"); + is(CFGetTypeID(CFArrayGetValueAtIndex(imported_items, 0)), CFDictionaryGetTypeID(), + "Got back a dictionary"); + ok(itemDict = CFArrayGetValueAtIndex(imported_items, 0), "Retreive item dictionary"); + is(CFGetTypeID(CFDictionaryGetValue(itemDict, kSecImportItemIdentity)), SecIdentityGetTypeID(), + "Got back an identity"); + ok(identity = (SecIdentityRef) CFRetainSafe(CFDictionaryGetValue(itemDict, kSecImportItemIdentity)), + "Retrieve identity"); + ok_status(CMSEncoderAddSigners(encoder, identity), "Set Signer identity"); + + /* Add signing time attribute for 3 November 2015 */ + ok_status(CMSEncoderAddSignedAttributes(encoder, kCMSAttrSigningTime), + "Set signing time flag"); + ok_status(CMSEncoderSetSigningTime(encoder, 468295000.0), "Set Signing time"); + + /* Add hash agility attribute */ + ok_status(CMSEncoderAddSignedAttributes(encoder, kCMSAttrAppleCodesigningHashAgility), + "Set hash agility flag"); + ok(attributeData = CFDataCreate(NULL, attribute, sizeof(attribute)), + "Create atttribute object"); + ok_status(CMSEncoderSetAppleCodesigningHashAgility(encoder, attributeData), + "Set hash agility data"); + + /* Load content */ + ok_status(CMSEncoderSetHasDetachedContent(encoder, true), "Set detached content"); + ok_status(CMSEncoderUpdateContent(encoder, content, sizeof(content)), "Set content"); + + /* output cms message */ + ok_status(CMSEncoderCopyEncodedContent(encoder, &message), "Finish encoding and output message"); + + /* decode message */ + CMSDecoderRef decoder = NULL; + CFDataRef contentData = NULL; + isnt(message, NULL, "Encoded message exists"); + ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); + ok_status(CMSDecoderUpdateMessage(decoder, CFDataGetBytePtr(message), CFDataGetLength(message)), + "Update decoder with CMS message"); + ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); + ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + + + CFReleaseNull(encoder); + CFReleaseNull(p12Data); + CFReleaseNull(imported_items); + CFReleaseNull(identity); + CFReleaseNull(attributeData); + CFReleaseNull(message); + CFReleaseNull(decoder); + CFReleaseNull(contentData); +} + +static void decode_positive_test(void) +{ + CMSDecoderRef decoder = NULL; + CFDataRef contentData = NULL, attrValue = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CMSSignerStatus signerStatus; + CFAbsoluteTime signingTime = 0.0; + + /* Create decoder and decode */ + ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); + ok_status(CMSDecoderUpdateMessage(decoder, valid_message, sizeof(valid_message)), + "Update decoder with CMS message"); + ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); + ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + + /* Get signer status */ + ok(policy = SecPolicyCreateBasicX509(), "Create policy"); + ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), + "Copy Signer status"); + is(signerStatus, kCMSSignerValid, "Valid signature"); + + /* Get Hash Agility Attribute value */ + ok_status(CMSDecoderCopySignerAppleCodesigningHashAgility(decoder, 0, &attrValue), + "Copy hash agility attribute value"); + is((size_t)CFDataGetLength(attrValue), sizeof(attribute), "Decoded attribute size"); + is(memcmp(attribute, CFDataGetBytePtr(attrValue), sizeof(attribute)), 0, + "Decoded value same as input value"); + + /* Get Signing Time Attribute value */ + ok_status(CMSDecoderCopySignerSigningTime(decoder, 0, &signingTime), + "Copy signing time attribute value"); + is(signingTime, 468295000.0, "Decoded date same as input date"); + + CFReleaseNull(decoder); + CFReleaseNull(contentData); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(attrValue); +} + +static void decode_negative_test(void) +{ + CMSDecoderRef decoder = NULL; + CFDataRef contentData = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CMSSignerStatus signerStatus; + + /* Create decoder and decode */ + ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); + ok_status(CMSDecoderUpdateMessage(decoder, invalid_message, sizeof(invalid_message)), + "Update decoder with CMS message"); + ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); + ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + + /* Get signer status */ + ok(policy = SecPolicyCreateBasicX509(), "Create policy"); + ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), + "Copy Signer status"); + is(signerStatus, kCMSSignerInvalidSignature, "Invalid signature"); + + CFReleaseNull(decoder); + CFReleaseNull(contentData); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +static void decode_no_attr_test(void) +{ + CMSDecoderRef decoder = NULL; + CFDataRef contentData = NULL, attrValue = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CMSSignerStatus signerStatus; + + /* Create decoder and decode */ + ok_status(CMSDecoderCreate(&decoder), "Create CMS decoder"); + ok_status(CMSDecoderUpdateMessage(decoder, valid_no_attr, sizeof(valid_no_attr)), + "Update decoder with CMS message"); + ok(contentData = CFDataCreate(NULL, content, sizeof(content)), "Create detached content"); + ok_status(CMSDecoderSetDetachedContent(decoder, contentData), "Set detached content"); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + + /* Get signer status */ + ok(policy = SecPolicyCreateBasicX509(), "Create policy"); + ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), + "Copy Signer status"); + is(signerStatus, kCMSSignerValid, "Valid signature"); + + /* Get Hash Agility Attribute value */ + ok_status(CMSDecoderCopySignerAppleCodesigningHashAgility(decoder, 0, &attrValue), + "Copy empty hash agility attribute value"); + is(attrValue, NULL, "NULL attribute value"); + + CFReleaseNull(decoder); + CFReleaseNull(contentData); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(attrValue); +} + +static void macos_shim_tests(void) { + encode_test(); + decode_positive_test(); + decode_negative_test(); + decode_no_attr_test(); +} + +/* MARK: V2 Attribute testing */ +static void ios_shim_V2_tests(void) { + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CFDictionaryRef tmpAttrs = NULL; + NSMutableData *message = nil; + NSData *contentData = nil, *hashAgilityV2Oid = nil; + NSDictionary *attrs = nil, *hashAgilityValue = nil; + NSArray *attrValues = nil; + NSDate *signingTime = nil; + + message = [NSMutableData dataWithBytes:_V2_valid_message length:sizeof(_V2_valid_message)]; + contentData = [NSData dataWithBytes:content length:sizeof(content)]; + policy = SecPolicyCreateBasicX509(); + + /* verify the valid message and copy out attributes */ + is(SecCMSVerifyCopyDataAndAttributes((__bridge CFDataRef)message, (__bridge CFDataRef)contentData, policy, &trust, NULL, &tmpAttrs), + errSecSuccess, "Verify valid CMS message and get attributes"); + attrs = CFBridgingRelease(tmpAttrs); + require_string(attrs, exit, "Copy CMS attributes"); + + /* verify we can get the parsed attribute */ + uint8_t appleHashAgilityOid[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, 0x64, 0x9, 0x2 }; + hashAgilityV2Oid = [NSData dataWithBytes:appleHashAgilityOid length:sizeof(appleHashAgilityOid)]; + attrValues = attrs[hashAgilityV2Oid]; + require_string([attrValues count] == (size_t)1, exit, "One attribute value"); + require_string(hashAgilityValue = attrValues[0], exit, "Get hash agility value"); + ok([hashAgilityValue[@(SEC_OID_SHA1)] isEqualToData:[NSData dataWithBytes:_attributev2 length:20]], + "Got wrong SHA1 agility value"); + ok([hashAgilityValue[@(SEC_OID_SHA256)] isEqualToData:[NSData dataWithBytes:(_attributev2+32) length:32]], + "Got wrong SHA256 agility value"); + + /* verify we can get the "cooked" parsed attribute */ + require_string(hashAgilityValue = (NSDictionary *)attrs[(__bridge NSString*)kSecCMSHashAgilityV2], exit, + "Get cooked hash agility value"); + ok([hashAgilityValue[@(SEC_OID_SHA1)] isEqualToData:[NSData dataWithBytes:_attributev2 length:20]], + "Got wrong SHA1 agility value"); + ok([hashAgilityValue[@(SEC_OID_SHA256)] isEqualToData:[NSData dataWithBytes:(_attributev2+32) length:32]], + "Got wrong SHA256 agility value"); + + attrValues = NULL; + + /*verify we can get the signing time attribute */ + require_string(signingTime = attrs[(__bridge NSString*)kSecCMSSignDate], exit, "Failed to get signing time"); + ok([signingTime isEqualToDate:[NSDate dateWithTimeIntervalSinceReferenceDate:530700000.0]], "Got wrong signing time"); + + /* verify the invalid message */ + message = [NSMutableData dataWithBytes:_V2_valid_message length:sizeof(_V2_valid_message)]; + [message resetBytesInRange:NSMakeRange(2110, 0)]; /* reset byte in hash agility attribute */ + is(SecCMSVerify((__bridge CFDataRef)message, (__bridge CFDataRef)contentData, policy, &trust, NULL), errSecAuthFailed, + "Verify invalid CMS message"); + + /* verify the valid message with no hash agility attribute */ + message = [NSMutableData dataWithBytes:valid_no_attr length:sizeof(valid_no_attr)]; + is(SecCMSVerifyCopyDataAndAttributes((__bridge CFDataRef)message, (__bridge CFDataRef)contentData, policy, &trust, NULL, &tmpAttrs), + errSecSuccess, "Verify 2nd valid CMS message and get attributes"); + attrs = CFBridgingRelease(tmpAttrs); + isnt(attrs, NULL, "Copy 2nd CMS attributes"); + + /* verify we can't get the hash agility attribute */ + is(attrs[hashAgilityV2Oid], NULL, "Got hash agility V2 attribute"); + is(attrs[(__bridge NSString*)kSecCMSHashAgilityV2], NULL, "Got cooked hash agility V2 attribute"); + +exit: + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +/* macOS shim test - encode */ +static void encode_V2_test(void) { + CMSEncoderRef encoder = NULL; + CMSDecoderRef decoder = NULL; + NSData *p12Data = nil; + CFArrayRef tmp_imported_items = NULL; + NSArray *imported_items = nil; + SecIdentityRef identity = NULL; + CFDataRef message = NULL; + NSDictionary *attrValues = nil, *options = @{ (__bridge NSString *)kSecImportExportPassphrase : @"password" }; + + /* Create encoder */ + require_noerr_string(CMSEncoderCreate(&encoder), exit, "Failed to create CMS encoder"); + require_noerr_string(CMSEncoderSetSignerAlgorithm(encoder, kCMSEncoderDigestAlgorithmSHA256), exit, + "Failed to set digest algorithm to SHA256"); + + /* Load identity and set as signer */ + p12Data = [NSData dataWithBytes:signing_identity_p12 length:sizeof(signing_identity_p12)]; + require_noerr_string(SecPKCS12Import((__bridge CFDataRef)p12Data, (__bridge CFDictionaryRef)options, + &tmp_imported_items), exit, + "Failed to import identity"); + imported_items = CFBridgingRelease(tmp_imported_items); + require_noerr_string([imported_items count] == 0 && + [imported_items[0] isKindOfClass:[NSDictionary class]], exit, + "Wrong imported items output"); + identity = (SecIdentityRef)CFBridgingRetain(imported_items[0][(__bridge NSString*)kSecImportItemIdentity]); + require_string(identity, exit, "Failed to get identity"); + require_noerr_string(CMSEncoderAddSigners(encoder, identity), exit, "Failed to add signer identity"); + + /* Add signing time attribute for 26 October 2017 */ + require_noerr_string(CMSEncoderAddSignedAttributes(encoder, kCMSAttrSigningTime), exit, + "Failed to set signing time flag"); + require_noerr_string(CMSEncoderSetSigningTime(encoder, 530700000.0), exit, "Failed to set signing time"); + + /* Add hash agility attribute */ + attrValues = @{ @(SEC_OID_SHA1) : [NSData dataWithBytes:_attributev2 length:20], + @(SEC_OID_SHA256) : [NSData dataWithBytes:(_attributev2 + 32) length:32], + }; + ok_status(CMSEncoderAddSignedAttributes(encoder, kCMSAttrAppleCodesigningHashAgilityV2), + "Set hash agility flag"); + ok_status(CMSEncoderSetAppleCodesigningHashAgilityV2(encoder, (__bridge CFDictionaryRef)attrValues), + "Set hash agility data"); + + /* Load content */ + require_noerr_string(CMSEncoderSetHasDetachedContent(encoder, true), exit, "Failed to set detached content"); + require_noerr_string(CMSEncoderUpdateContent(encoder, content, sizeof(content)), exit, "Failed to set content"); + + /* output cms message */ + ok_status(CMSEncoderCopyEncodedContent(encoder, &message), "Finish encoding and output message"); + isnt(message, NULL, "Encoded message exists"); + + /* decode message */ + require_noerr_string(CMSDecoderCreate(&decoder), exit, "Create CMS decoder"); + require_noerr_string(CMSDecoderUpdateMessage(decoder, CFDataGetBytePtr(message), + CFDataGetLength(message)), exit, + "Update decoder with CMS message"); + require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)[NSData dataWithBytes:content + length:sizeof(content)]), + exit, "Set detached content"); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + +exit: + CFReleaseNull(encoder); + CFReleaseNull(identity); + CFReleaseNull(message); + CFReleaseNull(decoder); +} + +/* macOS shim test - decode positive */ +static void decode_V2_positive_test(void) { + CMSDecoderRef decoder = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CMSSignerStatus signerStatus; + NSData *contentData = nil; + CFDictionaryRef tmpAttrValue = NULL; + NSDictionary *attrValue = nil; + + /* Create decoder and decode */ + require_noerr_string(CMSDecoderCreate(&decoder), exit, "Failed to create CMS decoder"); + require_noerr_string(CMSDecoderUpdateMessage(decoder, _V2_valid_message, sizeof(_V2_valid_message)), exit, + "Failed to update decoder with CMS message"); + contentData = [NSData dataWithBytes:content length:sizeof(content)]; + require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit, + "Failed to set detached content"); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + + /* Get signer status */ + require_string(policy = SecPolicyCreateBasicX509(), exit, "Failed to Create policy"); + ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), + "Copy Signer status"); + is(signerStatus, kCMSSignerValid, "Valid signature"); + + /* Get Hash Agility Attribute value */ + ok_status(CMSDecoderCopySignerAppleCodesigningHashAgilityV2(decoder, 0, &tmpAttrValue), + "Copy hash agility attribute value"); + attrValue = CFBridgingRelease(tmpAttrValue); + ok([attrValue[@(SEC_OID_SHA1)] isEqualToData:[NSData dataWithBytes:_attributev2 length:20]], + "Got wrong SHA1 agility value"); + ok([attrValue[@(SEC_OID_SHA256)] isEqualToData:[NSData dataWithBytes:(_attributev2+32) length:32]], + "Got wrong SHA256 agility value"); + +exit: + CFReleaseNull(decoder); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +/* macOS shim test - decode negative */ +static void decode_V2_negative_test(void) { + CMSDecoderRef decoder = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CMSSignerStatus signerStatus; + NSData *contentData = nil; + NSMutableData *invalid_message = nil; + + /* Create decoder and decode */ + invalid_message = [NSMutableData dataWithBytes:_V2_valid_message length:sizeof(_V2_valid_message)]; + [invalid_message resetBytesInRange:NSMakeRange(2110, 1)]; /* reset byte in hash agility attribute */ + require_noerr_string(CMSDecoderCreate(&decoder), exit, "Failed to create CMS decoder"); + require_noerr_string(CMSDecoderUpdateMessage(decoder, [invalid_message bytes], [invalid_message length]), exit, + "Failed to update decoder with CMS message"); + contentData = [NSData dataWithBytes:content length:sizeof(content)]; + require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit, + "Failed to set detached content"); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + + /* Get signer status */ + require_string(policy = SecPolicyCreateBasicX509(), exit, "Failed to Create policy"); + ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), + "Copy Signer status"); + is(signerStatus, kCMSSignerInvalidSignature, "Valid signature"); + +exit: + CFReleaseNull(decoder); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +/* macOS shim test - no attribute */ +static void decodeV2_no_attr_test(void) { + CMSDecoderRef decoder = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CMSSignerStatus signerStatus; + NSData *contentData = nil; + CFDictionaryRef attrValue = NULL; + + /* Create decoder and decode */ + require_noerr_string(CMSDecoderCreate(&decoder), exit, "Failed to create CMS decoder"); + require_noerr_string(CMSDecoderUpdateMessage(decoder, valid_message, sizeof(valid_message)), exit, + "Failed to update decoder with CMS message"); + contentData = [NSData dataWithBytes:content length:sizeof(content)]; + require_noerr_string(CMSDecoderSetDetachedContent(decoder, (__bridge CFDataRef)contentData), exit, + "Failed to set detached content"); + ok_status(CMSDecoderFinalizeMessage(decoder), "Finalize decoder"); + + /* Get signer status */ + require_string(policy = SecPolicyCreateBasicX509(), exit, "Failed to Create policy"); + ok_status(CMSDecoderCopySignerStatus(decoder, 0, policy, false, &signerStatus, &trust, NULL), + "Copy Signer status"); + is(signerStatus, kCMSSignerValid, "Valid signature"); + + /* Get Hash Agility Attribute value */ + ok_status(CMSDecoderCopySignerAppleCodesigningHashAgilityV2(decoder, 0, &attrValue), + "Copy hash agility attribute value"); + is(attrValue, NULL, "NULL attribute value"); + +exit: + CFReleaseNull(decoder); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(attrValue); +} + +static void macOS_shim_V2_tests(void) { + encode_V2_test(); + decode_V2_positive_test(); + decode_V2_negative_test(); + decodeV2_no_attr_test(); +} + +int si_89_cms_hash_agility(int argc, char *const *argv) +{ + plan_tests(99); + + ios_shim_tests(); + macos_shim_tests(); + ios_shim_V2_tests(); + macOS_shim_V2_tests(); + + return 0; +} diff --git a/OSX/sec/Security/Regressions/secitem/si-95-cms-basic.c b/OSX/sec/Security/Regressions/secitem/si-95-cms-basic.c index cc305319..04a292f3 100644 --- a/OSX/sec/Security/Regressions/secitem/si-95-cms-basic.c +++ b/OSX/sec/Security/Regressions/secitem/si-95-cms-basic.c @@ -345,7 +345,6 @@ static OSStatus decrypt_please(const uint8_t *data_to_decrypt, size_t length) { status = errSecDecode, "Unable to get message contents"); /* verify the output matches expected results */ - require_action_string(sizeof(encrypted_string) == content->Length, out, status = -1, "Output size differs from expected"); require_noerr_action_string(memcmp(encrypted_string, content->Data, content->Length), out, @@ -446,7 +445,7 @@ static void encrypt_tests(SecCertificateRef certificate) { is(encrypt_please(certificate, SEC_OID_DES_EDE3_CBC, 192), errSecSuccess, "Encrypt with 3DES"); is(encrypt_please(certificate, SEC_OID_RC2_CBC, 128), - SEC_ERROR_INVALID_ALGORITHM, "Encrypt with 128-bit RC2"); + errSecDecode, "Encrypt with 128-bit RC2"); is(encrypt_please(certificate, SEC_OID_AES_128_CBC, 128), errSecSuccess, "Encrypt with 128-bit AES"); is(encrypt_please(certificate, SEC_OID_AES_192_CBC, 192), @@ -462,7 +461,7 @@ static void decrypt_tests(bool isRsa) { errSecSuccess, "Decrypt 3DES"); is(decrypt_please((isRsa) ? rsa_RC2 : ec_RC2, (isRsa) ? sizeof(rsa_RC2) : sizeof(ec_RC2)), - SEC_ERROR_INVALID_ALGORITHM, "Decrypt 128-bit RC2"); + errSecDecode, "Decrypt 128-bit RC2"); is(decrypt_please((isRsa) ? rsa_AES_128 : ec_AES_128, (isRsa) ? sizeof(rsa_AES_128) : sizeof(ec_AES_128)), errSecSuccess, "Decrypt 128-bit AES"); diff --git a/OSX/sec/Security/Regressions/secitem/si_77_SecAccessControl.c b/OSX/sec/Security/Regressions/secitem/si_77_SecAccessControl.c index 66d6339d..a5ed23cc 100644 --- a/OSX/sec/Security/Regressions/secitem/si_77_SecAccessControl.c +++ b/OSX/sec/Security/Regressions/secitem/si_77_SecAccessControl.c @@ -77,26 +77,26 @@ static void tests(void) CFReleaseNull(error); CFReleaseNull(acl); - // ACL with protection and kSecAccessControlTouchIDCurrentSet - acl = SecAccessControlCreateWithFlags(allocator, protection, kSecAccessControlTouchIDCurrentSet, &error); + // ACL with protection and kSecAccessControlBiometryCurrentSet + acl = SecAccessControlCreateWithFlags(allocator, protection, kSecAccessControlBiometryCurrentSet, &error); ok(acl != NULL, "SecAccessControlCreateWithFlags: %@", error); CFReleaseNull(error); CFReleaseNull(acl); // ACL with protection and flags - acl = SecAccessControlCreateWithFlags(allocator, protection, kSecAccessControlTouchIDAny | kSecAccessControlDevicePasscode | kSecAccessControlOr, &error); + acl = SecAccessControlCreateWithFlags(allocator, protection, kSecAccessControlBiometryAny | kSecAccessControlDevicePasscode | kSecAccessControlOr, &error); ok(acl != NULL, "SecAccessControlCreateWithFlags: %@", error); CFReleaseNull(error); CFReleaseNull(acl); // ACL with protection and flags - acl = SecAccessControlCreateWithFlags(allocator, protection, kSecAccessControlTouchIDAny | kSecAccessControlDevicePasscode | kSecAccessControlAnd, &error); + acl = SecAccessControlCreateWithFlags(allocator, protection, kSecAccessControlBiometryAny | kSecAccessControlDevicePasscode | kSecAccessControlAnd, &error); ok(acl != NULL, "SecAccessControlCreateWithFlags: %@", error); CFReleaseNull(error); CFReleaseNull(acl); // ACL with protection and flags - acl = SecAccessControlCreateWithFlags(allocator, protection, kSecAccessControlTouchIDAny | kSecAccessControlDevicePasscode | kSecAccessControlAnd | kSecAccessControlApplicationPassword, &error); + acl = SecAccessControlCreateWithFlags(allocator, protection, kSecAccessControlBiometryAny | kSecAccessControlDevicePasscode | kSecAccessControlAnd | kSecAccessControlApplicationPassword, &error); ok(acl != NULL, "SecAccessControlCreateWithFlags: %@", error); CFReleaseNull(error); CFReleaseNull(acl); @@ -114,7 +114,7 @@ static void tests(void) CFReleaseNull(acl); // negative test of ACL with protection and, kSecAccessControlUserPresence can be in combination with kSecAccessControlApplicationPassword and kSecAccessControlPrivateKeyUsage - acl = SecAccessControlCreateWithFlags(allocator, protection, kSecAccessControlUserPresence | kSecAccessControlTouchIDAny, &error); + acl = SecAccessControlCreateWithFlags(allocator, protection, kSecAccessControlUserPresence | kSecAccessControlBiometryAny, &error); ok(acl == NULL, "SecAccessControlCreateWithFlag wrong combination of flags"); CFReleaseNull(error); CFReleaseNull(acl); @@ -170,17 +170,17 @@ static void tests(void) CFUUIDRef uuid = CFUUIDCreate(allocator); CFStringRef uuidString = CFUUIDCreateString(allocator, uuid); CFDataRef uuidData = CFStringCreateExternalRepresentation(allocator, uuidString, kCFStringEncodingUTF8, 0); - SecAccessConstraintRef touchID = SecAccessConstraintCreateTouchIDCurrentSet(allocator, uuidData, uuidData); - // TouchID constraint - ok(touchID != NULL, "SecAccessConstraintCreateTouchID: %@", error); - ok(isDictionary(touchID), "SecAccessConstraintCreateTouchID"); - ok(CFDictionaryGetValue(touchID, CFSTR(kACMKeyAclConstraintBio)), "SecAccessConstraintCreateTouchID"); - CFDictionaryRef bioRef = CFDictionaryGetValue(touchID, CFSTR(kACMKeyAclConstraintBio)); - ok(isDictionary(bioRef), "SecAccessConstraintCreateTouchID"); - is(CFDictionaryGetValue(bioRef, CFSTR(kACMKeyAclParamBioCatacombUUID)), uuidData, "SecAccessConstraintCreateTouchID"); - is(CFDictionaryGetValue(bioRef, CFSTR(kACMKeyAclParamBioDatabaseHash)), uuidData, "SecAccessConstraintCreateTouchID"); + SecAccessConstraintRef biometry = SecAccessConstraintCreateBiometryCurrentSet(allocator, uuidData, uuidData); + // Biometry constraint + ok(biometry != NULL, "SecAccessConstraintCreateBiometry: %@", error); + ok(isDictionary(biometry), "SecAccessConstraintCreateBiometry"); + ok(CFDictionaryGetValue(biometry, CFSTR(kACMKeyAclConstraintBio)), "SecAccessConstraintCreateBiometry"); + CFDictionaryRef bioRef = CFDictionaryGetValue(biometry, CFSTR(kACMKeyAclConstraintBio)); + ok(isDictionary(bioRef), "SecAccessConstraintCreateBiometry"); + is(CFDictionaryGetValue(bioRef, CFSTR(kACMKeyAclParamBioCatacombUUID)), uuidData, "SecAccessConstraintCreateBiometry"); + is(CFDictionaryGetValue(bioRef, CFSTR(kACMKeyAclParamBioDatabaseHash)), uuidData, "SecAccessConstraintCreateBiometry"); CFReleaseNull(error); - CFReleaseNull(touchID); + CFReleaseNull(biometry); CFReleaseNull(uuidData); CFReleaseNull(uuidString); CFReleaseNull(uuid); @@ -188,22 +188,22 @@ static void tests(void) uuid = CFUUIDCreate(allocator); uuidString = CFUUIDCreateString(allocator, uuid); uuidData = CFStringCreateExternalRepresentation(allocator, uuidString, kCFStringEncodingUTF8, 0); - touchID = SecAccessConstraintCreateTouchIDAny(allocator, uuidData); - // TouchID constraint - ok(touchID != NULL, "SecAccessConstraintCreateTouchID: %@", error); - ok(isDictionary(touchID), "SecAccessConstraintCreateTouchID"); - ok(CFDictionaryGetValue(touchID, CFSTR(kACMKeyAclConstraintBio)), "SecAccessConstraintCreateTouchID"); - bioRef = CFDictionaryGetValue(touchID, CFSTR(kACMKeyAclConstraintBio)); - ok(isDictionary(bioRef), "SecAccessConstraintCreateTouchID"); - is(CFDictionaryGetValue(bioRef, CFSTR(kACMKeyAclParamBioCatacombUUID)), uuidData, "SecAccessConstraintCreateTouchID"); + biometry = SecAccessConstraintCreateBiometryAny(allocator, uuidData); + // Biometry constraint + ok(biometry != NULL, "SecAccessConstraintCreateBiometry: %@", error); + ok(isDictionary(biometry), "SecAccessConstraintCreateBiometry"); + ok(CFDictionaryGetValue(biometry, CFSTR(kACMKeyAclConstraintBio)), "SecAccessConstraintCreateBiometry"); + bioRef = CFDictionaryGetValue(biometry, CFSTR(kACMKeyAclConstraintBio)); + ok(isDictionary(bioRef), "SecAccessConstraintCreateBiometry"); + is(CFDictionaryGetValue(bioRef, CFSTR(kACMKeyAclParamBioCatacombUUID)), uuidData, "SecAccessConstraintCreateBiometry"); CFReleaseNull(error); - // CFReleaseNull(touchID); touchID will be used in later tests + // CFReleaseNull(biometry); biometry will be used in later tests CFReleaseNull(uuidData); CFReleaseNull(uuidString); CFReleaseNull(uuid); // KofN constraint - CFTypeRef constraints_array[] = { passcode, touchID }; + CFTypeRef constraints_array[] = { passcode, biometry }; CFArrayRef constraintsArray = CFArrayCreate(allocator, constraints_array, array_size(constraints_array), &kCFTypeArrayCallBacks); SecAccessConstraintRef kofn = SecAccessConstraintCreateKofN(allocator, 1, constraintsArray, &error); ok(kofn != NULL, "SecAccessConstraintCreateKofN: %@", error); @@ -221,14 +221,14 @@ static void tests(void) CFReleaseNull(passcode); // Add ACL constraint for operation - result = SecAccessControlAddConstraintForOperation(acl, kAKSKeyOpDecrypt, touchID, &error); + result = SecAccessControlAddConstraintForOperation(acl, kAKSKeyOpDecrypt, biometry, &error); ok(result, "SecAccessControlAddConstraintForOperation: %@", error); CFReleaseNull(error); // Get ACL operation constraint SecAccessConstraintRef constraint = SecAccessControlGetConstraint(acl, kAKSKeyOpDecrypt); - is(constraint, touchID, "SecAccessControlGetConstraint"); - CFReleaseNull(touchID); + is(constraint, biometry, "SecAccessControlGetConstraint"); + CFReleaseNull(biometry); // Add ACL constraint for operation (kCFBooleanTrue) result = SecAccessControlAddConstraintForOperation(acl, kAKSKeyOpDecrypt, kCFBooleanTrue, &error); diff --git a/OSX/sec/Security/SFKeychainControl.h b/OSX/sec/Security/SFKeychainControl.h new file mode 100644 index 00000000..0f2b7fb5 --- /dev/null +++ b/OSX/sec/Security/SFKeychainControl.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import + +@protocol SFKeychainControl + +- (void)rpcFindCorruptedItemsWithReply:(void (^)(NSArray* corruptedItems, NSError* error))reply; +- (void)rpcDeleteCorruptedItemsWithReply:(void (^)(bool success, NSError* error))reply; + +@end diff --git a/OSX/sec/Security/SecAccessControl.c b/OSX/sec/Security/SecAccessControl.c index b6141fe1..8dab3c49 100644 --- a/OSX/sec/Security/SecAccessControl.c +++ b/OSX/sec/Security/SecAccessControl.c @@ -27,10 +27,10 @@ #include #include -#include -#include -#include -#include +#include "SecAccessControl.h" +#include "SecAccessControlPriv.h" +#include "SecItem.h" +#include "SecItemPriv.h" #include #include #include @@ -90,7 +90,7 @@ SecAccessControlRef SecAccessControlCreate(CFAllocatorRef allocator, CFErrorRef access_control->dict = CFDictionaryCreateMutableForCFTypes(allocator); return access_control; } -#if TARGET_OS_IPHONE || (!RC_HIDE_J79 && !RC_HIDE_J80) + static CFDataRef _getEmptyData() { static CFMutableDataRef emptyData = NULL; static dispatch_once_t onceToken; @@ -101,7 +101,6 @@ static CFDataRef _getEmptyData() { return emptyData; } -#endif SecAccessControlRef SecAccessControlCreateWithFlags(CFAllocatorRef allocator, CFTypeRef protection, SecAccessControlCreateFlags flags, CFErrorRef *error) { @@ -115,7 +114,6 @@ SecAccessControlRef SecAccessControlCreateWithFlags(CFAllocatorRef allocator, CF goto errOut; if (flags) { -#if TARGET_OS_IPHONE || (!RC_HIDE_J79 && !RC_HIDE_J80) bool or = (flags & kSecAccessControlOr) ? true : false; bool and = (flags & kSecAccessControlAnd) ? true : false; @@ -124,16 +122,16 @@ SecAccessControlRef SecAccessControlCreateWithFlags(CFAllocatorRef allocator, CF goto errOut; } - SecAccessControlCreateFlags maskedFlags = flags & (kSecAccessControlTouchIDAny | kSecAccessControlTouchIDCurrentSet); - if (maskedFlags && maskedFlags != kSecAccessControlTouchIDAny && maskedFlags != kSecAccessControlTouchIDCurrentSet) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability-new" + + SecAccessControlCreateFlags maskedFlags = flags & (kSecAccessControlBiometryAny | kSecAccessControlBiometryCurrentSet); + if (maskedFlags && maskedFlags != kSecAccessControlBiometryAny && maskedFlags != kSecAccessControlBiometryCurrentSet) { SecError(errSecParam, error, CFSTR("only one bio constraint can be set")); goto errOut; } if (flags & kSecAccessControlUserPresence && flags & ~(kSecAccessControlUserPresence | kSecAccessControlApplicationPassword | kSecAccessControlPrivateKeyUsage)) { -#else - if (flags & kSecAccessControlUserPresence && flags != kSecAccessControlUserPresence) { -#endif SecError(errSecParam, error, CFSTR("kSecAccessControlUserPresence can be combined only with kSecAccessControlApplicationPassword and kSecAccessControlPrivateKeyUsage")); goto errOut; } @@ -152,25 +150,25 @@ SecAccessControlRef SecAccessControlCreateWithFlags(CFAllocatorRef allocator, CF CFReleaseNull(constraint); } -#if TARGET_OS_IPHONE || (!RC_HIDE_J79 && !RC_HIDE_J80) - if (flags & kSecAccessControlTouchIDAny) { - require_quiet(constraint = SecAccessConstraintCreateTouchIDAny(allocator, _getEmptyData()), errOut); + if (flags & kSecAccessControlBiometryAny) { + require_quiet(constraint = SecAccessConstraintCreateBiometryAny(allocator, _getEmptyData()), errOut); CFArrayAppendValue(constraints, constraint); CFReleaseNull(constraint); } - if (flags & kSecAccessControlTouchIDCurrentSet) { - require_quiet(constraint = SecAccessConstraintCreateTouchIDCurrentSet(allocator, _getEmptyData(), _getEmptyData()), errOut); + if (flags & kSecAccessControlBiometryCurrentSet) { + require_quiet(constraint = SecAccessConstraintCreateBiometryCurrentSet(allocator, _getEmptyData(), _getEmptyData()), errOut); CFArrayAppendValue(constraints, constraint); CFReleaseNull(constraint); } +#pragma clang diagnostic pop + if (flags & kSecAccessControlApplicationPassword) { SecAccessControlSetRequirePassword(access_control, true); } -#endif + CFIndex constraints_count = CFArrayGetCount(constraints); -#if TARGET_OS_IPHONE || (!RC_HIDE_J79 && !RC_HIDE_J80) if (constraints_count > 1) { require_quiet(constraint = SecAccessConstraintCreateValueOfKofN(allocator, or?1:constraints_count, constraints, error), errOut); if (flags & kSecAccessControlPrivateKeyUsage) { @@ -184,25 +182,18 @@ SecAccessControlRef SecAccessControlCreateWithFlags(CFAllocatorRef allocator, CF } require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDelete, kCFBooleanTrue, error), errOut); CFReleaseNull(constraint); - } else -#endif - if (constraints_count == 1) { -#if TARGET_OS_IPHONE || (!RC_HIDE_J79 && !RC_HIDE_J80) + } else if (constraints_count == 1) { if (flags & kSecAccessControlPrivateKeyUsage) { require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpSign, CFArrayGetValueAtIndex(constraints, 0), error), errOut); require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpComputeKey, CFArrayGetValueAtIndex(constraints, 0), error), errOut); require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpAttest, kCFBooleanTrue, error), errOut); } else { -#endif require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDecrypt, CFArrayGetValueAtIndex(constraints, 0), error), errOut); require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpEncrypt, kCFBooleanTrue, error), errOut); -#if TARGET_OS_IPHONE || (!RC_HIDE_J79 && !RC_HIDE_J80) } -#endif require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDelete, kCFBooleanTrue, error), errOut); } else { -#if TARGET_OS_IPHONE || (!RC_HIDE_J79 && !RC_HIDE_J80) if (flags & kSecAccessControlPrivateKeyUsage) { require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpSign, kCFBooleanTrue, error), errOut); require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpComputeKey, kCFBooleanTrue, error), errOut); @@ -210,11 +201,8 @@ SecAccessControlRef SecAccessControlCreateWithFlags(CFAllocatorRef allocator, CF require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDelete, kCFBooleanTrue, error), errOut); } else { -#endif require_quiet(SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpDefaultAcl, kCFBooleanTrue, error), errOut); -#if TARGET_OS_IPHONE || (!RC_HIDE_J79 && !RC_HIDE_J80) } -#endif } CFReleaseNull(constraints); @@ -280,14 +268,18 @@ SecAccessConstraintRef SecAccessConstraintCreatePasscode(CFAllocatorRef allocato return CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclConstraintUserPasscode), kCFBooleanTrue, NULL); } -SecAccessConstraintRef SecAccessConstraintCreateTouchIDAny(CFAllocatorRef allocator, CFDataRef catacombUUID) { +SecAccessConstraintRef SecAccessConstraintCreateBiometryAny(CFAllocatorRef allocator, CFDataRef catacombUUID) { CFMutableDictionaryRef bioDict = CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclParamBioCatacombUUID), catacombUUID, NULL); SecAccessConstraintRef constraint = CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclConstraintBio), bioDict, NULL); CFReleaseSafe(bioDict); return constraint; } -SecAccessConstraintRef SecAccessConstraintCreateTouchIDCurrentSet(CFAllocatorRef allocator, CFDataRef catacombUUID, CFDataRef bioDbHash) { +SecAccessConstraintRef SecAccessConstraintCreateTouchIDAny(CFAllocatorRef allocator, CFDataRef catacombUUID) { + return SecAccessConstraintCreateBiometryAny(allocator, catacombUUID); +} + +SecAccessConstraintRef SecAccessConstraintCreateBiometryCurrentSet(CFAllocatorRef allocator, CFDataRef catacombUUID, CFDataRef bioDbHash) { CFMutableDictionaryRef bioDict = CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclParamBioCatacombUUID), catacombUUID, NULL); CFDictionarySetValue(bioDict, CFSTR(kACMKeyAclParamBioDatabaseHash), bioDbHash); SecAccessConstraintRef constraint = CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclConstraintBio), bioDict, NULL); @@ -295,6 +287,10 @@ SecAccessConstraintRef SecAccessConstraintCreateTouchIDCurrentSet(CFAllocatorRef return constraint; } +SecAccessConstraintRef SecAccessConstraintCreateTouchIDCurrentSet(CFAllocatorRef allocator, CFDataRef catacombUUID, CFDataRef bioDbHash) { + return SecAccessConstraintCreateBiometryCurrentSet(allocator, catacombUUID, bioDbHash); +} + static SecAccessConstraintRef SecAccessConstraintCreateValueOfKofN(CFAllocatorRef allocator, size_t numRequired, CFArrayRef constraints, CFErrorRef *error) { CFNumberRef k = CFNumberCreateWithCFIndex(allocator, numRequired); CFMutableDictionaryRef kofn = CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclParamKofN), k, NULL); @@ -342,9 +338,7 @@ errOut: bool SecAccessControlAddConstraintForOperation(SecAccessControlRef access_control, CFTypeRef operation, CFTypeRef constraint, CFErrorRef *error) { CheckItemInArray(operation, ItemArray(kAKSKeyOpEncrypt, kAKSKeyOpDecrypt, -#if TARGET_OS_IPHONE || (!RC_HIDE_J79 && !RC_HIDE_J80) kAKSKeyOpSign, kAKSKeyOpAttest, kAKSKeyOpComputeKey, -#endif kAKSKeyOpSync, kAKSKeyOpDefaultAcl, kAKSKeyOpDelete), CFSTR("SecAccessControl: invalid operation")); if (!isDictionary(constraint) && !CFEqual(constraint, kCFBooleanTrue) && !CFEqual(constraint, kCFBooleanFalse) ) { diff --git a/OSX/sec/Security/SecAccessControlExports.exp-in b/OSX/sec/Security/SecAccessControlExports.exp-in index 1ace3743..f287ba95 100644 --- a/OSX/sec/Security/SecAccessControlExports.exp-in +++ b/OSX/sec/Security/SecAccessControlExports.exp-in @@ -2,6 +2,8 @@ // sec // +_SecAccessConstraintCreateBiometryAny +_SecAccessConstraintCreateBiometryCurrentSet _SecAccessConstraintCreateKofN _SecAccessConstraintCreatePasscode _SecAccessConstraintCreatePolicy diff --git a/OSX/sec/Security/SecAccessControlPriv.h b/OSX/sec/Security/SecAccessControlPriv.h index 624bb618..9a57a15a 100644 --- a/OSX/sec/Security/SecAccessControlPriv.h +++ b/OSX/sec/Security/SecAccessControlPriv.h @@ -54,11 +54,19 @@ SecAccessConstraintRef SecAccessConstraintCreatePolicy(CFAllocatorRef allocator, /*! Creates constraint which requires passcode verification. */ SecAccessConstraintRef SecAccessConstraintCreatePasscode(CFAllocatorRef allocator); -/*! Creates constraint which requires TouchID verification.*/ -SecAccessConstraintRef SecAccessConstraintCreateTouchIDAny(CFAllocatorRef allocator, CFDataRef catacombUUID); +/*! Creates constraint which requires Touch ID or Face ID verification.*/ +SecAccessConstraintRef SecAccessConstraintCreateBiometryAny(CFAllocatorRef allocator, CFDataRef catacombUUID); -/*! Creates constraint which requires TouchID verification.*/ -SecAccessConstraintRef SecAccessConstraintCreateTouchIDCurrentSet(CFAllocatorRef allocator, CFDataRef catacombUUID, CFDataRef bioDbHash); +/*! Creates constraint which requires Touch ID verification.*/ +SecAccessConstraintRef SecAccessConstraintCreateTouchIDAny(CFAllocatorRef allocator, CFDataRef catacombUUID) +API_DEPRECATED_WITH_REPLACEMENT("SecAccessConstraintCreateBiometryAny", macos(10.12.1, 10.13.4), ios(9.0, 11.3)); + +/*! Creates constraint which requires Touch ID or Face ID verification.*/ +SecAccessConstraintRef SecAccessConstraintCreateBiometryCurrentSet(CFAllocatorRef allocator, CFDataRef catacombUUID, CFDataRef bioDbHash); + +/*! Creates constraint which requires Touch ID verification.*/ +SecAccessConstraintRef SecAccessConstraintCreateTouchIDCurrentSet(CFAllocatorRef allocator, CFDataRef catacombUUID, CFDataRef bioDbHash) +API_DEPRECATED_WITH_REPLACEMENT("SecAccessConstraintCreateBiometryCurrentSet", macos(10.12.1, 10.13.4), ios(9.0, 11.3)); /*! Creates constraint composed of other constraints. @param numRequired Number of constraints required to be satisfied in order to consider overal constraint satisfied. diff --git a/OSX/sec/Security/SecCMS.c b/OSX/sec/Security/SecCMS.c index ea18169d..f9bc72ed 100644 --- a/OSX/sec/Security/SecCMS.c +++ b/OSX/sec/Security/SecCMS.c @@ -77,6 +77,7 @@ CFTypeRef kSecCMSSignedAttributes = CFSTR("kSecCMSSignedAttributes"); CFTypeRef kSecCMSSignDate = CFSTR("kSecCMSSignDate"); CFTypeRef kSecCMSAllCerts = CFSTR("kSecCMSAllCerts"); CFTypeRef kSecCMSHashAgility = CFSTR("kSecCMSHashAgility"); +CFTypeRef kSecCMSHashAgilityV2 = CFSTR("kSecCMSHashAgilityV2"); CFTypeRef kSecCMSBulkEncryptionAlgorithm = CFSTR("kSecCMSBulkEncryptionAlgorithm"); CFTypeRef kSecCMSEncryptionAlgorithmDESCBC = CFSTR("kSecCMSEncryptionAlgorithmDESCBC"); @@ -361,8 +362,7 @@ OSStatus SecCMSCreateSignedData(SecIdentityRef identity, CFDataRef data, } else if (CFEqual(kSecCMSHashingAlgorithmSHA512, algorithm_name)) { algorithm = SEC_OID_SHA512; } else { - // signing with MD5 is no longer allowed - algorithm = SEC_OID_UNKNOWN; + return errSecParam; } } @@ -513,6 +513,13 @@ static OSStatus SecCMSVerifySignedData_internal(CFDataRef message, CFDataRef det } } + CFDictionaryRef hash_agility_values = NULL; + if (errSecSuccess == SecCmsSignerInfoGetAppleCodesigningHashAgilityV2(sigd->signerInfos[0], &hash_agility_values)) { + if (hash_agility_values) { + CFDictionarySetValue(attrs, kSecCMSHashAgilityV2, hash_agility_values); + } + } + *signed_attributes = attrs; CFReleaseSafe(certs); } diff --git a/OSX/sec/Security/SecCMS.h b/OSX/sec/Security/SecCMS.h index 224dec7d..268100ca 100644 --- a/OSX/sec/Security/SecCMS.h +++ b/OSX/sec/Security/SecCMS.h @@ -45,6 +45,7 @@ extern const void * kSecCMSSignedAttributes; extern const void * kSecCMSSignDate; extern const void * kSecCMSAllCerts; extern const void * kSecCMSHashAgility; +extern const void * kSecCMSHashAgilityV2; extern const void * kSecCMSEncryptionAlgorithmDESCBC; extern const void * kSecCMSEncryptionAlgorithmAESCBC; diff --git a/OSX/sec/Security/SecCertificate.c b/OSX/sec/Security/SecCertificate.c index 007c8008..85686e09 100644 --- a/OSX/sec/Security/SecCertificate.c +++ b/OSX/sec/Security/SecCertificate.c @@ -48,7 +48,7 @@ #include #include #include -#include +#include #include "SecBasePriv.h" #include "SecRSAKey.h" #include "SecFramework.h" @@ -109,7 +109,7 @@ struct __SecCertificate { CFAbsoluteTime _notBefore; CFAbsoluteTime _notAfter; DERItem _subject; /* Sequence of RDN. */ - DERItem _subjectPublicKeyInfo; /* SPKI */ + DERItem _subjectPublicKeyInfo; /* SPKI (without tag/length) */ DERAlgorithmId _algId; /* oid and params of _pubKeyDER. */ DERItem _pubKeyDER; /* contents of bit string */ DERItem _issuerUniqueID; /* bit string, optional */ @@ -542,10 +542,10 @@ badDER: /************************************************************************/ typedef OSStatus (*parseX501NameCallback)(void *context, const DERItem *type, - const DERItem *value, CFIndex rdnIX); + const DERItem *value, CFIndex rdnIX, bool localized); static OSStatus parseRDNContent(const DERItem *rdnSetContent, void *context, - parseX501NameCallback callback) { + parseX501NameCallback callback, bool localized) { DERSequence rdn; DERReturn drtn = DERDecodeSeqContentInit(rdnSetContent, &rdn); require_noerr_quiet(drtn, badDER); @@ -560,9 +560,10 @@ static OSStatus parseRDNContent(const DERItem *rdnSetContent, void *context, &atv, sizeof(atv)); require_noerr_quiet(drtn, badDER); require_quiet(atv.type.length != 0, badDER); - OSStatus status = callback(context, &atv.type, &atv.value, rdnIX++); - if (status) + OSStatus status = callback(context, &atv.type, &atv.value, rdnIX++, localized); + if (status) { return status; + } } require_quiet(drtn == DR_EndOfSequence, badDER); @@ -572,7 +573,7 @@ badDER: } static OSStatus parseX501NameContent(const DERItem *x501NameContent, void *context, - parseX501NameCallback callback) { + parseX501NameCallback callback, bool localized) { DERSequence derSeq; DERReturn drtn = DERDecodeSeqContentInit(x501NameContent, &derSeq); require_noerr_quiet(drtn, badDER); @@ -580,9 +581,10 @@ static OSStatus parseX501NameContent(const DERItem *x501NameContent, void *conte while ((drtn = DERDecodeSeqNext(&derSeq, &currDecoded)) == DR_Success) { require_quiet(currDecoded.tag == ASN1_CONSTR_SET, badDER); OSStatus status = parseRDNContent(&currDecoded.content, context, - callback); - if (status) + callback, localized); + if (status) { return status; + } } require_quiet(drtn == DR_EndOfSequence, badDER); @@ -593,14 +595,14 @@ badDER: } static OSStatus parseX501Name(const DERItem *x501Name, void *context, - parseX501NameCallback callback) { + parseX501NameCallback callback, bool localized) { DERDecodedInfo x501NameContent; if (DERDecodeItem(x501Name, &x501NameContent) || x501NameContent.tag != ASN1_CONSTR_SEQUENCE) { return errSecInvalidCertificate; } else { return parseX501NameContent(&x501NameContent.content, context, - callback); + callback, localized); } } @@ -1242,6 +1244,11 @@ static bool SecCEPEscrowMarker(SecCertificateRef certificate, return true; } +static bool SecCEPOCSPNoCheck(SecCertificateRef certificate, + const SecCertificateExtension *extn) { + secdebug("cert", "ocsp-nocheck critical: %s", extn->critical ? "yes" : "no"); + return true; +} /* Dictionary key callback for comparing to DERItems. */ static Boolean SecDERItemEqual(const void *value1, const void *value2) { @@ -1292,7 +1299,8 @@ static void SecCertificateInitializeExtensionParsers(void) { &oidSubjectInfoAccess, &oidNetscapeCertType, &oidEntrustVersInfo, - &oidApplePolicyEscrowService + &oidApplePolicyEscrowService, + &oidOCSPNoCheck, }; static const void *extnParsers[] = { SecCEPSubjectKeyIdentifier, @@ -1314,6 +1322,7 @@ static void SecCertificateInitializeExtensionParsers(void) { SecCEPNetscapeCertType, SecCEPEntrustVersInfo, SecCEPEscrowMarker, + SecCEPOCSPNoCheck, }; sExtensionParsers = CFDictionaryCreate(kCFAllocatorDefault, extnOIDs, extnParsers, array_size(extnOIDs), @@ -1701,9 +1710,9 @@ static bool SecCertificateParse(SecCertificateRef certificate) /* Keep the SPKI around for CT */ certificate->_subjectPublicKeyInfo = tbsCert.subjectPubKey; - /* sequence we're given: encoded DERSubjPubKeyInfo - it was saved in full DER form */ + /* sequence we're given: encoded DERSubjPubKeyInfo */ DERSubjPubKeyInfo pubKeyInfo; - drtn = DERParseSequence(&tbsCert.subjectPubKey, + drtn = DERParseSequenceContent(&tbsCert.subjectPubKey, DERNumSubjPubKeyInfoItemSpecs, DERSubjPubKeyInfoItemSpecs, &pubKeyInfo, sizeof(pubKeyInfo)); require_noerr_quiet(drtn, badCert); @@ -2081,38 +2090,47 @@ CFStringRef SecDERItemCopyOIDDecimalRepresentation(CFAllocatorRef allocator, return result; } -static CFStringRef copyLocalizedOidDescription(CFAllocatorRef allocator, - const DERItem *oid) { - if (oid->length == 0) { - return SecCopyCertString(SEC_NULL_KEY); +static CFStringRef copyOidDescription(CFAllocatorRef allocator, + const DERItem *oid, bool localized) { + if (!oid || oid->length == 0) { + return (localized) ? SecCopyCertString(SEC_NULL_KEY) : SEC_NULL_KEY; + } + + CFStringRef name = SecDERItemCopyOIDDecimalRepresentation(allocator, oid); + if (!localized) { + return name; } /* Build the key we use to lookup the localized OID description. */ CFMutableStringRef oidKey = CFStringCreateMutable(allocator, oid->length * 3 + 5); CFStringAppendFormat(oidKey, NULL, CFSTR("06 %02lX"), oid->length); - DERSize ix; - for (ix = 0; ix < oid->length; ++ix) + for (DERSize ix = 0; ix < oid->length; ++ix) { CFStringAppendFormat(oidKey, NULL, CFSTR(" %02X"), oid->data[ix]); - - CFStringRef name = SecFrameworkCopyLocalizedString(oidKey, CFSTR("OID")); - if (CFEqual(oidKey, name)) { - CFRelease(name); - name = SecDERItemCopyOIDDecimalRepresentation(allocator, oid); + } + CFStringRef locname = SecFrameworkCopyLocalizedString(oidKey, CFSTR("OID")); + if (locname && !CFEqual(oidKey, locname)) { + /* Found localized description string, so use it instead of OID. */ + CFReleaseSafe(name); + name = locname; + } else { + CFReleaseSafe(locname); } CFRelease(oidKey); return name; } -/* Return the ipAddress as a dotted quad for ipv4 or as 8 colon separated - 4 digit hex strings for ipv6. Return NULL if the passed in IP doesn't - have a length of exactly 4 or 16 octects. */ +/* Return the ipAddress as a dotted quad for ipv4, or as 8 colon separated + 4 digit hex strings for ipv6. Return NULL if the provided IP doesn't + have a length of exactly 4 or 16 octets. +*/ static CFStringRef copyIPAddressContentDescription(CFAllocatorRef allocator, const DERItem *ip) { - /* @@@ This is the IP Address as an OCTECT STRING. For IPv4 it's - 4 octects addr, or 8 octects, addr/mask for ipv6 it's - 16 octects addr, or 32 octects addr/mask. */ + /* This is the IP Address as an OCTET STRING. + For IPv4 it's 4 octets addr, or 8 octets, addr/mask. + For IPv6 it's 16 octets addr, or 32 octets addr/mask. + */ CFStringRef value = NULL; if (ip->length == 4) { value = CFStringCreateWithFormat(allocator, NULL, @@ -2132,13 +2150,16 @@ static CFStringRef copyIPAddressContentDescription(CFAllocatorRef allocator, } void appendProperty(CFMutableArrayRef properties, CFStringRef propertyType, - CFStringRef label, CFStringRef localizedLabel, CFTypeRef value) { + CFStringRef label, CFStringRef localizedLabel, CFTypeRef value, + bool localized) { CFDictionaryRef property; if (label) { - CFStringRef ll; - if (localizedLabel) { - ll = NULL; - } else { + CFStringRef ll = NULL; + if (!localized) { + /* use unlocalized label, overriding localizedLabel */ + ll = localizedLabel = (CFStringRef) CFRetainSafe(label); + } else if (!localizedLabel) { + /* copy localized label for unlocalized label */ ll = localizedLabel = SecCopyCertString(label); } const void *all_keys[4]; @@ -2367,11 +2388,12 @@ __attribute__((__nonnull__)) static bool derDateGetAbsoluteTime(const DERItem *d } static void appendDataProperty(CFMutableArrayRef properties, - CFStringRef label, CFStringRef localizedLabel, const DERItem *der_data) { + CFStringRef label, CFStringRef localizedLabel, const DERItem *der_data, + bool localized) { CFDataRef data = CFDataCreate(CFGetAllocator(properties), der_data->data, der_data->length); appendProperty(properties, kSecPropertyTypeData, label, localizedLabel, - data); + data, localized); CFRelease(data); } @@ -2379,150 +2401,163 @@ static void appendRelabeledProperty(CFMutableArrayRef properties, CFStringRef label, CFStringRef localizedLabel, const DERItem *der_data, - CFStringRef labelFormat) { + CFStringRef labelFormat, + bool localized) { CFStringRef newLabel = CFStringCreateWithFormat(CFGetAllocator(properties), NULL, labelFormat, label); - CFStringRef ll; - if (localizedLabel) { - ll = NULL; + CFStringRef ll = NULL; + CFStringRef localizedLabelFormat = NULL; + if (!localized) { + /* use provided label and format strings; do not localize */ + ll = localizedLabel = (CFStringRef) CFRetainSafe(label); + localizedLabelFormat = (CFStringRef) CFRetainSafe(labelFormat); } else { - ll = localizedLabel = SecCopyCertString(label); + if (!localizedLabel) { + /* copy localized label for provided label */ + ll = localizedLabel = SecCopyCertString(label); + } + /* copy localized format for provided format */ + localizedLabelFormat = SecCopyCertString(labelFormat); } - CFStringRef localizedLabelFormat = SecCopyCertString(labelFormat); + CFStringRef newLocalizedLabel = CFStringCreateWithFormat(CFGetAllocator(properties), NULL, localizedLabelFormat, localizedLabel); CFReleaseSafe(ll); CFReleaseSafe(localizedLabelFormat); - appendDataProperty(properties, newLabel, newLocalizedLabel, der_data); + appendDataProperty(properties, newLabel, newLocalizedLabel, der_data, localized); CFReleaseSafe(newLabel); CFReleaseSafe(newLocalizedLabel); } static void appendUnparsedProperty(CFMutableArrayRef properties, - CFStringRef label, CFStringRef localizedLabel, const DERItem *der_data) { + CFStringRef label, CFStringRef localizedLabel, + const DERItem *der_data, bool localized) { appendRelabeledProperty(properties, label, localizedLabel, der_data, - SEC_UNPARSED_KEY); + SEC_UNPARSED_KEY, localized); } static void appendInvalidProperty(CFMutableArrayRef properties, - CFStringRef label, const DERItem *der_data) { - appendRelabeledProperty(properties, label, NULL, der_data, SEC_INVALID_KEY); + CFStringRef label, const DERItem *der_data, bool localized) { + appendRelabeledProperty(properties, label, NULL, der_data, + SEC_INVALID_KEY, localized); } static void appendDateContentProperty(CFMutableArrayRef properties, CFStringRef label, DERTag tag, - const DERItem *dateContent) { + const DERItem *dateContent, bool localized) { CFAbsoluteTime absTime; if (!derDateContentGetAbsoluteTime(tag, dateContent, &absTime)) { - /* Date decode failure insert hex bytes instead. */ - return appendInvalidProperty(properties, label, dateContent); + /* Date decode failure; insert hex bytes instead. */ + return appendInvalidProperty(properties, label, dateContent, localized); } CFDateRef date = CFDateCreate(CFGetAllocator(properties), absTime); - appendProperty(properties, kSecPropertyTypeDate, label, NULL, date); + appendProperty(properties, kSecPropertyTypeDate, label, NULL, date, localized); CFRelease(date); } static void appendDateProperty(CFMutableArrayRef properties, - CFStringRef label, CFAbsoluteTime absTime) { + CFStringRef label, CFAbsoluteTime absTime, bool localized) { CFDateRef date = CFDateCreate(CFGetAllocator(properties), absTime); - appendProperty(properties, kSecPropertyTypeDate, label, NULL, date); + appendProperty(properties, kSecPropertyTypeDate, label, NULL, date, localized); CFRelease(date); } static void appendValidityPeriodProperty(CFMutableArrayRef parent, CFStringRef label, - SecCertificateRef certificate) { + SecCertificateRef certificate, bool localized) { CFAllocatorRef allocator = CFGetAllocator(parent); CFMutableArrayRef properties = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); appendDateProperty(properties, SEC_NOT_VALID_BEFORE_KEY, - certificate->_notBefore); + certificate->_notBefore, localized); appendDateProperty(properties, SEC_NOT_VALID_AFTER_KEY, - certificate->_notAfter); + certificate->_notAfter, localized); - appendProperty(parent, kSecPropertyTypeSection, label, NULL, properties); + appendProperty(parent, kSecPropertyTypeSection, label, NULL, properties, localized); CFReleaseNull(properties); } static void appendIPAddressContentProperty(CFMutableArrayRef properties, - CFStringRef label, const DERItem *ip) { + CFStringRef label, const DERItem *ip, bool localized) { CFStringRef value = copyIPAddressContentDescription(CFGetAllocator(properties), ip); if (value) { - appendProperty(properties, kSecPropertyTypeString, label, NULL, value); + appendProperty(properties, kSecPropertyTypeString, label, NULL, value, localized); CFRelease(value); } else { - appendUnparsedProperty(properties, label, NULL, ip); + appendUnparsedProperty(properties, label, NULL, ip, localized); } } static void appendURLContentProperty(CFMutableArrayRef properties, - CFStringRef label, const DERItem *urlContent) { + CFStringRef label, const DERItem *urlContent, bool localized) { CFURLRef url = CFURLCreateWithBytes(CFGetAllocator(properties), urlContent->data, urlContent->length, kCFStringEncodingASCII, NULL); if (url) { - appendProperty(properties, kSecPropertyTypeURL, label, NULL, url); + appendProperty(properties, kSecPropertyTypeURL, label, NULL, url, localized); CFRelease(url); } else { - appendInvalidProperty(properties, label, urlContent); + appendInvalidProperty(properties, label, urlContent, localized); } } static void appendURLProperty(CFMutableArrayRef properties, - CFStringRef label, const DERItem *url) { + CFStringRef label, const DERItem *url, bool localized) { DERDecodedInfo decoded; DERReturn drtn; drtn = DERDecodeItem(url, &decoded); if (drtn || decoded.tag != ASN1_IA5_STRING) { - appendInvalidProperty(properties, label, url); + appendInvalidProperty(properties, label, url, localized); } else { - appendURLContentProperty(properties, label, &decoded.content); + appendURLContentProperty(properties, label, &decoded.content, localized); } } static void appendOIDProperty(CFMutableArrayRef properties, - CFStringRef label, CFStringRef llabel, const DERItem *oid) { + CFStringRef label, CFStringRef llabel, const DERItem *oid, bool localized) { CFStringRef oid_string = - copyLocalizedOidDescription(CFGetAllocator(properties), oid); + copyOidDescription(CFGetAllocator(properties), oid, localized); appendProperty(properties, kSecPropertyTypeString, label, llabel, - oid_string); + oid_string, localized); CFRelease(oid_string); } static void appendAlgorithmProperty(CFMutableArrayRef properties, - CFStringRef label, const DERAlgorithmId *algorithm) { + CFStringRef label, const DERAlgorithmId *algorithm, bool localized) { CFMutableArrayRef alg_props = CFArrayCreateMutable(CFGetAllocator(properties), 0, &kCFTypeArrayCallBacks); - appendOIDProperty(alg_props, SEC_ALGORITHM_KEY, NULL, &algorithm->oid); + appendOIDProperty(alg_props, SEC_ALGORITHM_KEY, NULL, + &algorithm->oid, localized); if (algorithm->params.length) { if (algorithm->params.length == 2 && algorithm->params.data[0] == ASN1_NULL && algorithm->params.data[1] == 0) { CFStringRef value = SecCopyCertString(SEC_NONE_KEY); appendProperty(alg_props, kSecPropertyTypeString, - SEC_PARAMETERS_KEY, NULL, value); + SEC_PARAMETERS_KEY, NULL, value, localized); CFRelease(value); } else { appendUnparsedProperty(alg_props, SEC_PARAMETERS_KEY, NULL, - &algorithm->params); + &algorithm->params, localized); } } - appendProperty(properties, kSecPropertyTypeSection, label, NULL, alg_props); + appendProperty(properties, kSecPropertyTypeSection, label, NULL, + alg_props, localized); CFRelease(alg_props); } static void appendPublicKeyProperty(CFMutableArrayRef parent, CFStringRef label, - SecCertificateRef certificate) { + SecCertificateRef certificate, bool localized) { CFAllocatorRef allocator = CFGetAllocator(parent); CFMutableArrayRef properties = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); /* Public key algorithm. */ appendAlgorithmProperty(properties, SEC_PUBLIC_KEY_ALG_KEY, - &certificate->_algId); + &certificate->_algId, localized); /* Public Key Size */ #if TARGET_OS_IPHONE @@ -2536,7 +2571,7 @@ static void appendPublicKeyProperty(CFMutableArrayRef parent, CFStringRef label, CFSTR("%ld"), (sizeInBytes*8)); if (sizeInBitsString) { appendProperty(properties, kSecPropertyTypeString, SEC_PUBLIC_KEY_SIZE_KEY, - NULL, sizeInBitsString); + NULL, sizeInBitsString, localized); } CFReleaseNull(sizeInBitsString); } @@ -2545,42 +2580,46 @@ static void appendPublicKeyProperty(CFMutableArrayRef parent, CFStringRef label, /* Consider breaking down an RSA public key into modulus and exponent? */ appendDataProperty(properties, SEC_PUBLIC_KEY_DATA_KEY, NULL, - &certificate->_pubKeyDER); + &certificate->_pubKeyDER, localized); - appendProperty(parent, kSecPropertyTypeSection, label, NULL, properties); + appendProperty(parent, kSecPropertyTypeSection, label, NULL, + properties, localized); CFReleaseNull(properties); } static void appendSignatureProperty(CFMutableArrayRef parent, CFStringRef label, - SecCertificateRef certificate) { + SecCertificateRef certificate, bool localized) { CFAllocatorRef allocator = CFGetAllocator(parent); CFMutableArrayRef properties = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); appendAlgorithmProperty(properties, SEC_SIGNATURE_ALGORITHM_KEY, - &certificate->_tbsSigAlg); + &certificate->_tbsSigAlg, localized); appendDataProperty(properties, SEC_SIGNATURE_DATA_KEY, NULL, - &certificate->_signature); + &certificate->_signature, localized); - appendProperty(parent, kSecPropertyTypeSection, label, NULL, properties); + appendProperty(parent, kSecPropertyTypeSection, label, NULL, + properties, localized); CFReleaseNull(properties); } -static void appendFingerprintsProperty(CFMutableArrayRef parent, CFStringRef label, SecCertificateRef certificate) { +static void appendFingerprintsProperty(CFMutableArrayRef parent, CFStringRef label, + SecCertificateRef certificate, bool localized) { CFAllocatorRef allocator = CFGetAllocator(parent); CFMutableArrayRef properties = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); CFDataRef sha256Fingerprint = SecCertificateCopySHA256Digest(certificate); if (sha256Fingerprint) { appendProperty(properties, kSecPropertyTypeData, SEC_SHA2_FINGERPRINT_KEY, - NULL, sha256Fingerprint); + NULL, sha256Fingerprint, localized); } CFReleaseNull(sha256Fingerprint); appendProperty(properties, kSecPropertyTypeData, SEC_SHA1_FINGERPRINT_KEY, - NULL, SecCertificateGetSHA1Digest(certificate)); + NULL, SecCertificateGetSHA1Digest(certificate), localized); - appendProperty(parent, kSecPropertyTypeSection, label, NULL, properties); + appendProperty(parent, kSecPropertyTypeSection, label, NULL, + properties, localized); CFReleaseNull(properties); } @@ -2598,14 +2637,17 @@ static CFStringRef copyHexDescription(CFAllocatorRef allocator, return string; } -/* Returns a (localized) blob string. */ static CFStringRef copyBlobString(CFAllocatorRef allocator, - CFStringRef blobType, CFStringRef quanta, const DERItem *blob) { - CFStringRef localizedBlobType = SecCopyCertString(blobType); - CFStringRef localizedQuanta = SecCopyCertString(quanta); + CFStringRef blobType, CFStringRef quanta, + const DERItem *blob, bool localized) { + CFStringRef localizedBlobType = (localized) ? + SecCopyCertString(blobType) : (CFStringRef) CFRetainSafe(blobType); + CFStringRef localizedQuanta = (localized) ? + SecCopyCertString(quanta) : (CFStringRef) CFRetainSafe(quanta); /* "format string for encoded field data (e.g. Sequence; 128 bytes; " "data = 00 00 ...)" */ - CFStringRef blobFormat = SecCopyCertString(SEC_BLOB_KEY); + CFStringRef blobFormat = (localized) ? + SecCopyCertString(SEC_BLOB_KEY) : SEC_BLOB_KEY; CFStringRef hex = copyHexDescription(allocator, blob); CFStringRef result = CFStringCreateWithFormat(allocator, NULL, blobFormat, localizedBlobType, blob->length, localizedQuanta, hex); @@ -2658,7 +2700,8 @@ static CFStringRef copyContentString(CFAllocatorRef allocator, */ /* Return the given numeric data as a string: decimal up to 64 bits, - hex otherwise. */ + hex otherwise. +*/ static CFStringRef copyIntegerContentDescription(CFAllocatorRef allocator, const DERItem *integer) { uint64_t value = 0; @@ -2676,7 +2719,7 @@ static CFStringRef copyIntegerContentDescription(CFAllocatorRef allocator, } static CFStringRef copyDERThingContentDescription(CFAllocatorRef allocator, - DERTag tag, const DERItem *derThing, bool printableOnly) { + DERTag tag, const DERItem *derThing, bool printableOnly, bool localized) { if (!derThing) { return NULL; } switch(tag) { case ASN1_INTEGER: @@ -2698,26 +2741,27 @@ static CFStringRef copyDERThingContentDescription(CFAllocatorRef allocator, case ASN1_OCTET_STRING: return printableOnly ? NULL : copyBlobString(allocator, SEC_BYTE_STRING_KEY, SEC_BYTES_KEY, - derThing); - //return copyBlobString(BYTE_STRING_STR, BYTES_STR, derThing); + derThing, localized); case ASN1_BIT_STRING: return printableOnly ? NULL : copyBlobString(allocator, SEC_BIT_STRING_KEY, SEC_BITS_KEY, - derThing); + derThing, localized); case ASN1_CONSTR_SEQUENCE: return printableOnly ? NULL : copyBlobString(allocator, SEC_SEQUENCE_KEY, SEC_BYTES_KEY, - derThing); + derThing, localized); case ASN1_CONSTR_SET: return printableOnly ? NULL : - copyBlobString(allocator, SEC_SET_KEY, SEC_BYTES_KEY, derThing); + copyBlobString(allocator, SEC_SET_KEY, SEC_BYTES_KEY, + derThing, localized); case ASN1_OBJECT_ID: - return printableOnly ? NULL : copyLocalizedOidDescription(allocator, derThing); + return printableOnly ? NULL : copyOidDescription(allocator, derThing, localized); default: if (printableOnly) { return NULL; } else { - CFStringRef fmt = SecCopyCertString(SEC_NOT_DISPLAYED_KEY); + CFStringRef fmt = (localized) ? + SecCopyCertString(SEC_NOT_DISPLAYED_KEY) : SEC_NOT_DISPLAYED_KEY; if (!fmt) { return NULL; } CFStringRef result = CFStringCreateWithFormat(allocator, NULL, fmt, (unsigned long)tag, (unsigned long)derThing->length); @@ -2728,7 +2772,7 @@ static CFStringRef copyDERThingContentDescription(CFAllocatorRef allocator, } static CFStringRef copyDERThingDescription(CFAllocatorRef allocator, - const DERItem *derThing, bool printableOnly) { + const DERItem *derThing, bool printableOnly, bool localized) { DERDecodedInfo decoded; DERReturn drtn; @@ -2739,23 +2783,25 @@ static CFStringRef copyDERThingDescription(CFAllocatorRef allocator, return printableOnly ? NULL : copyHexDescription(allocator, derThing); } else { return copyDERThingContentDescription(allocator, decoded.tag, - &decoded.content, false); + &decoded.content, false, localized); } } static void appendDERThingProperty(CFMutableArrayRef properties, - CFStringRef label, CFStringRef localizedLabel, const DERItem *derThing) { + CFStringRef label, CFStringRef localizedLabel, + const DERItem *derThing, bool localized) { CFStringRef value = copyDERThingDescription(CFGetAllocator(properties), - derThing, false); + derThing, false, localized); if (value) { appendProperty(properties, kSecPropertyTypeString, label, localizedLabel, - value); + value, localized); } CFReleaseSafe(value); } static OSStatus appendRDNProperty(void *context, const DERItem *rdnType, - const DERItem *rdnValue, CFIndex rdnIX) { + const DERItem *rdnValue, CFIndex rdnIX, + bool localized) { CFMutableArrayRef properties = (CFMutableArrayRef)context; if (rdnIX > 0) { /* If there is more than one value pair we create a subsection for the @@ -2773,7 +2819,7 @@ static OSStatus appendRDNProperty(void *context, const DERItem *rdnType, CFArrayAppendValue(rdn_props, lastValue); CFArrayRemoveValueAtIndex(properties, lastIX); appendProperty(properties, kSecPropertyTypeSection, NULL, NULL, - rdn_props); + rdn_props, localized); properties = rdn_props; // rdn_props is now retained by the original properties array CFReleaseSafe(rdn_props); @@ -2788,25 +2834,28 @@ static OSStatus appendRDNProperty(void *context, const DERItem *rdnType, } /* Finally we append the new rdn value to the property array. */ - CFStringRef label = SecDERItemCopyOIDDecimalRepresentation(CFGetAllocator(properties), - rdnType); - CFStringRef localizedLabel = - copyLocalizedOidDescription(CFGetAllocator(properties), rdnType); - appendDERThingProperty(properties, label, localizedLabel, rdnValue); + CFStringRef label = + SecDERItemCopyOIDDecimalRepresentation(CFGetAllocator(properties), + rdnType); + CFStringRef localizedLabel = copyOidDescription(CFGetAllocator(properties), + rdnType, localized); + appendDERThingProperty(properties, label, localizedLabel, + rdnValue, localized); CFReleaseSafe(label); CFReleaseSafe(localizedLabel); return errSecSuccess; } static CFArrayRef createPropertiesForRDNContent(CFAllocatorRef allocator, - const DERItem *rdnSetContent) { + const DERItem *rdnSetContent, bool localized) { CFMutableArrayRef properties = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); OSStatus status = parseRDNContent(rdnSetContent, properties, - appendRDNProperty); + appendRDNProperty, localized); if (status) { CFArrayRemoveAllValues(properties); - appendInvalidProperty(properties, SEC_RDN_KEY, rdnSetContent); + appendInvalidProperty(properties, SEC_RDN_KEY, rdnSetContent, + localized); } return properties; @@ -2831,68 +2880,75 @@ static CFArrayRef createPropertiesForRDNContent(CFAllocatorRef allocator, */ static CFArrayRef createPropertiesForX501NameContent(CFAllocatorRef allocator, - const DERItem *x501NameContent) { + const DERItem *x501NameContent, bool localized) { CFMutableArrayRef properties = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); OSStatus status = parseX501NameContent(x501NameContent, properties, - appendRDNProperty); + appendRDNProperty, localized); if (status) { CFArrayRemoveAllValues(properties); - appendInvalidProperty(properties, SEC_X501_NAME_KEY, x501NameContent); + appendInvalidProperty(properties, SEC_X501_NAME_KEY, + x501NameContent, localized); } return properties; } static CFArrayRef createPropertiesForX501Name(CFAllocatorRef allocator, - const DERItem *x501Name) { + const DERItem *x501Name, bool localized) { CFMutableArrayRef properties = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); - OSStatus status = parseX501Name(x501Name, properties, appendRDNProperty); + OSStatus status = parseX501Name(x501Name, properties, appendRDNProperty, localized); if (status) { CFArrayRemoveAllValues(properties); - appendInvalidProperty(properties, SEC_X501_NAME_KEY, x501Name); + appendInvalidProperty(properties, SEC_X501_NAME_KEY, + x501Name, localized); } return properties; } static void appendIntegerProperty(CFMutableArrayRef properties, - CFStringRef label, const DERItem *integer) { + CFStringRef label, const DERItem *integer, bool localized) { CFStringRef string = copyIntegerContentDescription( CFGetAllocator(properties), integer); - appendProperty(properties, kSecPropertyTypeString, label, NULL, string); + appendProperty(properties, kSecPropertyTypeString, label, NULL, + string, localized); CFRelease(string); } static void appendBoolProperty(CFMutableArrayRef properties, - CFStringRef label, bool boolean) { - CFStringRef value = SecCopyCertString(boolean ? SEC_YES_KEY : SEC_NO_KEY); - appendProperty(properties, kSecPropertyTypeString, label, NULL, value); + CFStringRef label, bool boolean, bool localized) { + CFStringRef key = (boolean) ? SEC_YES_KEY : SEC_NO_KEY; + CFStringRef value = (localized) ? SecCopyCertString(key) : key; + appendProperty(properties, kSecPropertyTypeString, label, NULL, + value, localized); CFRelease(value); } static void appendBooleanProperty(CFMutableArrayRef properties, - CFStringRef label, const DERItem *boolean, bool defaultValue) { + CFStringRef label, const DERItem *boolean, + bool defaultValue, bool localized) { bool result; DERReturn drtn = DERParseBooleanWithDefault(boolean, defaultValue, &result); if (drtn) { /* Couldn't parse boolean; dump the raw unparsed data as hex. */ - appendInvalidProperty(properties, label, boolean); + appendInvalidProperty(properties, label, boolean, localized); } else { - appendBoolProperty(properties, label, result); + appendBoolProperty(properties, label, result, localized); } } static void appendSerialNumberProperty(CFMutableArrayRef parent, CFStringRef label, - DERItem *serialNum) { + DERItem *serialNum, bool localized) { CFAllocatorRef allocator = CFGetAllocator(parent); CFMutableArrayRef properties = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); if (serialNum->length) { appendIntegerProperty(properties, SEC_SERIAL_NUMBER_KEY, - serialNum); - appendProperty(parent, kSecPropertyTypeSection, label, NULL, properties); + serialNum, localized); + appendProperty(parent, kSecPropertyTypeSection, label, NULL, + properties, localized); } CFReleaseNull(properties); @@ -2900,7 +2956,8 @@ static void appendSerialNumberProperty(CFMutableArrayRef parent, CFStringRef lab static void appendBitStringContentNames(CFMutableArrayRef properties, CFStringRef label, const DERItem *bitStringContent, - const CFStringRef *names, CFIndex namesCount) { + const CFStringRef *names, CFIndex namesCount, + bool localized) { DERSize len = bitStringContent->length - 1; require_quiet(len == 1 || len == 2, badDER); DERByte numUnusedBits = bitStringContent->data[0]; @@ -2916,7 +2973,8 @@ static void appendBitStringContentNames(CFMutableArrayRef properties, mask = 0x80; } uint_fast16_t ix; - CFStringRef fmt = SecCopyCertString(SEC_STRING_LIST_KEY); + CFStringRef fmt = (localized) ? + SecCopyCertString(SEC_STRING_LIST_KEY) : SEC_STRING_LIST_KEY; CFStringRef string = NULL; for (ix = 0; ix < bits; ++ix) { if (value & mask) { @@ -2935,29 +2993,30 @@ static void appendBitStringContentNames(CFMutableArrayRef properties, } CFRelease(fmt); appendProperty(properties, kSecPropertyTypeString, label, NULL, - string ? string : CFSTR("")); + string ? string : CFSTR(""), localized); CFReleaseSafe(string); return; badDER: - appendInvalidProperty(properties, label, bitStringContent); + appendInvalidProperty(properties, label, bitStringContent, localized); } static void appendBitStringNames(CFMutableArrayRef properties, CFStringRef label, const DERItem *bitString, - const CFStringRef *names, CFIndex namesCount) { + const CFStringRef *names, CFIndex namesCount, + bool localized) { DERDecodedInfo bitStringContent; DERReturn drtn = DERDecodeItem(bitString, &bitStringContent); require_noerr_quiet(drtn, badDER); require_quiet(bitStringContent.tag == ASN1_BIT_STRING, badDER); appendBitStringContentNames(properties, label, &bitStringContent.content, - names, namesCount); + names, namesCount, localized); return; badDER: - appendInvalidProperty(properties, label, bitString); + appendInvalidProperty(properties, label, bitString, localized); } static void appendKeyUsage(CFMutableArrayRef properties, - const DERItem *extnValue) { + const DERItem *extnValue, bool localized) { static const CFStringRef usageNames[] = { SEC_DIGITAL_SIGNATURE_KEY, SEC_NON_REPUDIATION_KEY, @@ -2970,40 +3029,42 @@ static void appendKeyUsage(CFMutableArrayRef properties, SEC_DECIPHER_ONLY_KEY }; appendBitStringNames(properties, SEC_USAGE_KEY, extnValue, - usageNames, array_size(usageNames)); + usageNames, array_size(usageNames), localized); } static void appendPrivateKeyUsagePeriod(CFMutableArrayRef properties, - const DERItem *extnValue) { + const DERItem *extnValue, bool localized) { DERPrivateKeyUsagePeriod pkup; - DERReturn drtn = DERParseSequence(extnValue, + DERReturn drtn = DERParseSequence(extnValue, DERNumPrivateKeyUsagePeriodItemSpecs, DERPrivateKeyUsagePeriodItemSpecs, &pkup, sizeof(pkup)); - require_noerr_quiet(drtn, badDER); + require_noerr_quiet(drtn, badDER); if (pkup.notBefore.length) { appendDateContentProperty(properties, SEC_NOT_VALID_BEFORE_KEY, - ASN1_GENERALIZED_TIME, &pkup.notBefore); + ASN1_GENERALIZED_TIME, &pkup.notBefore, localized); } if (pkup.notAfter.length) { appendDateContentProperty(properties, SEC_NOT_VALID_AFTER_KEY, - ASN1_GENERALIZED_TIME, &pkup.notAfter); + ASN1_GENERALIZED_TIME, &pkup.notAfter, localized); } return; badDER: - appendInvalidProperty(properties, SEC_PRIVATE_KU_PERIOD_KEY, extnValue); + appendInvalidProperty(properties, SEC_PRIVATE_KU_PERIOD_KEY, + extnValue, localized); } static void appendStringContentProperty(CFMutableArrayRef properties, - CFStringRef label, const DERItem *stringContent, - CFStringEncoding encoding) { + CFStringRef label, const DERItem *stringContent, + CFStringEncoding encoding, bool localized) { CFStringRef string = CFStringCreateWithBytes(CFGetAllocator(properties), - stringContent->data, stringContent->length, encoding, FALSE); + stringContent->data, stringContent->length, encoding, FALSE); if (string) { - appendProperty(properties, kSecPropertyTypeString, label, NULL, string); + appendProperty(properties, kSecPropertyTypeString, label, NULL, + string, localized); CFRelease(string); - } else { - appendInvalidProperty(properties, label, stringContent); - } + } else { + appendInvalidProperty(properties, label, stringContent, localized); + } } /* @@ -3012,7 +3073,7 @@ static void appendStringContentProperty(CFMutableArrayRef properties, value [0] EXPLICIT ANY DEFINED BY type-id } */ static void appendOtherNameContentProperty(CFMutableArrayRef properties, - const DERItem *otherNameContent) { + const DERItem *otherNameContent, bool localized) { DEROtherName on; DERReturn drtn = DERParseSequenceContent(otherNameContent, DERNumOtherNameItemSpecs, DEROtherNameItemSpecs, @@ -3022,20 +3083,23 @@ static void appendOtherNameContentProperty(CFMutableArrayRef properties, CFStringRef label = SecDERItemCopyOIDDecimalRepresentation(allocator, &on.typeIdentifier); CFStringRef localizedLabel = - copyLocalizedOidDescription(allocator, &on.typeIdentifier); - CFStringRef value_string = copyDERThingDescription(allocator, &on.value, false); - if (value_string) + copyOidDescription(allocator, &on.typeIdentifier, localized); + CFStringRef value_string = copyDERThingDescription(allocator, &on.value, + false, localized); + if (value_string) { appendProperty(properties, kSecPropertyTypeString, label, - localizedLabel, value_string); - else - appendUnparsedProperty(properties, label, localizedLabel, &on.value); - + localizedLabel, value_string, localized); + } else { + appendUnparsedProperty(properties, label, localizedLabel, + &on.value, localized); + } CFReleaseSafe(value_string); CFReleaseSafe(label); CFReleaseSafe(localizedLabel); return; badDER: - appendInvalidProperty(properties, SEC_OTHER_NAME_KEY, otherNameContent); + appendInvalidProperty(properties, SEC_OTHER_NAME_KEY, + otherNameContent, localized); } /* @@ -3055,54 +3119,55 @@ badDER: partyName [1] DirectoryString } */ static bool appendGeneralNameContentProperty(CFMutableArrayRef properties, - DERTag tag, const DERItem *generalName) { + DERTag tag, const DERItem *generalName, bool localized) { switch (tag) { case ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0: - appendOtherNameContentProperty(properties, generalName); + appendOtherNameContentProperty(properties, generalName, localized); break; case ASN1_CONTEXT_SPECIFIC | 1: /* IA5String. */ appendStringContentProperty(properties, SEC_EMAIL_ADDRESS_KEY, - generalName, kCFStringEncodingASCII); + generalName, kCFStringEncodingASCII, localized); break; case ASN1_CONTEXT_SPECIFIC | 2: /* IA5String. */ appendStringContentProperty(properties, SEC_DNS_NAME_KEY, generalName, - kCFStringEncodingASCII); + kCFStringEncodingASCII, localized); break; case ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3: appendUnparsedProperty(properties, SEC_X400_ADDRESS_KEY, NULL, - generalName); + generalName, localized); break; case ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 4: { CFArrayRef directory_plist = createPropertiesForX501Name(CFGetAllocator(properties), - generalName); + generalName, localized); appendProperty(properties, kSecPropertyTypeSection, - SEC_DIRECTORY_NAME_KEY, NULL, directory_plist); + SEC_DIRECTORY_NAME_KEY, NULL, directory_plist, localized); CFRelease(directory_plist); break; } case ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 5: appendUnparsedProperty(properties, SEC_EDI_PARTY_NAME_KEY, NULL, - generalName); + generalName, localized); break; case ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 6: /* Technically I don't think this is valid, but there are certs out in the wild that use a constructed IA5String. In particular the VeriSign Time Stamping Authority CA.cer does this. */ - appendURLProperty(properties, SEC_URI_KEY, generalName); + appendURLProperty(properties, SEC_URI_KEY, generalName, localized); break; case ASN1_CONTEXT_SPECIFIC | 6: - appendURLContentProperty(properties, SEC_URI_KEY, generalName); + appendURLContentProperty(properties, SEC_URI_KEY, generalName, localized); break; case ASN1_CONTEXT_SPECIFIC | 7: appendIPAddressContentProperty(properties, SEC_IP_ADDRESS_KEY, - generalName); + generalName, localized); break; case ASN1_CONTEXT_SPECIFIC | 8: - appendOIDProperty(properties, SEC_REGISTERED_ID_KEY, NULL, generalName); + appendOIDProperty(properties, SEC_REGISTERED_ID_KEY, NULL, + generalName, localized); break; default: goto badDER; @@ -3114,15 +3179,16 @@ badDER: } static void appendGeneralNameProperty(CFMutableArrayRef properties, - const DERItem *generalName) { + const DERItem *generalName, bool localized) { DERDecodedInfo generalNameContent; DERReturn drtn = DERDecodeItem(generalName, &generalNameContent); require_noerr_quiet(drtn, badDER); if (appendGeneralNameContentProperty(properties, generalNameContent.tag, - &generalNameContent.content)) + &generalNameContent.content, localized)) return; badDER: - appendInvalidProperty(properties, SEC_GENERAL_NAME_KEY, generalName); + appendInvalidProperty(properties, SEC_GENERAL_NAME_KEY, + generalName, localized); } @@ -3130,7 +3196,7 @@ badDER: GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName */ static void appendGeneralNamesContent(CFMutableArrayRef properties, - const DERItem *generalNamesContent) { + const DERItem *generalNamesContent, bool localized) { DERSequence gnSeq; DERReturn drtn = DERDecodeSeqContentInit(generalNamesContent, &gnSeq); require_noerr_quiet(drtn, badDER); @@ -3138,7 +3204,7 @@ static void appendGeneralNamesContent(CFMutableArrayRef properties, while ((drtn = DERDecodeSeqNext(&gnSeq, &generalNameContent)) == DR_Success) { if (!appendGeneralNameContentProperty(properties, - generalNameContent.tag, &generalNameContent.content)) { + generalNameContent.tag, &generalNameContent.content, localized)) { goto badDER; } } @@ -3146,29 +3212,31 @@ static void appendGeneralNamesContent(CFMutableArrayRef properties, return; badDER: appendInvalidProperty(properties, SEC_GENERAL_NAMES_KEY, - generalNamesContent); + generalNamesContent, localized); } static void appendGeneralNames(CFMutableArrayRef properties, - const DERItem *generalNames) { + const DERItem *generalNames, bool localized) { DERDecodedInfo generalNamesContent; DERReturn drtn = DERDecodeItem(generalNames, &generalNamesContent); require_noerr_quiet(drtn, badDER); require_quiet(generalNamesContent.tag == ASN1_CONSTR_SEQUENCE, badDER); - appendGeneralNamesContent(properties, &generalNamesContent.content); + appendGeneralNamesContent(properties, &generalNamesContent.content, + localized); return; badDER: - appendInvalidProperty(properties, SEC_GENERAL_NAMES_KEY, generalNames); + appendInvalidProperty(properties, SEC_GENERAL_NAMES_KEY, + generalNames, localized); } /* -BasicConstraints ::= SEQUENCE { - cA BOOLEAN DEFAULT FALSE, - pathLenConstraint INTEGER (0..MAX) OPTIONAL } + BasicConstraints ::= SEQUENCE { + cA BOOLEAN DEFAULT FALSE, + pathLenConstraint INTEGER (0..MAX) OPTIONAL } */ static void appendBasicConstraints(CFMutableArrayRef properties, - const DERItem *extnValue) { + const DERItem *extnValue, bool localized) { DERBasicConstraints basicConstraints; DERReturn drtn = DERParseSequence(extnValue, DERNumBasicConstraintsItemSpecs, DERBasicConstraintsItemSpecs, @@ -3176,15 +3244,16 @@ static void appendBasicConstraints(CFMutableArrayRef properties, require_noerr_quiet(drtn, badDER); appendBooleanProperty(properties, SEC_CERT_AUTHORITY_KEY, - &basicConstraints.cA, false); + &basicConstraints.cA, false, localized); if (basicConstraints.pathLenConstraint.length != 0) { appendIntegerProperty(properties, SEC_PATH_LEN_CONSTRAINT_KEY, - &basicConstraints.pathLenConstraint); + &basicConstraints.pathLenConstraint, localized); } return; badDER: - appendInvalidProperty(properties, SEC_BASIC_CONSTRAINTS_KEY, extnValue); + appendInvalidProperty(properties, SEC_BASIC_CONSTRAINTS_KEY, + extnValue, localized); } /* @@ -3204,7 +3273,7 @@ badDER: * BaseDistance ::= INTEGER (0..MAX) */ static void appendNameConstraints(CFMutableArrayRef properties, - const DERItem *extnValue) { + const DERItem *extnValue, bool localized) { CFAllocatorRef allocator = CFGetAllocator(properties); DERNameConstraints nc; DERReturn drtn; @@ -3226,17 +3295,19 @@ static void appendNameConstraints(CFMutableArrayRef properties, &derGS, sizeof(derGS)); require_noerr_quiet(drtn, badDER); if (derGS.minimum.length) { - appendIntegerProperty(properties, SEC_PERMITTED_MINIMUM_KEY, &derGS.minimum); + appendIntegerProperty(properties, SEC_PERMITTED_MINIMUM_KEY, + &derGS.minimum, localized); } if (derGS.maximum.length) { - appendIntegerProperty(properties, SEC_PERMITTED_MAXIMUM_KEY, &derGS.maximum); + appendIntegerProperty(properties, SEC_PERMITTED_MAXIMUM_KEY, + &derGS.maximum, localized); } if (derGS.generalName.length) { CFMutableArrayRef base = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); appendProperty(properties, kSecPropertyTypeSection, - SEC_PERMITTED_NAME_KEY, NULL, base); - appendGeneralNameProperty(base, &derGS.generalName); + SEC_PERMITTED_NAME_KEY, NULL, base, localized); + appendGeneralNameProperty(base, &derGS.generalName, localized); CFRelease(base); } } @@ -3255,17 +3326,19 @@ static void appendNameConstraints(CFMutableArrayRef properties, &derGS, sizeof(derGS)); require_noerr_quiet(drtn, badDER); if (derGS.minimum.length) { - appendIntegerProperty(properties, SEC_EXCLUDED_MINIMUM_KEY, &derGS.minimum); + appendIntegerProperty(properties, SEC_EXCLUDED_MINIMUM_KEY, + &derGS.minimum, localized); } if (derGS.maximum.length) { - appendIntegerProperty(properties, SEC_EXCLUDED_MAXIMUM_KEY, &derGS.maximum); + appendIntegerProperty(properties, SEC_EXCLUDED_MAXIMUM_KEY, + &derGS.maximum, localized); } if (derGS.generalName.length) { CFMutableArrayRef base = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); appendProperty(properties, kSecPropertyTypeSection, - SEC_EXCLUDED_NAME_KEY, NULL, base); - appendGeneralNameProperty(base, &derGS.generalName); + SEC_EXCLUDED_NAME_KEY, NULL, base, localized); + appendGeneralNameProperty(base, &derGS.generalName, localized); CFRelease(base); } } @@ -3274,7 +3347,8 @@ static void appendNameConstraints(CFMutableArrayRef properties, return; badDER: - appendInvalidProperty(properties, SEC_NAME_CONSTRAINTS_KEY, extnValue); + appendInvalidProperty(properties, SEC_NAME_CONSTRAINTS_KEY, + extnValue, localized); } /* @@ -3301,7 +3375,7 @@ badDER: aACompromise (8) } */ static void appendCrlDistributionPoints(CFMutableArrayRef properties, - const DERItem *extnValue) { + const DERItem *extnValue, bool localized) { CFAllocatorRef allocator = CFGetAllocator(properties); DERTag tag; DERSequence dpSeq; @@ -3325,13 +3399,13 @@ static void appendCrlDistributionPoints(CFMutableArrayRef properties, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0)) { /* Full Name */ appendGeneralNamesContent(properties, - &distributionPointName.content); + &distributionPointName.content, localized); } else if (distributionPointName.tag == (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1)) { CFArrayRef rdn_props = createPropertiesForRDNContent(allocator, - &dp.reasons); + &dp.reasons, localized); appendProperty(properties, kSecPropertyTypeSection, - SEC_NAME_REL_CRL_ISSUER_KEY, NULL, rdn_props); + SEC_NAME_REL_CRL_ISSUER_KEY, NULL, rdn_props, localized); CFRelease(rdn_props); } else { goto badDER; @@ -3351,33 +3425,38 @@ static void appendCrlDistributionPoints(CFMutableArrayRef properties, }; appendBitStringContentNames(properties, SEC_REASONS_KEY, &dp.reasons, - reasonNames, array_size(reasonNames)); + reasonNames, array_size(reasonNames), localized); } if (dp.cRLIssuer.length) { CFMutableArrayRef crlIssuer = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); appendProperty(properties, kSecPropertyTypeSection, - SEC_CRL_ISSUER_KEY, NULL, crlIssuer); + SEC_CRL_ISSUER_KEY, NULL, crlIssuer, localized); CFRelease(crlIssuer); - appendGeneralNames(crlIssuer, &dp.cRLIssuer); + appendGeneralNames(crlIssuer, &dp.cRLIssuer, localized); } } require_quiet(drtn == DR_EndOfSequence, badDER); return; badDER: - appendInvalidProperty(properties, SEC_CRL_DISTR_POINTS_KEY, extnValue); + appendInvalidProperty(properties, SEC_CRL_DISTR_POINTS_KEY, + extnValue, localized); } -/* Decode a sequence of integers into a comma separated list of ints. */ +/* + Decode a sequence of integers into a comma separated list of ints. +*/ static void appendIntegerSequenceContent(CFMutableArrayRef properties, - CFStringRef label, const DERItem *intSequenceContent) { + CFStringRef label, const DERItem *intSequenceContent, + bool localized) { CFAllocatorRef allocator = CFGetAllocator(properties); DERSequence intSeq; CFStringRef fmt = NULL, value = NULL, intDesc = NULL, v = NULL; DERReturn drtn = DERDecodeSeqContentInit(intSequenceContent, &intSeq); require_noerr_quiet(drtn, badDER); DERDecodedInfo intContent; - fmt = SecCopyCertString(SEC_STRING_LIST_KEY); + fmt = (localized) ? + SecCopyCertString(SEC_STRING_LIST_KEY) : SEC_STRING_LIST_KEY; require_quiet(fmt, badDER); while ((drtn = DERDecodeSeqNext(&intSeq, &intContent)) == DR_Success) { require_quiet(intContent.tag == ASN1_INTEGER, badDER); @@ -3398,7 +3477,8 @@ static void appendIntegerSequenceContent(CFMutableArrayRef properties, CFReleaseNull(fmt); require_quiet(drtn == DR_EndOfSequence, badDER); if (value) { - appendProperty(properties, kSecPropertyTypeString, label, NULL, value); + appendProperty(properties, kSecPropertyTypeString, label, NULL, + value, localized); CFRelease(value); return; } @@ -3407,11 +3487,11 @@ badDER: CFReleaseNull(fmt); CFReleaseNull(intDesc); CFReleaseNull(value); - appendInvalidProperty(properties, label, intSequenceContent); + appendInvalidProperty(properties, label, intSequenceContent, localized); } static void appendCertificatePolicies(CFMutableArrayRef properties, - const DERItem *extnValue) { + const DERItem *extnValue, bool localized) { CFAllocatorRef allocator = CFGetAllocator(properties); CFStringRef piLabel = NULL, piFmt = NULL, lpiLabel = NULL; CFStringRef pqLabel = NULL, pqFmt = NULL, lpqLabel = NULL; @@ -3430,13 +3510,17 @@ static void appendCertificatePolicies(CFMutableArrayRef properties, DERPolicyInformationItemSpecs, &pi, sizeof(pi)); require_noerr_quiet(drtn, badDER); - require_quiet(piLabel = CFStringCreateWithFormat(allocator, NULL, - SEC_POLICY_IDENTIFIER_KEY, pin), badDER); - require_quiet(piFmt = SecCopyCertString(SEC_POLICY_IDENTIFIER_KEY), badDER); - require_quiet(lpiLabel = CFStringCreateWithFormat(allocator, NULL, - piFmt, pin++), badDER); + piLabel = CFStringCreateWithFormat(allocator, NULL, + SEC_POLICY_IDENTIFIER_KEY, pin); + require_quiet(piLabel, badDER); + piFmt = (localized) ? + SecCopyCertString(SEC_POLICY_IDENTIFIER_KEY) : SEC_POLICY_IDENTIFIER_KEY; + require_quiet(piFmt, badDER); + lpiLabel = CFStringCreateWithFormat(allocator, NULL, piFmt, pin++); + require_quiet(lpiLabel, badDER); CFReleaseNull(piFmt); - appendOIDProperty(properties, piLabel, lpiLabel, &pi.policyIdentifier); + appendOIDProperty(properties, piLabel, lpiLabel, + &pi.policyIdentifier, localized); CFReleaseNull(piLabel); CFReleaseNull(lpiLabel); if (pi.policyQualifiers.length == 0) @@ -3457,20 +3541,23 @@ static void appendCertificatePolicies(CFMutableArrayRef properties, DERDecodedInfo qualifierContent; drtn = DERDecodeItem(&pqi.qualifier, &qualifierContent); require_noerr_quiet(drtn, badDER); - require_quiet(pqLabel = CFStringCreateWithFormat(allocator, NULL, - SEC_POLICY_QUALIFIER_KEY, pqn), badDER); - require_quiet(pqFmt = SecCopyCertString(SEC_POLICY_QUALIFIER_KEY), badDER); - require_quiet(lpqLabel = CFStringCreateWithFormat(allocator, NULL, - pqFmt, pqn++), badDER); + pqLabel = CFStringCreateWithFormat(allocator, NULL, + SEC_POLICY_QUALIFIER_KEY, pqn); + require_quiet(pqLabel, badDER); + pqFmt = (localized) ? + SecCopyCertString(SEC_POLICY_QUALIFIER_KEY) : SEC_POLICY_QUALIFIER_KEY; + require_quiet(pqFmt, badDER); + lpqLabel = CFStringCreateWithFormat(allocator, NULL, pqFmt, pqn++); + require_quiet(lpqLabel, badDER); CFReleaseNull(pqFmt); appendOIDProperty(properties, pqLabel, lpqLabel, - &pqi.policyQualifierID); + &pqi.policyQualifierID, localized); CFReleaseNull(pqLabel); CFReleaseNull(lpqLabel); if (DEROidCompare(&oidQtCps, &pqi.policyQualifierID)) { require_quiet(qualifierContent.tag == ASN1_IA5_STRING, badDER); appendURLContentProperty(properties, SEC_CPS_URI_KEY, - &qualifierContent.content); + &qualifierContent.content, localized); } else if (DEROidCompare(&oidQtUNotice, &pqi.policyQualifierID)) { require_quiet(qualifierContent.tag == ASN1_CONSTR_SEQUENCE, badDER); DERUserNotice un; @@ -3488,17 +3575,17 @@ static void appendCertificatePolicies(CFMutableArrayRef properties, require_noerr_quiet(drtn, badDER); appendDERThingProperty(properties, SEC_ORGANIZATION_KEY, NULL, - &nr.organization); + &nr.organization, localized); appendIntegerSequenceContent(properties, - SEC_NOTICE_NUMBERS_KEY, &nr.noticeNumbers); + SEC_NOTICE_NUMBERS_KEY, &nr.noticeNumbers, localized); } if (un.explicitText.length) { appendDERThingProperty(properties, SEC_EXPLICIT_TEXT_KEY, - NULL, &un.explicitText); + NULL, &un.explicitText, localized); } } else { appendUnparsedProperty(properties, SEC_QUALIFIER_KEY, NULL, - &pqi.qualifier); + &pqi.qualifier, localized); } } require_quiet(drtn == DR_EndOfSequence, badDER); @@ -3512,23 +3599,24 @@ badDER: CFReleaseNull(pqFmt); CFReleaseNull(pqLabel); CFReleaseNull(lpqLabel); - appendInvalidProperty(properties, SEC_CERT_POLICIES_KEY, extnValue); + appendInvalidProperty(properties, SEC_CERT_POLICIES_KEY, + extnValue, localized); } static void appendSubjectKeyIdentifier(CFMutableArrayRef properties, - const DERItem *extnValue) { + const DERItem *extnValue, bool localized) { DERReturn drtn; DERDecodedInfo keyIdentifier; drtn = DERDecodeItem(extnValue, &keyIdentifier); require_noerr_quiet(drtn, badDER); require_quiet(keyIdentifier.tag == ASN1_OCTET_STRING, badDER); appendDataProperty(properties, SEC_KEY_IDENTIFIER_KEY, NULL, - &keyIdentifier.content); + &keyIdentifier.content, localized); return; badDER: appendInvalidProperty(properties, SEC_SUBJ_KEY_ID_KEY, - extnValue); + extnValue, localized); } /* @@ -3542,7 +3630,7 @@ AuthorityKeyIdentifier ::= SEQUENCE { KeyIdentifier ::= OCTET STRING */ static void appendAuthorityKeyIdentifier(CFMutableArrayRef properties, - const DERItem *extnValue) { + const DERItem *extnValue, bool localized) { DERAuthorityKeyIdentifier akid; DERReturn drtn; drtn = DERParseSequence(extnValue, @@ -3552,7 +3640,7 @@ static void appendAuthorityKeyIdentifier(CFMutableArrayRef properties, require_noerr_quiet(drtn, badDER); if (akid.keyIdentifier.length) { appendDataProperty(properties, SEC_KEY_IDENTIFIER_KEY, NULL, - &akid.keyIdentifier); + &akid.keyIdentifier, localized); } if (akid.authorityCertIssuer.length || akid.authorityCertSerialNumber.length) { @@ -3560,14 +3648,15 @@ static void appendAuthorityKeyIdentifier(CFMutableArrayRef properties, akid.authorityCertSerialNumber.length, badDER); /* Perhaps put in a subsection called Authority Certificate Issuer. */ appendGeneralNamesContent(properties, - &akid.authorityCertIssuer); + &akid.authorityCertIssuer, localized); appendIntegerProperty(properties, SEC_AUTH_CERT_SERIAL_KEY, - &akid.authorityCertSerialNumber); + &akid.authorityCertSerialNumber, localized); } return; badDER: - appendInvalidProperty(properties, SEC_AUTHORITY_KEY_ID_KEY, extnValue); + appendInvalidProperty(properties, SEC_AUTHORITY_KEY_ID_KEY, + extnValue, localized); } /* @@ -3578,7 +3667,7 @@ badDER: SkipCerts ::= INTEGER (0..MAX) */ static void appendPolicyConstraints(CFMutableArrayRef properties, - const DERItem *extnValue) { + const DERItem *extnValue, bool localized) { DERPolicyConstraints pc; DERReturn drtn; drtn = DERParseSequence(extnValue, @@ -3588,17 +3677,18 @@ static void appendPolicyConstraints(CFMutableArrayRef properties, require_noerr_quiet(drtn, badDER); if (pc.requireExplicitPolicy.length) { appendIntegerProperty(properties, SEC_REQUIRE_EXPL_POLICY_KEY, - &pc.requireExplicitPolicy); + &pc.requireExplicitPolicy, localized); } if (pc.inhibitPolicyMapping.length) { appendIntegerProperty(properties, SEC_INHIBIT_POLICY_MAP_KEY, - &pc.inhibitPolicyMapping); + &pc.inhibitPolicyMapping, localized); } return; badDER: - appendInvalidProperty(properties, SEC_POLICY_CONSTRAINTS_KEY, extnValue); + appendInvalidProperty(properties, SEC_POLICY_CONSTRAINTS_KEY, + extnValue, localized); } /* @@ -3609,7 +3699,7 @@ extendedKeyUsage EXTENSION ::= { KeyPurposeId ::= OBJECT IDENTIFIER */ static void appendExtendedKeyUsage(CFMutableArrayRef properties, - const DERItem *extnValue) { + const DERItem *extnValue, bool localized) { DERTag tag; DERSequence derSeq; DERReturn drtn = DERDecodeSeqInit(extnValue, &tag, &derSeq); @@ -3619,12 +3709,13 @@ static void appendExtendedKeyUsage(CFMutableArrayRef properties, while ((drtn = DERDecodeSeqNext(&derSeq, &currDecoded)) == DR_Success) { require_quiet(currDecoded.tag == ASN1_OBJECT_ID, badDER); appendOIDProperty(properties, SEC_PURPOSE_KEY, NULL, - &currDecoded.content); + &currDecoded.content, localized); } require_quiet(drtn == DR_EndOfSequence, badDER); return; badDER: - appendInvalidProperty(properties, SEC_EXTENDED_KEY_USAGE_KEY, extnValue); + appendInvalidProperty(properties, SEC_EXTENDED_KEY_USAGE_KEY, + extnValue, localized); } /* @@ -3644,7 +3735,7 @@ badDER: id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 } */ static void appendInfoAccess(CFMutableArrayRef properties, - const DERItem *extnValue) { + const DERItem *extnValue, bool localized) { DERTag tag; DERSequence adSeq; DERReturn drtn = DERDecodeSeqInit(extnValue, &tag, &adSeq); @@ -3660,18 +3751,19 @@ static void appendInfoAccess(CFMutableArrayRef properties, &ad, sizeof(ad)); require_noerr_quiet(drtn, badDER); appendOIDProperty(properties, SEC_ACCESS_METHOD_KEY, NULL, - &ad.accessMethod); + &ad.accessMethod, localized); //TODO: Do something with SEC_ACCESS_LOCATION_KEY - appendGeneralNameProperty(properties, &ad.accessLocation); + appendGeneralNameProperty(properties, &ad.accessLocation, localized); } require_quiet(drtn == DR_EndOfSequence, badDER); return; badDER: - appendInvalidProperty(properties, SEC_AUTH_INFO_ACCESS_KEY, extnValue); + appendInvalidProperty(properties, SEC_AUTH_INFO_ACCESS_KEY, + extnValue, localized); } static void appendNetscapeCertType(CFMutableArrayRef properties, - const DERItem *extnValue) { + const DERItem *extnValue, bool localized) { static const CFStringRef certTypes[] = { SEC_SSL_CLIENT_KEY, SEC_SSL_SERVER_KEY, @@ -3683,11 +3775,11 @@ static void appendNetscapeCertType(CFMutableArrayRef properties, SEC_OBJECT_SIGNING_CA_KEY }; appendBitStringNames(properties, SEC_USAGE_KEY, extnValue, - certTypes, array_size(certTypes)); + certTypes, array_size(certTypes), localized); } static bool appendPrintableDERSequence(CFMutableArrayRef properties, - CFStringRef label, const DERItem *sequence) { + CFStringRef label, const DERItem *sequence, bool localized) { DERTag tag; DERSequence derSeq; DERReturn drtn = DERDecodeSeqInit(sequence, &tag, &derSeq); @@ -3717,11 +3809,11 @@ static bool appendPrintableDERSequence(CFMutableArrayRef properties, { CFStringRef string = copyDERThingContentDescription(CFGetAllocator(properties), - currDecoded.tag, &currDecoded.content, false); + currDecoded.tag, &currDecoded.content, false, localized); require_quiet(string, badSequence); appendProperty(properties, kSecPropertyTypeString, label, NULL, - string); + string, localized); CFReleaseNull(string); appendedSomething = true; break; @@ -3737,7 +3829,8 @@ badSequence: } static void appendExtension(CFMutableArrayRef parent, - const SecCertificateExtension *extn) { + const SecCertificateExtension *extn, + bool localized) { CFAllocatorRef allocator = CFGetAllocator(parent); CFMutableArrayRef properties = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); @@ -3747,7 +3840,7 @@ static void appendExtension(CFMutableArrayRef parent, CFStringRef label = NULL; CFStringRef localizedLabel = NULL; - appendBoolProperty(properties, SEC_CRITICAL_KEY, extn->critical); + appendBoolProperty(properties, SEC_CRITICAL_KEY, extn->critical, localized); require_quiet(extnID, xit); bool handled = true; @@ -3757,41 +3850,41 @@ static void appendExtension(CFMutableArrayRef parent, { switch (extnID->data[extnID->length - 1]) { case 14: /* SubjectKeyIdentifier id-ce 14 */ - appendSubjectKeyIdentifier(properties, extnValue); + appendSubjectKeyIdentifier(properties, extnValue, localized); break; case 15: /* KeyUsage id-ce 15 */ - appendKeyUsage(properties, extnValue); + appendKeyUsage(properties, extnValue, localized); break; case 16: /* PrivateKeyUsagePeriod id-ce 16 */ - appendPrivateKeyUsagePeriod(properties, extnValue); + appendPrivateKeyUsagePeriod(properties, extnValue, localized); break; case 17: /* SubjectAltName id-ce 17 */ case 18: /* IssuerAltName id-ce 18 */ - appendGeneralNames(properties, extnValue); + appendGeneralNames(properties, extnValue, localized); break; case 19: /* BasicConstraints id-ce 19 */ - appendBasicConstraints(properties, extnValue); + appendBasicConstraints(properties, extnValue, localized); break; case 30: /* NameConstraints id-ce 30 */ - appendNameConstraints(properties, extnValue); + appendNameConstraints(properties, extnValue, localized); break; case 31: /* CRLDistributionPoints id-ce 31 */ - appendCrlDistributionPoints(properties, extnValue); + appendCrlDistributionPoints(properties, extnValue, localized); break; case 32: /* CertificatePolicies id-ce 32 */ - appendCertificatePolicies(properties, extnValue); + appendCertificatePolicies(properties, extnValue, localized); break; case 33: /* PolicyMappings id-ce 33 */ handled = false; break; case 35: /* AuthorityKeyIdentifier id-ce 35 */ - appendAuthorityKeyIdentifier(properties, extnValue); + appendAuthorityKeyIdentifier(properties, extnValue, localized); break; case 36: /* PolicyConstraints id-ce 36 */ - appendPolicyConstraints(properties, extnValue); + appendPolicyConstraints(properties, extnValue, localized); break; case 37: /* ExtKeyUsage id-ce 37 */ - appendExtendedKeyUsage(properties, extnValue); + appendExtendedKeyUsage(properties, extnValue, localized); break; case 46: /* FreshestCRL id-ce 46 */ handled = false; @@ -3808,13 +3901,13 @@ static void appendExtension(CFMutableArrayRef parent, { switch (extnID->data[extnID->length - 1]) { case 1: /* AuthorityInfoAccess id-pe 1 */ - appendInfoAccess(properties, extnValue); + appendInfoAccess(properties, extnValue, localized); break; case 3: /* QCStatements id-pe 3 */ handled = false; break; case 11: /* SubjectInfoAccess id-pe 11 */ - appendInfoAccess(properties, extnValue); + appendInfoAccess(properties, extnValue, localized); break; default: handled = false; @@ -3822,24 +3915,24 @@ static void appendExtension(CFMutableArrayRef parent, } } else if (DEROidCompare(extnID, &oidNetscapeCertType)) { /* 2.16.840.1.113730.1.1 netscape 1 1 */ - appendNetscapeCertType(properties, extnValue); + appendNetscapeCertType(properties, extnValue, localized); } else { handled = false; } if (!handled) { /* Try to parse and display printable string(s). */ - if (appendPrintableDERSequence(properties, SEC_DATA_KEY, extnValue)) { + if (appendPrintableDERSequence(properties, SEC_DATA_KEY, extnValue, localized)) { /* Nothing to do here appendPrintableDERSequence did the work. */ } else { /* Couldn't parse extension; dump the raw unparsed data as hex. */ - appendUnparsedProperty(properties, SEC_DATA_KEY, NULL, extnValue); + appendUnparsedProperty(properties, SEC_DATA_KEY, NULL, extnValue, localized); } } label = SecDERItemCopyOIDDecimalRepresentation(allocator, extnID); - localizedLabel = copyLocalizedOidDescription(allocator, extnID); - appendProperty(parent, kSecPropertyTypeSection, label, localizedLabel, properties); - + localizedLabel = copyOidDescription(allocator, extnID, localized); + appendProperty(parent, kSecPropertyTypeSection, label, localizedLabel, + properties, localized); xit: CFReleaseSafe(localizedLabel); CFReleaseSafe(label); @@ -3862,7 +3955,8 @@ struct Summary { }; static OSStatus obtainSummaryFromX501Name(void *context, - const DERItem *type, const DERItem *value, CFIndex rdnIX) { + const DERItem *type, const DERItem *value, CFIndex rdnIX, + bool localized) { struct Summary *summary = (struct Summary *)context; enum SummaryType stype = kSummaryTypeNone; CFStringRef string = NULL; @@ -3873,11 +3967,14 @@ static OSStatus obtainSummaryFromX501Name(void *context, } else if (DEROidCompare(type, &oidOrganizationName)) { stype = kSummaryTypeOrganizationName; } else if (DEROidCompare(type, &oidDescription)) { - string = copyDERThingDescription(kCFAllocatorDefault, value, true); + string = copyDERThingDescription(kCFAllocatorDefault, value, + true, localized); if (string) { if (summary->description) { - CFStringRef fmt = SecCopyCertString(SEC_STRING_LIST_KEY); - CFStringRef newDescription = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, fmt, string, summary->description); + CFStringRef fmt = (localized) ? + SecCopyCertString(SEC_STRING_LIST_KEY) : SEC_STRING_LIST_KEY; + CFStringRef newDescription = CFStringCreateWithFormat(kCFAllocatorDefault, + NULL, fmt, string, summary->description); CFRelease(fmt); CFRelease(summary->description); summary->description = newDescription; @@ -3895,13 +3992,16 @@ static OSStatus obtainSummaryFromX501Name(void *context, component type in reverse order encountered comma separated list, The order of desirability is defined by enum SummaryType. */ if (summary->type <= stype) { - if (!string) - string = copyDERThingDescription(kCFAllocatorDefault, value, true); - + if (!string) { + string = copyDERThingDescription(kCFAllocatorDefault, value, + true, localized); + } if (string) { if (summary->type == stype) { - CFStringRef fmt = SecCopyCertString(SEC_STRING_LIST_KEY); - CFStringRef newSummary = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, fmt, string, summary->summary); + CFStringRef fmt = (localized) ? + SecCopyCertString(SEC_STRING_LIST_KEY) : SEC_STRING_LIST_KEY; + CFStringRef newSummary = CFStringCreateWithFormat(kCFAllocatorDefault, + NULL, fmt, string, summary->summary); CFRelease(fmt); CFRelease(string); string = newSummary; @@ -3920,7 +4020,10 @@ static OSStatus obtainSummaryFromX501Name(void *context, CFStringRef SecCertificateCopySubjectSummary(SecCertificateRef certificate) { struct Summary summary = {}; - parseX501NameContent(&certificate->_subject, &summary, obtainSummaryFromX501Name); + OSStatus status = parseX501NameContent(&certificate->_subject, &summary, obtainSummaryFromX501Name, true); + if (status != errSecSuccess) { + return NULL; + } /* If we found a description and a common name we change the summary to CommonName (Description). */ if (summary.description) { @@ -3955,7 +4058,10 @@ CFStringRef SecCertificateCopySubjectSummary(SecCertificateRef certificate) { CFStringRef SecCertificateCopyIssuerSummary(SecCertificateRef certificate) { struct Summary summary = {}; - parseX501NameContent(&certificate->_issuer, &summary, obtainSummaryFromX501Name); + OSStatus status = parseX501NameContent(&certificate->_issuer, &summary, obtainSummaryFromX501Name, true); + if (status != errSecSuccess) { + return NULL; + } /* If we found a description and a common name we change the summary to CommonName (Description). */ if (summary.description) { @@ -4027,12 +4133,13 @@ CFMutableArrayRef SecCertificateCopySummaryProperties( CFAllocatorRef allocator = CFGetAllocator(certificate); CFMutableArrayRef summary = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); + bool localized = true; /* First we put the subject summary name. */ CFStringRef ssummary = SecCertificateCopySubjectSummary(certificate); if (ssummary) { appendProperty(summary, kSecPropertyTypeTitle, - NULL, NULL, ssummary); + NULL, NULL, ssummary, localized); CFRelease(ssummary); } @@ -4072,9 +4179,9 @@ CFMutableArrayRef SecCertificateCopySummaryProperties( } } - appendDateProperty(summary, label, when); + appendDateProperty(summary, label, when, localized); CFStringRef lmessage = SecCopyCertString(message); - appendProperty(summary, ptype, NULL, NULL, lmessage); + appendProperty(summary, ptype, NULL, NULL, lmessage, localized); CFRelease(lmessage); return summary; @@ -4093,68 +4200,68 @@ CFArrayRef SecCertificateCopyLegacyProperties(SecCertificateRef certificate) { /* Subject Name */ CFArrayRef subject_plist = createPropertiesForX501NameContent(allocator, - &certificate->_subject); + &certificate->_subject, false); appendProperty(properties, kSecPropertyTypeSection, CFSTR("Subject Name"), - NULL, subject_plist); + NULL, subject_plist, false); CFRelease(subject_plist); /* Issuer Name */ CFArrayRef issuer_plist = createPropertiesForX501NameContent(allocator, - &certificate->_issuer); + &certificate->_issuer, false); appendProperty(properties, kSecPropertyTypeSection, CFSTR("Issuer Name"), - NULL, issuer_plist); + NULL, issuer_plist, false); CFRelease(issuer_plist); /* Version */ CFStringRef versionString = CFStringCreateWithFormat(allocator, NULL, CFSTR("%d"), certificate->_version + 1); appendProperty(properties, kSecPropertyTypeString, CFSTR("Version"), - NULL, versionString); + NULL, versionString, false); CFRelease(versionString); /* Serial Number */ if (certificate->_serialNum.length) { appendIntegerProperty(properties, CFSTR("Serial Number"), - &certificate->_serialNum); + &certificate->_serialNum, false); } /* Signature Algorithm */ appendAlgorithmProperty(properties, CFSTR("Signature Algorithm"), - &certificate->_tbsSigAlg); + &certificate->_tbsSigAlg, false); /* Validity dates */ - appendDateProperty(properties, CFSTR("Not Valid Before"), certificate->_notBefore); - appendDateProperty(properties, CFSTR("Not Valid After"), certificate->_notAfter); + appendDateProperty(properties, CFSTR("Not Valid Before"), certificate->_notBefore, false); + appendDateProperty(properties, CFSTR("Not Valid After"), certificate->_notAfter, false); if (certificate->_subjectUniqueID.length) { appendDataProperty(properties, CFSTR("Subject Unique ID"), - NULL, &certificate->_subjectUniqueID); + NULL, &certificate->_subjectUniqueID, false); } if (certificate->_issuerUniqueID.length) { appendDataProperty(properties, CFSTR("Issuer Unique ID"), - NULL, &certificate->_issuerUniqueID); + NULL, &certificate->_issuerUniqueID, false); } /* Public Key Algorithm */ appendAlgorithmProperty(properties, CFSTR("Public Key Algorithm"), - &certificate->_algId); + &certificate->_algId, false); /* Public Key Data */ appendDataProperty(properties, CFSTR("Public Key Data"), - NULL, &certificate->_pubKeyDER); + NULL, &certificate->_pubKeyDER, false); /* Signature */ appendDataProperty(properties, CFSTR("Signature"), - NULL, &certificate->_signature); + NULL, &certificate->_signature, false); /* Extensions */ CFIndex ix; for (ix = 0; ix < certificate->_extensionCount; ++ix) { - appendExtension(properties, &certificate->_extensions[ix]); + appendExtension(properties, &certificate->_extensions[ix], false); } /* Fingerprints */ - appendFingerprintsProperty(properties, CFSTR("Fingerprints"), certificate); + appendFingerprintsProperty(properties, CFSTR("Fingerprints"), certificate, false); return properties; } @@ -4165,23 +4272,25 @@ CFArrayRef SecCertificateCopyProperties(SecCertificateRef certificate) { CFMutableArrayRef properties = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); require_quiet(properties, out); - + bool localized = true; /* First we put the Subject Name in the property list. */ CFArrayRef subject_plist = createPropertiesForX501NameContent(allocator, - &certificate->_subject); + &certificate->_subject, + localized); if (subject_plist) { appendProperty(properties, kSecPropertyTypeSection, - SEC_SUBJECT_NAME_KEY, NULL, subject_plist); + SEC_SUBJECT_NAME_KEY, NULL, subject_plist, localized); } CFReleaseNull(subject_plist); /* Next we put the Issuer Name in the property list. */ CFArrayRef issuer_plist = createPropertiesForX501NameContent(allocator, - &certificate->_issuer); + &certificate->_issuer, + localized); if (issuer_plist) { appendProperty(properties, kSecPropertyTypeSection, - SEC_ISSUER_NAME_KEY, NULL, issuer_plist); + SEC_ISSUER_NAME_KEY, NULL, issuer_plist, localized); } CFReleaseNull(issuer_plist); @@ -4195,36 +4304,36 @@ CFArrayRef SecCertificateCopyProperties(SecCertificateRef certificate) { CFReleaseNull(fmt); if (versionString) { appendProperty(properties, kSecPropertyTypeString, - SEC_VERSION_KEY, NULL, versionString); + SEC_VERSION_KEY, NULL, versionString, localized); } CFReleaseNull(versionString); /* Serial Number */ - appendSerialNumberProperty(properties, SEC_SERIAL_NUMBER_KEY, &certificate->_serialNum); + appendSerialNumberProperty(properties, SEC_SERIAL_NUMBER_KEY, &certificate->_serialNum, localized); /* Validity dates. */ - appendValidityPeriodProperty(properties, SEC_VALIDITY_PERIOD_KEY, certificate); + appendValidityPeriodProperty(properties, SEC_VALIDITY_PERIOD_KEY, certificate, localized); if (certificate->_subjectUniqueID.length) { appendDataProperty(properties, SEC_SUBJECT_UNIQUE_ID_KEY, NULL, - &certificate->_subjectUniqueID); + &certificate->_subjectUniqueID, localized); } if (certificate->_issuerUniqueID.length) { appendDataProperty(properties, SEC_ISSUER_UNIQUE_ID_KEY, NULL, - &certificate->_issuerUniqueID); + &certificate->_issuerUniqueID, localized); } - appendPublicKeyProperty(properties, SEC_PUBLIC_KEY_KEY, certificate); + appendPublicKeyProperty(properties, SEC_PUBLIC_KEY_KEY, certificate, localized); CFIndex ix; for (ix = 0; ix < certificate->_extensionCount; ++ix) { - appendExtension(properties, &certificate->_extensions[ix]); + appendExtension(properties, &certificate->_extensions[ix], localized); } /* Signature */ - appendSignatureProperty(properties, SEC_SIGNATURE_KEY, certificate); + appendSignatureProperty(properties, SEC_SIGNATURE_KEY, certificate, localized); - appendFingerprintsProperty(properties, SEC_FINGERPRINTS_KEY, certificate); + appendFingerprintsProperty(properties, SEC_FINGERPRINTS_KEY, certificate, localized); certificate->_properties = properties; } @@ -4403,11 +4512,12 @@ CFArrayRef SecCertificateCopyIPAddresses(SecCertificateRef certificate) { } static OSStatus appendIPAddressesFromX501Name(void *context, const DERItem *type, - const DERItem *value, CFIndex rdnIX) { + const DERItem *value, CFIndex rdnIX, + bool localized) { CFMutableArrayRef addrs = (CFMutableArrayRef)context; if (DEROidCompare(type, &oidCommonName)) { CFStringRef string = copyDERThingDescription(kCFAllocatorDefault, - value, true); + value, true, localized); if (string) { CFDataRef data = NULL; if (convertIPAddress(string, &data)) { @@ -4426,7 +4536,7 @@ CFArrayRef SecCertificateCopyIPAddressesFromSubject(SecCertificateRef certificat CFMutableArrayRef addrs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); OSStatus status = parseX501NameContent(&certificate->_subject, addrs, - appendIPAddressesFromX501Name); + appendIPAddressesFromX501Name, true); if (status || CFArrayGetCount(addrs) == 0) { CFReleaseNull(addrs); return NULL; @@ -4534,11 +4644,11 @@ notDNS: } static OSStatus appendDNSNamesFromX501Name(void *context, const DERItem *type, - const DERItem *value, CFIndex rdnIX) { + const DERItem *value, CFIndex rdnIX, bool localized) { CFMutableArrayRef dnsNames = (CFMutableArrayRef)context; if (DEROidCompare(type, &oidCommonName)) { CFStringRef string = copyDERThingDescription(kCFAllocatorDefault, - value, true); + value, true, localized); if (string) { if (isDNSName(string)) { /* We found a common name that is formatted like a valid @@ -4557,7 +4667,7 @@ CFArrayRef SecCertificateCopyDNSNamesFromSubject(SecCertificateRef certificate) CFMutableArrayRef dnsNames = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); OSStatus status = parseX501NameContent(&certificate->_subject, dnsNames, - appendDNSNamesFromX501Name); + appendDNSNamesFromX501Name, true); if (status || CFArrayGetCount(dnsNames) == 0) { CFReleaseNull(dnsNames); return NULL; @@ -4579,18 +4689,32 @@ CFArrayRef SecCertificateCopyDNSNamesFromSubject(SecCertificateRef certificate) return result; } +CFArrayRef SecCertificateCopyDNSNamesFromSAN(SecCertificateRef certificate) { + CFMutableArrayRef dnsNames = CFArrayCreateMutable(kCFAllocatorDefault, + 0, &kCFTypeArrayCallBacks); + OSStatus status = errSecSuccess; + if (certificate->_subjectAltName) { + status = SecCertificateParseGeneralNames(&certificate->_subjectAltName->extnValue, + dnsNames, appendDNSNamesFromGeneralNames); + } + + if (status || CFArrayGetCount(dnsNames) == 0) { + CFReleaseNull(dnsNames); + } + return dnsNames; +} + /* Not everything returned by this function is going to be a proper DNS name, we also return the certificates common name entries from the subject, assuming they look like dns names as specified in RFC 1035. */ CFArrayRef SecCertificateCopyDNSNames(SecCertificateRef certificate) { /* These can exist in the subject alt name or in the subject. */ - CFMutableArrayRef dnsNames = CFArrayCreateMutable(kCFAllocatorDefault, - 0, &kCFTypeArrayCallBacks); - OSStatus status = errSecSuccess; - if (certificate->_subjectAltName) { - status = SecCertificateParseGeneralNames(&certificate->_subjectAltName->extnValue, - dnsNames, appendDNSNamesFromGeneralNames); - } + CFArrayRef sanNames = SecCertificateCopyDNSNamesFromSAN(certificate); + if (sanNames && CFArrayGetCount(sanNames) > 0) { + return sanNames; + } + CFReleaseNull(sanNames); + /* RFC 2818 section 3.1. Server Identity [...] If a subjectAltName extension of type dNSName is present, that MUST @@ -4604,15 +4728,18 @@ CFArrayRef SecCertificateCopyDNSNames(SecCertificateRef certificate) { subjectAltName, we should not use the Common Name of the subject as a DNSName. */ - if (!status && CFArrayGetCount(dnsNames) == 0) { - status = parseX501NameContent(&certificate->_subject, dnsNames, - appendDNSNamesFromX501Name); - } - if (status || CFArrayGetCount(dnsNames) == 0) { - CFRelease(dnsNames); - dnsNames = NULL; - } - return dnsNames; + + /* To preserve bug for bug compatibility, we can't use SecCertificateCopyDNSNamesFromSubject + * because that function filters out IP Addresses. This function is Private, but + * SecCertificateCopyValues uses it and that's Public. */ + CFMutableArrayRef dnsNames = CFArrayCreateMutable(kCFAllocatorDefault, + 0, &kCFTypeArrayCallBacks); + OSStatus status = parseX501NameContent(&certificate->_subject, dnsNames, + appendDNSNamesFromX501Name, true); + if (status || CFArrayGetCount(dnsNames) == 0) { + CFReleaseNull(dnsNames); + } + return dnsNames; } static OSStatus appendRFC822NamesFromGeneralNames(void *context, @@ -4633,11 +4760,11 @@ static OSStatus appendRFC822NamesFromGeneralNames(void *context, } static OSStatus appendRFC822NamesFromX501Name(void *context, const DERItem *type, - const DERItem *value, CFIndex rdnIX) { + const DERItem *value, CFIndex rdnIX, bool localized) { CFMutableArrayRef dnsNames = (CFMutableArrayRef)context; if (DEROidCompare(type, &oidEmailAddress)) { CFStringRef string = copyDERThingDescription(kCFAllocatorDefault, - value, true); + value, true, localized); if (string) { CFArrayAppendValue(dnsNames, string); CFRelease(string); @@ -4659,7 +4786,7 @@ CFArrayRef SecCertificateCopyRFC822Names(SecCertificateRef certificate) { } if (!status) { status = parseX501NameContent(&certificate->_subject, rfc822Names, - appendRFC822NamesFromX501Name); + appendRFC822NamesFromX501Name, true); } if (status || CFArrayGetCount(rfc822Names) == 0) { CFRelease(rfc822Names); @@ -4683,7 +4810,7 @@ CFArrayRef SecCertificateCopyRFC822NamesFromSubject(SecCertificateRef certificat CFMutableArrayRef rfc822Names = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); OSStatus status = parseX501NameContent(&certificate->_subject, rfc822Names, - appendRFC822NamesFromX501Name); + appendRFC822NamesFromX501Name, true); if (status || CFArrayGetCount(rfc822Names) == 0) { CFRelease(rfc822Names); rfc822Names = NULL; @@ -4692,11 +4819,11 @@ CFArrayRef SecCertificateCopyRFC822NamesFromSubject(SecCertificateRef certificat } static OSStatus appendCommonNamesFromX501Name(void *context, - const DERItem *type, const DERItem *value, CFIndex rdnIX) { + const DERItem *type, const DERItem *value, CFIndex rdnIX, bool localized) { CFMutableArrayRef commonNames = (CFMutableArrayRef)context; if (DEROidCompare(type, &oidCommonName)) { CFStringRef string = copyDERThingDescription(kCFAllocatorDefault, - value, true); + value, true, localized); if (string) { CFArrayAppendValue(commonNames, string); CFRelease(string); @@ -4712,7 +4839,7 @@ CFArrayRef SecCertificateCopyCommonNames(SecCertificateRef certificate) { 0, &kCFTypeArrayCallBacks); OSStatus status; status = parseX501NameContent(&certificate->_subject, commonNames, - appendCommonNamesFromX501Name); + appendCommonNamesFromX501Name, true); if (status || CFArrayGetCount(commonNames) == 0) { CFRelease(commonNames); commonNames = NULL; @@ -4739,11 +4866,11 @@ OSStatus SecCertificateCopyCommonName(SecCertificateRef certificate, CFStringRef } static OSStatus appendOrganizationFromX501Name(void *context, - const DERItem *type, const DERItem *value, CFIndex rdnIX) { + const DERItem *type, const DERItem *value, CFIndex rdnIX, bool localized) { CFMutableArrayRef organization = (CFMutableArrayRef)context; if (DEROidCompare(type, &oidOrganizationName)) { CFStringRef string = copyDERThingDescription(kCFAllocatorDefault, - value, true); + value, true, localized); if (string) { CFArrayAppendValue(organization, string); CFRelease(string); @@ -4759,7 +4886,7 @@ CFArrayRef SecCertificateCopyOrganization(SecCertificateRef certificate) { 0, &kCFTypeArrayCallBacks); OSStatus status; status = parseX501NameContent(&certificate->_subject, organization, - appendOrganizationFromX501Name); + appendOrganizationFromX501Name, true); if (status || CFArrayGetCount(organization) == 0) { CFRelease(organization); organization = NULL; @@ -4768,11 +4895,11 @@ CFArrayRef SecCertificateCopyOrganization(SecCertificateRef certificate) { } static OSStatus appendOrganizationalUnitFromX501Name(void *context, - const DERItem *type, const DERItem *value, CFIndex rdnIX) { + const DERItem *type, const DERItem *value, CFIndex rdnIX, bool localized) { CFMutableArrayRef organizationalUnit = (CFMutableArrayRef)context; if (DEROidCompare(type, &oidOrganizationalUnitName)) { CFStringRef string = copyDERThingDescription(kCFAllocatorDefault, - value, true); + value, true, localized); if (string) { CFArrayAppendValue(organizationalUnit, string); CFRelease(string); @@ -4788,7 +4915,7 @@ CFArrayRef SecCertificateCopyOrganizationalUnit(SecCertificateRef certificate) { 0, &kCFTypeArrayCallBacks); OSStatus status; status = parseX501NameContent(&certificate->_subject, organizationalUnit, - appendOrganizationalUnitFromX501Name); + appendOrganizationalUnitFromX501Name, true); if (status || CFArrayGetCount(organizationalUnit) == 0) { CFRelease(organizationalUnit); organizationalUnit = NULL; @@ -4797,11 +4924,11 @@ CFArrayRef SecCertificateCopyOrganizationalUnit(SecCertificateRef certificate) { } static OSStatus appendCountryFromX501Name(void *context, - const DERItem *type, const DERItem *value, CFIndex rdnIX) { + const DERItem *type, const DERItem *value, CFIndex rdnIX, bool localized) { CFMutableArrayRef countries = (CFMutableArrayRef)context; if (DEROidCompare(type, &oidCountryName)) { CFStringRef string = copyDERThingDescription(kCFAllocatorDefault, - value, true); + value, true, localized); if (string) { CFArrayAppendValue(countries, string); CFRelease(string); @@ -4817,7 +4944,7 @@ CFArrayRef SecCertificateCopyCountry(SecCertificateRef certificate) { 0, &kCFTypeArrayCallBacks); OSStatus status; status = parseX501NameContent(&certificate->_subject, countries, - appendCountryFromX501Name); + appendCountryFromX501Name, true); if (status || CFArrayGetCount(countries) == 0) { CFRelease(countries); countries = NULL; @@ -4887,7 +5014,7 @@ static OSStatus appendNTPrincipalNamesFromGeneralNames(void *context, if (DEROidCompare(&on.typeIdentifier, &oidMSNTPrincipalName)) { CFStringRef string; require_quiet(string = copyDERThingDescription(kCFAllocatorDefault, - &on.value, true), badDER); + &on.value, true, true), badDER); CFArrayAppendValue(ntPrincipalNames, string); CFRelease(string); } @@ -4915,7 +5042,7 @@ CFArrayRef SecCertificateCopyNTPrincipalNames(SecCertificateRef certificate) { } static OSStatus appendToRFC2253String(void *context, - const DERItem *type, const DERItem *value, CFIndex rdnIX) { + const DERItem *type, const DERItem *value, CFIndex rdnIX, bool localized) { CFMutableStringRef string = (CFMutableStringRef)context; /* CN commonName @@ -4967,7 +5094,7 @@ static OSStatus appendToRFC2253String(void *context, CFStringAppend(string, CFSTR("=")); CFStringRef raw = NULL; if (!oid) - raw = copyDERThingDescription(kCFAllocatorDefault, value, true); + raw = copyDERThingDescription(kCFAllocatorDefault, value, true, localized); if (raw) { /* Append raw to string while escaping: @@ -5009,7 +5136,7 @@ static OSStatus appendToRFC2253String(void *context, CFStringRef SecCertificateCopySubjectString(SecCertificateRef certificate) { CFMutableStringRef string = CFStringCreateMutable(kCFAllocatorDefault, 0); - OSStatus status = parseX501NameContent(&certificate->_subject, string, appendToRFC2253String); + OSStatus status = parseX501NameContent(&certificate->_subject, string, appendToRFC2253String, true); if (status || CFStringGetLength(string) == 0) { CFRelease(string); string = NULL; @@ -5018,7 +5145,7 @@ CFStringRef SecCertificateCopySubjectString(SecCertificateRef certificate) { } static OSStatus appendToCompanyNameString(void *context, - const DERItem *type, const DERItem *value, CFIndex rdnIX) { + const DERItem *type, const DERItem *value, CFIndex rdnIX, bool localized) { CFMutableStringRef string = (CFMutableStringRef)context; if (CFStringGetLength(string) != 0) return errSecSuccess; @@ -5027,7 +5154,7 @@ static OSStatus appendToCompanyNameString(void *context, return errSecSuccess; CFStringRef raw; - raw = copyDERThingDescription(kCFAllocatorDefault, value, true); + raw = copyDERThingDescription(kCFAllocatorDefault, value, true, localized); if (!raw) return errSecSuccess; CFStringAppend(string, raw); @@ -5039,7 +5166,7 @@ static OSStatus appendToCompanyNameString(void *context, CFStringRef SecCertificateCopyCompanyName(SecCertificateRef certificate) { CFMutableStringRef string = CFStringCreateMutable(kCFAllocatorDefault, 0); OSStatus status = parseX501NameContent(&certificate->_subject, string, - appendToCompanyNameString); + appendToCompanyNameString, true); if (status || CFStringGetLength(string) == 0) { CFRelease(string); string = NULL; @@ -5256,20 +5383,49 @@ CFDataRef SecCertificateCopyPublicKeySHA1Digest(SecCertificateRef certificate) { certificate->_pubKeyDER.data, certificate->_pubKeyDER.length); } -CFDataRef SecCertificateCopySubjectPublicKeyInfoSHA1Digest(SecCertificateRef certificate) { +static CFDataRef SecCertificateCopySPKIEncoded(SecCertificateRef certificate) { + /* SPKI is saved without the tag/length by libDER, so we need to re-encode */ if (!certificate || !certificate->_subjectPublicKeyInfo.data) { return NULL; } - return SecSHA1DigestCreate(CFGetAllocator(certificate), - certificate->_subjectPublicKeyInfo.data, certificate->_subjectPublicKeyInfo.length); + DERSize size = DERLengthOfItem(ASN1_CONSTR_SEQUENCE, certificate->_subjectPublicKeyInfo.length); + if (size < certificate->_subjectPublicKeyInfo.length) { + return NULL; + } + uint8_t *temp = malloc(size); + if (!temp) { + return NULL; + } + DERReturn drtn = DEREncodeItem(ASN1_CONSTR_SEQUENCE, + certificate->_subjectPublicKeyInfo.length, + certificate->_subjectPublicKeyInfo.data, + temp, &size); + CFDataRef encodedSPKI = NULL; + if (drtn == DR_Success) { + encodedSPKI = CFDataCreate(NULL, temp, size); + } + free(temp); + return encodedSPKI; +} + +CFDataRef SecCertificateCopySubjectPublicKeyInfoSHA1Digest(SecCertificateRef certificate) { + CFDataRef encodedSPKI = SecCertificateCopySPKIEncoded(certificate); + if (!encodedSPKI) { return NULL; } + CFDataRef hash = SecSHA1DigestCreate(CFGetAllocator(certificate), + CFDataGetBytePtr(encodedSPKI), + CFDataGetLength(encodedSPKI)); + CFReleaseNull(encodedSPKI); + return hash; } CFDataRef SecCertificateCopySubjectPublicKeyInfoSHA256Digest(SecCertificateRef certificate) { - if (!certificate || !certificate->_subjectPublicKeyInfo.data) { - return NULL; - } - return SecSHA256DigestCreate(CFGetAllocator(certificate), - certificate->_subjectPublicKeyInfo.data, certificate->_subjectPublicKeyInfo.length); + CFDataRef encodedSPKI = SecCertificateCopySPKIEncoded(certificate); + if (!encodedSPKI) { return NULL; } + CFDataRef hash = SecSHA256DigestCreate(CFGetAllocator(certificate), + CFDataGetBytePtr(encodedSPKI), + CFDataGetLength(encodedSPKI)); + CFReleaseNull(encodedSPKI); + return hash; } CFTypeRef SecCertificateCopyKeychainItem(SecCertificateRef certificate) @@ -5880,6 +6036,42 @@ DERItem *SecCertificateGetExtensionValue(SecCertificateRef certificate, CFTypeRe return NULL; } +CFDataRef SecCertificateCopyExtensionValue(SecCertificateRef certificate, CFTypeRef extensionOID, bool *isCritical) { + if (!certificate || !extensionOID) { + return NULL; + } + + CFDataRef oid = NULL, extensionValue = NULL; + if (CFGetTypeID(extensionOID) == CFDataGetTypeID()) { + oid = CFRetainSafe(extensionOID); + } else if (CFGetTypeID(extensionOID) == CFStringGetTypeID()) { + oid = SecCertificateCreateOidDataFromString(NULL, extensionOID); + } + if (!oid) { + return NULL; + } + + CFIndex ix; + const uint8_t *oid_data = CFDataGetBytePtr(oid); + size_t oid_len = CFDataGetLength(oid); + + for (ix = 0; ix < certificate->_extensionCount; ++ix) { + const SecCertificateExtension *extn = &certificate->_extensions[ix]; + if (extn->extnID.length == oid_len + && !memcmp(extn->extnID.data, oid_data, extn->extnID.length)) + { + if (isCritical) { + *isCritical = extn->critical; + } + extensionValue = CFDataCreate(NULL, extn->extnValue.data, extn->extnValue.length); + break; + } + } + + CFReleaseNull(oid); + return extensionValue; +} + CFDataRef SecCertificateCopyiAPAuthCapabilities(SecCertificateRef certificate) { if (!certificate) { return NULL; @@ -5936,8 +6128,14 @@ SeciAuthVersion SecCertificateGetiAuthVersion(SecCertificateRef certificate) { } if (NULL != SecCertificateGetExtensionValue(certificate, CFSTR("1.2.840.113635.100.6.36"))) { + /* v3 Capabilities Extension */ return kSeciAuthVersion3; } + if (NULL != SecCertificateGetExtensionValue(certificate, + CFSTR("1.2.840.113635.100.6.59.1"))) { + /* SW Auth General Capabilities Extension */ + return kSeciAuthVersionSW; + } DERItem serialNumber = certificate->_serialNum; require_quiet(serialNumber.data, out); require_quiet(serialNumber.length == 15, out); diff --git a/OSX/sec/Security/SecCertificateInternal.h b/OSX/sec/Security/SecCertificateInternal.h index 9bb87ba3..96472c93 100644 --- a/OSX/sec/Security/SecCertificateInternal.h +++ b/OSX/sec/Security/SecCertificateInternal.h @@ -28,9 +28,28 @@ #ifndef _SECURITY_SECCERTIFICATEINTERNAL_H_ #define _SECURITY_SECCERTIFICATEINTERNAL_H_ +#include +#include + +#include #include + #include -#include + +// This file can only be included under the ios view of the headers. +// If you're not under that view, we'll forward declare the things you need here. +#if SECURITY_PROJECT_TAPI_HACKS && SEC_OS_OSX +typedef enum { + NO_ENUM_VALUES, +} SecCEGeneralNameType; // The real enum values are already declared. + +typedef struct {} SecCEBasicConstraints; +typedef struct {} SecCEPolicyConstraints; +typedef struct {} SecCEPolicyMapping; +typedef struct {} SecCEPolicyMappings; +typedef struct {} SecCECertificatePolicies; +typedef struct {} SecCEInhibitAnyPolicy; +#endif __BEGIN_DECLS @@ -76,11 +95,6 @@ CFDictionaryRef SecCertificateCopyAttributeDictionary( SecCertificateRef SecCertificateCreateFromAttributeDictionary( CFDictionaryRef refAttributes); -/* Return a SecKeyRef for the public key embedded in the cert. */ -#if TARGET_OS_OSX -SecKeyRef SecCertificateCopyPublicKey_ios(SecCertificateRef certificate); -#endif - /* Return the SecCEBasicConstraints extension for this certificate if it has one. */ const SecCEBasicConstraints * @@ -133,14 +147,19 @@ CFArrayRef SecCertificateCopyLegacyProperties(SecCertificateRef certificate); OSStatus SecCertificateIsSignedBy(SecCertificateRef certificate, SecKeyRef issuerKey); +#ifndef SECURITY_PROJECT_TAPI_HACKS void appendProperty(CFMutableArrayRef properties, CFStringRef propertyType, - CFStringRef label, CFStringRef localizedLabel, CFTypeRef value); + CFStringRef label, CFStringRef localizedLabel, CFTypeRef value, bool localized); +#endif /* Utility functions. */ CFStringRef SecDERItemCopyOIDDecimalRepresentation(CFAllocatorRef allocator, const DERItem *oid); + +#ifndef SECURITY_PROJECT_TAPI_HACKS CFDataRef createNormalizedX501Name(CFAllocatorRef allocator, const DERItem *x501name); +#endif /* Decode a choice of UTCTime or GeneralizedTime to a CFAbsoluteTime. Return an absoluteTime if the date was valid and properly decoded. Return @@ -165,6 +184,7 @@ bool SecCertificateIsAtLeastMinKeySize(SecCertificateRef certificate, bool SecCertificateIsStrongKey(SecCertificateRef certificate); extern const CFStringRef kSecSignatureDigestAlgorithmUnknown; +#ifndef SECURITY_PROJECT_TAPI_HACKS extern const CFStringRef kSecSignatureDigestAlgorithmMD2; extern const CFStringRef kSecSignatureDigestAlgorithmMD4; extern const CFStringRef kSecSignatureDigestAlgorithmMD5; @@ -173,6 +193,7 @@ extern const CFStringRef kSecSignatureDigestAlgorithmSHA224; extern const CFStringRef kSecSignatureDigestAlgorithmSHA256; extern const CFStringRef kSecSignatureDigestAlgorithmSHA384; extern const CFStringRef kSecSignatureDigestAlgorithmSHA512; +#endif bool SecCertificateIsWeakHash(SecCertificateRef certificate); @@ -185,6 +206,8 @@ CFArrayRef SecCertificateCopyDNSNamesFromSubject(SecCertificateRef certificate); CFArrayRef SecCertificateCopyIPAddressesFromSubject(SecCertificateRef certificate); CFArrayRef SecCertificateCopyRFC822NamesFromSubject(SecCertificateRef certificate); +CFArrayRef SecCertificateCopyDNSNamesFromSAN(SecCertificateRef certificate); + __END_DECLS #endif /* !_SECURITY_SECCERTIFICATEINTERNAL_H_ */ diff --git a/OSX/sec/Security/SecCertificatePath.c b/OSX/sec/Security/SecCertificatePath.c index 373136d2..3ab927f7 100644 --- a/OSX/sec/Security/SecCertificatePath.c +++ b/OSX/sec/Security/SecCertificatePath.c @@ -46,7 +46,7 @@ #include #include #include "SecRSAKey.h" -#include +#include #include #include #include diff --git a/OSX/sec/Security/SecCertificatePath.h b/OSX/sec/Security/SecCertificatePath.h deleted file mode 100644 index efa8eb81..00000000 --- a/OSX/sec/Security/SecCertificatePath.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2007-2009,2012-2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/*! - @header SecCertificatePath - CoreFoundation based certificate path object -*/ - -#ifndef _SECURITY_SECCERTIFICATEPATH_H_ -#define _SECURITY_SECCERTIFICATEPATH_H_ - -#include -#include -#include -#include -#include -#include - -__BEGIN_DECLS - -typedef struct SecCertificatePath *SecCertificatePathRef; - -/* SecCertificatePath API functions. */ -CFTypeID SecCertificatePathGetTypeID(void); - -/* Create a new certificate path from an xpc_array of datas. */ -SecCertificatePathRef SecCertificatePathCreateWithXPCArray(xpc_object_t xpc_path, CFErrorRef *error); - -/* Create a new certificate path from a CFArray of datas. */ -SecCertificatePathRef SecCertificatePathCreateDeserialized(CFArrayRef certificates, CFErrorRef *error); - -/* Create an array of CFDataRefs from a certificate path. */ -xpc_object_t SecCertificatePathCopyXPCArray(SecCertificatePathRef path, CFErrorRef *error); - -/* Create an array of SecCertificateRefs from a certificate path. */ -CFArrayRef SecCertificatePathCopyCertificates(SecCertificatePathRef path, CFErrorRef *error); - -/* Create a new certificate path from an array of SecCertificateRefs. */ -SecCertificatePathRef SecCertificatePathCreateWithCertificates(CFArrayRef certificates, CFErrorRef *error); - -/* Create a serialized Certificate Array from a certificate path. */ -CFArrayRef SecCertificatePathCreateSerialized(SecCertificatePathRef path, CFErrorRef *error); - -CFIndex SecCertificatePathGetCount( - SecCertificatePathRef certificatePath); - -SecCertificateRef SecCertificatePathGetCertificateAtIndex( - SecCertificatePathRef certificatePath, CFIndex ix); - -/* Return the index of certificate in path or kCFNotFound if certificate is - not in path. */ -CFIndex SecCertificatePathGetIndexOfCertificate(SecCertificatePathRef path, - SecCertificateRef certificate); - -SecKeyRef SecCertificatePathCopyPublicKeyAtIndex( - SecCertificatePathRef certificatePath, CFIndex ix); - -__END_DECLS - -#endif /* !_SECURITY_SECCERTIFICATEPATH_H_ */ diff --git a/OSX/sec/Security/SecCertificateRequest.c b/OSX/sec/Security/SecCertificateRequest.c index e24320be..47f853ea 100644 --- a/OSX/sec/Security/SecCertificateRequest.c +++ b/OSX/sec/Security/SecCertificateRequest.c @@ -54,6 +54,7 @@ OSStatus SecCmsArraySortByDER(void **objs, const SecAsn1Template *objtemplate, v #include #include #include +#include #if TARGET_OS_IPHONE #include @@ -65,18 +66,47 @@ OSStatus SecCmsArraySortByDER(void **objs, const SecAsn1Template *objtemplate, v #include "SecCertificateRequest.h" -CFTypeRef kSecOidCommonName = CFSTR("CN"); -CFTypeRef kSecOidCountryName = CFSTR("C"); -CFTypeRef kSecOidStateProvinceName = CFSTR("ST"); -CFTypeRef kSecOidLocalityName = CFSTR("L"); -CFTypeRef kSecOidOrganization = CFSTR("O"); -CFTypeRef kSecOidOrganizationalUnit = CFSTR("OU"); +/* Subject Name Attribute OID constants */ +const CFStringRef kSecOidCommonName = CFSTR("CN"); +const CFStringRef kSecOidCountryName = CFSTR("C"); +const CFStringRef kSecOidStateProvinceName = CFSTR("ST"); +const CFStringRef kSecOidLocalityName = CFSTR("L"); +const CFStringRef kSecOidOrganization = CFSTR("O"); +const CFStringRef kSecOidOrganizationalUnit = CFSTR("OU"); //CFTypeRef kSecOidEmailAddress = CFSTR("1.2.840.113549.1.9.1"); // keep natural order: C > ST > L > O > OU > CN > Email +/* Type constants */ const unsigned char SecASN1PrintableString = SEC_ASN1_PRINTABLE_STRING; const unsigned char SecASN1UTF8String = SEC_ASN1_UTF8_STRING; +/* Parameter dictionary keys */ +const CFStringRef kSecCSRChallengePassword = CFSTR("csrChallengePassword"); +const CFStringRef kSecSubjectAltName = CFSTR("subjectAltName"); +const CFStringRef kSecCertificateKeyUsage = CFSTR("keyUsage"); +const CFStringRef kSecCSRBasicContraintsPathLen = CFSTR("basicConstraints"); +const CFStringRef kSecCertificateExtensions = CFSTR("certificateExtensions"); +const CFStringRef kSecCertificateExtensionsEncoded = CFSTR("certificateExtensionsEncoded"); + +/* SubjectAltName dictionary keys */ +const CFStringRef kSecSubjectAltNameDNSName = CFSTR("dNSName"); +const CFStringRef kSecSubjectAltNameEmailAddress = CFSTR("rfc822Name"); +const CFStringRef kSecSubjectAltNameURI = CFSTR("uniformResourceIdentifier"); +const CFStringRef kSecSubjectAltNameNTPrincipalName = CFSTR("ntPrincipalName"); + +/* PKCS9 OIDs */ +static const uint8_t pkcs9ExtensionsRequested[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 14 }; +static const uint8_t pkcs9ChallengePassword[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 7 }; + +/* ASN1 BOOLEAN TRUE */ +static const uint8_t encoded_asn1_true = 0xFF; +static const SecAsn1Item asn1_true = +{ sizeof(encoded_asn1_true), (uint8_t*)&encoded_asn1_true }; + +/* ASN1 NULL */ +static const uint8_t encoded_null[2] = { SEC_ASN1_NULL, 0 }; +static const SecAsn1Item asn1_null = { sizeof(encoded_null), (uint8_t*)encoded_null }; + static uint8_t * mod128_oid_encoding_ptr(uint8_t *ptr, uint32_t src, bool final) { if (src > 128) @@ -160,7 +190,7 @@ static inline bool printable_string(CFStringRef string) } static bool make_nss_atv(PRArenaPool *poolp, - const void * oid, const void * value, const unsigned char type_in, NSS_ATV *nss_atv) + CFTypeRef oid, const void * value, const unsigned char type_in, NSS_ATV *nss_atv) { size_t length = 0; char *buffer = NULL; @@ -291,13 +321,13 @@ static void make_general_names(const void *key, const void *value, void *context } NSS_GeneralName general_name_item = { { }, -1 }; - if (kCFCompareEqualTo == CFStringCompare(CFSTR("dNSName"), key, kCFCompareCaseInsensitive)) + if (kCFCompareEqualTo == CFStringCompare(kSecSubjectAltNameDNSName, key, kCFCompareCaseInsensitive)) general_name_item.tag = NGT_DNSName; - else if (kCFCompareEqualTo == CFStringCompare(CFSTR("rfc822Name"), key, kCFCompareCaseInsensitive)) + else if (kCFCompareEqualTo == CFStringCompare(kSecSubjectAltNameEmailAddress, key, kCFCompareCaseInsensitive)) general_name_item.tag = NGT_RFC822Name; - else if (kCFCompareEqualTo == CFStringCompare(CFSTR("uniformResourceIdentifier"), key, kCFCompareCaseInsensitive)) + else if (kCFCompareEqualTo == CFStringCompare(kSecSubjectAltNameURI, key, kCFCompareCaseInsensitive)) general_name_item.tag = NGT_URI; - else if (kCFCompareEqualTo == CFStringCompare(CFSTR("ntPrincipalName"), key, kCFCompareCaseInsensitive)) + else if (kCFCompareEqualTo == CFStringCompare(kSecSubjectAltNameNTPrincipalName, key, kCFCompareCaseInsensitive)) { /* NT Principal in SubjectAltName is defined in the context of Smartcards: @@ -404,20 +434,6 @@ static SecAsn1Item make_subjectAltName_extension(PRArenaPool *poolp, CFDictionar return subjectAltExt; } -CFTypeRef kSecCSRChallengePassword = CFSTR("csrChallengePassword"); -CFTypeRef kSecSubjectAltName = CFSTR("subjectAltName"); -CFTypeRef kSecCertificateKeyUsage = CFSTR("keyUsage"); -CFTypeRef kSecCSRBasicContraintsPathLen = CFSTR("basicConstraints"); -CFTypeRef kSecCertificateExtensions = CFSTR("certificateExtensions"); -CFTypeRef kSecCertificateExtensionsEncoded = CFSTR("certificateExtensionsEncoded"); - -static const uint8_t pkcs9ExtensionsRequested[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 14 }; -static const uint8_t pkcs9ChallengePassword[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 7 }; - -static const uint8_t encoded_asn1_true = 0xFF; -static const SecAsn1Item asn1_true = - { sizeof(encoded_asn1_true), (uint8_t*)&encoded_asn1_true }; - struct add_custom_extension_args { PLArenaPool *poolp; NSS_CertExtension *csr_extension; @@ -577,8 +593,6 @@ out: return csr_extensions; } - - static NSS_Attribute **nss_attributes_from_parameters_dict(PRArenaPool *poolp, CFDictionaryRef parameters) { @@ -662,19 +676,125 @@ out: #endif } -static const uint8_t encoded_null[2] = { SEC_ASN1_NULL, 0 }; -static const SecAsn1Item asn1_null = { sizeof(encoded_null), (uint8_t*)encoded_null }; +static CF_RETURNS_RETAINED CFDataRef make_public_key (SecKeyRef publicKey, SecAsn1PubKeyInfo *publicKeyInfo, bool *allocated_parameters) { + CFDataRef publicKeyData = SecKeyCopyExternalRepresentation(publicKey, NULL); + if (!publicKeyData) { return NULL; } + uint8_t *spki_params = NULL; + + if (SecKeyGetAlgorithmId(publicKey) == kSecRSAAlgorithmID) { + publicKeyInfo->algorithm.algorithm.Length = oidRsa.length; + publicKeyInfo->algorithm.algorithm.Data = oidRsa.data; + publicKeyInfo->algorithm.parameters = asn1_null; + *allocated_parameters = false; + } else if (SecKeyGetAlgorithmId(publicKey) == kSecECDSAAlgorithmID) { + publicKeyInfo->algorithm.algorithm.Length = oidEcPubKey.length; + publicKeyInfo->algorithm.algorithm.Data = oidEcPubKey.data; + size_t parameters_size = 0; + SecECNamedCurve namedCurve = SecECKeyGetNamedCurve(publicKey); + switch (namedCurve) { + case kSecECCurveSecp256r1: + parameters_size = oidEcPrime256v1.length + 2; + spki_params = malloc(parameters_size); + memcpy(spki_params + 2, oidEcPrime256v1.data, oidEcPrime256v1.length); + break; + case kSecECCurveSecp384r1: + parameters_size = oidAnsip384r1.length + 2; + spki_params = malloc(parameters_size); + memcpy(spki_params + 2, oidAnsip384r1.data, oidAnsip384r1.length); + break; + case kSecECCurveSecp521r1: + parameters_size = oidAnsip521r1.length + 2; + spki_params = malloc(parameters_size); + memcpy(spki_params + 2, oidAnsip521r1.data, oidAnsip521r1.length); + break; + default: + CFReleaseNull(publicKeyData); + return NULL; + } + spki_params[0] = 0x06; + spki_params[1] = (uint8_t)(parameters_size - 2); + publicKeyInfo->algorithm.parameters.Length = parameters_size; + publicKeyInfo->algorithm.parameters.Data = spki_params; + *allocated_parameters = true; + } else { + CFReleaseNull(publicKeyData); + return NULL; + } + + publicKeyInfo->subjectPublicKey.Data = (uint8_t *)CFDataGetBytePtr(publicKeyData); + publicKeyInfo->subjectPublicKey.Length = CFDataGetLength(publicKeyData) * 8; + + return publicKeyData; +} + +static CF_RETURNS_RETAINED CFDataRef make_signature (void *data_pointer, size_t data_length, SecKeyRef privateKey, + CFStringRef digestAlgorithm, SecAsn1AlgId *signature_algorithm_info) { + SecKeyAlgorithm keyAlgorithm = NULL; + CFIndex keyAlgorithmId = SecKeyGetAlgorithmId(privateKey); + if (keyAlgorithmId == kSecRSAAlgorithmID) { + if (!digestAlgorithm || CFEqualSafe(digestAlgorithm, kSecCMSHashingAlgorithmSHA1)) { + /* default is SHA-1 for backwards compatibility */ + keyAlgorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1; + signature_algorithm_info->algorithm.Length = oidSha1Rsa.length; + signature_algorithm_info->algorithm.Data = oidSha1Rsa.data; + } else if (CFEqualSafe(digestAlgorithm, kSecCMSHashingAlgorithmSHA256)) { + keyAlgorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256; + signature_algorithm_info->algorithm.Length = oidSha256Rsa.length; + signature_algorithm_info->algorithm.Data = oidSha256Rsa.data; + } else if (CFEqualSafe(digestAlgorithm, kSecCMSHashingAlgorithmSHA384)) { + keyAlgorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384; + signature_algorithm_info->algorithm.Length = oidSha384Rsa.length; + signature_algorithm_info->algorithm.Data = oidSha384Rsa.data; + } else if (CFEqualSafe(digestAlgorithm, kSecCMSHashingAlgorithmSHA512)) { + keyAlgorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512; + signature_algorithm_info->algorithm.Length = oidSha512Rsa.length; + signature_algorithm_info->algorithm.Data = oidSha512Rsa.data; + } + /* All RSA signatures use NULL paramters */ + signature_algorithm_info->parameters = asn1_null; + } else if (keyAlgorithmId == kSecECDSAAlgorithmID) { + if (!digestAlgorithm || CFEqualSafe(digestAlgorithm, kSecCMSHashingAlgorithmSHA256)) { + keyAlgorithm = kSecKeyAlgorithmECDSASignatureMessageX962SHA256; + signature_algorithm_info->algorithm.Length = oidSha256Ecdsa.length; + signature_algorithm_info->algorithm.Data = oidSha256Ecdsa.data; + } else if (CFEqualSafe(digestAlgorithm, kSecCMSHashingAlgorithmSHA384)) { + keyAlgorithm = kSecKeyAlgorithmECDSASignatureMessageX962SHA384; + signature_algorithm_info->algorithm.Length = oidSha384Ecdsa.length; + signature_algorithm_info->algorithm.Data = oidSha384Ecdsa.data; + } else if (CFEqualSafe(digestAlgorithm, kSecCMSHashingAlgorithmSHA512)) { + keyAlgorithm = kSecKeyAlgorithmECDSASignatureMessageX962SHA512; + signature_algorithm_info->algorithm.Length = oidSha512Ecdsa.length; + signature_algorithm_info->algorithm.Data = oidSha512Ecdsa.data; + } + /* All EC signatures use absent paramters */ + signature_algorithm_info->parameters.Length = 0; + signature_algorithm_info->parameters.Data = NULL; + } + + if (!keyAlgorithm) { return NULL; } + + CFDataRef data = NULL, signature = NULL; + if (!data_pointer || data_length == 0) { return NULL; } + data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, data_pointer, data_length, kCFAllocatorNull); + signature = SecKeyCreateSignature(privateKey, keyAlgorithm, data, NULL); + CFReleaseSafe(data); + if (!signature) { return NULL; } + + return signature; +} CFDataRef SecGenerateCertificateRequestWithParameters(SecRDN *subject, - CFDictionaryRef parameters, SecKeyRef publicKey, SecKeyRef privateKey) + CFDictionaryRef parameters, SecKeyRef __unused publicKey, SecKeyRef privateKey) { if (subject == NULL || *subject == NULL) { return NULL; } CFDataRef csr = NULL; - CFDataRef publicKeyData= NULL; - uint8_t *signature = NULL, *spki_params = NULL; + CFDataRef publicKeyData= NULL, signature = NULL; + bool allocated_parameters = false; + SecKeyRef realPublicKey = NULL; /* We calculate this from the private key rather than + * trusting the caller to give us the right one. */ PRArenaPool *poolp = PORT_NewArena(1024); if (!poolp) @@ -723,43 +843,10 @@ CFDataRef SecGenerateCertificateRequestWithParameters(SecRDN *subject, certReq.reqInfo.subject.rdns = rdnps; /* public key info */ - if (SecKeyGetAlgorithmId(publicKey) == kSecRSAAlgorithmID) { - certReq.reqInfo.subjectPublicKeyInfo.algorithm.algorithm.Length = oidRsa.length; - certReq.reqInfo.subjectPublicKeyInfo.algorithm.algorithm.Data = oidRsa.data; - certReq.reqInfo.subjectPublicKeyInfo.algorithm.parameters = asn1_null; - } else if (SecKeyGetAlgorithmId(publicKey) == kSecECDSAAlgorithmID) { - certReq.reqInfo.subjectPublicKeyInfo.algorithm.algorithm.Length = oidEcPubKey.length; - certReq.reqInfo.subjectPublicKeyInfo.algorithm.algorithm.Data = oidEcPubKey.data; - size_t parameters_size = 0; - SecECNamedCurve namedCurve = SecECKeyGetNamedCurve(publicKey); - switch (namedCurve) { - case kSecECCurveSecp256r1: - parameters_size = oidEcPrime256v1.length + 2; - spki_params = malloc(parameters_size); - memcpy(spki_params + 2, oidEcPrime256v1.data, oidEcPrime256v1.length); - break; - case kSecECCurveSecp384r1: - parameters_size = oidAnsip384r1.length + 2; - spki_params = malloc(parameters_size); - memcpy(spki_params + 2, oidAnsip384r1.data, oidAnsip384r1.length); - break; - case kSecECCurveSecp521r1: - parameters_size = oidAnsip521r1.length + 2; - spki_params = malloc(parameters_size); - memcpy(spki_params + 2, oidAnsip521r1.data, oidAnsip521r1.length); - break; - default: - goto out; - } - spki_params[0] = 0x06; - spki_params[1] = (uint8_t)(parameters_size - 2); - certReq.reqInfo.subjectPublicKeyInfo.algorithm.parameters.Length = parameters_size; - certReq.reqInfo.subjectPublicKeyInfo.algorithm.parameters.Data = spki_params; - } - - publicKeyData = SecKeyCopyExternalRepresentation(publicKey, NULL); - certReq.reqInfo.subjectPublicKeyInfo.subjectPublicKey.Length = 8 * CFDataGetLength(publicKeyData); - certReq.reqInfo.subjectPublicKeyInfo.subjectPublicKey.Data = (uint8_t*)CFDataGetBytePtr(publicKeyData); + realPublicKey = SecKeyCopyPublicKey(privateKey); + require_quiet(realPublicKey, out); + publicKeyData = make_public_key(realPublicKey, &certReq.reqInfo.subjectPublicKeyInfo, &allocated_parameters); + require_quiet(publicKeyData, out); certReq.reqInfo.attributes = nss_attributes_from_parameters_dict(poolp, parameters); SecCmsArraySortByDER((void **)certReq.reqInfo.attributes, kSecAsn1AttributeTemplate, NULL); @@ -768,49 +855,15 @@ CFDataRef SecGenerateCertificateRequestWithParameters(SecRDN *subject, SecAsn1Item reqinfo = {}; SEC_ASN1EncodeItem(poolp, &reqinfo, &certReq.reqInfo, kSecAsn1CertRequestInfoTemplate); - /* Use SHA-1 for RSA for backwards compatbility. */ - if (SecKeyGetAlgorithmId(privateKey) == kSecRSAAlgorithmID) { - /* calculate signature */ - uint8_t reqinfo_hash[CC_SHA1_DIGEST_LENGTH]; - CCDigest(kCCDigestSHA1, reqinfo.Data, (CC_LONG)reqinfo.Length, reqinfo_hash); - CFDataRef digest = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reqinfo_hash, CC_SHA1_DIGEST_LENGTH, kCFAllocatorNull); - CFDataRef sigData = SecKeyCreateSignature(privateKey, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1, - digest, nil); - CFReleaseNull(digest); - require_quiet(sigData, out); - size_t signature_length = (size_t)CFDataGetLength(sigData); - signature = malloc(signature_length); - memcpy(signature, CFDataGetBytePtr(sigData), CFDataGetLength(sigData)); - CFReleaseNull(sigData); - - /* signature and info */ - certReq.signatureAlgorithm.algorithm.Length = oidSha1Rsa.length; - certReq.signatureAlgorithm.algorithm.Data = oidSha1Rsa.data; - certReq.signatureAlgorithm.parameters = asn1_null; - certReq.signature.Data = signature; - certReq.signature.Length = signature_length * 8; - } else if (SecKeyGetAlgorithmId(privateKey) == kSecECDSAAlgorithmID) { - /* calculate signature */ - uint8_t reqinfo_hash[CC_SHA256_DIGEST_LENGTH]; - CCDigest(kCCDigestSHA256, reqinfo.Data, (CC_LONG)reqinfo.Length, reqinfo_hash); - CFDataRef digest = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reqinfo_hash, CC_SHA256_DIGEST_LENGTH, kCFAllocatorNull); - CFDataRef sigData = SecKeyCreateSignature(privateKey, kSecKeyAlgorithmECDSASignatureDigestX962SHA256, - digest, nil); - CFReleaseNull(digest); - require_quiet(sigData, out); - size_t signature_length = (size_t)CFDataGetLength(sigData); - signature = malloc(signature_length); - memcpy(signature, CFDataGetBytePtr(sigData), CFDataGetLength(sigData)); - CFReleaseNull(sigData); - - /* signature and info */ - certReq.signatureAlgorithm.algorithm.Length = oidSha256Ecdsa.length; - certReq.signatureAlgorithm.algorithm.Data = oidSha256Ecdsa.data; - certReq.signatureAlgorithm.parameters.Data = NULL; - certReq.signatureAlgorithm.parameters.Length = 0; - certReq.signature.Data = signature; - certReq.signature.Length = signature_length * 8; + /* calculate signature and encode signature info */ + CFStringRef algorithm = NULL; + if (parameters) { + algorithm = CFDictionaryGetValue(parameters, kSecCMSSignHashAlgorithm); } + signature = make_signature(reqinfo.Data, reqinfo.Length, privateKey, algorithm, &certReq.signatureAlgorithm); + require_quiet(signature, out); + certReq.signature.Data = (uint8_t *)CFDataGetBytePtr(signature); + certReq.signature.Length = 8 * CFDataGetLength(signature); /* encode csr */ SecAsn1Item cert_request = {}; @@ -819,21 +872,26 @@ CFDataRef SecGenerateCertificateRequestWithParameters(SecRDN *subject, csr = CFDataCreate(kCFAllocatorDefault, cert_request.Data, cert_request.Length); out: + if (allocated_parameters) { + free(certReq.reqInfo.subjectPublicKeyInfo.algorithm.parameters.Data); + } if (poolp) PORT_FreeArena(poolp, PR_TRUE); - if (signature) { free(signature); } - if (spki_params) { free(spki_params); } + CFReleaseSafe(realPublicKey); CFReleaseSafe(publicKeyData); + CFReleaseSafe(signature); return csr; } CFDataRef SecGenerateCertificateRequest(CFArrayRef subject, - CFDictionaryRef parameters, SecKeyRef publicKey, SecKeyRef privateKey) + CFDictionaryRef parameters, SecKeyRef __unused publicKey, SecKeyRef privateKey) { CFDataRef csr = NULL; PRArenaPool *poolp = PORT_NewArena(1024); - CFDataRef publicKeyData = NULL; - uint8_t *signature = NULL; + CFDataRef publicKeyData = NULL, signature = NULL; + SecKeyRef realPublicKey = NULL; /* We calculate this from the private key rather than + * trusting the caller to give us the right one. */ + bool allocated_parameters = false; if (!poolp) return NULL; @@ -850,13 +908,10 @@ CFDataRef SecGenerateCertificateRequest(CFArrayRef subject, certReq.reqInfo.subject.rdns = make_subject(poolp, (CFArrayRef)subject); /* public key info */ - certReq.reqInfo.subjectPublicKeyInfo.algorithm.algorithm.Length = oidRsa.length; - certReq.reqInfo.subjectPublicKeyInfo.algorithm.algorithm.Data = oidRsa.data; - certReq.reqInfo.subjectPublicKeyInfo.algorithm.parameters = asn1_null; - - publicKeyData = SecKeyCopyExternalRepresentation(publicKey, NULL); - certReq.reqInfo.subjectPublicKeyInfo.subjectPublicKey.Length = 8 * CFDataGetLength(publicKeyData); - certReq.reqInfo.subjectPublicKeyInfo.subjectPublicKey.Data = (uint8_t*)CFDataGetBytePtr(publicKeyData); + realPublicKey = SecKeyCopyPublicKey(privateKey); + require_quiet(realPublicKey, out); + publicKeyData = make_public_key(realPublicKey, &certReq.reqInfo.subjectPublicKeyInfo, &allocated_parameters); + require_quiet(publicKeyData, out); certReq.reqInfo.attributes = nss_attributes_from_parameters_dict(poolp, parameters); SecCmsArraySortByDER((void **)certReq.reqInfo.attributes, kSecAsn1AttributeTemplate, NULL); @@ -865,25 +920,15 @@ CFDataRef SecGenerateCertificateRequest(CFArrayRef subject, SecAsn1Item reqinfo = {}; SEC_ASN1EncodeItem(poolp, &reqinfo, &certReq.reqInfo, kSecAsn1CertRequestInfoTemplate); - /* calculate signature */ - uint8_t reqinfo_hash[CC_SHA1_DIGEST_LENGTH]; - CCDigest(kCCDigestSHA1, reqinfo.Data, reqinfo.Length, reqinfo_hash); - CFDataRef digest = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reqinfo_hash, CC_SHA1_DIGEST_LENGTH, kCFAllocatorNull); - CFDataRef sigData = SecKeyCreateSignature(privateKey, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1, - digest, nil); - CFReleaseNull(digest); - require_quiet(sigData, out); - size_t signature_length = (size_t)CFDataGetLength(sigData); - signature = malloc(signature_length); - memcpy(signature, CFDataGetBytePtr(sigData), CFDataGetLength(sigData)); - CFReleaseNull(sigData); - - /* signature and info */ - certReq.signatureAlgorithm.algorithm.Length = oidSha1Rsa.length; - certReq.signatureAlgorithm.algorithm.Data = oidSha1Rsa.data; - certReq.signatureAlgorithm.parameters = asn1_null; - certReq.signature.Data = signature; - certReq.signature.Length = signature_length * 8; + /* calculate signature and encode signature info */ + CFStringRef algorithm = NULL; + if (parameters) { + algorithm = CFDictionaryGetValue(parameters, kSecCMSSignHashAlgorithm); + } + signature = make_signature(reqinfo.Data, reqinfo.Length, privateKey, algorithm, &certReq.signatureAlgorithm); + require_quiet(signature, out); + certReq.signature.Data = (uint8_t *)CFDataGetBytePtr(signature); + certReq.signature.Length = 8 * CFDataGetLength(signature); /* encode csr */ SecAsn1Item cert_request = {}; @@ -892,96 +937,121 @@ CFDataRef SecGenerateCertificateRequest(CFArrayRef subject, csr = CFDataCreate(kCFAllocatorDefault, cert_request.Data, cert_request.Length); out: + if (allocated_parameters) { + free(certReq.reqInfo.subjectPublicKeyInfo.algorithm.parameters.Data); + } if (poolp) PORT_FreeArena(poolp, PR_TRUE); + CFReleaseSafe(realPublicKey); CFReleaseSafe(publicKeyData); - if (signature) { free(signature); } + CFReleaseSafe(signature); return csr; } +static SecKeyAlgorithm determine_key_algorithm(bool isRsa, SecAsn1AlgId *algId) { + SecKeyAlgorithm keyAlg = NULL; + SecAsn1Oid oid = algId->algorithm; + + /* We don't check the parameters match the algorithm OID since there was some RFC confusion + * about NULL or absent parameters. */ + if (isRsa) { + if (oid.Length == oidSha1Rsa.length && + (0 == memcmp(oidSha1Rsa.data, oid.Data, oid.Length))) { + keyAlg = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1; + } else if (oid.Length == oidSha256Rsa.length && + (0 == memcmp(oidSha256Rsa.data, oid.Data, oid.Length))) { + keyAlg = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256; + } else if (oid.Length == oidSha384Rsa.length && + (0 == memcmp(oidSha384Rsa.data, oid.Data, oid.Length))) { + keyAlg = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384; + } else if (oid.Length == oidSha512Rsa.length && + (0 == memcmp(oidSha512Rsa.data, oid.Data, oid.Length))) { + keyAlg = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512; + } + } else { + if (oid.Length == oidSha256Ecdsa.length && + (0 == memcmp(oidSha256Ecdsa.data, oid.Data, oid.Length))) { + keyAlg = kSecKeyAlgorithmECDSASignatureMessageX962SHA256; + } else if (oid.Length == oidSha384Ecdsa.length && + (0 == memcmp(oidSha384Ecdsa.data, oid.Data, oid.Length))) { + keyAlg = kSecKeyAlgorithmECDSASignatureMessageX962SHA384; + } else if (oid.Length == oidSha512Ecdsa.length && + (0 == memcmp(oidSha512Ecdsa.data, oid.Data, oid.Length))) { + keyAlg = kSecKeyAlgorithmECDSASignatureMessageX962SHA512; + } + } + + return keyAlg; +} + bool SecVerifyCertificateRequest(CFDataRef csr, SecKeyRef *publicKey, CFStringRef *challenge, CFDataRef *subject, CFDataRef *extensions) { PRArenaPool *poolp = PORT_NewArena(1024); SecKeyRef candidatePublicKey = NULL; CFMutableDictionaryRef keyAttrs = NULL; - CFDataRef keyData = NULL, hash = NULL, signature = NULL; + CFDataRef keyData = NULL, signature = NULL, data = NULL; bool valid = false; - NSSCertRequest certReq; - memset(&certReq, 0, sizeof(certReq)); + NSSCertRequest decodedCertReq; + NSS_SignedCertRequest undecodedCertReq; + memset(&decodedCertReq, 0, sizeof(decodedCertReq)); + memset(&undecodedCertReq, 0, sizeof(undecodedCertReq)); + + /* Decode the CSR */ SecAsn1Item csr_item = { CFDataGetLength(csr), (uint8_t*)CFDataGetBytePtr(csr) }; - require_noerr_quiet(SEC_ASN1DecodeItem(poolp, &certReq, kSecAsn1CertRequestTemplate, + require_noerr_quiet(SEC_ASN1DecodeItem(poolp, &decodedCertReq, kSecAsn1CertRequestTemplate, + &csr_item), out); + require_noerr_quiet(SEC_ASN1DecodeItem(poolp, &undecodedCertReq, kSecAsn1SignedCertRequestTemplate, &csr_item), out); - /* signature and info */ - require(certReq.signatureAlgorithm.algorithm.Length == oidSha1Rsa.length || - certReq.signatureAlgorithm.algorithm.Length == oidSha256Ecdsa.length, out); - require(0 == memcmp(oidSha1Rsa.data, certReq.signatureAlgorithm.algorithm.Data, - oidSha1Rsa.length) || - 0 == memcmp(oidSha256Ecdsa.data, certReq.signatureAlgorithm.algorithm.Data, - oidSha256Ecdsa.length), out); - require(certReq.signatureAlgorithm.parameters.Length == asn1_null.Length || - certReq.signatureAlgorithm.parameters.Length == 0, out); - require(certReq.signatureAlgorithm.parameters.Length == 0 || - 0 == memcmp(asn1_null.Data, certReq.signatureAlgorithm.parameters.Data, - asn1_null.Length), out); - - /* encode request info by itself to calculate signature */ - SecAsn1Item reqinfo = {}; - SEC_ASN1EncodeItem(poolp, &reqinfo, &certReq.reqInfo, kSecAsn1CertRequestInfoTemplate); - - /* calculate signature */ - uint8_t reqinfo_hash[CC_SHA256_DIGEST_LENGTH]; - CFIndex hash_size = 0; - if (0 == memcmp(oidSha1Rsa.data, certReq.signatureAlgorithm.algorithm.Data, - oidSha1Rsa.length)) { - require(reqinfo.Length<=UINT32_MAX, out); - CCDigest(kCCDigestSHA1, reqinfo.Data, (CC_LONG)reqinfo.Length, reqinfo_hash); - hash_size = CC_SHA1_DIGEST_LENGTH; - } else { - require(reqinfo.Length<=UINT32_MAX, out); - CCDigest(kCCDigestSHA256, reqinfo.Data, (CC_LONG)reqinfo.Length, reqinfo_hash); - hash_size = CC_SHA256_DIGEST_LENGTH; - } - - /* @@@ check for version 0 */ - SecKeyAlgorithm alg = NULL; - if (certReq.reqInfo.subjectPublicKeyInfo.algorithm.algorithm.Length == oidRsa.length && - 0 == memcmp(oidRsa.data, certReq.reqInfo.subjectPublicKeyInfo.algorithm.algorithm.Data, oidRsa.length)) { + /* get public key */ + bool isRsa = true; + if (decodedCertReq.reqInfo.subjectPublicKeyInfo.algorithm.algorithm.Length == oidRsa.length && + 0 == memcmp(oidRsa.data, decodedCertReq.reqInfo.subjectPublicKeyInfo.algorithm.algorithm.Data, oidRsa.length)) { require(candidatePublicKey = SecKeyCreateRSAPublicKey(kCFAllocatorDefault, - certReq.reqInfo.subjectPublicKeyInfo.subjectPublicKey.Data, - certReq.reqInfo.subjectPublicKeyInfo.subjectPublicKey.Length / 8, + decodedCertReq.reqInfo.subjectPublicKeyInfo.subjectPublicKey.Data, + decodedCertReq.reqInfo.subjectPublicKeyInfo.subjectPublicKey.Length / 8, kSecKeyEncodingPkcs1), out); - alg = kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1; - } else if (certReq.reqInfo.subjectPublicKeyInfo.algorithm.algorithm.Length == oidEcPubKey.length && - 0 == memcmp(oidEcPubKey.data, certReq.reqInfo.subjectPublicKeyInfo.algorithm.algorithm.Data, oidEcPubKey.length)) { + } else if (decodedCertReq.reqInfo.subjectPublicKeyInfo.algorithm.algorithm.Length == oidEcPubKey.length && + 0 == memcmp(oidEcPubKey.data, decodedCertReq.reqInfo.subjectPublicKeyInfo.algorithm.algorithm.Data, oidEcPubKey.length)) { keyData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, - certReq.reqInfo.subjectPublicKeyInfo.subjectPublicKey.Data, - certReq.reqInfo.subjectPublicKeyInfo.subjectPublicKey.Length / 8, - kCFAllocatorNull); + decodedCertReq.reqInfo.subjectPublicKeyInfo.subjectPublicKey.Data, + decodedCertReq.reqInfo.subjectPublicKeyInfo.subjectPublicKey.Length / 8, + kCFAllocatorNull); keyAttrs = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); + &kCFTypeDictionaryValueCallBacks); CFDictionaryAddValue(keyAttrs, kSecAttrKeyType, kSecAttrKeyTypeECSECPrimeRandom); CFDictionaryAddValue(keyAttrs, kSecAttrKeyClass, kSecAttrKeyClassPublic); require(candidatePublicKey = SecKeyCreateWithData(keyData, keyAttrs, NULL), out); - alg = kSecKeyAlgorithmECDSASignatureDigestX962SHA256; + isRsa = false; } else { goto out; } - hash = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reqinfo_hash, hash_size, kCFAllocatorNull); - signature = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, certReq.signature.Data, certReq.signature.Length / 8, kCFAllocatorNull); - require_quiet(SecKeyVerifySignature(candidatePublicKey, alg, hash, signature, NULL), out); + /* get the signature algorithm */ + SecAsn1AlgId algId = decodedCertReq.signatureAlgorithm; + /* check the parameters are NULL or absent */ + require(algId.parameters.Length == asn1_null.Length || algId.parameters.Length == 0, out); + require(algId.parameters.Length == 0 || 0 == memcmp(asn1_null.Data, algId.parameters.Data, asn1_null.Length), out); + SecKeyAlgorithm alg = determine_key_algorithm(isRsa, &algId); + + /* verify signature */ + signature = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, undecodedCertReq.signature.Data, + undecodedCertReq.signature.Length / 8, kCFAllocatorNull); + data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, undecodedCertReq.certRequestBlob.Data, + undecodedCertReq.certRequestBlob.Length, kCFAllocatorNull); + require_quiet(alg && signature && data, out); + require_quiet(SecKeyVerifySignature(candidatePublicKey, alg, data, signature, NULL), out); SecAsn1Item subject_item = { 0 }, extensions_item = { 0 }, challenge_item = { 0 }; require_quiet(SEC_ASN1EncodeItem(poolp, &subject_item, - &certReq.reqInfo.subject, kSecAsn1NameTemplate), out); + &decodedCertReq.reqInfo.subject, kSecAsn1NameTemplate), out); - if (*certReq.reqInfo.attributes) { + if (*decodedCertReq.reqInfo.attributes) { uint32_t ix; - for (ix = 0; certReq.reqInfo.attributes[ix]; ix++) { - NSS_Attribute *attr = certReq.reqInfo.attributes[ix]; + for (ix = 0; decodedCertReq.reqInfo.attributes[ix]; ix++) { + NSS_Attribute *attr = decodedCertReq.reqInfo.attributes[ix]; if ( (sizeof(pkcs9ChallengePassword) == attr->attrType.Length) && !memcmp(pkcs9ChallengePassword, attr->attrType.Data, sizeof(pkcs9ChallengePassword))) challenge_item = *attr->attrValue[0]; @@ -1014,7 +1084,7 @@ out: CFReleaseSafe(candidatePublicKey); CFReleaseNull(keyAttrs); CFReleaseNull(keyData); - CFReleaseNull(hash); + CFReleaseNull(data); CFReleaseNull(signature); if (poolp) PORT_FreeArena(poolp, PR_TRUE); @@ -1068,13 +1138,15 @@ DER_CFDateToUTCTime(PRArenaPool *poolp, CFAbsoluteTime date, SecAsn1Item * utcTi SecCertificateRef SecGenerateSelfSignedCertificate(CFArrayRef subject, CFDictionaryRef parameters, - SecKeyRef publicKey, SecKeyRef privateKey) + SecKeyRef __unused publicKey, SecKeyRef privateKey) { SecCertificateRef cert = NULL; PRArenaPool *poolp = PORT_NewArena(1024); CFDictionaryRef pubkey_attrs = NULL; - CFDataRef publicKeyData = NULL; - uint8_t *signature = NULL; + CFDataRef publicKeyData = NULL, signature = NULL; + SecKeyRef realPublicKey = NULL; /* We calculate this from the private key rather than + * trusting the caller to give us the right one. */ + bool allocated_parameters = false; if (!poolp) return NULL; @@ -1103,72 +1175,65 @@ SecGenerateSelfSignedCertificate(CFArrayRef subject, CFDictionaryRef parameters, /* extensions */ cert_tmpl.tbs.extensions = extensions_from_parameters(poolp, parameters); - /* @@@ we only handle rsa keys */ - pubkey_attrs = SecKeyCopyAttributeDictionary(publicKey); - CFTypeRef key_type = CFDictionaryGetValue(pubkey_attrs, kSecAttrKeyType); - if (key_type && CFEqual(key_type, kSecAttrKeyTypeRSA)) { - /* public key data and algorithm */ - cert_tmpl.tbs.subjectPublicKeyInfo.algorithm.algorithm = CSSMOID_RSA; - cert_tmpl.tbs.subjectPublicKeyInfo.algorithm.parameters = asn1_null; - - publicKeyData = SecKeyCopyExternalRepresentation(publicKey, NULL); - cert_tmpl.tbs.subjectPublicKeyInfo.subjectPublicKey.Length = 8 * CFDataGetLength(publicKeyData); - cert_tmpl.tbs.subjectPublicKeyInfo.subjectPublicKey.Data = (uint8_t*)CFDataGetBytePtr(publicKeyData); - - /* signature algorithm */ - cert_tmpl.tbs.signature.algorithm = CSSMOID_SHA1WithRSA; - cert_tmpl.tbs.signature.parameters = asn1_null; - cert_tmpl.signatureAlgorithm.algorithm = CSSMOID_SHA1WithRSA; - cert_tmpl.signatureAlgorithm.parameters = asn1_null; - - /* encode request info by itself to calculate signature */ - SecAsn1Item tbscert = {}; - SEC_ASN1EncodeItem(poolp, &tbscert, &cert_tmpl.tbs, kSecAsn1TBSCertificateTemplate); - - /* calculate signature */ - uint8_t tbscert_hash[CC_SHA1_DIGEST_LENGTH]; - CCDigest(kCCDigestSHA1, tbscert.Data, tbscert.Length, tbscert_hash); - CFDataRef digest = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, tbscert_hash, CC_SHA1_DIGEST_LENGTH, kCFAllocatorNull); - CFDataRef sigData = SecKeyCreateSignature(privateKey, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1, - digest, NULL); - CFReleaseNull(digest); - require_quiet(sigData, out); - size_t signature_length = (size_t)CFDataGetLength(sigData); - signature = malloc(signature_length); - memcpy(signature, CFDataGetBytePtr(sigData), CFDataGetLength(sigData)); - CFReleaseNull(sigData); - - /* signature */ - cert_tmpl.signature.Data = signature; - cert_tmpl.signature.Length = signature_length * 8; - - /* encode cert */ - SecAsn1Item signed_cert = {}; - require_quiet(SEC_ASN1EncodeItem(poolp, &signed_cert, &cert_tmpl, - kSecAsn1SignedCertTemplate), out); - cert = SecCertificateCreateWithBytes(kCFAllocatorDefault, - signed_cert.Data, signed_cert.Length); + /* encode public key */ + realPublicKey = SecKeyCopyPublicKey(privateKey); + require_quiet(realPublicKey, out); + publicKeyData = make_public_key(realPublicKey, &cert_tmpl.tbs.subjectPublicKeyInfo, &allocated_parameters); + require_quiet(publicKeyData, out); + + /* encode the signature algorithm info */ + CFStringRef algorithm = NULL; + if (parameters) { + algorithm = CFDictionaryGetValue(parameters, kSecCMSSignHashAlgorithm); } + signature = make_signature(NULL, 0, privateKey, algorithm, &cert_tmpl.tbs.signature); + CFReleaseNull(signature); + + /* encode request info by itself to calculate signature */ + SecAsn1Item tbscert = {}; + SEC_ASN1EncodeItem(poolp, &tbscert, &cert_tmpl.tbs, kSecAsn1TBSCertificateTemplate); + + /* calculate signature and encode signature algorithm info */ + signature = make_signature(tbscert.Data, tbscert.Length, privateKey, algorithm, &cert_tmpl.signatureAlgorithm); + require_quiet(signature, out); + cert_tmpl.signature.Data = (uint8_t *)CFDataGetBytePtr(signature); + cert_tmpl.signature.Length = CFDataGetLength(signature) * 8; + + /* encode cert */ + SecAsn1Item signed_cert = {}; + require_quiet(SEC_ASN1EncodeItem(poolp, &signed_cert, &cert_tmpl, + kSecAsn1SignedCertTemplate), out); + cert = SecCertificateCreateWithBytes(kCFAllocatorDefault, + signed_cert.Data, signed_cert.Length); out: + if (allocated_parameters) { + free(cert_tmpl.tbs.subjectPublicKeyInfo.algorithm.parameters.Data); + } if (poolp) PORT_FreeArena(poolp, PR_TRUE); + CFReleaseSafe(realPublicKey); CFReleaseSafe(pubkey_attrs); CFReleaseNull(publicKeyData); - if (signature) { free(signature); } + CFReleaseNull(signature); return cert; } - SecCertificateRef SecIdentitySignCertificate(SecIdentityRef issuer, CFDataRef serialno, - SecKeyRef publicKey, CFTypeRef subject, CFTypeRef extensions) + SecKeyRef publicKey, CFTypeRef subject, CFTypeRef extensions) { + return SecIdentitySignCertificateWithAlgorithm(issuer, serialno, publicKey, subject, extensions, NULL); +} + +SecCertificateRef +SecIdentitySignCertificateWithAlgorithm(SecIdentityRef issuer, CFDataRef serialno, + SecKeyRef publicKey, CFTypeRef subject, CFTypeRef extensions, CFStringRef hashingAlgorithm) { SecCertificateRef cert = NULL; SecKeyRef privateKey = NULL; - uint8_t *signature = NULL; + bool allocated_parameters = false; PRArenaPool *poolp = PORT_NewArena(1024); - CFDataRef publicKeyData = NULL; + CFDataRef publicKeyData = NULL, signature = NULL; if (!poolp) return NULL; @@ -1218,58 +1283,41 @@ SecIdentitySignCertificate(SecIdentityRef issuer, CFDataRef serialno, } } - /* @@@ we only handle rsa keys */ - if (SecKeyGetAlgorithmId(publicKey) == kSecRSAAlgorithmID) { - /* public key data and algorithm */ - cert_tmpl.tbs.subjectPublicKeyInfo.algorithm.algorithm = CSSMOID_RSA; - cert_tmpl.tbs.subjectPublicKeyInfo.algorithm.parameters = asn1_null; - - publicKeyData = SecKeyCopyExternalRepresentation(publicKey, NULL); - cert_tmpl.tbs.subjectPublicKeyInfo.subjectPublicKey.Length = 8 * CFDataGetLength(publicKeyData); - cert_tmpl.tbs.subjectPublicKeyInfo.subjectPublicKey.Data = (uint8_t*)CFDataGetBytePtr(publicKeyData); - - /* signature algorithm */ - cert_tmpl.tbs.signature.algorithm = CSSMOID_SHA1WithRSA; - cert_tmpl.tbs.signature.parameters = asn1_null; - cert_tmpl.signatureAlgorithm.algorithm = CSSMOID_SHA1WithRSA; - cert_tmpl.signatureAlgorithm.parameters = asn1_null; - - /* encode request info by itself to calculate signature */ - SecAsn1Item tbscert = {}; - SEC_ASN1EncodeItem(poolp, &tbscert, &cert_tmpl.tbs, kSecAsn1TBSCertificateTemplate); - - /* calculate signature */ - uint8_t tbscert_hash[CC_SHA1_DIGEST_LENGTH]; - CCDigest(kCCDigestSHA1, tbscert.Data, tbscert.Length, tbscert_hash); - - require_noerr_quiet(SecIdentityCopyPrivateKey(issuer, &privateKey), out); - CFDataRef digest = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, tbscert_hash, CC_SHA1_DIGEST_LENGTH, kCFAllocatorNull); - CFDataRef sigData = SecKeyCreateSignature(privateKey, kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA1, - digest, NULL); - CFReleaseNull(digest); - require_quiet(sigData, out); - size_t signature_length = (size_t)CFDataGetLength(sigData); - signature = malloc(signature_length); - memcpy(signature, CFDataGetBytePtr(sigData), CFDataGetLength(sigData)); - CFReleaseNull(sigData); - - /* signature */ - cert_tmpl.signature.Data = signature; - cert_tmpl.signature.Length = signature_length * 8; - - /* encode cert */ - SecAsn1Item signed_cert = {}; - require_quiet(SEC_ASN1EncodeItem(poolp, &signed_cert, &cert_tmpl, - kSecAsn1SignedCertTemplate), out); - cert = SecCertificateCreateWithBytes(kCFAllocatorDefault, - signed_cert.Data, signed_cert.Length); - } + /* subject public key info */ + publicKeyData = make_public_key(publicKey, &cert_tmpl.tbs.subjectPublicKeyInfo, &allocated_parameters); + require_quiet(publicKeyData, out); + + /* encode the signature algorithm info */ + require_noerr_quiet(SecIdentityCopyPrivateKey(issuer, &privateKey), out); + signature = make_signature(NULL, 0, privateKey, hashingAlgorithm, &cert_tmpl.tbs.signature); + CFReleaseNull(signature); + + /* encode request info by itself to calculate signature */ + SecAsn1Item tbscert = {}; + SEC_ASN1EncodeItem(poolp, &tbscert, &cert_tmpl.tbs, kSecAsn1TBSCertificateTemplate); + + /* calculate signature and encode signature algorithm info */ + signature = make_signature(tbscert.Data, tbscert.Length, privateKey, hashingAlgorithm, &cert_tmpl.signatureAlgorithm); + require_quiet(signature, out); + cert_tmpl.signature.Data = (uint8_t *)CFDataGetBytePtr(signature); + cert_tmpl.signature.Length = CFDataGetLength(signature) * 8; + + /* encode cert */ + SecAsn1Item signed_cert = {}; + require_quiet(SEC_ASN1EncodeItem(poolp, &signed_cert, &cert_tmpl, + kSecAsn1SignedCertTemplate), out); + cert = SecCertificateCreateWithBytes(kCFAllocatorDefault, + signed_cert.Data, signed_cert.Length); + out: - CFReleaseSafe(privateKey); + if (allocated_parameters) { + free(cert_tmpl.tbs.subjectPublicKeyInfo.algorithm.parameters.Data); + } + CFReleaseSafe(privateKey); if (poolp) PORT_FreeArena(poolp, PR_TRUE); CFReleaseSafe(publicKeyData); - if (signature) { free(signature); } + CFReleaseSafe(signature); return cert; } @@ -1283,7 +1331,7 @@ SecGenerateCertificateRequestSubject(SecCertificateRef ca_certificate, CFArrayRe return NULL; /* - Going agains the spec here: + Going against the spec here: 3.2.3. GetCertInitial diff --git a/OSX/sec/Security/SecExports.exp-in b/OSX/sec/Security/SecExports.exp-in index af8c6c75..652bc80c 100644 --- a/OSX/sec/Security/SecExports.exp-in +++ b/OSX/sec/Security/SecExports.exp-in @@ -41,9 +41,8 @@ _SecPasswordValidatePasswordFormat _SecBase64Encode _SecBase64Decode -#if TARGET_OS_IPHONE _SecBase64Encode2 -#endif +_SecBase64Decode2 // // Trust @@ -51,155 +50,55 @@ _SecBase64Encode2 _SecIsInternalRelease // Policies - -_kSecPolicyAppleAppTransportSecurity -_kSecPolicyAppleAST2DiagnosticsServerAuth -_kSecPolicyAppleATVVPNProfileSigning -_kSecPolicyAppleBasicAttestationSystem -_kSecPolicyAppleBasicAttestationUser -_kSecPolicyAppleCodeSigning -_kSecPolicyAppleEAP -_kSecPolicyAppleEscrowProxyCompatibilityServerAuth -_kSecPolicyAppleEscrowProxyServerAuth -_kSecPolicyAppleEscrowService -_kSecPolicyAppleExternalDeveloper -_kSecPolicyAppleFactoryDeviceCertificate -_kSecPolicyAppleFMiPServerAuth -_kSecPolicyAppleGenericApplePinned -_kSecPolicyAppleGenericAppleSSLPinned -_kSecPolicyAppleGSService -_kSecPolicyAppleHomeKitServerAuth -_kSecPolicyAppleiAP -_kSecPolicyAppleiCloudSetupServerAuth -_kSecPolicyAppleiCloudSetupCompatibilityServerAuth -_kSecPolicyAppleIDAuthority -_kSecPolicyAppleIDSService -_kSecPolicyAppleIDSServiceContext -_kSecPolicyAppleIDValidation -_kSecPolicyAppleIDValidationRecordSigning +// kSecPolicy constants +#undef POLICYMACRO +#define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \ +_kSecPolicyApple##NAME +#include "Security/SecPolicy.list" +#undef POLICYMACRO +#define __P_DO_EXPORT_(NAME) +#define __P_DO_EXPORT_P(NAME) _kSecPolicyNameApple##NAME +#define __P_DO_EXPORT_I(NAME) _kSecPolicyName##NAME +#define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \ +__P_DO_EXPORT_##ISPUBLIC(NAME) +#include "SecPolicy.list" +#if TARGET_OS_OSX +_kSecPolicyAppleiChat +#endif _kSecPolicyAppleIDValidationRecordSigningPolicy -_kSecPolicyAppleiPhoneActivation -_kSecPolicyAppleiPhoneApplicationSigning -_kSecPolicyAppleiPhoneDeviceCertificate -_kSecPolicyAppleiPhoneProfileApplicationSigning -_kSecPolicyAppleiPhoneProvisioningProfileSigning -_kSecPolicyAppleiPhoneVPNApplicationSigning -_kSecPolicyAppleIPsec -_kSecPolicyAppleiTunesStoreURLBag -_kSecPolicyAppleLegacyPushService -_kSecPolicyAppleLockdownPairing -_kSecPolicyAppleMacOSProfileApplicationSigning -_kSecPolicyAppleMMCSCompatibilityServerAuth -_kSecPolicyAppleMMCSService -_kSecPolicyAppleMobileAsset -_kSecPolicyAppleMobileAssetDevelopment -_kSecPolicyAppleMobileSoftwareUpdate -_kSecPolicyAppleMobileStore -_kSecPolicyAppleOCSPSigner -_kSecPolicyAppleOSXProvisioningProfileSigning -_kSecPolicyAppleOTAPKISigner -_kSecPolicyAppleOTATasking -_kSecPolicyApplePackageSigning -_kSecPolicyApplePassbookSigning -_kSecPolicyApplePayIssuerEncryption -_kSecPolicyApplePCSEscrowService -_kSecPolicyApplePKINITClient -_kSecPolicyApplePKINITServer -_kSecPolicyApplePPQService -_kSecPolicyApplePPQSigning -_kSecPolicyAppleProfileSigner -_kSecPolicyApplePushService -_kSecPolicyAppleQAProfileSigner -_kSecPolicyAppleRevocation -_kSecPolicyAppleSecureIOStaticAsset -_kSecPolicyAppleServerAuthentication -_kSecPolicyAppleSMIME -_kSecPolicyAppleSMPEncryption -_kSecPolicyAppleSoftwareSigning -_kSecPolicyAppleSSL -_kSecPolicyAppleSWUpdateSigning -_kSecPolicyAppleTestMobileStore -_kSecPolicyAppleTestOTAPKISigner -_kSecPolicyAppleTestPPQSigning -_kSecPolicyAppleTestSMPEncryption -_kSecPolicyAppleTimeStamping -_kSecPolicyAppleTVOSApplicationSigning -_kSecPolicyAppleUniqueDeviceIdentifierCertificate -_kSecPolicyAppleURLBag -_kSecPolicyAppleWarsaw -_kSecPolicyAppleX509Basic _kSecPolicyMacAppStoreReceipt +_kSecPolicyNameAppleAIDCService _kSecPolicyNameAppleAST2Service _kSecPolicyNameAppleEscrowProxyService _kSecPolicyNameAppleFMiPService -_kSecPolicyNameAppleGalaxyProviderService _kSecPolicyNameAppleGSService +_kSecPolicyNameAppleHealthProviderService _kSecPolicyNameAppleHomeKitService _kSecPolicyNameAppleiCloudSetupService _kSecPolicyNameAppleIDSService +_kSecPolicyNameAppleMapsService _kSecPolicyNameAppleMMCSService +_kSecPolicyNameAppleParsecService _kSecPolicyNameApplePPQService _kSecPolicyNameApplePushService +_kSecPolicyNameEAPClient +_kSecPolicyNameEAPServer +_kSecPolicyNameIPSecClient +_kSecPolicyNameIPSecServer +_kSecPolicyNameSMIME +_kSecPolicyNameSSLClient +_kSecPolicyNameSSLServer + // Policy Checks +#undef POLICYCHECKMACRO +#define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) \ +_kSecPolicyCheck##NAME +#include "Security/SecPolicyChecks.list" _kSecPolicyAppleAnchorIncludeTestRoots -_kSecPolicyCheckAnchorSHA1 -_kSecPolicyCheckAnchorSHA256 -_kSecPolicyCheckAnchorApple -_kSecPolicyCheckAnchorTrusted -_kSecPolicyCheckBasicCertificateProcessing -_kSecPolicyCheckBasicConstraints -_kSecPolicyCheckBlackListedKey -_kSecPolicyCheckBlackListedLeaf -_kSecPolicyCheckCertificatePolicy -_kSecPolicyCheckCertificateTransparency -_kSecPolicyCheckChainLength -_kSecPolicyCheckCriticalExtensions -_kSecPolicyCheckEAPTrustedServerNames -_kSecPolicyCheckEmail -_kSecPolicyCheckExtendedKeyUsage -_kSecPolicyCheckExtendedValidation -_kSecPolicyCheckGrayListedKey -_kSecPolicyCheckGrayListedLeaf -_kSecPolicyCheckIdLinkage -_kSecPolicyCheckIntermediateCountry -_kSecPolicyCheckIntermediateEKU -_kSecPolicyCheckIntermediateMarkerOid -_kSecPolicyCheckIntermediateOrganization -_kSecPolicyCheckIntermediateSPKISHA256 -_kSecPolicyCheckIssuerCommonName -_kSecPolicyCheckKeySize -_kSecPolicyCheckKeyUsage -_kSecPolicyCheckLeafMarkerOid -_kSecPolicyCheckLeafMarkerOidWithoutValueCheck -_kSecPolicyCheckLeafMarkersProdAndQA -_kSecPolicyCheckNoNetworkAccess -_kSecPolicyCheckNonEmptySubject -_kSecPolicyCheckNotValidBefore -_kSecPolicyCheckPinningRequired -_kSecPolicyCheckQualifiedCertStatements -_kSecPolicyCheckRevocation _kSecPolicyCheckRevocationAny _kSecPolicyCheckRevocationCRL _kSecPolicyCheckRevocationOCSP -_kSecPolicyCheckRevocationOnline -_kSecPolicyCheckRevocationResponseRequired -_kSecPolicyCheckSignatureHashAlgorithms -_kSecPolicyCheckSSLHostname -_kSecPolicyCheckSubjectCommonName -_kSecPolicyCheckSubjectCommonNamePrefix -_kSecPolicyCheckSubjectCommonNameTEST -_kSecPolicyCheckSubjectOrganization -_kSecPolicyCheckSubjectOrganizationalUnit -_kSecPolicyCheckSystemTrustedWeakHash -_kSecPolicyCheckSystemTrustedWeakKey -_kSecPolicyCheckUsageConstraints -_kSecPolicyCheckValidIntermediates -_kSecPolicyCheckValidLeaf -_kSecPolicyCheckValidRoot -_kSecPolicyCheckWeakIntermediates -_kSecPolicyCheckWeakLeaf -_kSecPolicyCheckWeakRoot _kSecPolicyLeafMarkerProd _kSecPolicyLeafMarkerQA @@ -208,10 +107,12 @@ _kSecPolicyClient _kSecPolicyContext _kSecPolicyIntermediateMarkerOid _kSecPolicyLeafMarkerOid +_kSecPolicyRootDigest _kSecPolicyName _kSecPolicyOid _kSecPolicyPolicyName _kSecPolicyRevocationFlags +_kSecPolicyRootDigest _kSecPolicyTeamIdentifier #if TARGET_OS_OSX @@ -226,96 +127,16 @@ _kSecPolicyKU_KeyEncipherment _kSecPolicyKU_NonRepudiation #endif -_SecPolicyCheckCertEAPTrustedServerNames -_SecPolicyCheckCertEmail -_SecPolicyCheckCertExtendedKeyUsage -_SecPolicyCheckCertLeafMarkerOid -_SecPolicyCheckCertLeafMarkerOidWithoutValueCheck -_SecPolicyCheckCertKeyUsage -_SecPolicyCheckCertNonEmptySubject -_SecPolicyCheckCertNotValidBefore -_SecPolicyCheckCertSignatureHashAlgorithms -_SecPolicyCheckCertSSLHostname -_SecPolicyCheckCertSubjectCommonName -_SecPolicyCheckCertSubjectCommonNamePrefix -_SecPolicyCheckCertSubjectCommonNameTEST +#undef POLICYCHECKMACRO +#define __PC_DO_EXPORT_(NAME) +#define __PC_DO_EXPORT_O(NAME) _SecPolicyCheckCert##NAME +#define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) \ +__PC_DO_EXPORT_##LEAFONLY(NAME) +#include "SecPolicyChecks.list" _SecPolicyCheckCertSubjectCountry -_SecPolicyCheckCertSubjectOrganization -_SecPolicyCheckCertSubjectOrganizationalUnit + _SecPolicyCopyProperties _SecPolicyCreate -_SecPolicyCreateAppleAppTransportSecurity -_SecPolicyCreateAppleAST2Service -_SecPolicyCreateAppleATVVPNProfileSigning -_SecPolicyCreateAppleBasicAttestationSystem -_SecPolicyCreateAppleBasicAttestationUser -_SecPolicyCreateAppleCompatibilityEscrowProxyService -_SecPolicyCreateAppleCompatibilityMMCSService -_SecPolicyCreateAppleCompatibilityiCloudSetupService -_SecPolicyCreateAppleEscrowProxyService -_SecPolicyCreateAppleExternalDeveloper -_SecPolicyCreateAppleFMiPService -_SecPolicyCreateAppleGSService -_SecPolicyCreateAppleHomeKitServerAuth -_SecPolicyCreateAppleiCloudSetupService -_SecPolicyCreateAppleIDAuthorityPolicy -_SecPolicyCreateAppleIDSService -_SecPolicyCreateAppleIDSServiceContext -_SecPolicyCreateAppleIDValidationRecordSigningPolicy -_SecPolicyCreateAppleMMCSService -_SecPolicyCreateApplePackageSigning -_SecPolicyCreateApplePayIssuerEncryption -_SecPolicyCreateApplePinned -_SecPolicyCreateApplePPQService -_SecPolicyCreateApplePPQSigning -_SecPolicyCreateApplePushService -_SecPolicyCreateApplePushServiceLegacy -_SecPolicyCreateAppleSecureIOStaticAsset -_SecPolicyCreateAppleSMPEncryption -_SecPolicyCreateAppleSoftwareSigning -_SecPolicyCreateAppleSSLPinned -_SecPolicyCreateAppleSSLService -_SecPolicyCreateAppleTimeStamping -_SecPolicyCreateAppleTVOSApplicationSigning -_SecPolicyCreateAppleWarsaw -_SecPolicyCreateBasicX509 -_SecPolicyCreateCodeSigning -_SecPolicyCreateConfigurationProfileSigner -_SecPolicyCreateEAP -_SecPolicyCreateEscrowServiceSigner -_SecPolicyCreateFactoryDeviceCertificate -_SecPolicyCreateiAP -_SecPolicyCreateiPhoneActivation -_SecPolicyCreateiPhoneApplicationSigning -_SecPolicyCreateiPhoneDeviceCertificate -_SecPolicyCreateiPhoneProfileApplicationSigning -_SecPolicyCreateiPhoneProvisioningProfileSigning -_SecPolicyCreateiPhoneVPNApplicationSigning -_SecPolicyCreateIPSec -_SecPolicyCreateiTunesStoreURLBag -_SecPolicyCreateLockdownPairing -_SecPolicyCreateMacAppStoreReceipt -_SecPolicyCreateMacOSProfileApplicationSigning -_SecPolicyCreateMobileAsset -_SecPolicyCreateMobileAssetDevelopment -_SecPolicyCreateMobileSoftwareUpdate -_SecPolicyCreateMobileStoreSigner -_SecPolicyCreateOCSPSigner -_SecPolicyCreateOSXProvisioningProfileSigning -_SecPolicyCreateOTAPKISigner -_SecPolicyCreateOTATasking -_SecPolicyCreatePassbookCardSigner -_SecPolicyCreatePCSEscrowServiceSigner -_SecPolicyCreateQAConfigurationProfileSigner -_SecPolicyCreateRevocation -_SecPolicyCreateSSL -_SecPolicyCreateSMIME -_SecPolicyCreateTestApplePPQSigning -_SecPolicyCreateTestAppleSMPEncryption -_SecPolicyCreateTestMobileStoreSigner -_SecPolicyCreateTestOTAPKISigner -_SecPolicyCreateAppleUniqueDeviceCertificate -_SecPolicyCreateURLBag _SecPolicyCreateWithProperties _SecPolicyGetName _SecPolicyGetOidString @@ -339,6 +160,11 @@ _SecPolicySetProperties _SecPolicySetValue #endif +#undef POLICYMACRO +#define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \ +_SecPolicyCreate##FUNCTION +#include "SecPolicy.list" + _kSecCertificateDetailSHA1Digest _kSecCertificateDetailStatusCodes @@ -357,6 +183,7 @@ _kSecPropertyTypeURL _kSecPropertyTypeWarning _kSecSignatureDigestAlgorithmUnknown +#if TARGET_OS_IPHONE _kSecSignatureDigestAlgorithmMD2 _kSecSignatureDigestAlgorithmMD4 _kSecSignatureDigestAlgorithmMD5 @@ -365,6 +192,7 @@ _kSecSignatureDigestAlgorithmSHA224 _kSecSignatureDigestAlgorithmSHA256 _kSecSignatureDigestAlgorithmSHA384 _kSecSignatureDigestAlgorithmSHA512 +#endif _kSecTrustCertificateTransparency _kSecTrustCertificateTransparencyWhiteList @@ -400,17 +228,21 @@ _SecTrustDeserialize _SecTrustEvaluate _SecTrustEvaluateAsync _SecTrustEvaluateLeafOnly +_SecTrustEvaluateWithError +_SecTrustFlushResponseCache _SecTrustGetCertificateAtIndex _SecTrustGetCertificateCount _SecTrustGetDetails _SecTrustGetKeychainsAllowed _SecTrustGetNetworkFetchAllowed -_SecTrustGetOTAPKIAssetVersionNumber _SecTrustGetTrustResult +_SecTrustGetTrustStoreVersionNumber _SecTrustGetTypeID _SecTrustGetVerifyTime +_SecTrustGetTrustExceptionsArray _SecTrustIsExpiredOnly _SecTrustOTAPKIGetUpdatedAsset +_SecTrustReportTLSAnalytics _SecTrustSerialize _SecTrustSetAnchorCertificates _SecTrustSetAnchorCertificatesOnly @@ -427,6 +259,7 @@ _SecTrustSetVerifyDate #if TARGET_OS_OSX _SecTrustCopyAnchorCertificates _SecTrustCopyExtendedResult +_SecTrustCopyPublicKey_ios _SecTrustCopyProperties_ios _SecTrustGetCSSMAnchorCertificates _SecTrustGetCssmResult @@ -443,6 +276,8 @@ _SecTrustSetParameters _SecTrustSetUserTrust _SecTrustSetUserTrustLegacy +_SecTrustSettingsCertHashStrFromCert +_SecTrustSettingsCertHashStrFromData _SecTrustSettingsCopyCertificates _SecTrustSettingsCopyCertificatesForUserAdminDomains _SecTrustSettingsCopyModificationDate @@ -452,6 +287,7 @@ _SecTrustSettingsCopyUnrestrictedRoots _SecTrustSettingsCreateExternalRepresentation _SecTrustSettingsEvaluateCert _SecTrustSettingsImportExternalRepresentation +_SecTrustSettingsPurgeUserAdminCertsCache _SecTrustSettingsRemoveTrustSettings _SecTrustSettingsSetTrustSettings _SecTrustSettingsSetTrustSettingsExternal @@ -470,6 +306,7 @@ _SecTrustedApplicationRemoveEquivalence _SecTrustedApplicationSetData _SecTrustedApplicationUseAlternateSystem _SecTrustedApplicationValidateWithPath + #endif #if TARGET_OS_IPHONE @@ -506,11 +343,13 @@ _SecCertificateCopyCommonNames _SecCertificateCopyCompanyName _SecCertificateCopyCountry _SecCertificateCopyDNSNames +_SecCertificateCopyDNSNamesFromSAN _SecCertificateCopyDNSNamesFromSubject _SecCertificateCopyData _SecCertificateCopyEmailAddresses _SecCertificateCopyEscrowRoots _SecCertificateCopyExtendedKeyUsage +_SecCertificateCopyExtensionValue _SecCertificateCopyiAPAuthCapabilities _SecCertificateCopyIPAddresses _SecCertificateCopyIPAddressesFromSubject @@ -595,6 +434,10 @@ _SecCertificateShow _SecCertificateVersion _SecDistinguishedNameCopyNormalizedContent _SecDistinguishedNameCopyNormalizedSequence + +_SecCertificateArrayCopyXPCArray +_SecCertificateAppendToXPCArray +_SecCertificateCreateWithXPCArrayAtIndex #if TARGET_OS_OSX _SecCertificateAddToKeychain _SecCertificateCopyFieldValues @@ -605,14 +448,13 @@ _SecCertificateCopyNormalizedSubjectContent _SecCertificateCopyPreference _SecCertificateCopyPreferred _SecCertificateCopyPublicKey_ios -_SecCertificateCopyPublicKeyP _SecCertificateCopyPublicKeySHA1DigestFromCertificateData _SecCertificateCopyShortDescription _SecCertificateCopySubjectComponent _SecCertificateCopyValues _SecCertificateCreateFromData _SecCertificateCreateItemImplInstance -_SecCertificateCreateWithDataP +_SecCertificateCreateFromItemImplInstance _SecCertificateFindByEmail _SecCertificateFindByIssuerAndSN _SecCertificateFindBySubjectKeyID @@ -627,6 +469,7 @@ _SecCertificateGetSubject _SecCertificateGetType _SecCertificateInferLabel _SecCertificateIsValidX +_SecCertificateIsItemImplInstance _SecCertificateReleaseFieldValues _SecCertificateReleaseFirstFieldValue _SecCertificateSetPreference @@ -643,24 +486,13 @@ _SecCertificateBundleExport _SecCertificateBundleImport #endif /* TARGET_OS_OSX */ -// -// CertificatePath -// -_SecCertificatePathCopyPublicKeyAtIndex -_SecCertificatePathCopyXPCArray -_SecCertificatePathCreateDeserialized -_SecCertificatePathCreateSerialized -_SecCertificatePathCreateWithCertificates -_SecCertificatePathGetCertificateAtIndex -_SecCertificatePathGetCount -_SecCertificatePathGetIndexOfCertificate - #if TARGET_OS_IPHONE // // SCEP // _SecSCEPCreateTemporaryIdentity _SecSCEPCertifyRequest +_SecSCEPCertifyRequestWithAlgorithms _SecSCEPGenerateCertificateRequest _SecSCEPVerifyReply _SecSCEPValidateCACertMessage @@ -682,53 +514,97 @@ _kSecOidOrganization _kSecOidOrganizationalUnit _kSecOidStateProvinceName _kSecSubjectAltName +_kSecSubjectAltNameDNSName +_kSecSubjectAltNameEmailAddress +_kSecSubjectAltNameNTPrincipalName +_kSecSubjectAltNameURI _SecASN1PrintableString _SecASN1UTF8String _SecGenerateCertificateRequest _SecGenerateCertificateRequestWithParameters _SecGenerateSelfSignedCertificate _SecIdentitySignCertificate +_SecIdentitySignCertificateWithAlgorithm _SecVerifyCertificateRequest -#if TARGET_OS_OSX -_SecCertificateFindRequest -_SecCertificateRequestCreate -_SecCertificateRequestGetData -_SecCertificateRequestGetResult -_SecCertificateRequestGetType -_SecCertificateRequestGetTypeID -_SecCertificateRequestSubmit -#endif +_SecGenerateCertificateRequestSubject // // OTR // -#if TARGET_OS_IPHONE -_SecFDHKAppendCompactPublicSerialization -_SecFDHKAppendPublicSerialization +_SecOTRPacketTypeString +_SecOTRSEndSession +_SecOTRSPrecalculateKeys +_SecOTRSessionCreateRemote +_SecOTRSessionProcessPacketRemote -_SecOTRCopyIncomingBytes -_SecOTRDHKGenerateOTRKeys +_SecOTRAdvertiseHashes _SecOTRFIAppendSerialization _SecOTRFIPurgeAllFromKeychain _SecOTRFIPurgeFromKeychain -_SecOTRFullDHKCreate _SecOTRFullIdentityCreate _SecOTRFullIdentityCreateFromData +_SecOTRFullIdentityCreateFromBytes + _SecOTRPIAppendSerialization -_SecOTRPacketTypeString +_SecOTRPublicIdentityCopyFromPrivate +_SecOTRPublicIdentityCreateFromData +_SecOTRPublicIdentityCreateFromBytes + +#if TARGET_OS_IPHONE +_SecFDHKAppendCompactPublicSerialization +_SecFDHKAppendPublicSerialization + +_SecOTRCopyIncomingBytes +_SecOTRDHKGenerateOTRKeys +_SecOTRFullDHKCreate _SecOTRPublicDHKCreateFromCompactSerialization _SecOTRPublicDHKCreateFromFullKey _SecOTRPublicDHKCreateFromSerialization -_SecOTRPublicIdentityCopyFromPrivate -_SecOTRPublicIdentityCreateFromData -_SecOTRSEndSession _SecOTRSGetKeyID _SecOTRSGetTheirKeyID +_SOSOTRSRoll _SecOTRSKickTimeToRoll -_SecOTRSPrecalculateKeys -_SecOTRSessionCreateRemote -_SecOTRSessionProcessPacketRemote +_SecDHKIsGreater +_SecECKeyGeneratePair +_SecFDHKAppendSerialization +_SecFDHKGetHash +_SecFDHKNewKey +_SecPDHKAppendCompactSerialization +_SecPDHKAppendSerialization +_SecPDHKGetHash +_SecPDHKeyGenerateS + +_SecOTRAppendDHKeyMessage +_SecOTRAppendDHMessage +_SecOTRAppendRevealSignatureMessage +_SecOTRAppendSignatureMessage +_SecOTRCreateError +_SecOTRFIAppendPublicHash +_SecOTRFIAppendSignature +_SecOTRFIComparePublicHash +_SecOTRFICompareToPublicKey +_SecOTRFISignatureSize +_SecOTRFullDHKCreateFromBytes +_SecOTRPIAppendHash +_SecOTRPICompareHash +_SecOTRPICompareToPublicKey +_SecOTRPICopyHash +_SecOTRPIEqual +_SecOTRPIEqualToBytes +_SecOTRPISignatureSize +_SecOTRPIVerifySignature +_SecOTRPrepareOutgoingBytes +_SecOTRPublicDHKCreateFromBytes +_SecOTRSetupInitialRemoteKey + +_kOTRSignatureAlgIDPtr +_DeriveOTR128BitPairFromS +_DeriveOTR256BitsFromS +_DeriveOTR64BitsFromS +_EnsureOTRAlgIDInited +_AES_CTR_HighHalf_Transform +_AES_CTR_IV0_Transform #endif _SecOTRSessionIsSessionInAwaitingState @@ -756,9 +632,7 @@ _SecOTRSessionReset _SecDHComputeKey _SecDHCreate -#if TARGET_OS_IPHONE _SecDHCreateFromAlgorithmId -#endif _SecDHCreateFromParameters _SecDHDecodeParams _SecDHDestroy @@ -833,6 +707,7 @@ _CMSEncoderSetEncoder _CMSEncoderAddSignedAttributes _CMSEncoderSetSigningTime _CMSEncoderSetAppleCodesigningHashAgility +_CMSEncoderSetAppleCodesigningHashAgilityV2 _CMSEncoderSetCertificateChainMode _CMSEncoderGetCertificateChainMode _CMSEncoderUpdateContent @@ -855,6 +730,7 @@ _CMSDecoderCopySignerEmailAddress _CMSDecoderCopySignerCert _CMSDecoderCopySignerSigningTime _CMSDecoderCopySignerAppleCodesigningHashAgility +_CMSDecoderCopySignerAppleCodesigningHashAgilityV2 _SecCMSCertificatesOnlyMessageCopyCertificates _SecCMSCreateCertificatesOnlyMessage _SecCMSCreateCertificatesOnlyMessageIAP @@ -878,6 +754,7 @@ _SecCmsContentInfoSetContentEncAlg _SecCmsContentInfoSetContentEncAlgID _SecCmsContentInfoSetContentEncryptedData _SecCmsContentInfoSetContentEnvelopedData +_SecCmsContentInfoSetContentOther _SecCmsContentInfoSetContentSignedData _SecCmsDecoderCreate _SecCmsDecoderDestroy @@ -916,6 +793,7 @@ _SecCmsMessageIsEncrypted _SecCmsMessageIsSigned _SecCmsRecipientInfoCreate _SecCmsRecipientInfoCreateWithSubjKeyID +_SecCmsRecipientInfoCreateWithSubjKeyIDFromCert _SecCmsSignedDataAddCertChain _SecCmsSignedDataAddCertList _SecCmsSignedDataAddCertificate @@ -935,6 +813,7 @@ _SecCmsSignedDataSignerInfoCount _SecCmsSignedDataVerifyCertsOnly _SecCmsSignedDataVerifySignerInfo _SecCmsSignerInfoAddAppleCodesigningHashAgility +_SecCmsSignerInfoAddAppleCodesigningHashAgilityV2 _SecCmsSignerInfoAddCounterSignature _SecCmsSignerInfoAddMSSMIMEEncKeyPrefs _SecCmsSignerInfoAddSMIMECaps @@ -943,6 +822,7 @@ _SecCmsSignerInfoAddSigningTime _SecCmsSignerInfoCreate _SecCmsSignerInfoCreateWithSubjKeyID _SecCmsSignerInfoGetAppleCodesigningHashAgility +_SecCmsSignerInfoGetAppleCodesigningHashAgilityV2 _SecCmsSignerInfoGetCertList _SecCmsSignerInfoGetDigestAlg _SecCmsSignerInfoGetDigestAlgTag @@ -963,6 +843,7 @@ _kSecCMSCertChainModeNone _kSecCMSEncryptionAlgorithmAESCBC _kSecCMSEncryptionAlgorithmDESCBC _kSecCMSHashAgility +_kSecCMSHashAgilityV2 _kSecCMSHashingAlgorithmMD5 _kSecCMSHashingAlgorithmSHA1 _kSecCMSHashingAlgorithmSHA256 @@ -1068,15 +949,18 @@ _SecCmsSignedDataSignerInfoCount _SecCmsSignedDataVerifyCertsOnly _SecCmsSignedDataVerifySignerInfo _SecCmsSignerInfoAddAppleCodesigningHashAgility +_SecCmsSignerInfoAddAppleCodesigningHashAgilityV2 _SecCmsSignerInfoAddCounterSignature _SecCmsSignerInfoAddMSSMIMEEncKeyPrefs _SecCmsSignerInfoAddSMIMECaps _SecCmsSignerInfoAddSMIMEEncKeyPrefs _SecCmsSignerInfoAddSigningTime +_SecCmsSignerInfoAddTimeStamp _SecCmsSignerInfoCreate _SecCmsSignerInfoCreateWithSubjKeyID _SecCmsSignerInfoDestroy _SecCmsSignerInfoGetAppleCodesigningHashAgility +_SecCmsSignerInfoGetAppleCodesigningHashAgilityV2 _SecCmsSignerInfoGetCertList _SecCmsSignerInfoGetDigestAlg _SecCmsSignerInfoGetDigestAlgTag @@ -1085,15 +969,19 @@ _SecCmsSignerInfoGetSignerCommonName _SecCmsSignerInfoGetSignerEmailAddress _SecCmsSignerInfoGetSigningCertificate _SecCmsSignerInfoGetSigningTime +_SecCmsSignerInfoGetTimestampCertList +_SecCmsSignerInfoGetTimestampSigningCert _SecCmsSignerInfoGetTimestampTime +_SecCmsSignerInfoGetTimestampTimeWithPolicy _SecCmsSignerInfoGetVerificationStatus _SecCmsSignerInfoIncludeCerts _SecCmsSignerInfoSaveSMIMEProfile _SecCmsSignerInfoCopyCertFromEncryptionKeyPreference +_SecCmsSignerInfoVerifyUnAuthAttrs +_SecCmsSignerInfoVerifyUnAuthAttrsWithPolicy _SecCmsTSADefaultCallback _SecCmsTSAGetDefaultContext _SecCmsUtilVerificationStatusToString -_SecTSAResponseCopyDEREncoding _kSecCMSAdditionalCerts _kSecCMSAllCerts _kSecCMSBulkEncryptionAlgorithm @@ -1101,6 +989,7 @@ _kSecCMSCertChainMode _kSecCMSEncryptionAlgorithmAESCBC _kSecCMSEncryptionAlgorithmDESCBC _kSecCMSHashAgility +_kSecCMSHashAgilityV2 _kSecCMSHashingAlgorithmSHA1 _kSecCMSHashingAlgorithmSHA256 _kSecCMSHashingAlgorithmSHA384 @@ -1112,8 +1001,6 @@ _kSecCMSSignHashAlgorithm _kSecCMSSignedAttributes _kTSAContextKeyNoCerts _kTSAContextKeyURL -_kTSADebugContextKeyBadNonce -_kTSADebugContextKeyBadReq #endif // TARGET_OS_OSX _SecCMSVerify @@ -1151,6 +1038,9 @@ _SecECKeyGetNamedCurve _SecKeyCopyAttestationKey #if TARGET_OS_IPHONE _SecKeyCopyAttributeDictionary +_SecKeyCreatePublicFromDER +_SecKeyGeneratePrivateAttributeDictionary +_SecKeyGeneratePublicAttributeDictionary #endif /* TARGET_OS_IPHONE */ _SecKeyCopyAttributes _SecKeyCopyExponent @@ -1288,6 +1178,7 @@ _kSecKeyAlgorithmECDSASignatureMessageX962SHA256 _kSecKeyAlgorithmECDSASignatureMessageX962SHA384 _kSecKeyAlgorithmECDSASignatureMessageX962SHA512 _kSecKeyAlgorithmECDSASignatureRFC4754 +_kSecKeyAlgorithmECIESEncryptionAKSSmartCard _kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA224AESGCM _kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA256AESGCM _kSecKeyAlgorithmECIESEncryptionCofactorVariableIVX963SHA384AESGCM @@ -1697,6 +1588,7 @@ _SecItemCopyParentCertificates_ios _SecItemDelete #if TARGET_OS_IPHONE _SecItemDeleteAll +_SecItemUpdateWithError #endif _SecItemUpdate __SecItemAddAndNotifyOnSync @@ -1708,6 +1600,7 @@ __SecItemCreatePersistentRef __SecItemParsePersistentRef __SecKeychainBackupSyncable __SecKeychainCopyBackup +__SecKeychainCopyEMCSBackup __SecKeychainCopyOTABackup __SecKeychainRestoreBackup __SecKeychainRestoreBackupFromFileDescriptor @@ -1719,10 +1612,16 @@ __SecKeychainCopyKeybagUUIDFromFileDescriptor _SecItemBackupWithRegisteredBackups _SecItemBackupSetConfirmedManifest _SecItemBackupRestore +_SecBackupKeybagAdd +_SecBackupKeybagDelete _SecItemBackupCopyMatching +_SecItemBackupCreateManifest _SecItemBackupWithChanges -#if TARGET_OS_IPHONE +_SecBackupKeybagAdd +_SecBackupKeybagDelete + __SecKeychainRollKeys +#if TARGET_OS_IPHONE _SecAddSharedWebCredential _SecRequestSharedWebCredential @@ -1741,7 +1640,7 @@ _SecItemDeleteAllWithAccessGroups _SecTokenItemValueCopy __SecSecuritydCopyCKKSEndpoint -__SecSecuritydCopySOSStatusEndpoint +__SecSecuritydCopyKeychainControlEndpoint #if TARGET_OS_IPHONE _kSecXPCKeyAttributesToUpdate diff --git a/OSX/sec/Security/SecFramework.c b/OSX/sec/Security/SecFramework.c index 83d7782c..25e219d1 100644 --- a/OSX/sec/Security/SecFramework.c +++ b/OSX/sec/Security/SecFramework.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2010,2012-2014 Apple Inc. All Rights Reserved. + * Copyright (c) 2006-2017 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -106,6 +106,60 @@ CFDataRef SecFrameworkCopyResourceContents(CFStringRef resourceName, return data; } +static CFStringRef copyErrorMessageFromBundle(OSStatus status, CFStringRef tableName); + +// caller MUST release the string, since it is gotten with "CFCopyLocalizedStringFromTableInBundle" +// intended use of reserved param is to pass in CFStringRef with name of the Table for lookup +// Will look by default in "SecErrorMessages.strings" in the resources of Security.framework. + + +CFStringRef +SecCopyErrorMessageString(OSStatus status, void *reserved) +{ + CFStringRef result = copyErrorMessageFromBundle(status, CFSTR("SecErrorMessages")); + if (!result) + result = copyErrorMessageFromBundle(status, CFSTR("SecDebugErrorMessages")); + + if (!result) + { + // no error message found, so format a faked-up error message from the status + result = CFStringCreateWithFormat(NULL, NULL, CFSTR("OSStatus %d"), (int)status); + } + + return result; +} + +CFStringRef +copyErrorMessageFromBundle(OSStatus status,CFStringRef tableName) +{ + + CFStringRef errorString = nil; + CFStringRef keyString = nil; + CFBundleRef secBundle = NULL; + + // Make a bundle instance using the URLRef. + secBundle = CFBundleGetBundleWithIdentifier(kSecFrameworkBundleID); + if (!secBundle) + goto exit; + + // Convert status to Int32 string representation, e.g. "-25924" + keyString = CFStringCreateWithFormat (kCFAllocatorDefault, NULL, CFSTR("%d"), (int)status); + if (!keyString) + goto exit; + + errorString = CFCopyLocalizedStringFromTableInBundle(keyString, tableName, secBundle, NULL); + if (CFStringCompare(errorString, keyString, 0) == kCFCompareEqualTo) // no real error message + { + if (errorString) + CFRelease(errorString); + errorString = nil; + } +exit: + if (keyString) + CFRelease(keyString); + + return errorString; +} const SecRandomRef kSecRandomDefault = NULL; diff --git a/OSX/sec/Security/SecFrameworkStrings.h b/OSX/sec/Security/SecFrameworkStrings.h index 702093b6..8ae87f60 100644 --- a/OSX/sec/Security/SecFrameworkStrings.h +++ b/OSX/sec/Security/SecFrameworkStrings.h @@ -1,15 +1,15 @@ /* - * Copyright (c) 2009,2012-2014 Apple Inc. All Rights Reserved. + * Copyright (c) 2009,2012-2014,2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ */ @@ -39,11 +39,11 @@ __BEGIN_DECLS /* SecCertificate Strings */ #define SEC_NULL_KEY SecStringWithDefaultValue("", "Certificate", 0, "", "Value of a field if its length is 0") -#define SEC_OID_TOO_LONG_KEY SecStringWithDefaultValue("Oid too long", "Certificate", 0, "Oid too long", "value of an oid field if it's length is more than what we allow for oids") +#define SEC_OID_TOO_LONG_KEY SecStringWithDefaultValue("OID too long", "Certificate", 0, "OID too long", "value of an OID field if it's length is more than what we allow for oids") #define SEC_UNPARSED_KEY SecStringWithDefaultValue("Unparsed %@", "Certificate", 0, "Unparsed %@", "Label of a value is printed into this string if the data can not been parsed according to it's type") #define SEC_INVALID_KEY SecStringWithDefaultValue("Invalid %@", "Certificate", 0, "Invalid %@", "Label of a value is printed into this string if the data is not valid") -#define SEC_ALGORITHM_KEY SecStringWithDefaultValue("Algorithm", "Certificate", 0, "Algorithm", "Label of the algorithm subfield of an AlgorithmIdentifer") -#define SEC_PARAMETERS_KEY SecStringWithDefaultValue("Parameters", "Certificate", 0, "Parameters", "Label of the parameters subfield of an AlgorithmIdentifer") +#define SEC_ALGORITHM_KEY SecStringWithDefaultValue("Algorithm", "Certificate", 0, "Algorithm", "Label of the algorithm sub-field of an AlgorithmIdentifer") +#define SEC_PARAMETERS_KEY SecStringWithDefaultValue("Parameters", "Certificate", 0, "Parameters", "Label of the parameters sub-field of an AlgorithmIdentifer") #define SEC_NONE_KEY SecStringWithDefaultValue("none", "Certificate", 0, "none", "field value of parameters field when no parameters are present") #define SEC_BLOB_KEY SecStringWithDefaultValue("%@; %d %@; data = %@", "Certificate", 0, "%@; %d %@; data = %@", "Format string for encoded field data (e.g. Sequence; 128 bytes; data = 00 00 ...)") #define SEC_BYTE_STRING_KEY SecStringWithDefaultValue("Byte string", "Certificate", 0, "Byte string", "First argument to SEC_BLOB_KEY format string for a Byte string") @@ -58,20 +58,20 @@ __BEGIN_DECLS #define SEC_YES_KEY SecStringWithDefaultValue("Yes", "Certificate", 0, "Yes", "Value for a boolean property when it's value is true (example critical: yes)") #define SEC_NO_KEY SecStringWithDefaultValue("No", "Certificate", 0, "No", "Value for a boolean property when it's value is false (example critical: no)") #define SEC_STRING_LIST_KEY SecStringWithDefaultValue("%@, %@", "Certificate", 0, "%@, %@", "Format string used to build a list of values, first argument is list second argument is to be appended element") -#define SEC_DIGITAL_SIGNATURE_KEY SecStringWithDefaultValue("Digital Signature", "Certificate", 0, "Digital Signature", "X.509 key usage bitfield name") -#define SEC_NON_REPUDIATION_KEY SecStringWithDefaultValue("Non-Repudiation", "Certificate", 0, "Non-Repudiation", "X.509 key usage bitfield name") -#define SEC_KEY_ENCIPHERMENT_KEY SecStringWithDefaultValue("Key Encipherment", "Certificate", 0, "Key Encipherment", "X.509 key usage bitfield name") -#define SEC_DATA_ENCIPHERMENT_KEY SecStringWithDefaultValue("Data Encipherment", "Certificate", 0, "Data Encipherment", "X.509 key usage bitfield name") -#define SEC_KEY_AGREEMENT_KEY SecStringWithDefaultValue("Key Agreement", "Certificate", 0, "Key Agreement", "X.509 key usage bitfield name") -#define SEC_CERT_SIGN_KEY SecStringWithDefaultValue("Cert Sign", "Certificate", 0, "Cert Sign", "X.509 key usage bitfield name") -#define SEC_CRL_SIGN_KEY SecStringWithDefaultValue("CRL Sign", "Certificate", 0, "CRL Sign", "X.509 key usage bitfield name") -#define SEC_ENCIPHER_ONLY_KEY SecStringWithDefaultValue("Encipher Only", "Certificate", 0, "Encipher Only", "X.509 key usage bitfield name") -#define SEC_DECIPHER_ONLY_KEY SecStringWithDefaultValue("Decipher Only", "Certificate", 0, "Decipher Only", "X.509 key usage bitfield name") -#define SEC_USAGE_KEY SecStringWithDefaultValue("Usage", "Certificate", 0, "Usage", "Label for KeyUsage bitfield values") +#define SEC_DIGITAL_SIGNATURE_KEY SecStringWithDefaultValue("Digital Signature", "Certificate", 0, "Digital Signature", "X.509 key usage bit-field name") +#define SEC_NON_REPUDIATION_KEY SecStringWithDefaultValue("Non-Repudiation", "Certificate", 0, "Non-Repudiation", "X.509 key usage bit-field name") +#define SEC_KEY_ENCIPHERMENT_KEY SecStringWithDefaultValue("Key Encipherment", "Certificate", 0, "Key Encipherment", "X.509 key usage bit-field name") +#define SEC_DATA_ENCIPHERMENT_KEY SecStringWithDefaultValue("Data Encipherment", "Certificate", 0, "Data Encipherment", "X.509 key usage bit-field name") +#define SEC_KEY_AGREEMENT_KEY SecStringWithDefaultValue("Key Agreement", "Certificate", 0, "Key Agreement", "X.509 key usage bit-field name") +#define SEC_CERT_SIGN_KEY SecStringWithDefaultValue("Cert Sign", "Certificate", 0, "Cert Sign", "X.509 key usage bit-field name") +#define SEC_CRL_SIGN_KEY SecStringWithDefaultValue("CRL Sign", "Certificate", 0, "CRL Sign", "X.509 key usage bit-field name") +#define SEC_ENCIPHER_ONLY_KEY SecStringWithDefaultValue("Encipher Only", "Certificate", 0, "Encipher Only", "X.509 key usage bit-field name") +#define SEC_DECIPHER_ONLY_KEY SecStringWithDefaultValue("Decipher Only", "Certificate", 0, "Decipher Only", "X.509 key usage bit-field name") +#define SEC_USAGE_KEY SecStringWithDefaultValue("Usage", "Certificate", 0, "Usage", "Label for Key Usage bit-field values") #define SEC_NOT_VALID_BEFORE_KEY SecStringWithDefaultValue("Not Valid Before", "Certificate", 0, "Not Valid Before", "label indicating the soonest date at which something is valid") #define SEC_NOT_VALID_AFTER_KEY SecStringWithDefaultValue("Not Valid After", "Certificate", 0, "Not Valid After", "label indicating the date after which something is no longer valid") #define SEC_VALIDITY_PERIOD_KEY SecStringWithDefaultValue("Validity Period", "Certificate", 0, "Validity Period", "") -#define SEC_PRIVATE_KU_PERIOD_KEY SecStringWithDefaultValue("Private Key Usage Period", "Certificate", 0, "Private Key Usage Period", "Label for an invlaid private key se perion value") +#define SEC_PRIVATE_KU_PERIOD_KEY SecStringWithDefaultValue("Private Key Usage Period", "Certificate", 0, "Private Key Usage Period", "Label for an invalid private key usage period value") #define SEC_OTHER_NAME_KEY SecStringWithDefaultValue("Other Name", "Certificate", 0, "Other Name", "Label used for Other Name RDN when value is invalid") #define SEC_EMAIL_ADDRESS_KEY SecStringWithDefaultValue("Email Address", "Certificate", 0, "Email Address", "label for general name field value") #define SEC_DNS_NAME_KEY SecStringWithDefaultValue("DNS Name", "Certificate", 0, "DNS Name", "label for general name field value") @@ -90,10 +90,10 @@ __BEGIN_DECLS /* Name Constraints extension */ #define SEC_NAME_CONSTRAINTS_KEY SecStringWithDefaultValue("Name Constraints", "Certificate", 0, "Name Constraints", "Label used for Name Constraints when value is invalid") #define SEC_PERMITTED_MINIMUM_KEY SecStringWithDefaultValue("Permitted Subtree Minimum", "Certificate", 0, "Permitted Subtree Minimum", "Label for minimum base distance property of a permitted subtree in name constraints extension.") -#define SEC_PERMITTED_MAXIMUM_KEY SecStringWithDefaultValue("Permitted Subtree Maxmimum", "Certificate", 0, "Permitted Subtree Maximum", "Label for maximum base distance property of a permitted subtree in name constraints extension.") +#define SEC_PERMITTED_MAXIMUM_KEY SecStringWithDefaultValue("Permitted Subtree Maximum", "Certificate", 0, "Permitted Subtree Maximum", "Label for maximum base distance property of a permitted subtree in name constraints extension.") #define SEC_PERMITTED_NAME_KEY SecStringWithDefaultValue("Permitted Subtree General Name", "Certificate", 0, "Permitted Subtree General Name", "Label for general name of a permitted subtree in name constraints extension.") #define SEC_EXCLUDED_MINIMUM_KEY SecStringWithDefaultValue("Excluded Subtree Minimum", "Certificate", 0, "Excluded Subtree Minimum", "Label for minimum base distance property of an excluded subtree in name constraints extension.") -#define SEC_EXCLUDED_MAXIMUM_KEY SecStringWithDefaultValue("Excluded Subtree Maxmimum", "Certificate", 0, "Excluded Subtree Maximum", "Label for maximum base distance property of an excluded subtree in name constraints extension.") +#define SEC_EXCLUDED_MAXIMUM_KEY SecStringWithDefaultValue("Excluded Subtree Maximum", "Certificate", 0, "Excluded Subtree Maximum", "Label for maximum base distance property of an excluded subtree in name constraints extension.") #define SEC_EXCLUDED_NAME_KEY SecStringWithDefaultValue("Excluded Subtree General Name", "Certificate", 0, "Excluded Subtree General Name", "Label for general name of an excluded subtree in name constraints extension.") /* CRL Distribution Points extension */ @@ -107,7 +107,7 @@ __BEGIN_DECLS #define SEC_CERTIFICATE_HOLD_KEY SecStringWithDefaultValue("Certificate Hold", "Certificate", 0, "Certificate Hold", "CRL Distribution Points extension supported reason name") #define SEC_PRIV_WITHDRAWN_KEY SecStringWithDefaultValue("Privilege Withdrawn", "Certificate", 0, "Privilege Withdrawn", "CRL Distribution Points extension supported reason name") #define SEC_AA_COMPROMISE_KEY SecStringWithDefaultValue("AA Compromise", "Certificate", 0, "AA Compromise", "CRL Distribution Points extension supported reason name") -#define SEC_REASONS_KEY SecStringWithDefaultValue("Reasons", "Certificate", 0, "Reasons", "CRL Distribution Points extension supported reasons bitfield label") +#define SEC_REASONS_KEY SecStringWithDefaultValue("Reasons", "Certificate", 0, "Reasons", "CRL Distribution Points extension supported reasons bit-field label") #define SEC_CRL_ISSUER_KEY SecStringWithDefaultValue("CRL Issuer", "Certificate", 0, "CRL Issuer", "Label for CRL issuer field of CRL Distribution Points extension") #define SEC_CRL_DISTR_POINTS_KEY SecStringWithDefaultValue("CRL Distribution Points", "Certificate", 0, "CRL Distribution Points", "CRL Distribution Points extension label") @@ -155,7 +155,7 @@ __BEGIN_DECLS #define SEC_CRITICAL_KEY SecStringWithDefaultValue("Critical", "Certificate", 0, "Critical", "Label of field in extension that indicates whether this extension is critical") #define SEC_DATA_KEY SecStringWithDefaultValue("Data", "Certificate", 0, "Data", "Label for raw data of extension (used for unknown extensions)") -#define SEC_COMMON_NAME_DESC_KEY SecStringWithDefaultValue("%@ (%@)", "Certificate", 0, "%@ (%@)", "If a X500 name has a description and a common name we display CommonName (Description) using this format string") +#define SEC_COMMON_NAME_DESC_KEY SecStringWithDefaultValue("%@ (%@)", "Certificate", 0, "%@ (%@)", "If a X.500 name has a description and a common name we display Common Name (Description) using this format string") //#define SEC_ISSUER_SUMMARY_KEY SecStringWithDefaultValue("Issuer Summary", "Certificate", 0, "Issuer Summary", "") //#define SEC_ISSUED_BY_KEY SecStringWithDefaultValue("Issued By", "Certificate", 0, "Issued By", "") @@ -190,15 +190,7 @@ __BEGIN_DECLS #define SEC_SHA1_FINGERPRINT_KEY SecStringWithDefaultValue("SHA-1", "Certificate", 0, "SHA-1", "") #define SEC_SHA2_FINGERPRINT_KEY SecStringWithDefaultValue("SHA-256", "Certificate", 0, "SHA-256", "") -/* SecTrust Strings. */ -#define SEC_INVALID_LINKAGE_KEY SecStringWithDefaultValue("Invalid certificate chain linkage.", "Certificate", 0, "Invalid certificate chain linkage.", "") -#define SEC_BAD_CRIT_EXTN_KEY SecStringWithDefaultValue("One or more unsupported critical extensions found.", "Certificate", 0, "One or more unsupported critical extensions found.", "") -#define SEC_ROOT_UNTRUSTED_KEY SecStringWithDefaultValue("Root certificate is not trusted.", "Certificate", 0, "Root certificate is not trusted.", "") -#define SEC_HOSTNAME_MISMATCH_KEY SecStringWithDefaultValue("Hostname mismatch.", "Certificate", 0, "Hostname mismatch.", "") -#define SEC_POLICY__REQ_NOT_MET_KEY SecStringWithDefaultValue("Policy requirements not met.", "Certificate", 0, "Policy requirements not met.", "") -#define SEC_CHAIN_VALIDITY_ERR_KEY SecStringWithDefaultValue("One or more certificates have expired or are not valid yet.", "Certificate", 0, "One or more certificates have expired or are not valid yet.", "") -#define SEC_WEAK_KEY_ERR_KEY SecStringWithDefaultValue("One or more certificates is using a weak key size.", "Certificate", 0, "One or more certificates is using a weak key size.", "") - +/* Cloud Keychain Strings */ #define SEC_CK_PASSWORD_INCORRECT SecStringWithDefaultValue("Incorrect Password For “%@”", "CloudKeychain", 0, "Incorrect Password For “%@”", "Title for alert when password has been entered incorrectly") #define SEC_CK_TRY_AGAIN SecStringWithDefaultValue("Try Again", "CloudKeychain", 0, "Try Again", "Button for try again after incorrect password") #define SEC_CK_ALLOW SecStringWithDefaultValue("Allow", "CloudKeychain", 0, "Allow", "Allow button") @@ -215,7 +207,7 @@ __BEGIN_DECLS #define SEC_CK_TID_DAYS SecStringWithDefaultValue("days", "CloudKeychain", 0, "days", "More than one day") #define SEC_CK_PWD_REQUIRED_TITLE SecStringWithDefaultValue("Apple ID Password Required", "CloudKeychain", 0, "Apple ID Password Required", "Title for alert when iCloud keychain was disabled or reset") -#define SEC_CK_PWD_REQUIRED_BODY_OSX SecStringWithDefaultValue("Enter your password in iCloud Preferences.", "CloudKeychain", 0, "Enter your password in iCloud Preferences.", "OSX alert text when iCloud keychain was disabled or reset") +#define SEC_CK_PWD_REQUIRED_BODY_OSX SecStringWithDefaultValue("Enter your password in iCloud Preferences.", "CloudKeychain", 0, "Enter your password in iCloud Preferences.", "macOS alert text when iCloud keychain was disabled or reset") #define SEC_CK_PWD_REQUIRED_BODY_IOS SecStringWithDefaultValue("Enter your password in iCloud Settings.", "CloudKeychain", 0, "Enter your password in iCloud Settings.", "iOS alert text when iCloud keychain was disabled or reset") #define SEC_CK_CR_REASON_INTERNAL SecStringWithDefaultValue(" (AppleInternal: departure reason %s)", "CloudKeychain", 0, " (AppleInternal: departure reason %s)", "Display departure reason code on internal devices") #define SEC_CK_CONTINUE SecStringWithDefaultValue("Continue", "CloudKeychain", 0, "Continue", "Button text to continue to iCloud settings (iOS)") @@ -227,8 +219,8 @@ __BEGIN_DECLS #define SEC_CK_APPROVAL_BODY_OSX_IPOD SecStringWithDefaultValue("This iPod wants to use your iCloud account.", "CloudKeychain", 0, "This iPod wants to use your iCloud account.", "Body text when approving an iPod on Mac") #define SEC_CK_APPROVAL_BODY_OSX_MAC SecStringWithDefaultValue("This Mac wants to use your iCloud account.", "CloudKeychain", 0, "This Mac wants to use your iCloud account.", "Body text when approving a Mac on Mac") #define SEC_CK_APPROVAL_BODY_OSX_GENERIC SecStringWithDefaultValue("This device wants to use your iCloud account.", "CloudKeychain", 0, "This device wants to use your iCloud account.", "Body text when approving a device on Mac") -#define SEC_CK_APPROVE SecStringWithDefaultValue("Approve", "CloudKeychain", 0, "Approve", "Button text to approve icloud sign in request") -#define SEC_CK_DECLINE SecStringWithDefaultValue("Decline", "CloudKeychain", 0, "Decline", "Button text to decline icloud sign in request") +#define SEC_CK_APPROVE SecStringWithDefaultValue("Approve", "CloudKeychain", 0, "Approve", "Button text to approve iCloud sign in request") +#define SEC_CK_DECLINE SecStringWithDefaultValue("Decline", "CloudKeychain", 0, "Decline", "Button text to decline iCloud sign in request") #define SEC_CK_APPROVAL_BODY_IOS_IPAD SecStringWithDefaultValue("Enter the password for the Apple ID “%@” to allow this new iPad to use your iCloud account.", "CloudKeychain", 0, "Enter the password for the Apple ID “%@” to allow this new iPad to use your iCloud account.", "Body text when approving an iPad") #define SEC_CK_APPROVAL_BODY_IOS_IPHONE SecStringWithDefaultValue("Enter the password for the Apple ID “%@” to allow this new iPhone to use your iCloud account.", "CloudKeychain", 0, "Enter the password for the Apple ID “%@” to allow this new iPhone to use your iCloud account.", "Body text when approving an iPhone") @@ -246,6 +238,87 @@ __BEGIN_DECLS #define SEC_CK_REMINDER_BUTTON_ICSC SecStringWithDefaultValue("Use Security Code", "CloudKeychain", 0, "Use Security Code", "Button label to approve via iCSC") #define SEC_CK_REMINDER_BUTTON_OK SecStringWithDefaultValue("OK", "CloudKeychain", 0, "OK", "Button label to acknowledge/dismiss reminder alert without further action") +/* Trust errors */ +#define SEC_INVALID_LINKAGE_KEY SecStringWithDefaultValue("Invalid certificate chain linkage.", "Certificate", 0, "Invalid certificate chain linkage.", "") +#define SEC_BAD_CRIT_EXTN_KEY SecStringWithDefaultValue("One or more unsupported critical extensions found.", "Certificate", 0, "One or more unsupported critical extensions found.", "") +#define SEC_ROOT_UNTRUSTED_KEY SecStringWithDefaultValue("Root certificate is not trusted.", "Certificate", 0, "Root certificate is not trusted.", "") +#define SEC_HOSTNAME_MISMATCH_KEY SecStringWithDefaultValue("Hostname mismatch.", "Certificate", 0, "Hostname mismatch.", "") +#define SEC_POLICY__REQ_NOT_MET_KEY SecStringWithDefaultValue("Policy requirements not met.", "Certificate", 0, "Policy requirements not met.", "") +#define SEC_CHAIN_VALIDITY_ERR_KEY SecStringWithDefaultValue("One or more certificates have expired or are not valid yet.", "Certificate", 0, "One or more certificates have expired or are not valid yet.", "") +#define SEC_WEAK_KEY_ERR_KEY SecStringWithDefaultValue("One or more certificates is using a weak key size.", "Certificate", 0, "One or more certificates is using a weak key size.", "") + +#define SEC_TRUST_CERTIFICATE_ERROR SecStringWithDefaultValue("Certificate %ld “%@” has errors: ", "Trust", 0, "Certificate %ld “%@” has errors: ", "Preface for per-certificate errors") + +#define SEC_TRUST_ERROR_SUBTYPE_REVOKED SecStringWithDefaultValue("“%@” certificate is revoked", "Trust", 0, "“%@” certificate is revoked", "Error for revoked certificates") +#define SEC_TRUST_ERROR_SUBTYPE_KEYSIZE SecStringWithDefaultValue("“%@” certificate is using a broken key size", "Trust", 0, "“%@” certificate is using a broken key size", "Error for certificates with weak key sizes") +#define SEC_TRUST_ERROR_SUBTYPE_WEAKHASH SecStringWithDefaultValue("“%@” certificate is using a broken signature algorithm", "Trust", 0, "“%@” certificate is using a broken signature algorithm", "Error for certificates with weak signature algorithms") +#define SEC_TRUST_ERROR_SUBTYPE_DENIED SecStringWithDefaultValue("User or administrator set “%@” certificate as distrusted", "Trust", 0, "User or administrator set “%@” certificate as distrusted", "Error for certificates with deny trust settings") +#define SEC_TRUST_ERROR_SUBTYPE_COMPLIANCE SecStringWithDefaultValue("“%@” certificate is not standards compliant", "Trust", 0, "“%@” certificate is not standards compliant", "Error for certificates that violate standards") +#define SEC_TRUST_ERROR_SUBTYPE_EXPIRED SecStringWithDefaultValue("“%@” certificate is expired", "Trust", 0, "“%@” certificate is expired", "Error for certificates that are expired") +#define SEC_TRUST_ERROR_SUBTYPE_TRUST SecStringWithDefaultValue("“%@” certificate is not trusted", "Trust", 0, "“%@” certificate is not trusted", "Error for certificates that are not trusted") +#define SEC_TRUST_ERROR_SUBTYPE_NAME SecStringWithDefaultValue("“%@” certificate name does not match input", "Trust", 0, "“%@” certificate name does not match input", "Error for certificates whose names do not match the policy") +#define SEC_TRUST_ERROR_SUBTYPE_USAGE SecStringWithDefaultValue("“%@” certificate is not permitted for this usage", "Trust", 0, "“%@” certificate is not permitted for this usage", "Error for certificates whose usages do not match the policy") +#define SEC_TRUST_ERROR_SUBTYPE_PINNING SecStringWithDefaultValue("%@ certificates do not meet pinning requirements", "Trust", 0, "%@ certificates do not meet pinning requirements", "Error for certificates that do not meet pinning requirements") +#define SEC_TRUST_ERROR_SUBTYPE_INVALID SecStringWithDefaultValue("Unknown trust error for “%@” certificate", "Trust", 0, "Unknown trust error for “%@” certificate", "Error for unknown error") + +//Note the the following errors do not follow the casing conventions of the above so that they can be used with POLICYCHECKMACRO +#define SEC_TRUST_ERROR_SSLHostname SecStringWithDefaultValue("SSL hostname does not match name(s) in certificate", "Trust", 0, "SSL hostname does not match name(s) in certificate", "Error for SSL hostname mismatch") +#define SEC_TRUST_ERROR_Email SecStringWithDefaultValue("Email address does not match name(s) in certificate", "Trust", 0, "Email address does not match name(s) in certificate", "Error for email mismatch") +#define SEC_TRUST_ERROR_TemporalValidity SecStringWithDefaultValue("Certificate is not temporally valid", "Trust", 0, "Certificate is not temporally valid", "Error for temporal validity") +#define SEC_TRUST_ERROR_WeakKeySize SecStringWithDefaultValue("Certificate is using a broken key size", "Trust", 0, "Certificate is using a broken key size", "Error for weak keys") +#define SEC_TRUST_ERROR_WeakSignature SecStringWithDefaultValue("Certificate is using a broken signature algorithm", "Trust", 0, "Certificate is using a broken signature algorithm", "Error for weak signatures") +#define SEC_TRUST_ERROR_KeyUsage SecStringWithDefaultValue("Key usage does not match certificate usage", "Trust", 0, "Key usage does not match certificate usage", "Error for key usage mismatch") +#define SEC_TRUST_ERROR_ExtendedKeyUsage SecStringWithDefaultValue("Extended key usage does not match certificate usage", "Trust", 0, "Extended key usage does not match certificate usage", "Error for extended key usage mismatch") +#define SEC_TRUST_ERROR_SubjectCommonName SecStringWithDefaultValue("Common Name does not match expected name", "Trust", 0, "Common Name does not match expected name", "Error for subject common name mismatch") +#define SEC_TRUST_ERROR_SubjectCommonNamePrefix SecStringWithDefaultValue("Common Name does not match expected name", "Trust", 0, "Common Name does not match expected name", "Error for subject common name prefix mismatch") +#define SEC_TRUST_ERROR_SubjectCommonNameTEST SecStringWithDefaultValue("Common Name does not match expected name", "Trust", 0, "Common Name does not match expected name", "Error for subject common name mismatch, allowing test") +#define SEC_TRUST_ERROR_SubjectOrganization SecStringWithDefaultValue("Organization does not match expected name", "Trust", 0, "Organization does not match expected name", "Error for subject organization mismatch") +#define SEC_TRUST_ERROR_SubjectOrganizationalUnit SecStringWithDefaultValue("Organizational Unit does not match expected name", "Trust", 0, "Certificate Organizational Unit does not match expected name", "Error for subject organizational unit mismatch") +#define SEC_TRUST_ERROR_NotValidBefore SecStringWithDefaultValue("Certificate issued before allowed time", "Trust", 0, "Certificate issued before allowed time", "Error for not before date") +#define SEC_TRUST_ERROR_EAPTrustedServerNames SecStringWithDefaultValue("Trusted EAP hostname does not match name(s) in certificate", "Trust", 0, "Trusted EAP hostname does not match name(s) in certificate", "Error for EAP hostname mismatch") +#define SEC_TRUST_ERROR_LeafMarkerOid SecStringWithDefaultValue("Missing project-specific extension OID", "Trust", 0, "Missing project-specific extension OID", "Error for leaf marker OID") +#define SEC_TRUST_ERROR_LeafMarkerOidWithoutValueCheck SecStringWithDefaultValue("Missing project-specific extension OID", "Trust", 0, "Missing project-specific extension OID", "Error for leaf marker OID without value check") +#define SEC_TRUST_ERROR_LeafMarkersProdAndQA SecStringWithDefaultValue("Missing project-specific extension OID", "Trust", 0, "Missing project-specific extension OID", "Error for leaf marker OID allowing prod or QA") +#define SEC_TRUST_ERROR_BlackListedLeaf SecStringWithDefaultValue("Certificate is blocked", "Trust", 0, "Certificate is blocked", "Error for blocklisted certificates") +#define SEC_TRUST_ERROR_GrayListedLeaf SecStringWithDefaultValue("Certificate is listed as untrusted", "Trust", 0, "Certificate is listed as untrusted", "Error for graylisted certificates") +#define SEC_TRUST_ERROR_IssuerCommonName SecStringWithDefaultValue("Common Name does not match expected name", "Trust", 0, "Common Name does not match expected name", "Error for issuer common name mismatch") +#define SEC_TRUST_ERROR_BasicConstraints SecStringWithDefaultValue("Basic constraints are required but missing", "Trust", 0, "Basic constraints are required but missing", "Error for missing basic constraints") +#define SEC_TRUST_ERROR_BasicConstraintsCA SecStringWithDefaultValue("Non-CA certificate used as a CA", "Trust", 0, "Non-CA certificate used as a CA", "Error for CA basic constraints") +#define SEC_TRUST_ERROR_BasicConstraintsPathLen SecStringWithDefaultValue("Chain exceeded constrained path length", "Trust", 0, "Chain exceeded constrained path length", "Error for path length basic constraints") +#define SEC_TRUST_ERROR_IntermediateSPKISHA256 SecStringWithDefaultValue("Public key does not match pinned value", "Trust", 0, "Public key does not match pinned value", "Error for intermediate public key pin") +#define SEC_TRUST_ERROR_IntermediateEKU SecStringWithDefaultValue("Extended key usage does not match pinned value", "Trust", 0, "Extended key usage does not match pinned value", "Error for intermediate extended key usage pin") +#define SEC_TRUST_ERROR_IntermediateMarkerOid SecStringWithDefaultValue("Missing issuer-specific extension OID", "Trust", 0, "Missing issuer-specific extension OID", "Error for intermediate marker OID") +#define SEC_TRUST_ERROR_IntermediateOrganization SecStringWithDefaultValue("Organization does not match expected name", "Trust", 0, "Organization does not match expected name", "Error for issuer organization mismatch") +#define SEC_TRUST_ERROR_IntermediateCountry SecStringWithDefaultValue("Country does not match expected name", "Trust", 0, "Country does not match expected name", "Error for issuer country mismatch") +#define SEC_TRUST_ERROR_AnchorSHA1 SecStringWithDefaultValue("Anchor does not match pinned fingerprint", "Trust", 0, "Anchor does not match pinned fingerprint", "Error for anchor SHA-1 fingerprint pin") +#define SEC_TRUST_ERROR_AnchorSHA256 SecStringWithDefaultValue("Anchor does not match pinned fingerprint", "Trust", 0, "Anchor does not match pinned fingerprint", "Error for anchor SHA-256 fingerprint pin") +#define SEC_TRUST_ERROR_AnchorTrusted SecStringWithDefaultValue("Root is not trusted", "Trust", 0, "Root is not trusted", "Error for untrusted root") +#define SEC_TRUST_ERROR_MissingIntermediate SecStringWithDefaultValue("Unable to build chain to root (possible missing intermediate)", "Trust", 0, "Unable to build chain to root (possible missing intermediate)", "Error for missing intermediates") +#define SEC_TRUST_ERROR_AnchorApple SecStringWithDefaultValue("Anchor is not an Apple root", "Trust", 0, "Anchor is not an Apple root", "Error for Apple anchor pin") +#define SEC_TRUST_ERROR_NonEmptySubject SecStringWithDefaultValue("Certificate missing a name", "Trust", 0, "Certificate missing a name", "Error for empty subject name") +#define SEC_TRUST_ERROR_IdLinkage SecStringWithDefaultValue("SubjectKeyID/AuthorityKeyID mismatch in chain", "Trust", 0, "SubjectKeyID/AuthorityKeyID mismatch in chain", "Error for bad key ID linkage") +#define SEC_TRUST_ERROR_KeySize SecStringWithDefaultValue("Key size is not permitted for this use", "Trust", 0, "Key size is not permitted for this use", "Error for pinned key size") +#define SEC_TRUST_ERROR_SignatureHashAlgorithms SecStringWithDefaultValue("Signature hash algorithm is not permitted for this use", "Trust", 0, "Signature hash algorithm is not permitted for this use", "Error for pinned hash algorithm") +#define SEC_TRUST_ERROR_CertificatePolicy SecStringWithDefaultValue("Missing project-specific Certificate Policy OID", "Trust", 0, "Missing project-specific Certificate Policy OID", "Error for certificate policy marker OID") +#define SEC_TRUST_ERROR_ValidRoot SecStringWithDefaultValue("Root is not temporally valid", "Trust", 0, "Root is not temporally valid", "Error for root temporal validity") +#define SEC_TRUST_ERROR_CriticalExtensions SecStringWithDefaultValue("Found unknown critical extensions", "Trust", 0, "Found unknown critical extensions", "Error for unknown critical extensions") +#define SEC_TRUST_ERROR_ChainLength SecStringWithDefaultValue("Chain does not match expected path length", "Trust", 0, "Chain does not match expected path length", "Error for pinned chain length") +#define SEC_TRUST_ERROR_BasicCertificateProcessing SecStringWithDefaultValue("Certificate is not standards compliant", "Trust", 0, "Certificate is not standards compliant", "Error for certificates that violate standards") +#define SEC_TRUST_ERROR_NameConstraints SecStringWithDefaultValue("Name constraints violated", "Trust", 0, "Name constraints violated", "Error for name constraints") +#define SEC_TRUST_ERROR_PolicyConstraints SecStringWithDefaultValue("Policy constraints violated", "Trust", 0, "Policy constraints violated", "Error for policy constraints") +#define SEC_TRUST_ERROR_GrayListedKey SecStringWithDefaultValue("Key is listed as untrusted", "Trust", 0, "Key is listed as untrusted", "Error for graylisted keys") +#define SEC_TRUST_ERROR_BlackListedKey SecStringWithDefaultValue("Key is blocked", "Trust", 0, "Key is blocked", "Error for blocklisted keys") +#define SEC_TRUST_ERROR_UsageConstraints SecStringWithDefaultValue("User or administrator set certificate as distrusted", "Trust", 0, "User or administrator set certificate as distrusted", "Error for certificates with deny trust settings") +#define SEC_TRUST_ERROR_SystemTrustedWeakHash SecStringWithDefaultValue("Signature hash algorithm is not permitted for this use", "Trust", 0, "Signature hash algorithm is not permitted for this use", "Error for system-trust hash algorithm") +#define SEC_TRUST_ERROR_SystemTrustedWeakKey SecStringWithDefaultValue("Key size is not permitted for this use", "Trust", 0, "Key size is not permitted for this use", "Error for system-trust key size") +#define SEC_TRUST_ERROR_PinningRequired SecStringWithDefaultValue("Pinning required but not used", "Trust", 0, "Pinning required but not used", "Error for required pinning") +#define SEC_TRUST_ERROR_Revocation SecStringWithDefaultValue("Certificate is revoked", "Trust", 0, "Certificate is revoked", "Error for revocation") +#define SEC_TRUST_ERROR_RevocationResponseRequired SecStringWithDefaultValue("Failed to check revocation", "Trust", 0, "Failed to check revocation", "Error for revocation required") +#define SEC_TRUST_ERROR_CTRequired SecStringWithDefaultValue("CT validation required but missing", "Trust", 0, "CT validation required but missing", "Error for missing Certificate Transparency validation") +#define SEC_TRUST_ERROR_NoNetworkAccess SecStringWithDefaultValue("Unexpected error detail", "Trust", 0, "Unexpected error detail", "Error for unexpected error details") +#define SEC_TRUST_ERROR_ExtendedValidation SecStringWithDefaultValue("Unexpected error detail", "Trust", 0, "Unexpected error detail", "Error for unexpected error details") +#define SEC_TRUST_ERROR_RevocationOnline SecStringWithDefaultValue("Unexpected error detail", "Trust", 0, "Unexpected error detail", "Error for unexpected error details") + __END_DECLS #endif /* !_SECURITY_SECFRAMEWORKSTRINGS_H_ */ diff --git a/OSX/sec/Security/SecImportExport.c b/OSX/sec/Security/SecImportExport.c index 44ecf2eb..20f69d4c 100644 --- a/OSX/sec/Security/SecImportExport.c +++ b/OSX/sec/Security/SecImportExport.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include diff --git a/OSX/sec/Security/SecItem.c b/OSX/sec/Security/SecItem.c index 6e4f032e..41a9f732 100644 --- a/OSX/sec/Security/SecItem.c +++ b/OSX/sec/Security/SecItem.c @@ -434,11 +434,16 @@ SecItemCreateFromAttributeDictionary(CFDictionaryRef refAttributes) { } else if (CFEqual(class, kSecClassIdentity)) { CFDataRef data = CFDictionaryGetValue(refAttributes, kSecAttrIdentityCertificateData); SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, data); - SecKeyRef key = SecKeyCreateFromAttributeDictionary(refAttributes); - if (key && cert) - ref = SecIdentityCreate(kCFAllocatorDefault, cert, key); + SecKeyRef key = SecKeyCreateFromAttributeDictionary(refAttributes); + if (key && cert) { + ref = SecIdentityCreate(kCFAllocatorDefault, cert, key); + } + else { + secerror("SecItem: failed to create identity"); + } + + CFReleaseSafe(key); CFReleaseSafe(cert); - CFReleaseSafe(key); #ifdef SECITEM_SHIM_OSX } else { ref = SecItemCreateFromAttributeDictionary_osx(refAttributes); @@ -1691,11 +1696,10 @@ OSStatus SecItemCopyMatching(CFDictionaryRef inQuery, CFTypeRef *result) { bool wants_data = cf_bool_value(CFDictionaryGetValue(query.dictionary, kSecReturnData)); bool wants_attributes = cf_bool_value(CFDictionaryGetValue(query.dictionary, kSecReturnAttributes)); - if ((wants_data && !wants_attributes) || (!wants_data && wants_attributes)) { + if ((wants_data && !wants_attributes)) { // When either attributes or data are requested, we need to query both, because for token based items, // both are needed in order to generate proper data and/or attributes results. CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&query), kSecReturnAttributes, kCFBooleanTrue); - CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&query), kSecReturnData, kCFBooleanTrue); } status = SecOSStatusWith(^bool(CFErrorRef *error) { diff --git a/OSX/sec/Security/SecItem.m b/OSX/sec/Security/SecItem.m index 7af25f37..9584ca2e 100644 --- a/OSX/sec/Security/SecItem.m +++ b/OSX/sec/Security/SecItem.m @@ -102,19 +102,21 @@ void SecItemSetCurrentItemAcrossAllDevices(CFStringRef accessGroup, os_activity_t activity = os_activity_create("SecItemSetCurrentItemAcrossAllDevices", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); os_activity_scope(activity); - id rpc = SecuritydXPCProxyObject(^(NSError *error) { - complete((__bridge CFErrorRef) error); - }); - [rpc secItemSetCurrentItemAcrossAllDevices:(__bridge NSData*)newCurrentItemReference - newCurrentItemHash:(__bridge NSData*)newCurrentItemHash - accessGroup:(__bridge NSString*)accessGroup - identifier:(__bridge NSString*)identifier - viewHint:(__bridge NSString*)viewHint - oldCurrentItemReference:(__bridge NSData*)oldCurrentItemReference - oldCurrentItemHash:(__bridge NSData*)oldCurrentItemHash - complete: ^ (NSError* operror) { - complete((__bridge CFErrorRef) operror); - }]; + @autoreleasepool { + id rpc = SecuritydXPCProxyObject(^(NSError *error) { + complete((__bridge CFErrorRef) error); + }); + [rpc secItemSetCurrentItemAcrossAllDevices:(__bridge NSData*)newCurrentItemReference + newCurrentItemHash:(__bridge NSData*)newCurrentItemHash + accessGroup:(__bridge NSString*)accessGroup + identifier:(__bridge NSString*)identifier + viewHint:(__bridge NSString*)viewHint + oldCurrentItemReference:(__bridge NSData*)oldCurrentItemReference + oldCurrentItemHash:(__bridge NSData*)oldCurrentItemHash + complete: ^ (NSError* operror) { + complete((__bridge CFErrorRef) operror); + }]; + } } void SecItemFetchCurrentItemAcrossAllDevices(CFStringRef accessGroup, @@ -126,16 +128,18 @@ void SecItemFetchCurrentItemAcrossAllDevices(CFStringRef accessGroup, os_activity_t activity = os_activity_create("SecItemFetchCurrentItemAcrossAllDevices", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); os_activity_scope(activity); - id rpc = SecuritydXPCProxyObject(^(NSError *error) { - complete(NULL, (__bridge CFErrorRef) error); - }); - [rpc secItemFetchCurrentItemAcrossAllDevices:(__bridge NSString*)accessGroup - identifier:(__bridge NSString*)identifier - viewHint:(__bridge NSString*)viewHint - fetchCloudValue:fetchCloudValue - complete: ^(NSData* persistentRef, NSError* operror) { - complete((__bridge CFDataRef) persistentRef, (__bridge CFErrorRef) operror); - }]; + @autoreleasepool { + id rpc = SecuritydXPCProxyObject(^(NSError *error) { + complete(NULL, (__bridge CFErrorRef) error); + }); + [rpc secItemFetchCurrentItemAcrossAllDevices:(__bridge NSString*)accessGroup + identifier:(__bridge NSString*)identifier + viewHint:(__bridge NSString*)viewHint + fetchCloudValue:fetchCloudValue + complete: ^(NSData* persistentRef, NSError* operror) { + complete((__bridge CFDataRef) persistentRef, (__bridge CFErrorRef) operror); + }]; + } } void _SecItemFetchDigests(NSString *itemClass, NSString *accessGroup, void (^complete)(NSArray *, NSError *)) diff --git a/OSX/sec/Security/SecItemBackup.c b/OSX/sec/Security/SecItemBackup.c index c55d70f0..557f9790 100644 --- a/OSX/sec/Security/SecItemBackup.c +++ b/OSX/sec/Security/SecItemBackup.c @@ -49,11 +49,12 @@ #include -static CFDataRef client_data_data_to_data_error_request(enum SecXPCOperation op, SecurityClient *client, CFDataRef keybag, CFDataRef passcode, CFErrorRef *error) { +static CFDataRef client_data_data_bool_to_data_error_request(enum SecXPCOperation op, SecurityClient *client, CFDataRef keybag, CFDataRef passcode, bool emcs, CFErrorRef *error) { __block CFDataRef result = NULL; securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) { return SecXPCDictionarySetDataOptional(message, kSecXPCKeyKeybag, keybag, error) - && SecXPCDictionarySetDataOptional(message, kSecXPCKeyUserPassword, passcode, error); + && SecXPCDictionarySetDataOptional(message, kSecXPCKeyUserPassword, passcode, error) + && SecXPCDictionarySetBool(message, kSecXPCKeyEMCSBackup, emcs, NULL); }, ^bool(xpc_object_t response, CFErrorRef *error) { return (result = SecXPCDictionaryCopyData(response, kSecXPCKeyResult, error)); }); @@ -147,7 +148,7 @@ static int SecItemBackupHandoffFD(CFStringRef backupName, CFErrorRef *error) { CFDataRef _SecKeychainCopyOTABackup(void) { __block CFDataRef result; os_activity_initiate("_SecKeychainCopyOTABackup", OS_ACTIVITY_FLAG_DEFAULT, ^{ - result = SECURITYD_XPC(sec_keychain_backup, client_data_data_to_data_error_request, SecSecurityClientGet(), NULL, NULL, NULL); + result = SECURITYD_XPC(sec_keychain_backup, client_data_data_bool_to_data_error_request, SecSecurityClientGet(), NULL, NULL, false, NULL); }); return result; } @@ -155,7 +156,15 @@ CFDataRef _SecKeychainCopyOTABackup(void) { CFDataRef _SecKeychainCopyBackup(CFDataRef backupKeybag, CFDataRef password) { __block CFDataRef result; os_activity_initiate("_SecKeychainCopyBackup", OS_ACTIVITY_FLAG_DEFAULT, ^{ - result = SECURITYD_XPC(sec_keychain_backup, client_data_data_to_data_error_request, SecSecurityClientGet(), backupKeybag, password, NULL); + result = SECURITYD_XPC(sec_keychain_backup, client_data_data_bool_to_data_error_request, SecSecurityClientGet(), backupKeybag, password, false, NULL); + }); + return result; +} + +CFDataRef _SecKeychainCopyEMCSBackup(CFDataRef backupKeybag) { + __block CFDataRef result; + os_activity_initiate("_SecKeychainCopyEMCSBackup", OS_ACTIVITY_FLAG_DEFAULT, ^{ + result = SECURITYD_XPC(sec_keychain_backup, client_data_data_bool_to_data_error_request, SecSecurityClientGet(), backupKeybag, NULL, true, NULL); }); return result; } diff --git a/OSX/sec/Security/SecKey.c b/OSX/sec/Security/SecKey.c index ac6a5ef7..d8583ba4 100644 --- a/OSX/sec/Security/SecKey.c +++ b/OSX/sec/Security/SecKey.c @@ -1163,6 +1163,10 @@ SecKeyRef SecKeyCreateWithData(CFDataRef keyData, CFDictionaryRef parameters, CF if (CFDictionaryGetValue(parameters, kSecAttrTokenID) != NULL) { return SecKeyCreateCTKKey(allocator, parameters, error); } + else if (!keyData) { + SecError(errSecParam, error, CFSTR("Failed to provide key data to SecKeyCreateWithData")); + return NULL; + } /* First figure out the key type (algorithm). */ CFIndex algorithm, class; CFTypeRef ktype = CFDictionaryGetValue(parameters, kSecAttrKeyType); @@ -1231,13 +1235,33 @@ out: return key; } +// Similar to CFErrorPropagate, but does not consult input value of *error, it can contain any garbage and if overwritten, previous value is never released. +static inline bool SecKeyErrorPropagate(bool succeeded, CFErrorRef possibleError CF_CONSUMED, CFErrorRef *error) { + if (succeeded) { + return true; + } else { + if (error) { + *error = possibleError; + } else { + CFRelease(possibleError); + } + return false; + } +} + CFDataRef SecKeyCopyExternalRepresentation(SecKeyRef key, CFErrorRef *error) { if (!key->key_class->copyExternalRepresentation) { + if (error != NULL) { + *error = NULL; + } SecError(errSecUnimplemented, error, CFSTR("export not implemented for key %@"), key); return NULL; } - return key->key_class->copyExternalRepresentation(key, error); + CFErrorRef localError = NULL; + CFDataRef result = key->key_class->copyExternalRepresentation(key, &localError); + SecKeyErrorPropagate(result != NULL, localError, error); + return result; } CFDictionaryRef SecKeyCopyAttributes(SecKeyRef key) { @@ -1296,7 +1320,12 @@ fail: SecKeyRef SecKeyCreateRandomKey(CFDictionaryRef parameters, CFErrorRef *error) { SecKeyRef privKey = NULL, pubKey = NULL; OSStatus status = SecKeyGeneratePair(parameters, &pubKey, &privKey); - SecError(status, error, CFSTR("Key generation failed, error %d"), (int)status); + if (status != errSecSuccess) { + if (error != NULL) { + *error = NULL; + } + SecError(status, error, CFSTR("Key generation failed, error %d"), (int)status); + } CFReleaseSafe(pubKey); return privKey; } @@ -1311,8 +1340,14 @@ SecKeyRef SecKeyCreateDuplicate(SecKeyRef key) { Boolean SecKeySetParameter(SecKeyRef key, CFStringRef name, CFPropertyListRef value, CFErrorRef *error) { if (key->key_class->version >= 4 && key->key_class->setParameter) { - return key->key_class->setParameter(key, name, value, error); + CFErrorRef localError = NULL; + Boolean result = key->key_class->setParameter(key, name, value, &localError); + SecKeyErrorPropagate(result, localError, error); + return result; } else { + if (error != NULL) { + *error = NULL; + } return SecError(errSecUnimplemented, error, CFSTR("setParameter not implemented for %@"), key); } } @@ -1468,26 +1503,32 @@ static CFMutableArrayRef SecKeyCreateAlgorithmArray(SecKeyAlgorithm algorithm) { } CFDataRef SecKeyCreateSignature(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef dataToSign, CFErrorRef *error) { + CFErrorRef localError = NULL; SecKeyOperationContext context = { key, kSecKeyOperationTypeSign, SecKeyCreateAlgorithmArray(algorithm) }; - CFDataRef result = SecKeyRunAlgorithmAndCopyResult(&context, dataToSign, NULL, error); + CFDataRef result = SecKeyRunAlgorithmAndCopyResult(&context, dataToSign, NULL, &localError); SecKeyOperationContextDestroy(&context); + SecKeyErrorPropagate(result != NULL, localError, error); return result; } Boolean SecKeyVerifySignature(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef signedData, CFDataRef signature, CFErrorRef *error) { + CFErrorRef localError = NULL; SecKeyOperationContext context = { key, kSecKeyOperationTypeVerify, SecKeyCreateAlgorithmArray(algorithm) }; - CFTypeRef res = SecKeyRunAlgorithmAndCopyResult(&context, signedData, signature, error); + CFTypeRef res = SecKeyRunAlgorithmAndCopyResult(&context, signedData, signature, &localError); Boolean result = CFEqualSafe(res, kCFBooleanTrue); CFReleaseSafe(res); SecKeyOperationContextDestroy(&context); + SecKeyErrorPropagate(result, localError, error); return result; } CFDataRef SecKeyCreateEncryptedData(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef plainText, CFErrorRef *error) { + CFErrorRef localError = NULL; SecKeyOperationContext context = { key, kSecKeyOperationTypeEncrypt, SecKeyCreateAlgorithmArray(algorithm) }; - CFDataRef result = SecKeyRunAlgorithmAndCopyResult(&context, plainText, NULL, error); + CFDataRef result = SecKeyRunAlgorithmAndCopyResult(&context, plainText, NULL, &localError); SecKeyOperationContextDestroy(&context); + SecKeyErrorPropagate(result, localError, error); return result; } @@ -1500,10 +1541,12 @@ CFDataRef SecKeyCreateDecryptedData(SecKeyRef key, SecKeyAlgorithm algorithm, CF CFDataRef SecKeyCopyKeyExchangeResult(SecKeyRef key, SecKeyAlgorithm algorithm, SecKeyRef publicKey, CFDictionaryRef parameters, CFErrorRef *error) { + CFErrorRef localError = NULL; CFDataRef publicKeyData = NULL, result = NULL; SecKeyOperationContext context = { key, kSecKeyOperationTypeKeyExchange, SecKeyCreateAlgorithmArray(algorithm) }; require_quiet(publicKeyData = SecKeyCopyExternalRepresentation(publicKey, error), out); - result = SecKeyRunAlgorithmAndCopyResult(&context, publicKeyData, parameters, error); + result = SecKeyRunAlgorithmAndCopyResult(&context, publicKeyData, parameters, &localError); + SecKeyErrorPropagate(result != NULL, localError, error); out: CFReleaseSafe(publicKeyData); diff --git a/OSX/sec/Security/SecOTRIdentityPriv.h b/OSX/sec/Security/SecOTRIdentityPriv.h index b747719f..8ce081c9 100644 --- a/OSX/sec/Security/SecOTRIdentityPriv.h +++ b/OSX/sec/Security/SecOTRIdentityPriv.h @@ -35,8 +35,6 @@ #include __BEGIN_DECLS - -extern CFStringRef sErrorDomain; // OAEP Padding, uses lots of space. Might need this to be data // Driven when we support more key types. @@ -78,7 +76,6 @@ extern const SecAsn1AlgId *kOTRSignatureAlgIDPtr; void EnsureOTRAlgIDInited(void); // Private functions for Public and Full IDs -SecOTRFullIdentityRef SecOTRFullIdentityCreateWithSize(CFAllocatorRef allocator, int bits); bool SecOTRFIAppendSignature(SecOTRFullIdentityRef fullID, CFDataRef dataToHash, @@ -118,7 +115,6 @@ OSStatus appendPublicOctets(SecKeyRef fromKey, CFMutableDataRef appendTo); OSStatus appendPublicOctetsAndSize(SecKeyRef fromKey, CFMutableDataRef appendTo); OSStatus appendSizeAndData(CFDataRef data, CFMutableDataRef appendTo); -SecKeyRef CreateECPrivateKeyFrom(CFAllocatorRef allocator, const uint8_t** data, size_t* limit); SecKeyRef CreateECPublicKeyFrom(CFAllocatorRef allocator, const uint8_t** data, size_t* limit); bool SecOTRCreateError(enum SecOTRError family, CFIndex errorCode, CFStringRef descriptionString, CFErrorRef previousError, CFErrorRef *newError); diff --git a/OSX/sec/Security/SecOTRMath.c b/OSX/sec/Security/SecOTRMath.c index 2106016c..0528bdef 100644 --- a/OSX/sec/Security/SecOTRMath.c +++ b/OSX/sec/Security/SecOTRMath.c @@ -43,30 +43,6 @@ // Random Number Generation // -OSStatus GetRandomBytesInLSBs(size_t bytesOfRandomness, size_t n, cc_unit* place) -{ - OSStatus result = errSecParam; - require(bytesOfRandomness * 8 <= ccn_bitsof_n(n), fail); - { - uint8_t randomBytes[bytesOfRandomness]; - - result = SecRandomCopyBytes(kSecRandomDefault, sizeof(randomBytes), randomBytes); - - require_noerr(result, fail); - - ccn_read_uint(n, place, sizeof(randomBytes), randomBytes); - - bzero(randomBytes, bytesOfRandomness); - } -fail: - return result; -} - -OSStatus FillWithRandomBytes(size_t n, cc_unit* place) -{ - return GetRandomBytesInLSBs(ccn_sizeof(n), n, place); -} - static const uint8_t kIVZero[16] = { }; @@ -122,12 +98,12 @@ static void HashMPIWithPrefix(uint8_t byte, cc_size sN, const cc_unit* s, uint8_ CFReleaseNull(dataToHash); } -void DeriveOTR256BitsFromS(KeyType whichKey, cc_size sN, const cc_unit* s, size_t keySize, uint8_t* key) +void DeriveOTR256BitsFromS(OTRKeyType whichKey, cc_size sN, const cc_unit* s, size_t keySize, uint8_t* key) { HashMPIWithPrefix(whichKey, sN, s, key); } -void DeriveOTR128BitPairFromS(KeyType whichKey, size_t sSize, const cc_unit* s, +void DeriveOTR128BitPairFromS(OTRKeyType whichKey, size_t sSize, const cc_unit* s, size_t firstKeySize, uint8_t* firstKey, size_t secondKeySize, uint8_t* secondKey) { @@ -148,7 +124,7 @@ void DeriveOTR128BitPairFromS(KeyType whichKey, size_t sSize, const cc_unit* s, } -void DeriveOTR64BitsFromS(KeyType whichKey, size_t sn, const cc_unit* s, +void DeriveOTR64BitsFromS(OTRKeyType whichKey, size_t sn, const cc_unit* s, size_t topKeySize, uint8_t* topKey) { uint8_t hashBuffer[CCSHA256_OUTPUT_SIZE]; diff --git a/OSX/sec/Security/SecOTRMath.h b/OSX/sec/Security/SecOTRMath.h index 6f966e3a..4fbc42cc 100644 --- a/OSX/sec/Security/SecOTRMath.h +++ b/OSX/sec/Security/SecOTRMath.h @@ -44,13 +44,6 @@ #define kSHA256HMAC160Bits 160 #define kSHA256HMAC160Bytes (kSHA256HMAC160Bits/8) -// Result and exponent are expected to be kExponentiationUnits big. -void OTRExponentiate(cc_unit* res, const cc_unit* base, const cc_unit* exponent); -void OTRGroupExponentiate(cc_unit* result, const cc_unit* exponent); - -OSStatus GetRandomBytesInLSBs(size_t bytesOfRandomness, size_t n, cc_unit* place); -OSStatus FillWithRandomBytes(size_t n, cc_unit* place); - typedef enum { kSSID = 0x00, kCs = 0x01, @@ -58,14 +51,14 @@ typedef enum { kM2 = 0x03, kM1Prime = 0x04, kM2Prime = 0x05 -} KeyType; +} OTRKeyType; -void DeriveOTR256BitsFromS(KeyType whichKey, size_t sSize, const cc_unit* s, size_t keySize, uint8_t* key); -void DeriveOTR128BitPairFromS(KeyType whichHalf, size_t sSize, const cc_unit* s, +void DeriveOTR256BitsFromS(OTRKeyType whichKey, size_t sSize, const cc_unit* s, size_t keySize, uint8_t* key); +void DeriveOTR128BitPairFromS(OTRKeyType whichHalf, size_t sSize, const cc_unit* s, size_t firstKeySize, uint8_t* firstKey, size_t secondKeySize, uint8_t* secondKey); -void DeriveOTR64BitsFromS(KeyType whichKey, size_t sSize, const cc_unit* s, +void DeriveOTR64BitsFromS(OTRKeyType whichKey, size_t sSize, const cc_unit* s, size_t firstKeySize, uint8_t* firstKey); diff --git a/OSX/sec/Security/SecOTRPackets.c b/OSX/sec/Security/SecOTRPackets.c index 10919429..35bdc9c4 100644 --- a/OSX/sec/Security/SecOTRPackets.c +++ b/OSX/sec/Security/SecOTRPackets.c @@ -75,7 +75,7 @@ static inline void AppendSHA256HMAC_160(CFMutableDataRef appendTo, static inline void DeriveAndAppendSHA256HMAC(CFMutableDataRef appendTo, cc_size sN, const cc_unit* s, - KeyType whichKey, + OTRKeyType whichKey, size_t howMuch, const uint8_t* from) { @@ -92,7 +92,7 @@ static inline void DeriveAndAppendSHA256HMAC(CFMutableDataRef appendTo, static inline void DeriveAndAppendSHA256HMAC_160(CFMutableDataRef appendTo, cc_size sN, const cc_unit* s, - KeyType whichKey, + OTRKeyType whichKey, size_t howMuch, const uint8_t* from) { diff --git a/OSX/sec/Security/SecOTRSession.c b/OSX/sec/Security/SecOTRSession.c index 07244b17..56480f49 100644 --- a/OSX/sec/Security/SecOTRSession.c +++ b/OSX/sec/Security/SecOTRSession.c @@ -484,6 +484,7 @@ static void SecOTRSFindKeysForMessage(SecOTRSessionRef session, emptyKeys = &session->_keyCache[0]; } + assert(emptyKeys); // Fill in the entry. memcpy(emptyKeys->_fullKeyHash, SecFDHKGetHash(myKey), CCSHA1_OUTPUT_SIZE); @@ -1026,7 +1027,7 @@ static void SecOTRAcceptNewRemoteKey(SecOTRSessionRef session, SecOTRPublicDHKey SecOTRSEnableTimeToRoll(session); } -OSStatus SecOTRSetupInitialRemoteKey(SecOTRSessionRef session, SecOTRPublicDHKeyRef initialKey) { +OSStatus SecOTRSetupInitialRemoteKey(SecOTRSessionRef session, SecOTRPublicDHKeyRef CF_CONSUMED initialKey) { bzero(session->_keyCache, sizeof(session->_keyCache)); diff --git a/OSX/sec/Security/SecOTRSessionPriv.h b/OSX/sec/Security/SecOTRSessionPriv.h index 42c24122..76e0895e 100644 --- a/OSX/sec/Security/SecOTRSessionPriv.h +++ b/OSX/sec/Security/SecOTRSessionPriv.h @@ -113,7 +113,7 @@ struct _SecOTRSession { CFDataRef SecOTRCopyIncomingBytes(CFDataRef incomingMessage); void SecOTRPrepareOutgoingBytes(CFMutableDataRef destinationMessage, CFMutableDataRef protectedMessage); -OSStatus SecOTRSetupInitialRemoteKey(SecOTRSessionRef session, SecOTRPublicDHKeyRef initialKey); +OSStatus SecOTRSetupInitialRemoteKey(SecOTRSessionRef session, SecOTRPublicDHKeyRef CF_CONSUMED initialKey); void SOSOTRSRoll(SecOTRSessionRef session); int SecOTRSGetKeyID(SecOTRSessionRef session); int SecOTRSGetTheirKeyID(SecOTRSessionRef session); diff --git a/OSX/sec/Security/SecPasswordGenerate.c b/OSX/sec/Security/SecPasswordGenerate.c index 4d4e87d9..a095a5c3 100644 --- a/OSX/sec/Security/SecPasswordGenerate.c +++ b/OSX/sec/Security/SecPasswordGenerate.c @@ -505,6 +505,8 @@ static int SecPasswordNumberOfRepeatedDigits(CFStringRef passcode){ int finalRepeating = 0; if(highest != NULL) CFNumberGetValue(highest, kCFNumberIntType, &finalRepeating); + + CFReleaseNull(highestRepeatingcount); return finalRepeating; } diff --git a/OSX/sec/Security/SecPolicy.c b/OSX/sec/Security/SecPolicy.c index 30d663c6..7d18570f 100644 --- a/OSX/sec/Security/SecPolicy.c +++ b/OSX/sec/Security/SecPolicy.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include #include @@ -47,238 +47,35 @@ #include -/******************************************************** - **************** SecPolicy Constants ******************* - ********************************************************/ -// MARK: - -// MARK: SecPolicy Constants +#undef POLICYCHECKMACRO +#define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) \ + const CFStringRef kSecPolicyCheck##NAME = CFSTR(#NAME); +#include "SecPolicyChecks.list" #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v); /******************************************************** - ************** Unverified Leaf Checks ****************** + ******************* Feature toggles ******************** ********************************************************/ -SEC_CONST_DECL (kSecPolicyCheckSSLHostname, "SSLHostname"); -SEC_CONST_DECL (kSecPolicyCheckEmail, "email"); - -/* Checks that the issuer of the leaf has exactly one Common Name and that it - matches the specified string. */ -SEC_CONST_DECL (kSecPolicyCheckIssuerCommonName, "IssuerCommonName"); - -/* Checks that the leaf has exactly one Common Name and that it - matches the specified string. */ -SEC_CONST_DECL (kSecPolicyCheckSubjectCommonName, "SubjectCommonName"); - -/* Checks that the leaf has exactly one Common Name and that it has the - specified string as a prefix. */ -SEC_CONST_DECL (kSecPolicyCheckSubjectCommonNamePrefix, "SubjectCommonNamePrefix"); - -/* Checks that the leaf has exactly one Common Name and that it - matches the specified "" or "TEST TEST". */ -SEC_CONST_DECL (kSecPolicyCheckSubjectCommonNameTEST, "SubjectCommonNameTEST"); - -/* Checks that the leaf has exactly one Organization and that it - matches the specified string. */ -SEC_CONST_DECL (kSecPolicyCheckSubjectOrganization, "SubjectOrganization"); - -/* Checks that the leaf has exactly one Organizational Unit and that it - matches the specified string. */ -SEC_CONST_DECL (kSecPolicyCheckSubjectOrganizationalUnit, "SubjectOrganizationalUnit"); - -/* Check that the leaf is not valid before the specified date (or verifyDate - if none is provided?). */ -SEC_CONST_DECL (kSecPolicyCheckNotValidBefore, "NotValidBefore"); - -SEC_CONST_DECL (kSecPolicyCheckEAPTrustedServerNames, "EAPTrustedServerNames"); - -SEC_CONST_DECL (kSecPolicyCheckCertificatePolicy, "CertificatePolicy"); - -SEC_CONST_DECL (kSecPolicyCheckLeafMarkerOid, "CheckLeafMarkerOid"); -SEC_CONST_DECL (kSecPolicyCheckLeafMarkerOidWithoutValueCheck, "CheckLeafMarkerOidNoValueCheck"); -SEC_CONST_DECL (kSecPolicyCheckLeafMarkersProdAndQA, "CheckLeafMarkersProdAndQA"); +/* Option for AnchorApple */ +SEC_CONST_DECL (kSecPolicyAppleAnchorIncludeTestRoots, "AnchorAppleTestRoots"); /* options for kSecPolicyCheckLeafMarkersProdAndQA */ SEC_CONST_DECL (kSecPolicyLeafMarkerProd, "ProdMarker"); SEC_CONST_DECL (kSecPolicyLeafMarkerQA, "QAMarker"); -#if 0 -/* Check for basic constraints on leaf to be valid. (rfc5280 check) */ -SEC_CONST_DECL (kSecPolicyCheckLeafBasicConstraints, "LeafBasicContraints"); -#endif - -SEC_CONST_DECL (kSecPolicyCheckBlackListedLeaf, "BlackListedLeaf"); -SEC_CONST_DECL (kSecPolicyCheckGrayListedLeaf, "GrayListedLeaf"); - -/******************************************************** - *********** Unverified Intermediate Checks ************* - ********************************************************/ -SEC_CONST_DECL (kSecPolicyCheckKeyUsage, "KeyUsage"); /* (rfc5280 check) */ -SEC_CONST_DECL (kSecPolicyCheckExtendedKeyUsage, "ExtendedKeyUsage"); /* (rfc5280 check) */ -SEC_CONST_DECL (kSecPolicyCheckBasicConstraints, "BasicConstraints"); /* (rfc5280 check) */ -SEC_CONST_DECL (kSecPolicyCheckQualifiedCertStatements, "QualifiedCertStatements"); /* (rfc5280 check) */ -SEC_CONST_DECL (kSecPolicyCheckIntermediateSPKISHA256, "IntermediateSPKISHA256"); -SEC_CONST_DECL (kSecPolicyCheckIntermediateEKU, "IntermediateEKU"); -SEC_CONST_DECL (kSecPolicyCheckIntermediateMarkerOid, "CheckIntermediateMarkerOid"); -SEC_CONST_DECL (kSecPolicyCheckIntermediateOrganization, "CheckIntermediateOrganization"); -SEC_CONST_DECL (kSecPolicyCheckIntermediateCountry, "CheckIntermediateCountry"); - -/******************************************************** - ************** Unverified Anchor Checks **************** - ********************************************************/ -SEC_CONST_DECL (kSecPolicyCheckAnchorSHA1, "AnchorSHA1"); -SEC_CONST_DECL (kSecPolicyCheckAnchorSHA256, "AnchorSHA256"); - -/* Fake key for isAnchored check. */ -SEC_CONST_DECL (kSecPolicyCheckAnchorTrusted, "AnchorTrusted"); - -/* Anchor is one of the apple trust anchors */ -SEC_CONST_DECL (kSecPolicyCheckAnchorApple, "AnchorApple"); - -/* options for kSecPolicyCheckAnchorApple */ -SEC_CONST_DECL (kSecPolicyAppleAnchorIncludeTestRoots, "AnchorAppleTestRoots"); - -/******************************************************** - *********** Unverified Certificate Checks ************** - ********************************************************/ -/* Unverified Certificate Checks (any of the above) */ -SEC_CONST_DECL (kSecPolicyCheckNonEmptySubject, "NonEmptySubject"); -SEC_CONST_DECL (kSecPolicyCheckIdLinkage, "IdLinkage") /* (rfc5280 check) */ -SEC_CONST_DECL (kSecPolicyCheckValidIntermediates, "ValidIntermediates"); -SEC_CONST_DECL (kSecPolicyCheckValidLeaf, "ValidLeaf"); -SEC_CONST_DECL (kSecPolicyCheckValidRoot, "ValidRoot"); -SEC_CONST_DECL (kSecPolicyCheckWeakIntermediates, "WeakIntermediates"); -SEC_CONST_DECL (kSecPolicyCheckWeakLeaf, "WeakLeaf"); -SEC_CONST_DECL (kSecPolicyCheckWeakRoot, "WeakRoot"); -SEC_CONST_DECL (kSecPolicyCheckKeySize, "KeySize"); -SEC_CONST_DECL (kSecPolicyCheckSignatureHashAlgorithms, "SignatureHashAlgorithms"); - -/******************************************************** - **************** Verified Path Checks ****************** - ********************************************************/ -/* (rfc5280 check) Ideally we should dynamically track all the extensions - we processed for each certificate and fail this test if any critical - extensions remain. */ -SEC_CONST_DECL (kSecPolicyCheckCriticalExtensions, "CriticalExtensions"); - -/* Check that the certificate chain length matches the specificed CFNumberRef - length. */ -SEC_CONST_DECL (kSecPolicyCheckChainLength, "ChainLength"); - -/* (rfc5280 check) */ -SEC_CONST_DECL (kSecPolicyCheckBasicCertificateProcessing, "BasicCertificateProcessing"); - -/* Check Certificate Transparency if specified. */ -SEC_CONST_DECL (kSecPolicyCheckCertificateTransparency, "CertificateTransparency"); - -SEC_CONST_DECL (kSecPolicyCheckGrayListedKey, "GrayListedKey"); -SEC_CONST_DECL (kSecPolicyCheckBlackListedKey, "BlackListedKey"); - -SEC_CONST_DECL (kSecPolicyCheckUsageConstraints, "UsageConstraints"); - -SEC_CONST_DECL (kSecPolicyCheckSystemTrustedWeakHash, "SystemTrustedWeakHash"); -SEC_CONST_DECL (kSecPolicyCheckSystemTrustedWeakKey, "SystemTrustedWeakKey"); - -/* Binary requires pinning. */ -SEC_CONST_DECL (kSecPolicyCheckPinningRequired, "PinningRequired"); - -/******************************************************** - ******************* Feature toggles ******************** - ********************************************************/ - -/* Check revocation if specified. */ -SEC_CONST_DECL (kSecPolicyCheckExtendedValidation, "ExtendedValidation"); -SEC_CONST_DECL (kSecPolicyCheckRevocation, "Revocation"); -SEC_CONST_DECL (kSecPolicyCheckRevocationResponseRequired, "RevocationResponseRequired"); +/* Revocation toggles */ SEC_CONST_DECL (kSecPolicyCheckRevocationOCSP, "OCSP"); SEC_CONST_DECL (kSecPolicyCheckRevocationCRL, "CRL"); SEC_CONST_DECL (kSecPolicyCheckRevocationAny, "AnyRevocationMethod"); -SEC_CONST_DECL (kSecPolicyCheckRevocationOnline, "Online"); - -/* If present and true, we never go out to the network for anything - (OCSP, CRL or CA Issuer checking) but just used cached data instead. */ -SEC_CONST_DECL (kSecPolicyCheckNoNetworkAccess, "NoNetworkAccess"); - -/* Public policy names. */ -SEC_CONST_DECL (kSecPolicyAppleX509Basic, "1.2.840.113635.100.1.2"); -SEC_CONST_DECL (kSecPolicyAppleSSL, "1.2.840.113635.100.1.3"); -SEC_CONST_DECL (kSecPolicyAppleSMIME, "1.2.840.113635.100.1.8"); -SEC_CONST_DECL (kSecPolicyAppleEAP, "1.2.840.113635.100.1.9"); -SEC_CONST_DECL (kSecPolicyAppleSWUpdateSigning, "1.2.840.113635.100.1.10"); -SEC_CONST_DECL (kSecPolicyAppleIPsec, "1.2.840.113635.100.1.11"); -SEC_CONST_DECL (kSecPolicyApplePKINITClient, "1.2.840.113635.100.1.14"); -SEC_CONST_DECL (kSecPolicyApplePKINITServer, "1.2.840.113635.100.1.15"); -SEC_CONST_DECL (kSecPolicyAppleCodeSigning, "1.2.840.113635.100.1.16"); -SEC_CONST_DECL (kSecPolicyApplePackageSigning, "1.2.840.113635.100.1.17"); -SEC_CONST_DECL (kSecPolicyAppleIDValidation, "1.2.840.113635.100.1.18"); -SEC_CONST_DECL (kSecPolicyMacAppStoreReceipt, "1.2.840.113635.100.1.19"); -SEC_CONST_DECL (kSecPolicyAppleTimeStamping, "1.2.840.113635.100.1.20"); -SEC_CONST_DECL (kSecPolicyAppleRevocation, "1.2.840.113635.100.1.21"); -SEC_CONST_DECL (kSecPolicyApplePassbookSigning, "1.2.840.113635.100.1.22"); -SEC_CONST_DECL (kSecPolicyAppleMobileStore, "1.2.840.113635.100.1.23"); -SEC_CONST_DECL (kSecPolicyAppleEscrowService, "1.2.840.113635.100.1.24"); -SEC_CONST_DECL (kSecPolicyAppleProfileSigner, "1.2.840.113635.100.1.25"); -SEC_CONST_DECL (kSecPolicyAppleQAProfileSigner, "1.2.840.113635.100.1.26"); -SEC_CONST_DECL (kSecPolicyAppleTestMobileStore, "1.2.840.113635.100.1.27"); -SEC_CONST_DECL (kSecPolicyAppleOTAPKISigner, "1.2.840.113635.100.1.28"); -SEC_CONST_DECL (kSecPolicyAppleTestOTAPKISigner, "1.2.840.113635.100.1.29"); -SEC_CONST_DECL (kSecPolicyAppleIDValidationRecordSigningPolicy, "1.2.840.113635.100.1.30"); -SEC_CONST_DECL (kSecPolicyAppleIDValidationRecordSigning, "1.2.840.113635.100.1.30"); -SEC_CONST_DECL (kSecPolicyAppleSMPEncryption, "1.2.840.113635.100.1.31"); -SEC_CONST_DECL (kSecPolicyAppleTestSMPEncryption, "1.2.840.113635.100.1.32"); -SEC_CONST_DECL (kSecPolicyAppleServerAuthentication, "1.2.840.113635.100.1.33"); -SEC_CONST_DECL (kSecPolicyApplePCSEscrowService, "1.2.840.113635.100.1.34"); -SEC_CONST_DECL (kSecPolicyApplePPQSigning, "1.2.840.113635.100.1.35"); -SEC_CONST_DECL (kSecPolicyAppleTestPPQSigning, "1.2.840.113635.100.1.36"); -// Not in use. Use kSecPolicyAppleTVOSApplicationSigning instead. -// SEC_CONST_DECL (kSecPolicyAppleATVAppSigning, "1.2.840.113635.100.1.37"); -// SEC_CONST_DECL (kSecPolicyAppleTestATVAppSigning, "1.2.840.113635.100.1.38"); -SEC_CONST_DECL (kSecPolicyApplePayIssuerEncryption, "1.2.840.113635.100.1.39"); -SEC_CONST_DECL (kSecPolicyAppleOSXProvisioningProfileSigning, "1.2.840.113635.100.1.40"); -SEC_CONST_DECL (kSecPolicyAppleATVVPNProfileSigning, "1.2.840.113635.100.1.41"); -SEC_CONST_DECL (kSecPolicyAppleAST2DiagnosticsServerAuth, "1.2.840.113635.100.1.42"); -SEC_CONST_DECL (kSecPolicyAppleEscrowProxyServerAuth, "1.2.840.113635.100.1.43"); -SEC_CONST_DECL (kSecPolicyAppleFMiPServerAuth, "1.2.840.113635.100.1.44"); -SEC_CONST_DECL (kSecPolicyAppleMMCSService, "1.2.840.113635.100.1.45"); -SEC_CONST_DECL (kSecPolicyAppleGSService, "1.2.840.113635.100.1.46"); -SEC_CONST_DECL (kSecPolicyApplePPQService, "1.2.840.113635.100.1.47"); -SEC_CONST_DECL (kSecPolicyAppleHomeKitServerAuth, "1.2.840.113635.100.1.48"); -SEC_CONST_DECL (kSecPolicyAppleiPhoneActivation, "1.2.840.113635.100.1.49"); -SEC_CONST_DECL (kSecPolicyAppleiPhoneDeviceCertificate, "1.2.840.113635.100.1.50"); -SEC_CONST_DECL (kSecPolicyAppleFactoryDeviceCertificate, "1.2.840.113635.100.1.51"); -SEC_CONST_DECL (kSecPolicyAppleiAP, "1.2.840.113635.100.1.52"); -SEC_CONST_DECL (kSecPolicyAppleiTunesStoreURLBag, "1.2.840.113635.100.1.53"); -SEC_CONST_DECL (kSecPolicyAppleiPhoneApplicationSigning, "1.2.840.113635.100.1.54"); -SEC_CONST_DECL (kSecPolicyAppleiPhoneProfileApplicationSigning, "1.2.840.113635.100.1.55"); -SEC_CONST_DECL (kSecPolicyAppleiPhoneProvisioningProfileSigning, "1.2.840.113635.100.1.56"); -SEC_CONST_DECL (kSecPolicyAppleLockdownPairing, "1.2.840.113635.100.1.57"); -SEC_CONST_DECL (kSecPolicyAppleURLBag, "1.2.840.113635.100.1.58"); -SEC_CONST_DECL (kSecPolicyAppleOTATasking, "1.2.840.113635.100.1.59"); -SEC_CONST_DECL (kSecPolicyAppleMobileAsset, "1.2.840.113635.100.1.60"); -SEC_CONST_DECL (kSecPolicyAppleIDAuthority, "1.2.840.113635.100.1.61"); -SEC_CONST_DECL (kSecPolicyAppleGenericApplePinned, "1.2.840.113635.100.1.62"); -SEC_CONST_DECL (kSecPolicyAppleGenericAppleSSLPinned, "1.2.840.113635.100.1.63"); -SEC_CONST_DECL (kSecPolicyAppleSoftwareSigning, "1.2.840.113635.100.1.64"); -SEC_CONST_DECL (kSecPolicyAppleExternalDeveloper, "1.2.840.113635.100.1.65"); -SEC_CONST_DECL (kSecPolicyAppleOCSPSigner, "1.2.840.113635.100.1.66"); -SEC_CONST_DECL (kSecPolicyAppleIDSService, "1.2.840.113635.100.1.67"); -SEC_CONST_DECL (kSecPolicyAppleIDSServiceContext, "1.2.840.113635.100.1.68"); -SEC_CONST_DECL (kSecPolicyApplePushService, "1.2.840.113635.100.1.69"); -SEC_CONST_DECL (kSecPolicyAppleLegacyPushService, "1.2.840.113635.100.1.70"); -SEC_CONST_DECL (kSecPolicyAppleTVOSApplicationSigning, "1.2.840.113635.100.1.71"); -SEC_CONST_DECL (kSecPolicyAppleUniqueDeviceIdentifierCertificate, "1.2.840.113635.100.1.72"); -SEC_CONST_DECL (kSecPolicyAppleEscrowProxyCompatibilityServerAuth, "1.2.840.113635.100.1.73"); -SEC_CONST_DECL (kSecPolicyAppleMMCSCompatibilityServerAuth, "1.2.840.113635.100.1.74"); -SEC_CONST_DECL (kSecPolicyAppleSecureIOStaticAsset, "1.2.840.113635.100.1.75"); -SEC_CONST_DECL (kSecPolicyAppleWarsaw, "1.2.840.113635.100.1.76"); -SEC_CONST_DECL (kSecPolicyAppleiCloudSetupServerAuth, "1.2.840.113635.100.1.77"); -SEC_CONST_DECL (kSecPolicyAppleiCloudSetupCompatibilityServerAuth, "1.2.840.113635.100.1.78"); -SEC_CONST_DECL (kSecPolicyAppleAppTransportSecurity, "1.2.840.113635.100.1.80"); -SEC_CONST_DECL (kSecPolicyAppleMacOSProfileApplicationSigning, "1.2.840.113635.100.1.81"); -SEC_CONST_DECL (kSecPolicyAppleMobileSoftwareUpdate, "1.2.840.113635.100.1.82"); -SEC_CONST_DECL (kSecPolicyAppleMobileAssetDevelopment, "1.2.840.113635.100.1.83"); -SEC_CONST_DECL (kSecPolicyAppleBasicAttestationSystem, "1.2.840.113635.100.1.84"); -SEC_CONST_DECL (kSecPolicyAppleBasicAttestationUser, "1.2.840.113635.100.1.85"); -SEC_CONST_DECL (kSecPolicyAppleiPhoneVPNApplicationSigning, "1.2.840.113635.100.1.86"); + +/* Public policy oids. */ +#define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \ +const CFStringRef kSecPolicyApple##NAME = CFSTR("1.2.840.113635.100.1."#OID); +#include "SecPolicy.list" +//Some naming exceptions +SEC_CONST_DECL(kSecPolicyMacAppStoreReceipt, "1.2.840.113635.100.1.19") +SEC_CONST_DECL(kSecPolicyAppleIDValidationRecordSigningPolicy, "1.2.840.113635.100.1.30"); SEC_CONST_DECL (kSecPolicyOid, "SecPolicyOid"); SEC_CONST_DECL (kSecPolicyName, "SecPolicyName"); @@ -302,85 +99,35 @@ SEC_CONST_DECL (kSecPolicyKU_EncipherOnly, "CE_KU_EncipherOnly"); SEC_CONST_DECL (kSecPolicyKU_DecipherOnly, "CE_KU_DecipherOnly"); /* Internal policy names */ -static CFStringRef kSecPolicyNameBasicX509 = CFSTR("basicX509"); -static CFStringRef kSecPolicyNameSSLServer = CFSTR("sslServer"); -static CFStringRef kSecPolicyNameSSLClient = CFSTR("sslClient"); -static CFStringRef kSecPolicyNameiPhoneActivation = CFSTR("iPhoneActivation"); -static CFStringRef kSecPolicyNameiPhoneDeviceCertificate = - CFSTR("iPhoneDeviceCertificate"); -static CFStringRef kSecPolicyNameFactoryDeviceCertificate = - CFSTR("FactoryDeviceCertificate"); -static CFStringRef kSecPolicyNameiAP = CFSTR("iAP"); -static CFStringRef kSecPolicyNameiTunesStoreURLBag = CFSTR("iTunesStoreURLBag"); -static CFStringRef kSecPolicyNameEAPServer = CFSTR("eapServer"); -static CFStringRef kSecPolicyNameEAPClient = CFSTR("eapClient"); -static CFStringRef kSecPolicyNameIPSecServer = CFSTR("ipsecServer"); -static CFStringRef kSecPolicyNameIPSecClient = CFSTR("ipsecClient"); -static CFStringRef kSecPolicyNameiPhoneApplicationSigning = - CFSTR("iPhoneApplicationSigning"); -static CFStringRef kSecPolicyNameiPhoneProfileApplicationSigning = - CFSTR("iPhoneProfileApplicationSigning"); -static CFStringRef kSecPolicyNameiPhoneProvisioningProfileSigning = - CFSTR("iPhoneProvisioningProfileSigning"); -static CFStringRef kSecPolicyNameAppleSWUpdateSigning = CFSTR("AppleSWUpdateSigning"); -static CFStringRef kSecPolicyNameAppleTVOSApplicationSigning = - CFSTR("AppleTVApplicationSigning"); -static CFStringRef kSecPolicyNameRevocation = CFSTR("revocation"); -static CFStringRef kSecPolicyNameOCSPSigner = CFSTR("OCSPSigner"); -static CFStringRef kSecPolicyNameSMIME = CFSTR("SMIME"); -static CFStringRef kSecPolicyNameCodeSigning = CFSTR("CodeSigning"); -static CFStringRef kSecPolicyNamePackageSigning = CFSTR("PackageSigning"); -static CFStringRef kSecPolicyNameLockdownPairing = CFSTR("LockdownPairing"); -static CFStringRef kSecPolicyNameURLBag = CFSTR("URLBag"); -static CFStringRef kSecPolicyNameOTATasking = CFSTR("OTATasking"); -static CFStringRef kSecPolicyNameMobileAsset = CFSTR("MobileAsset"); -static CFStringRef kSecPolicyNameAppleIDAuthority = CFSTR("AppleIDAuthority"); -static CFStringRef kSecPolicyNameMacAppStoreReceipt = CFSTR("MacAppStoreReceipt"); -static CFStringRef kSecPolicyNameAppleTimeStamping = CFSTR("AppleTimeStamping"); -static CFStringRef kSecPolicyNameApplePassbook = CFSTR("ApplePassbook"); -static CFStringRef kSecPolicyNameAppleMobileStore = CFSTR("AppleMobileStore"); -static CFStringRef kSecPolicyNameAppleTestMobileStore = CFSTR("AppleTestMobileStore"); -static CFStringRef kSecPolicyNameAppleEscrowService = CFSTR("AppleEscrowService"); -static CFStringRef kSecPolicyNameApplePCSEscrowService = CFSTR("ApplePCSEscrowService"); -static CFStringRef kSecPolicyNameAppleProfileSigner = CFSTR("AppleProfileSigner"); -static CFStringRef kSecPolicyNameAppleQAProfileSigner = CFSTR("AppleQAProfileSigner"); -static CFStringRef kSecPolicyNameAppleOTAPKIAssetSigner = CFSTR("AppleOTAPKIAssetSigner"); -static CFStringRef kSecPolicyNameAppleTestOTAPKIAssetSigner = CFSTR("AppleTestOTAPKIAssetSigner"); -static CFStringRef kSecPolicyNameAppleIDValidationRecordSigningPolicy = CFSTR("AppleIDValidationRecordSigningPolicy"); -static CFStringRef kSecPolicyNameApplePayIssuerEncryption = CFSTR("ApplePayIssuerEncryption"); -static CFStringRef kSecPolicyNameAppleOSXProvisioningProfileSigning = CFSTR("AppleOSXProvisioningProfileSigning"); -static CFStringRef kSecPolicyNameAppleATVVPNProfileSigning = CFSTR("AppleATVVPNProfileSigning"); -static CFStringRef kSecPolicyNameAppleExternalDeveloper = CFSTR("Developer"); -static CFStringRef kSecPolicyNameAppleSoftwareSigning = CFSTR("SoftwareSigning"); -static CFStringRef kSecPolicyNameAppleSMPEncryption = CFSTR("AppleSMPEncryption"); -static CFStringRef kSecPolicyNameAppleTestSMPEncryption = CFSTR("AppleTestSMPEncryption"); -static CFStringRef kSecPolicyNameApplePPQSigning = CFSTR("ApplePPQSigning"); -static CFStringRef kSecPolicyNameAppleTestPPQSigning = CFSTR("AppleTestPPQSigning"); -static CFStringRef kSecPolicyNameAppleLegacyPushService = CFSTR("AppleLegacyPushService"); -static CFStringRef kSecPolicyNameAppleSSLService = CFSTR("AppleSSLService"); +#undef POLICYMACRO +#define __P_DO_DECLARE_(NAME, INTNAME) static CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME); +#define __P_DO_DECLARE_P(NAME, INTNAME) const CFStringRef kSecPolicyNameApple##NAME = CFSTR(#INTNAME); +#define __P_DO_DECLARE_I(NAME, INTNAME) const CFStringRef kSecPolicyName##NAME = CFSTR(#INTNAME); +#define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \ +__P_DO_DECLARE_##ISPUBLIC(NAME, INTNAME) +#include "SecPolicy.list" +//Some naming exceptions static CFStringRef kSecPolicyNameAppleIDSBag = CFSTR("IDSBag"); -static CFStringRef kSecPolicyNameAppleUniqueDeviceCertificate = CFSTR("UCRT"); -static CFStringRef kSecPolicyNameAppleSecureIOStaticAsset = CFSTR("SecureIOStaticAsset"); -static CFStringRef kSecPolicyNameAppleWarsaw = CFSTR("Warsaw"); -static CFStringRef kSecPolicyNameAppleAppTransportSecurity = CFSTR("ATS"); -static CFStringRef kSecPolicyNameMobileSoftwareUpdate = CFSTR("MobileSoftwareUpdate"); -static CFStringRef kSecPolicyNameAppleMacOSProfileApplicationSigning = CFSTR("macOSProfileApplicationSigning"); -static CFStringRef kSecPolicyNameAppleBasicAttestationSystem = CFSTR("BAA-SCRT"); -static CFStringRef kSecPolicyNameAppleBasicAttestationUser = CFSTR("BAA-UCRT"); -static CFStringRef kSecPolicyNameiPhoneVPNApplicationSigning = CFSTR("iPhoneVPNApplicationSigning"); - -/* Private policy names (SSL Pinned Services) */ + +/* External Policy Names + * These correspond to the names defined in CertificatePinning.plist + * in security_certificates */ +SEC_CONST_DECL (kSecPolicyNameSSLServer, "sslServer"); +SEC_CONST_DECL (kSecPolicyNameSSLClient, "sslClient"); +SEC_CONST_DECL (kSecPolicyNameEAPServer, "eapServer"); +SEC_CONST_DECL (kSecPolicyNameEAPClient, "eapClient"); +SEC_CONST_DECL (kSecPolicyNameIPSecServer, "ipsecServer"); +SEC_CONST_DECL (kSecPolicyNameIPSecClient, "ipsecClient"); SEC_CONST_DECL (kSecPolicyNameAppleiCloudSetupService, "iCloudSetup"); -SEC_CONST_DECL (kSecPolicyNameAppleGSService, "GS"); SEC_CONST_DECL (kSecPolicyNameAppleMMCSService, "MMCS"); -SEC_CONST_DECL (kSecPolicyNameApplePPQService, "PPQ"); -SEC_CONST_DECL (kSecPolicyNameAppleIDSService, "IDS"); -SEC_CONST_DECL (kSecPolicyNameApplePushService, "APN"); SEC_CONST_DECL (kSecPolicyNameAppleAST2Service, "AST2"); SEC_CONST_DECL (kSecPolicyNameAppleEscrowProxyService, "Escrow"); SEC_CONST_DECL (kSecPolicyNameAppleFMiPService, "FMiP"); SEC_CONST_DECL (kSecPolicyNameAppleHomeKitService, "HomeKit"); -SEC_CONST_DECL (kSecPolicyNameAppleGalaxyProviderService, "GalaxyProvider"); +SEC_CONST_DECL (kSecPolicyNameAppleAIDCService, "AIDC"); +SEC_CONST_DECL (kSecPolicyNameAppleMapsService, "Maps"); +SEC_CONST_DECL (kSecPolicyNameAppleHealthProviderService, "HealthProvider"); +SEC_CONST_DECL (kSecPolicyNameAppleParsecService, "Parsec"); #define kSecPolicySHA1Size 20 #define kSecPolicySHA256Size 32 @@ -541,306 +288,127 @@ SecPolicyRef SecPolicyCreateWithProperties(CFTypeRef policyIdentifier, goto errOut; } - /* These are in the same order as the constant declarations. */ - /* @@@ This should be turned into a table. */ - if (CFEqual(policyIdentifier, kSecPolicyAppleX509Basic)) { - policy = SecPolicyCreateBasicX509(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleSSL)) { - policy = SecPolicyCreateSSL(!client, name); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleSMIME)) { - policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage | kSecAnyEncryptSMIME, name); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleEAP)) { - CFArrayRef array = NULL; - if (isString(name)) { - array = CFArrayCreate(kCFAllocatorDefault, (const void **)&name, 1, &kCFTypeArrayCallBacks); - } else if (isArray(name)) { - array = CFArrayCreateCopy(NULL, name); - } - policy = SecPolicyCreateEAP(!client, array); - CFReleaseSafe(array); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleSWUpdateSigning)) { - policy = SecPolicyCreateAppleSWUpdateSigning(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleIPsec)) { + /* What follows are all the exceptional functions that do not match the macro below */ + if (CFEqual(policyIdentifier, kSecPolicyAppleSSL)) { + policy = SecPolicyCreateSSL(!client, name); + } else if (CFEqual(policyIdentifier, kSecPolicyAppleSMIME)) { + policy = SecPolicyCreateSMIME(kSecSignSMIMEUsage | kSecAnyEncryptSMIME, name); + } else if (CFEqual(policyIdentifier, kSecPolicyAppleEAP)) { + CFArrayRef array = NULL; + if (isString(name)) { + array = CFArrayCreate(kCFAllocatorDefault, (const void **)&name, 1, &kCFTypeArrayCallBacks); + } else if (isArray(name)) { + array = CFArrayCreateCopy(NULL, name); + } + policy = SecPolicyCreateEAP(!client, array); + CFReleaseSafe(array); + } else if (CFEqual(policyIdentifier, kSecPolicyAppleIPsec)) { policy = SecPolicyCreateIPSec(!client, name); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleCodeSigning)) { - policy = SecPolicyCreateCodeSigning(); - } - else if (CFEqual(policyIdentifier, kSecPolicyApplePackageSigning)) { - policy = SecPolicyCreateApplePackageSigning(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleIDValidation)) { - policy = SecPolicyCreateAppleIDAuthorityPolicy(); - } - else if (CFEqual(policyIdentifier, kSecPolicyMacAppStoreReceipt)) { + } else if (CFEqual(policyIdentifier, kSecPolicyMacAppStoreReceipt)) { policy = SecPolicyCreateMacAppStoreReceipt(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleTimeStamping)) { - policy = SecPolicyCreateAppleTimeStamping(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleRevocation)) { - policy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod); - } - else if (CFEqual(policyIdentifier, kSecPolicyApplePassbookSigning)) { - policy = SecPolicyCreatePassbookCardSigner(name, teamID); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleMobileStore)) { - policy = SecPolicyCreateMobileStoreSigner(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleEscrowService)) { - policy = SecPolicyCreateEscrowServiceSigner(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleProfileSigner)) { - policy = SecPolicyCreateConfigurationProfileSigner(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleQAProfileSigner)) { - policy = SecPolicyCreateQAConfigurationProfileSigner(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleTestMobileStore)) { - policy = SecPolicyCreateTestMobileStoreSigner(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleOTAPKISigner)) { - policy = SecPolicyCreateOTAPKISigner(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleTestOTAPKISigner)) { - policy = SecPolicyCreateTestOTAPKISigner(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleIDValidationRecordSigning)) { - policy = SecPolicyCreateAppleIDValidationRecordSigningPolicy(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleSMPEncryption)) { - policy = SecPolicyCreateAppleSMPEncryption(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleTestSMPEncryption)) { - policy = SecPolicyCreateTestAppleSMPEncryption(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleServerAuthentication)) { - policy = SecPolicyCreateAppleSSLService(name); - } - else if (CFEqual(policyIdentifier, kSecPolicyApplePCSEscrowService)) { - policy = SecPolicyCreatePCSEscrowServiceSigner(); - } - else if (CFEqual(policyIdentifier, kSecPolicyApplePPQSigning)) { - policy = SecPolicyCreateApplePPQSigning(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleTestPPQSigning)) { - policy = SecPolicyCreateTestApplePPQSigning(); - } - else if (CFEqual(policyIdentifier, kSecPolicyApplePayIssuerEncryption)) { - policy = SecPolicyCreateApplePayIssuerEncryption(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleOSXProvisioningProfileSigning)) { - policy = SecPolicyCreateOSXProvisioningProfileSigning(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleATVVPNProfileSigning)) { - policy = SecPolicyCreateAppleATVVPNProfileSigning(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleAST2DiagnosticsServerAuth)) { + } else if (CFEqual(policyIdentifier, kSecPolicyAppleRevocation)) { + policy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod); + } else if (CFEqual(policyIdentifier, kSecPolicyApplePassbookSigning)) { + policy = SecPolicyCreatePassbookCardSigner(name, teamID); + } else if (CFEqual(policyIdentifier, kSecPolicyAppleAST2DiagnosticsServerAuth)) { if (name) { policy = SecPolicyCreateAppleAST2Service(name, context); } else { secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); } - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleEscrowProxyServerAuth)) { + } else if (CFEqual(policyIdentifier, kSecPolicyAppleEscrowProxyServerAuth)) { if (name) { policy = SecPolicyCreateAppleEscrowProxyService(name, context); } else { secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); } - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleFMiPServerAuth)) { + } else if (CFEqual(policyIdentifier, kSecPolicyAppleFMiPServerAuth)) { if (name) { policy = SecPolicyCreateAppleFMiPService(name, context); } else { secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); } - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleMMCSService)) { + } else if (CFEqual(policyIdentifier, kSecPolicyAppleMMCService)) { if (name) { policy = SecPolicyCreateAppleMMCSService(name, context); } else { secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); } - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleGSService)) { + } else if (CFEqual(policyIdentifier, kSecPolicyAppleGSService)) { if (name) { policy = SecPolicyCreateAppleGSService(name, context); } else { secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); } - } - else if (CFEqual(policyIdentifier, kSecPolicyApplePPQService)) { + } else if (CFEqual(policyIdentifier, kSecPolicyApplePPQService)) { if (name) { policy = SecPolicyCreateApplePPQService(name, context); } else { secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); } - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleHomeKitServerAuth)) { - policy = SecPolicyCreateAppleHomeKitServerAuth(name); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleiPhoneActivation)) { - policy = SecPolicyCreateiPhoneActivation(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleiPhoneDeviceCertificate)) { - policy = SecPolicyCreateiPhoneDeviceCertificate(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleFactoryDeviceCertificate)) { - policy = SecPolicyCreateFactoryDeviceCertificate(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleiAP)) { - policy = SecPolicyCreateiAP(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleiTunesStoreURLBag)) { - policy = SecPolicyCreateiTunesStoreURLBag(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleiPhoneApplicationSigning)) { - policy = SecPolicyCreateiPhoneApplicationSigning(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleiPhoneProfileApplicationSigning)) { - policy = SecPolicyCreateiPhoneProfileApplicationSigning(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleiPhoneProvisioningProfileSigning)) { - policy = SecPolicyCreateiPhoneProvisioningProfileSigning(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleLockdownPairing)) { - policy = SecPolicyCreateLockdownPairing(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleURLBag)) { - policy = SecPolicyCreateURLBag(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleOTATasking)) { - policy = SecPolicyCreateOTATasking(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleMobileAsset)) { - policy = SecPolicyCreateMobileAsset(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleIDAuthority)) { - policy = SecPolicyCreateAppleIDAuthorityPolicy(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleGenericApplePinned)) { + } else if (CFEqual(policyIdentifier, kSecPolicyAppleGenericApplePinned)) { if (policyName) { policy = SecPolicyCreateApplePinned(policyName, intermediateMarkerOid, leafMarkerOid); } else { secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier); } - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleGenericAppleSSLPinned)) { + } else if (CFEqual(policyIdentifier, kSecPolicyAppleGenericAppleSSLPinned)) { if (policyName) { policy = SecPolicyCreateAppleSSLPinned(policyName, name, intermediateMarkerOid, leafMarkerOid); } else { secerror("policy \"%@\" requires kSecPolicyPolicyName input", policyIdentifier); } - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleSoftwareSigning)) { - policy = SecPolicyCreateAppleSoftwareSigning(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleExternalDeveloper)) { - policy = SecPolicyCreateAppleExternalDeveloper(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleOCSPSigner)) { - policy = SecPolicyCreateOCSPSigner(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleIDSService)) { - policy = SecPolicyCreateAppleIDSService(name); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleIDSServiceContext)) { + } else if (CFEqual(policyIdentifier, kSecPolicyAppleIDSServiceContext)) { if (name) { policy = SecPolicyCreateAppleIDSServiceContext(name, context); } else { secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); } - } - else if (CFEqual(policyIdentifier, kSecPolicyApplePushService)) { + } else if (CFEqual(policyIdentifier, kSecPolicyApplePushService)) { if (name) { policy = SecPolicyCreateApplePushService(name, context); } else { secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); } - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleLegacyPushService)) { - if (name) { - policy = SecPolicyCreateApplePushServiceLegacy(name); - } else { - secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); - } - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleTVOSApplicationSigning)) { - policy = SecPolicyCreateAppleTVOSApplicationSigning(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleUniqueDeviceIdentifierCertificate)) { + } else if (CFEqual(policyIdentifier, kSecPolicyAppleUniqueDeviceIdentifierCertificate)) { policy = SecPolicyCreateAppleUniqueDeviceCertificate(rootDigest); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleEscrowProxyCompatibilityServerAuth)) { - if (name) { - policy = SecPolicyCreateAppleCompatibilityEscrowProxyService(name); - } else { - secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); - } - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleMMCSCompatibilityServerAuth)) { - if (name) { - policy = SecPolicyCreateAppleCompatibilityMMCSService(name); - } else { - secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); - } - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleSecureIOStaticAsset)) { - policy = SecPolicyCreateAppleSecureIOStaticAsset(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleWarsaw)) { - policy = SecPolicyCreateAppleWarsaw(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleiCloudSetupServerAuth)) { + } else if (CFEqual(policyIdentifier, kSecPolicyAppleiCloudSetupServerAuth)) { if (name) { policy = SecPolicyCreateAppleiCloudSetupService(name, context); } else { secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); } - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleiCloudSetupCompatibilityServerAuth)) { - if (name) { - policy = SecPolicyCreateAppleCompatibilityiCloudSetupService(name); - } else { - secerror("policy \"%@\" requires kSecPolicyName input", policyIdentifier); - } - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleAppTransportSecurity)) { - policy = SecPolicyCreateAppleAppTransportSecurity(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleMobileAssetDevelopment)) { - policy = SecPolicyCreateMobileAssetDevelopment(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleMobileSoftwareUpdate)) { - policy = SecPolicyCreateMobileSoftwareUpdate(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleMacOSProfileApplicationSigning)) { - policy = SecPolicyCreateMacOSProfileApplicationSigning(); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleBasicAttestationSystem)) { - policy = SecPolicyCreateAppleBasicAttestationSystem(NULL); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleBasicAttestationUser)) { - policy = SecPolicyCreateAppleBasicAttestationUser(NULL); - } - else if (CFEqual(policyIdentifier, kSecPolicyAppleiPhoneVPNApplicationSigning)) { - policy = SecPolicyCreateiPhoneVPNApplicationSigning(); - } + } else if (CFEqual(policyIdentifier, kSecPolicyAppleBasicAttestationSystem)) { + policy = SecPolicyCreateAppleBasicAttestationSystem(rootDigest); + } else if (CFEqual(policyIdentifier, kSecPolicyAppleBasicAttestationUser)) { + policy = SecPolicyCreateAppleBasicAttestationUser(rootDigest); + } + /* For a couple of common patterns we use the macro */ +#define _P_OPTION_ +#define _P_OPTION_N name +#define _P_PROPERTIES_(NAME, IN_NAME, FUNCTION) +#define _P_PROPERTIES_Y(NAME, IN_NAME, FUNCTION) else if (CFEqual(policyIdentifier, kSecPolicyApple##NAME)) { \ + policy = SecPolicyCreate##FUNCTION(_P_OPTION_##IN_NAME); \ +} +#undef POLICYMACRO +#define POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) \ +_P_PROPERTIES_##IN_PROPERTIES(NAME, IN_NAME, FUNCTION) +#include "SecPolicy.list" else { secerror("ERROR: policy \"%@\" is unsupported", policyIdentifier); } + if (!policy) { + return NULL; + } + #ifdef TARGET_OS_OSX set_ku_from_properties(policy, properties); #endif - SecPolicySetName(policy, policyName); + if (policyName) { + SecPolicySetName(policy, policyName); + } errOut: return policy; @@ -1616,18 +1184,14 @@ static void SecPolicyAddBasicCertOptions(CFMutableDictionaryRef options) CFDictionaryAddValue(options, kSecPolicyCheckIdLinkage, kCFBooleanTrue); CFDictionaryAddValue(options, kSecPolicyCheckBasicConstraints, kCFBooleanTrue); CFDictionaryAddValue(options, kSecPolicyCheckNonEmptySubject, kCFBooleanTrue); - CFDictionaryAddValue(options, kSecPolicyCheckQualifiedCertStatements, kCFBooleanTrue); - CFDictionaryAddValue(options, kSecPolicyCheckWeakIntermediates, kCFBooleanTrue); - CFDictionaryAddValue(options, kSecPolicyCheckWeakLeaf, kCFBooleanTrue); - CFDictionaryAddValue(options, kSecPolicyCheckWeakRoot, kCFBooleanTrue); + CFDictionaryAddValue(options, kSecPolicyCheckWeakKeySize, kCFBooleanTrue); + CFDictionaryAddValue(options, kSecPolicyCheckWeakSignature, kCFBooleanTrue); } static void SecPolicyAddBasicX509Options(CFMutableDictionaryRef options) { SecPolicyAddBasicCertOptions(options); - CFDictionaryAddValue(options, kSecPolicyCheckValidIntermediates, kCFBooleanTrue); - CFDictionaryAddValue(options, kSecPolicyCheckValidLeaf, kCFBooleanTrue); - CFDictionaryAddValue(options, kSecPolicyCheckValidRoot, kCFBooleanTrue); + CFDictionaryAddValue(options, kSecPolicyCheckTemporalValidity, kCFBooleanTrue); // Make sure that black and gray leaf checks are performed for basic X509 chain building CFDictionaryAddValue(options, kSecPolicyCheckBlackListedLeaf, kCFBooleanTrue); @@ -1761,7 +1325,7 @@ SecPolicyRef SecPolicyCreateBasicX509(void) { CFDictionaryAddValue(options, kSecPolicyCheckNoNetworkAccess, kCFBooleanTrue); - require(result = SecPolicyCreate(kSecPolicyAppleX509Basic, kSecPolicyNameBasicX509, options), errOut); + require(result = SecPolicyCreate(kSecPolicyAppleX509Basic, kSecPolicyNameX509Basic, options), errOut); errOut: CFReleaseSafe(options); @@ -2336,7 +1900,7 @@ SecPolicyRef SecPolicyCreateMacOSProfileApplicationSigning(void) { /* On macOS, the cert in the provisioning profile may be one of: - leaf OID intermediate OID + leaf OID intermediate OID MAS Development .6.1.12 .6.2.1 MAS Submission .6.1.7 .6.2.1 Developer ID .6.1.13 .6.2.6 @@ -2352,7 +1916,7 @@ SecPolicyRef SecPolicyCreateMacOSProfileApplicationSigning(void) { require(result = SecPolicyCreate(kSecPolicyAppleMacOSProfileApplicationSigning, - kSecPolicyNameAppleMacOSProfileApplicationSigning, + kSecPolicyNameMacOSProfileApplicationSigning, options), errOut); errOut: @@ -2412,7 +1976,7 @@ SecPolicyRef SecPolicyCreateAppleTVOSApplicationSigning(void) { require(SecPolicyAddChainLengthOptions(options, 3), errOut); - require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleTVOSApplicationSigning), + require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameTVOSApplicationSigning), errOut); /* Check for intermediate: Apple Worldwide Developer Relations */ @@ -2428,7 +1992,7 @@ SecPolicyRef SecPolicyCreateAppleTVOSApplicationSigning(void) { add_leaf_marker(options, &oidAppleTVOSApplicationSigningProdQA); require(result = SecPolicyCreate(kSecPolicyAppleTVOSApplicationSigning, - kSecPolicyNameAppleTVOSApplicationSigning, options), + kSecPolicyNameTVOSApplicationSigning, options), errOut); errOut: @@ -2614,13 +2178,13 @@ SecPolicyRef SecPolicyCreateAppleSWUpdateSigning(void) { SecPolicyAddBasicX509Options(options); require(SecPolicyAddChainLengthOptions(options, 3), errOut); - require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleSWUpdateSigning), errOut); + require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameSWUpdateSigning), errOut); add_eku(options, &oidAppleExtendedKeyUsageCodeSigning); add_oid(options, kSecPolicyCheckIntermediateEKU, &oidAppleExtendedKeyUsageCodeSigning); require(result = SecPolicyCreate(kSecPolicyAppleSWUpdateSigning, - kSecPolicyNameAppleSWUpdateSigning, options), + kSecPolicyNameSWUpdateSigning, options), errOut); errOut: @@ -2677,11 +2241,7 @@ SecPolicyRef SecPolicyCreateLockdownPairing(void) { kCFBooleanTrue); CFDictionaryAddValue(options, kSecPolicyCheckBasicConstraints, kCFBooleanTrue); - CFDictionaryAddValue(options, kSecPolicyCheckQualifiedCertStatements, - kCFBooleanTrue); - CFDictionaryAddValue(options, kSecPolicyCheckWeakIntermediates, kCFBooleanTrue); - CFDictionaryAddValue(options, kSecPolicyCheckWeakLeaf, kCFBooleanTrue); - CFDictionaryAddValue(options, kSecPolicyCheckWeakRoot, kCFBooleanTrue); + CFDictionaryAddValue(options, kSecPolicyCheckWeakKeySize, kCFBooleanTrue); require(result = SecPolicyCreate(kSecPolicyAppleLockdownPairing, kSecPolicyNameLockdownPairing, options), errOut); @@ -2815,7 +2375,7 @@ SecPolicyRef SecPolicyCreateAppleIDAuthorityPolicy(void) SecPolicyAddBasicX509Options(options); // Apple CA anchored - require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleIDAuthority), out); + require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameIDAuthority), out); // with the addition of the existence check of an extension with "Apple ID Sharing Certificate" oid (1.2.840.113635.100.4.7) // NOTE: this obviously intended to have gone into Extended Key Usage, but evidence of existing certs proves the contrary. @@ -2826,7 +2386,7 @@ SecPolicyRef SecPolicyCreateAppleIDAuthorityPolicy(void) add_oid(options, kSecPolicyCheckIntermediateMarkerOid, &oidAppleIntmMarkerAppleID2); require(result = SecPolicyCreate(kSecPolicyAppleIDAuthority, - kSecPolicyNameAppleIDAuthority, options), out); + kSecPolicyNameIDAuthority, options), out); out: CFReleaseSafe(options); @@ -2879,7 +2439,7 @@ static SecPolicyRef _SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer, C &kCFTypeDictionaryValueCallBacks), out); SecPolicyAddBasicX509Options(options); - require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameApplePassbook), out); + require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNamePassbookSigning), out); // Chain length of 3 require(SecPolicyAddChainLengthOptions(options, 3), out); @@ -2906,7 +2466,7 @@ static SecPolicyRef _SecPolicyCreatePassbookCardSigner(CFStringRef cardIssuer, C add_eku(options, &oidAppleExtendedKeyUsagePassbook); require(result = SecPolicyCreate(kSecPolicyApplePassbookSigning, - kSecPolicyNameApplePassbook, options), out); + kSecPolicyNamePassbookSigning, options), out); out: CFReleaseSafe(options); @@ -2929,8 +2489,8 @@ static SecPolicyRef CreateMobileStoreSigner(Boolean forTest) &kCFTypeDictionaryValueCallBacks), errOut); SecPolicyAddBasicX509Options(options); require(SecPolicyAddAppleAnchorOptions(options, - ((forTest) ? kSecPolicyNameAppleTestMobileStore : - kSecPolicyNameAppleMobileStore)), errOut); + ((forTest) ? kSecPolicyNameTestMobileStore : + kSecPolicyNameMobileStore)), errOut); require(SecPolicyAddChainLengthOptions(options, 3), errOut); @@ -2944,7 +2504,7 @@ static SecPolicyRef CreateMobileStoreSigner(Boolean forTest) add_certificate_policy_oid(options, pOID); require(result = SecPolicyCreate((forTest) ? kSecPolicyAppleTestMobileStore : kSecPolicyAppleMobileStore, - (forTest) ? kSecPolicyNameAppleTestMobileStore : kSecPolicyNameAppleMobileStore, + (forTest) ? kSecPolicyNameTestMobileStore : kSecPolicyNameMobileStore, options), errOut); errOut: @@ -3019,7 +2579,7 @@ CF_RETURNS_RETAINED SecPolicyRef SecPolicyCreateEscrowServiceSigner(void) require(result = SecPolicyCreate(kSecPolicyAppleEscrowService, - kSecPolicyNameAppleEscrowService, options), errOut); + kSecPolicyNameEscrowService, options), errOut); errOut: CFReleaseSafe(anArray); @@ -3081,7 +2641,7 @@ CF_RETURNS_RETAINED SecPolicyRef SecPolicyCreatePCSEscrowServiceSigner(void) require(result = SecPolicyCreate(kSecPolicyApplePCSEscrowService, - kSecPolicyNameApplePCSEscrowService, options), errOut); + kSecPolicyNamePCSEscrowService, options), errOut); errOut: CFReleaseSafe(anArray); @@ -3097,7 +2657,7 @@ static SecPolicyRef CreateConfigurationProfileSigner(bool forTest) { &kCFTypeDictionaryValueCallBacks), errOut); SecPolicyAddBasicX509Options(options); - require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleProfileSigner), errOut); + require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameProfileSigner), errOut); //Chain length 3 require(SecPolicyAddChainLengthOptions(options, 3), errOut); @@ -3110,7 +2670,7 @@ static SecPolicyRef CreateConfigurationProfileSigner(bool forTest) { add_element(options, kSecPolicyCheckIntermediateMarkerOid, CFSTR("1.2.840.113635.100.6.2.3")); require(result = SecPolicyCreate((forTest) ? kSecPolicyAppleQAProfileSigner: kSecPolicyAppleProfileSigner, - (forTest) ? kSecPolicyNameAppleQAProfileSigner : kSecPolicyNameAppleProfileSigner, + (forTest) ? kSecPolicyNameQAProfileSigner : kSecPolicyNameProfileSigner, options), errOut); errOut: @@ -3142,7 +2702,7 @@ SecPolicyRef SecPolicyCreateOSXProvisioningProfileSigning(void) &kCFTypeDictionaryValueCallBacks), errOut); // Require valid chain from the Apple root SecPolicyAddBasicX509Options(options); - SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleOSXProvisioningProfileSigning); + SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameOSXProvisioningProfileSigning); // Require provisioning profile leaf marker OID (1.2.840.113635.100.4.11) add_leaf_marker(options, &oidAppleCertExtOSXProvisioningProfileSigning); @@ -3157,7 +2717,7 @@ SecPolicyRef SecPolicyCreateOSXProvisioningProfileSigning(void) CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP); require(result = SecPolicyCreate(kSecPolicyAppleOSXProvisioningProfileSigning, - kSecPolicyNameAppleOSXProvisioningProfileSigning, options), errOut); + kSecPolicyNameOSXProvisioningProfileSigning, options), errOut); errOut: CFReleaseSafe(options); @@ -3178,7 +2738,7 @@ SecPolicyRef SecPolicyCreateOTAPKISigner(void) require(SecPolicyAddChainLengthOptions(options, 2), errOut); require(result = SecPolicyCreate(kSecPolicyAppleOTAPKISigner, - kSecPolicyNameAppleOTAPKIAssetSigner, options), errOut); + kSecPolicyNameOTAPKISigner, options), errOut); errOut: CFReleaseSafe(options); @@ -3205,7 +2765,7 @@ SecPolicyRef SecPolicyCreateTestOTAPKISigner(void) require(SecPolicyAddChainLengthOptions(options, 2), errOut); require(result = SecPolicyCreate(kSecPolicyAppleTestOTAPKISigner, - kSecPolicyNameAppleTestOTAPKIAssetSigner, options), errOut); + kSecPolicyNameTestOTAPKISigner, options), errOut); errOut: CFReleaseSafe(options); @@ -3229,7 +2789,7 @@ SecPolicyRef SecPolicyCreateAppleSMPEncryption(void) &kCFTypeDictionaryValueCallBacks), errOut); SecPolicyAddBasicCertOptions(options); - require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleSMPEncryption), + require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameSMPEncryption), errOut); require(SecPolicyAddChainLengthOptions(options, 3), errOut); @@ -3248,7 +2808,7 @@ SecPolicyRef SecPolicyCreateAppleSMPEncryption(void) CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP); require(result = SecPolicyCreate(kSecPolicyAppleSMPEncryption, - kSecPolicyNameAppleSMPEncryption, options), errOut); + kSecPolicyNameSMPEncryption, options), errOut); errOut: CFReleaseSafe(options); @@ -3282,7 +2842,7 @@ SecPolicyRef SecPolicyCreateTestAppleSMPEncryption(void) CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP); require(result = SecPolicyCreate(kSecPolicyAppleTestSMPEncryption, - kSecPolicyNameAppleTestSMPEncryption, options), errOut); + kSecPolicyNameTestSMPEncryption, options), errOut); errOut: CFReleaseSafe(options); @@ -3303,7 +2863,7 @@ SecPolicyRef SecPolicyCreateAppleIDValidationRecordSigningPolicy(void) // Apple CA anchored require(SecPolicyAddAppleAnchorOptions(options, - kSecPolicyNameAppleIDValidationRecordSigningPolicy), + kSecPolicyNameIDValidationRecordSigning), errOut); // Check for an extension with " Apple ID Validation Record Signing" oid (1.2.840.113635.100.6.25) @@ -3320,7 +2880,7 @@ SecPolicyRef SecPolicyCreateAppleIDValidationRecordSigningPolicy(void) CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP); require(result = SecPolicyCreate(kSecPolicyAppleIDValidationRecordSigning, - kSecPolicyNameAppleIDValidationRecordSigningPolicy, options), errOut); + kSecPolicyNameIDValidationRecordSigning, options), errOut); errOut: CFReleaseSafe(options); @@ -3631,7 +3191,7 @@ SecPolicyRef SecPolicyCreateApplePushServiceLegacy(CFStringRef hostname) CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); result = SecPolicyCreate(kSecPolicyAppleLegacyPushService, - kSecPolicyNameAppleLegacyPushService, options); + kSecPolicyNameLegacyPushService, options); require(result, errOut); errOut: @@ -3646,7 +3206,7 @@ errOut: */ SecPolicyRef SecPolicyCreateAppleMMCSService(CFStringRef hostname, CFDictionaryRef context) { - return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleMMCSService, + return SecPolicyCreateAppleServerAuthCommon(hostname, context, kSecPolicyAppleMMCService, kSecPolicyNameAppleMMCSService, &oidAppleCertExtAppleServerAuthenticationMMCSProd, &oidAppleCertExtAppleServerAuthenticationMMCSProdQA); @@ -3691,7 +3251,7 @@ SecPolicyRef SecPolicyCreateAppleSSLService(CFStringRef hostname) require((options=(CFMutableDictionaryRef)policy->_options) != NULL, errOut); // Apple CA anchored - require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleSSLService), errOut); + require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameServerAuthentication), errOut); // Check leaf for Apple Server Authentication marker oid (1.2.840.113635.100.6.27.1) add_leaf_marker(options, &oidAppleCertExtAppleServerAuthentication); @@ -3706,7 +3266,7 @@ SecPolicyRef SecPolicyCreateAppleSSLService(CFStringRef hostname) CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationAny); SecPolicySetOid(policy, kSecPolicyAppleServerAuthentication); - SecPolicySetName(policy, kSecPolicyNameAppleSSLService); + SecPolicySetName(policy, kSecPolicyNameServerAuthentication); return policy; @@ -3733,7 +3293,7 @@ SecPolicyRef SecPolicyCreateApplePPQSigning(void) &kCFTypeDictionaryValueCallBacks), errOut); SecPolicyAddBasicCertOptions(options); - SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameApplePPQSigning); + SecPolicyAddAppleAnchorOptions(options, kSecPolicyNamePPQSigning); require(SecPolicyAddChainLengthOptions(options, 3), errOut); CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName, @@ -3748,7 +3308,7 @@ SecPolicyRef SecPolicyCreateApplePPQSigning(void) add_ku(options, kSecKeyUsageDigitalSignature); require(result = SecPolicyCreate(kSecPolicyApplePPQSigning, - kSecPolicyNameApplePPQSigning, options), errOut); + kSecPolicyNamePPQSigning, options), errOut); errOut: CFReleaseSafe(options); @@ -3777,7 +3337,7 @@ SecPolicyRef SecPolicyCreateTestApplePPQSigning(void) &kCFTypeDictionaryValueCallBacks), errOut); SecPolicyAddBasicCertOptions(options); - SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleTestPPQSigning); + SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameTestPPQSigning); require(SecPolicyAddChainLengthOptions(options, 3), errOut); CFDictionaryAddValue(options, kSecPolicyCheckIssuerCommonName, @@ -3792,7 +3352,7 @@ SecPolicyRef SecPolicyCreateTestApplePPQSigning(void) add_ku(options, kSecKeyUsageDigitalSignature); require(result = SecPolicyCreate(kSecPolicyAppleTestPPQSigning, - kSecPolicyNameAppleTestPPQSigning, options), errOut); + kSecPolicyNameTestPPQSigning, options), errOut); errOut: CFReleaseSafe(options); @@ -3816,7 +3376,7 @@ SecPolicyRef SecPolicyCreateAppleTimeStamping(void) add_eku(options, &oidExtendedKeyUsageTimeStamping); require(result = SecPolicyCreate(kSecPolicyAppleTimeStamping, - kSecPolicyNameAppleTimeStamping, options), errOut); + kSecPolicyNameTimeStamping, options), errOut); errOut: CFReleaseSafe(options); @@ -3839,7 +3399,7 @@ SecPolicyRef SecPolicyCreateApplePayIssuerEncryption(void) &kCFTypeDictionaryValueCallBacks), errOut); SecPolicyAddBasicCertOptions(options); - require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameApplePayIssuerEncryption), + require(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNamePayIssuerEncryption), errOut); require(SecPolicyAddChainLengthOptions(options, 3), errOut); @@ -3852,7 +3412,7 @@ SecPolicyRef SecPolicyCreateApplePayIssuerEncryption(void) add_ku(options, kSecKeyUsageKeyEncipherment); require(result = SecPolicyCreate(kSecPolicyApplePayIssuerEncryption, - kSecPolicyNameApplePayIssuerEncryption, options), errOut); + kSecPolicyNamePayIssuerEncryption, options), errOut); errOut: CFReleaseSafe(options); @@ -3900,7 +3460,7 @@ SecPolicyRef SecPolicyCreateAppleATVVPNProfileSigning(void) CFDictionaryAddValue(options, kSecPolicyCheckRevocation, kSecPolicyCheckRevocationOCSP); require(result = SecPolicyCreate(kSecPolicyAppleATVVPNProfileSigning, - kSecPolicyNameAppleATVVPNProfileSigning, options), errOut); + kSecPolicyNameATVVPNProfileSigning, options), errOut); errOut: CFReleaseSafe(options); @@ -3958,7 +3518,7 @@ SecPolicyRef SecPolicyCreateAppleExternalDeveloper(void) { SecPolicyRef result = NULL; /* Create basic Apple pinned policy */ - require(result = SecPolicyCreateApplePinned(kSecPolicyNameAppleExternalDeveloper, + require(result = SecPolicyCreateApplePinned(kSecPolicyNameExternalDeveloper, CFSTR("1.2.840.113635.100.6.2.1"), // WWDR Intermediate OID CFSTR("1.2.840.113635.100.6.1.2")), // "iPhone Developer" leaf OID errOut); @@ -4008,7 +3568,7 @@ SecPolicyRef SecPolicyCreateAppleSoftwareSigning(void) { SecPolicyAddBasicCertOptions(options); /* Anchored to the Apple Roots */ - require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleSoftwareSigning), + require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameSoftwareSigning), errOut); /* Exactly 3 certs in the chain */ @@ -4030,7 +3590,7 @@ SecPolicyRef SecPolicyCreateAppleSoftwareSigning(void) { require(SecPolicyAddStrongKeySizeOptions(options), errOut); require(result = SecPolicyCreate(kSecPolicyAppleSoftwareSigning, - kSecPolicyNameAppleSoftwareSigning, options), errOut); + kSecPolicyNameSoftwareSigning, options), errOut); errOut: CFReleaseSafe(options); @@ -4087,7 +3647,7 @@ SecPolicyRef SecPolicyCreateAppleUniqueDeviceCertificate(CFDataRef testRootHash) require(result = SecPolicyCreate(kSecPolicyAppleUniqueDeviceIdentifierCertificate, - kSecPolicyNameAppleUniqueDeviceCertificate, options), errOut); + kSecPolicyNameUniqueDeviceIdentifierCertificate, options), errOut); errOut: CFReleaseSafe(options); @@ -4110,7 +3670,7 @@ SecPolicyRef SecPolicyCreateAppleWarsaw(void) { SecPolicyAddBasicX509Options(options); /* Anchored to the Apple Roots. */ - require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleWarsaw), + require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameWarsaw), errOut); /* Exactly 3 certs in the chain */ @@ -4129,7 +3689,7 @@ SecPolicyRef SecPolicyCreateAppleWarsaw(void) { require(SecPolicyAddStrongKeySizeOptions(options), errOut); require(result = SecPolicyCreate(kSecPolicyAppleWarsaw, - kSecPolicyNameAppleWarsaw, options), errOut); + kSecPolicyNameWarsaw, options), errOut); errOut: CFReleaseSafe(options); @@ -4159,7 +3719,7 @@ SecPolicyRef SecPolicyCreateAppleSecureIOStaticAsset(void) { add_element(options, kSecPolicyCheckAnchorApple, appleAnchorOptions); CFReleaseSafe(appleAnchorOptions); #else - require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameAppleSecureIOStaticAsset), + require_quiet(SecPolicyAddAppleAnchorOptions(options, kSecPolicyNameSecureIOStaticAsset), errOut); #endif @@ -4176,7 +3736,7 @@ SecPolicyRef SecPolicyCreateAppleSecureIOStaticAsset(void) { require(SecPolicyAddStrongKeySizeOptions(options), errOut); require(result = SecPolicyCreate(kSecPolicyAppleSecureIOStaticAsset, - kSecPolicyNameAppleSecureIOStaticAsset, options), errOut); + kSecPolicyNameSecureIOStaticAsset, options), errOut); errOut: CFReleaseSafe(options); @@ -4205,7 +3765,7 @@ SecPolicyRef SecPolicyCreateAppleAppTransportSecurity(void) { add_element(options, kSecPolicyCheckSignatureHashAlgorithms, disallowedHashes); require_quiet(result = SecPolicyCreate(kSecPolicyAppleAppTransportSecurity, - kSecPolicyNameAppleAppTransportSecurity, + kSecPolicyNameAppTransportSecurity, options), errOut); errOut: @@ -4273,8 +3833,6 @@ const uint8_t BAUserRootCA_SHA256[kSecPolicySHA256Size] = { SecPolicyRef SecPolicyCreateAppleBasicAttestationSystem(CFDataRef testRootHash) { CFMutableDictionaryRef options = NULL; - CFDictionaryRef keySizes = NULL; - CFNumberRef ecSize = NULL; SecPolicyRef result = NULL; require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, @@ -4293,19 +3851,15 @@ SecPolicyRef SecPolicyCreateAppleBasicAttestationSystem(CFDataRef testRootHash) require(SecPolicyAddChainLengthOptions(options, 3), errOut); require(result = SecPolicyCreate(kSecPolicyAppleBasicAttestationSystem, - kSecPolicyNameAppleBasicAttestationSystem, options), errOut); + kSecPolicyNameBasicAttestationSystem, options), errOut); errOut: CFReleaseSafe(options); - CFReleaseSafe(keySizes); - CFReleaseSafe(ecSize); return result; } SecPolicyRef SecPolicyCreateAppleBasicAttestationUser(CFDataRef testRootHash) { CFMutableDictionaryRef options = NULL; - CFDictionaryRef keySizes = NULL; - CFNumberRef ecSize = NULL; SecPolicyRef result = NULL; require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, @@ -4324,11 +3878,35 @@ SecPolicyRef SecPolicyCreateAppleBasicAttestationUser(CFDataRef testRootHash) { require(SecPolicyAddChainLengthOptions(options, 3), errOut); require(result = SecPolicyCreate(kSecPolicyAppleBasicAttestationUser, - kSecPolicyNameAppleBasicAttestationUser, options), errOut); + kSecPolicyNameBasicAttestationUser, options), errOut); + +errOut: + CFReleaseSafe(options); + return result; +} + +SecPolicyRef SecPolicyCreateDemoDigitalCatalogSigning(void) { + CFMutableDictionaryRef options = NULL; + SecPolicyRef result = NULL; + + require(options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks), errOut); + SecPolicyAddBasicX509Options(options); + + /* Exactly 3 certs in the chain */ + require(SecPolicyAddChainLengthOptions(options, 3), errOut); + + /* Demo Signing Extension present in leaf */ + add_element(options, kSecPolicyCheckLeafMarkerOid, CFSTR("1.2.840.113635.100.6.60")); + + /* Issuer common name is "DemoUnit CA" */ + add_element(options, kSecPolicyCheckIssuerCommonName, CFSTR("DemoUnit CA")); + + require(result = SecPolicyCreate(kSecPolicyAppleDemoDigitalCatalog, + kSecPolicyNameDemoDigitalCatalog, options), errOut); errOut: CFReleaseSafe(options); - CFReleaseSafe(keySizes); - CFReleaseSafe(ecSize); return result; } diff --git a/OSX/sec/Security/SecPolicy.list b/OSX/sec/Security/SecPolicy.list new file mode 100644 index 00000000..3206ccfc --- /dev/null +++ b/OSX/sec/Security/SecPolicy.list @@ -0,0 +1,91 @@ +// Copyright (c) 2017 Apple Inc. All Rights Reserved. +// This is the list of Policies. To add a new policy put it in this file with the POLICYMACRO defined. +// Arguments for the POLICYMACRO in arg order are: +// POLICYMACRO(NAME, OID, ISPUBLIC, INTNAME, IN_NAME, IN_PROPERTIES, FUNCTION) +// NAME: the constant name. Will be kSecPolicyApple##NAME for the exported OID and kSecPolicyName##NAME for the private name +// OID: element of policy OID arc +// ISPUBLIC: P indicates that the kSecPolicyNameApple##NAME is exported, +// I indicates that the kSecPolicyName##NAME is exported +// INTNAME: The internal string value for kSecPolicyName##NAME +// IN_NAME: N indicates that the corresponding function takes a name parameter +// IN_PROPERTIES: Y indicates that the constant uses a macro for SecPolicyCreateWithProperties +// FUNCTION: SecPolicyCreate##FUNCTION is the function call for this policy; used in exports and macro for SecPolicyCreateWithProperties + + +POLICYMACRO(X509Basic, 2 , I, basicX509, , Y, BasicX509) +POLICYMACRO(SSL, 3 , , ssl, , , SSL) +POLICYMACRO(SMIME, 8 , I, SMIME, , , SMIME) +POLICYMACRO(EAP, 9 , , eap, , , EAP) +POLICYMACRO(SWUpdateSigning, 10, , AppleSWUpdateSigning, , Y, AppleSWUpdateSigning) +POLICYMACRO(IPsec, 11, , ipsec, , , IPSec) +POLICYMACRO(PKINITClient, 14, , pkinitClient, , , ) +POLICYMACRO(PKINITServer, 15, , pkinitServer, , , ) +POLICYMACRO(CodeSigning, 16, I, CodeSigning, , Y, CodeSigning) +POLICYMACRO(PackageSigning, 17, , PackageSigning, , Y, ApplePackageSigning) +POLICYMACRO(IDValidation, 18, , AppleIDAuthority, , Y, AppleIDAuthorityPolicy) +POLICYMACRO(MacAppStoreReceipt, 19, , MacAppStoreReceipt, , , MacAppStoreReceipt) +POLICYMACRO(TimeStamping, 20, I, AppleTimeStamping, , Y, AppleTimeStamping) +POLICYMACRO(Revocation, 21, , revocation, , , Revocation) +POLICYMACRO(PassbookSigning, 22, , ApplePassbook, , , PassbookCardSigner) +POLICYMACRO(MobileStore, 23, , AppleMobileStore, , Y, MobileStoreSigner) +POLICYMACRO(EscrowService, 24, , AppleEscrowService, , Y, EscrowServiceSigner) +POLICYMACRO(ProfileSigner, 25, , AppleProfileSigner, , Y, ConfigurationProfileSigner) +POLICYMACRO(QAProfileSigner, 26, , AppleQAProfileSigner, , Y, QAConfigurationProfileSigner) +POLICYMACRO(TestMobileStore, 27, , AppleTestMobileStore, , Y, TestMobileStoreSigner) +POLICYMACRO(OTAPKISigner, 28, , AppleOTAPKIAssetSigner, , Y, OTAPKISigner) +POLICYMACRO(TestOTAPKISigner, 29, , AppleTestOTAPKIAssetSigner, , Y, TestOTAPKISigner) +POLICYMACRO(IDValidationRecordSigning, 30, , AppleIDValidationRecordSigningPolicy, , Y, AppleIDValidationRecordSigningPolicy) +POLICYMACRO(SMPEncryption, 31, , AppleSMPEncryption, , Y, AppleSMPEncryption) +POLICYMACRO(TestSMPEncryption, 32, , AppleTestSMPEncryption, , Y, TestAppleSMPEncryption) +POLICYMACRO(ServerAuthentication, 33, , AppleSSLService, N, Y, AppleSSLService) +POLICYMACRO(PCSEscrowService, 34, , ApplePCSEscrowService, , Y, PCSEscrowServiceSigner) +POLICYMACRO(PPQSigning, 35, , ApplePPQSigning, , Y, ApplePPQSigning) +POLICYMACRO(TestPPQSigning, 36, , AppleTestPPQSigning, , Y, TestApplePPQSigning) +POLICYMACRO(PayIssuerEncryption, 39, , ApplePayIssuerEncryption, , Y, ApplePayIssuerEncryption) +POLICYMACRO(OSXProvisioningProfileSigning, 40, , AppleOSXProvisioningProfileSigning, , Y, OSXProvisioningProfileSigning) +POLICYMACRO(ATVVPNProfileSigning, 41, , AppleATVVPNProfileSigning, , Y, AppleATVVPNProfileSigning) +POLICYMACRO(AST2DiagnosticsServerAuth, 42, P, AST2, , , AppleAST2Service) +POLICYMACRO(EscrowProxyServerAuth, 43, P, Escrow, , , AppleEscrowProxyService) +POLICYMACRO(FMiPServerAuth, 44, P, FMiP, , , AppleFMiPService) +POLICYMACRO(MMCService, 45, P, MMCS, , , AppleMMCSService) +POLICYMACRO(GSService, 46, P, GS, , , AppleGSService) +POLICYMACRO(PPQService, 47, P, PPQ, , , ApplePPQService) +POLICYMACRO(HomeKitServerAuth, 48, P, HomeKit, N, Y, AppleHomeKitServerAuth) +POLICYMACRO(iPhoneActivation, 49, , iPhoneActivation, , Y, iPhoneActivation) +POLICYMACRO(iPhoneDeviceCertificate, 50, , iPhoneDeviceCertificate, , Y, iPhoneDeviceCertificate) +POLICYMACRO(FactoryDeviceCertificate, 51, , FactoryDeviceCertificate, , Y, FactoryDeviceCertificate) +POLICYMACRO(iAP, 52, , iAP, , Y, iAP) +POLICYMACRO(iTunesStoreURLBag, 53, , iTunesStoreURLBag, , Y, iTunesStoreURLBag) +POLICYMACRO(iPhoneApplicationSigning, 54, , iPhoneApplicationSigning, , Y, iPhoneApplicationSigning) +POLICYMACRO(iPhoneProfileApplicationSigning, 55, , iPhoneProfileApplicationSigning, , Y, iPhoneProfileApplicationSigning) +POLICYMACRO(iPhoneProvisioningProfileSigning, 56, , iPhoneProvisioningProfileSigning, , Y, iPhoneProvisioningProfileSigning) +POLICYMACRO(LockdownPairing, 57, , LockdownPairing, , Y, LockdownPairing) +POLICYMACRO(URLBag, 58, , URLBag, , Y, URLBag) +POLICYMACRO(OTATasking, 59, , OTATasking, , Y, OTATasking) +POLICYMACRO(MobileAsset, 60, , MobileAsset, , Y, MobileAsset) +POLICYMACRO(IDAuthority, 61, , AppleIDAuthority, , Y, AppleIDAuthorityPolicy) +POLICYMACRO(GenericApplePinned, 62, , Generic, , , ApplePinned) +POLICYMACRO(GenericAppleSSLPinned, 63, , GenericSSL, , , AppleSSLPinned) +POLICYMACRO(SoftwareSigning, 64, , SoftwareSigning, , Y, AppleSoftwareSigning) +POLICYMACRO(ExternalDeveloper, 65, , Developer, , Y, AppleExternalDeveloper) +POLICYMACRO(OCSPSigner, 66, I, OCSPSigner, , Y, OCSPSigner) +POLICYMACRO(IDSService, 67, P, IDS, N, Y, AppleIDSService) +POLICYMACRO(IDSServiceContext, 68, , IDS, , , AppleIDSServiceContext) +POLICYMACRO(PushService, 69, P, APN, , , ApplePushService) +POLICYMACRO(LegacyPushService, 70, , AppleLegacyPushService, N, Y, ApplePushServiceLegacy) +POLICYMACRO(TVOSApplicationSigning, 71, , AppleTVApplicationSigning, , Y, AppleTVOSApplicationSigning) +POLICYMACRO(UniqueDeviceIdentifierCertificate, 72, , UCRT, , , AppleUniqueDeviceCertificate) +POLICYMACRO(EscrowProxyCompatibilityServerAuth, 73, , Escrow, N, Y, AppleCompatibilityEscrowProxyService) +POLICYMACRO(MMCSCompatibilityServerAuth, 74, , MMCS, N, Y, AppleCompatibilityMMCSService) +POLICYMACRO(SecureIOStaticAsset, 75, , SecureIOStaticAsset, , Y, AppleSecureIOStaticAsset) +POLICYMACRO(Warsaw, 76, , Warsaw, , Y, AppleWarsaw) +POLICYMACRO(iCloudSetupServerAuth, 77, P, iCloudSetup, , , AppleiCloudSetupService) +POLICYMACRO(iCloudSetupCompatibilityServerAuth, 78, , iCloudSetup, N, Y, AppleCompatibilityiCloudSetupService) +POLICYMACRO(AppTransportSecurity, 80, , ATS, , Y, AppleAppTransportSecurity) +POLICYMACRO(MacOSProfileApplicationSigning, 81, , macOSProfileApplicationSigning, , Y, MacOSProfileApplicationSigning) +POLICYMACRO(MobileSoftwareUpdate, 82, , MobileSoftwareUpdate, , Y, MobileSoftwareUpdate) +POLICYMACRO(MobileAssetDevelopment, 83, , MobileAsset, , Y, MobileAssetDevelopment) +POLICYMACRO(BasicAttestationSystem, 84, , BAA-SCRT, , , AppleBasicAttestationSystem) +POLICYMACRO(BasicAttestationUser, 85, , BAA-UCRT, , , AppleBasicAttestationUser) +POLICYMACRO(iPhoneVPNApplicationSigning, 86, , iPhoneVPNApplicationSigning, , Y, iPhoneVPNApplicationSigning) +POLICYMACRO(DemoDigitalCatalog, 88, , DemoCatalog, , Y, DemoDigitalCatalogSigning) diff --git a/OSX/sec/Security/SecPolicyChecks.list b/OSX/sec/Security/SecPolicyChecks.list new file mode 100644 index 00000000..53553ca7 --- /dev/null +++ b/OSX/sec/Security/SecPolicyChecks.list @@ -0,0 +1,95 @@ +// Copyright (c) 2017-2018 Apple Inc. All Rights Reserved. +// This is the list of Policy Checks. To add a new policy check put it in this file with the POLICYCHECKMACRO defined. +// Then define a new SEC_TRUST_ERROR string in SecFrameworkStrings.h +// Arguments for the POLICYCHECKMACRO in arg order are: +// POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) +// NAME: the name of the check (both its constant name and string value) +// TRUSTRESULT: the trust result this check should produce. R is Recoverable, F is Fatal, D is Deny +// SUBTYPE: the type of failure. +// N is a name failure, E is expiration, S is key size, H is weak hash, U is usage, P is pinning, V is revocation +// T is trust, C is compliance, D is denied +// LEAFCHECK: L for checks that happen in the leaf callbacks +// PATHCHECK: A for checks that happen in the path callbacks +// LEAFONLY: O for checks that are done in leaf-only trust evaluations +// CSSMERR: The CSSM error status code for this error. The constant name of this status code follows in a comment. +// OSSTATUS: the OSStatus to return for this error + +/******************************************************** +************** Unverified Leaf Checks ****************** +********************************************************/ +POLICYCHECKMACRO(SSLHostname, R, N, L, , O, 0x80012400, errSecHostNameMismatch) //CSSMERR_APPLETP_HOSTNAME_MISMATCH +POLICYCHECKMACRO(Email, R, N, L, , O, 0x80012418, errSecSMIMEEmailAddressesNotFound) //CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND +POLICYCHECKMACRO(TemporalValidity, R, E, L, A, O, 0x8001210A, errSecCertificateExpired) //CSSMERR_TP_CERT_EXPIRED +POLICYCHECKMACRO(WeakKeySize, F, S, L, A, O, 0x80012115, errSecUnsupportedKeySize) //CSSMERR_TP_INVALID_CERTIFICATE +POLICYCHECKMACRO(WeakSignature, R, H, L, A, O, 0x80010955, errSecInvalidDigestAlgorithm) //CSSMERR_CSP_INVALID_DIGEST_ALGORITHM +POLICYCHECKMACRO(KeyUsage, R, U, L, , O, 0x80012406, errSecInvalidKeyUsageForPolicy) //CSSMERR_APPLETP_INVALID_KEY_USAGE +POLICYCHECKMACRO(ExtendedKeyUsage, R, U, L, , O, 0x80012407, errSecInvalidExtendedKeyUsage) //CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE +POLICYCHECKMACRO(SubjectCommonName, R, P, L, , O, 0x8001243B, errSecInvalidSubjectName) //CSSMERR_APPLETP_IDENTIFIER_MISSING +POLICYCHECKMACRO(SubjectCommonNamePrefix, R, P, L, , O, 0x8001243B, errSecInvalidSubjectName) //CSSMERR_APPLETP_IDENTIFIER_MISSING +POLICYCHECKMACRO(SubjectCommonNameTEST, R, P, L, , O, 0x8001243B, errSecInvalidSubjectName) //CSSMERR_APPLETP_IDENTIFIER_MISSING +POLICYCHECKMACRO(SubjectOrganization, R, P, L, , O, 0x8001243B, errSecInvalidSubjectName) //CSSMERR_APPLETP_IDENTIFIER_MISSING +POLICYCHECKMACRO(SubjectOrganizationalUnit, R, P, L, , O, 0x8001243B, errSecInvalidSubjectName) //CSSMERR_APPLETP_IDENTIFIER_MISSING +POLICYCHECKMACRO(NotValidBefore, R, P, L, , O, 0x8001210B, errSecCertificateNotValidYet) //CSSMERR_TP_CERT_NOT_VALID_YET +POLICYCHECKMACRO(EAPTrustedServerNames, R, N, L, , O, 0x80012400, errSecHostNameMismatch) //CSSMERR_APPLETP_HOSTNAME_MISMATCH +POLICYCHECKMACRO(LeafMarkerOid, R, P, L, , O, 0x80012439, errSecMissingRequiredExtension) //CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION +POLICYCHECKMACRO(LeafMarkerOidWithoutValueCheck, R, P, L, , O, 0x80012439, errSecMissingRequiredExtension) //CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION +POLICYCHECKMACRO(LeafMarkersProdAndQA, R, P, L, , O, 0x80012439, errSecMissingRequiredExtension) //CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION +POLICYCHECKMACRO(BlackListedLeaf, F, V, L, , , 0x8001210C, errSecCertificateRevoked) //CSSMERR_TP_CERT_REVOKED +POLICYCHECKMACRO(GrayListedLeaf, R, T, L, , , 0x8001212A, errSecNotTrusted) //CSSMERR_TP_NOT_TRUSTED + +/******************************************************** +*********** Unverified Intermediate Checks ************* +********************************************************/ +POLICYCHECKMACRO(IssuerCommonName, R, P, , A, , 0x8001243B, errSecInvalidSubjectName) //CSSMERR_APPLETP_IDENTIFIER_MISSING +POLICYCHECKMACRO(BasicConstraints, R, C, , A, , 0x80012402, errSecNoBasicConstraints) //CSSMERR_APPLETP_NO_BASIC_CONSTRAINTS +POLICYCHECKMACRO(BasicConstraintsCA, R, C, , , , 0x80012403, errSecNoBasicConstraintsCA) //CSSMERR_APPLETP_INVALID_CA +POLICYCHECKMACRO(BasicConstraintsPathLen, R, C, , , , 0x80012409, errSecPathLengthConstraintExceeded) //CSSMERR_APPLETP_PATH_LEN_CONSTRAINT +POLICYCHECKMACRO(IntermediateSPKISHA256, R, P, , A, , 0x8001243B, errSecPublicKeyInconsistent) //CSSMERR_APPLETP_IDENTIFIER_MISSING +POLICYCHECKMACRO(IntermediateEKU, R, P, , A, , 0x80012407, errSecInvalidExtendedKeyUsage) //CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE +POLICYCHECKMACRO(IntermediateMarkerOid, R, P, , A, , 0x80012439, errSecMissingRequiredExtension) //CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION +POLICYCHECKMACRO(IntermediateOrganization, R, P, , A, , 0x8001243B, errSecInvalidSubjectName) //CSSMERR_APPLETP_IDENTIFIER_MISSING +POLICYCHECKMACRO(IntermediateCountry, R, P, , A, , 0x8001243B, errSecInvalidSubjectName) //CSSMERR_APPLETP_IDENTIFIER_MISSING + +/******************************************************** +************** Unverified Anchor Checks **************** +********************************************************/ +POLICYCHECKMACRO(AnchorSHA1, R, P, , A, , 0x8001243C, errSecInvalidRoot) //CSSMERR_APPLETP_CA_PIN_MISMATCH +POLICYCHECKMACRO(AnchorSHA256, R, P, , A, , 0x8001243C, errSecInvalidRoot) //CSSMERR_APPLETP_CA_PIN_MISMATCH +POLICYCHECKMACRO(AnchorTrusted, R, T, , , , 0x8001212A, errSecNotTrusted) //CSSMERR_TP_NOT_TRUSTED +POLICYCHECKMACRO(MissingIntermediate, R, T, , , , 0x8001212A, errSecCreateChainFailed) //CSSMERR_TP_NOT_TRUSTED +POLICYCHECKMACRO(AnchorApple, R, P, , A, , 0x8001243C, errSecInvalidRoot) //CSSMERR_APPLETP_CA_PIN_MISMATCH + +/******************************************************** +*********** Unverified Certificate Checks ************** +********************************************************/ +POLICYCHECKMACRO(NonEmptySubject, R, C, , A, O, 0x80012437, errSecInvalidSubjectName) //CSSMERR_APPLETP_INVALID_EMPTY_SUBJECT +POLICYCHECKMACRO(IdLinkage, R, C, , A, , 0x80012404, errSecInvalidIDLinkage) //CSSMERR_APPLETP_INVALID_AUTHORITY_ID +POLICYCHECKMACRO(KeySize, R, P, , A, O, 0x80010918, errSecUnsupportedKeySize) //CSSMERR_CSP_UNSUPPORTED_KEY_SIZE +POLICYCHECKMACRO(SignatureHashAlgorithms, R, P, , A, O, 0x80010913, errSecInvalidDigestAlgorithm) //CSSMERR_CSP_ALGID_MISMATCH +POLICYCHECKMACRO(CertificatePolicy, R, P, , A, O, 0x80012439, errSecInvalidPolicyIdentifiers) //CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION +POLICYCHECKMACRO(ValidRoot, R, E, , , , 0x8001210A, errSecCertificateExpired) //CSSMERR_TP_CERT_EXPIRED + +/******************************************************** +**************** Verified Path Checks ****************** +********************************************************/ +POLICYCHECKMACRO(CriticalExtensions, R, C, , A, O, 0x80012401, errSecUnknownCriticalExtensionFlag) //CSSMERR_APPLETP_UNKNOWN_CRITICAL_EXTEN +POLICYCHECKMACRO(ChainLength, R, P, , A, , 0x80012409, errSecPathLengthConstraintExceeded) //CSSMERR_APPLETP_PATH_LEN_CONSTRAINT +POLICYCHECKMACRO(BasicCertificateProcessing, R, C, , A, , 0x80012115, errSecInvalidCertificateRef) //CSSMERR_TP_INVALID_CERTIFICATE +POLICYCHECKMACRO(NameConstraints, R, C, , , , 0x80012115, errSecInvalidName) //CSSMERR_TP_INVALID_CERTIFICATE +POLICYCHECKMACRO(PolicyConstraints, R, C, , , , 0x80012115, errSecInvalidPolicyIdentifiers) //CSSMERR_TP_INVALID_CERTIFICATE +POLICYCHECKMACRO(GrayListedKey, R, T, , , , 0x8001212A, errSecNotTrusted) //CSSMERR_TP_NOT_TRUSTED +POLICYCHECKMACRO(BlackListedKey, F, V, , , , 0x8001210C, errSecCertificateRevoked) //CSSMERR_TP_CERT_REVOKED +POLICYCHECKMACRO(UsageConstraints, D, D, , , , 0x80012436, errSecTrustSettingDeny) //CSSMERR_APPLETP_TRUST_SETTING_DENY +POLICYCHECKMACRO(SystemTrustedWeakHash, R, C, , A, , 0x80010955, errSecInvalidDigestAlgorithm) //CSSMERR_CSP_INVALID_DIGEST_ALGORITHM +POLICYCHECKMACRO(SystemTrustedWeakKey, R, C, , A, , 0x80010918, errSecUnsupportedKeySize) //CSSMERR_CSP_UNSUPPORTED_KEY_SIZE +POLICYCHECKMACRO(PinningRequired, R, P, L, , , 0x8001243C, errSecInvalidRoot) //CSSMERR_APPLETP_CA_PIN_MISMATCH +POLICYCHECKMACRO(Revocation, F, V, L, , , 0x8001210C, errSecCertificateRevoked) //CSSMERR_TP_CERT_REVOKED +POLICYCHECKMACRO(RevocationResponseRequired, R, P, L, , , 0x80012423, errSecIncompleteCertRevocationCheck) //CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK +POLICYCHECKMACRO(CTRequired, R, T, , , , 0x8001212A, errSecNotTrusted) //CSSMERR_TP_NOT_TRUSTED + +/******************************************************** +******************* Feature Toggles ********************* +********************************************************/ +POLICYCHECKMACRO(NoNetworkAccess, , , L, , , , errSecInternal) +POLICYCHECKMACRO(ExtendedValidation, , , , , , , errSecInternal) +POLICYCHECKMACRO(RevocationOnline, , , L, , , , errSecInternal) diff --git a/OSX/sec/Security/SecPolicyInternal.h b/OSX/sec/Security/SecPolicyInternal.h index 8285054c..6f6c4635 100644 --- a/OSX/sec/Security/SecPolicyInternal.h +++ b/OSX/sec/Security/SecPolicyInternal.h @@ -30,9 +30,10 @@ #ifndef _SECURITY_SECPOLICYINTERNAL_H_ #define _SECURITY_SECPOLICYINTERNAL_H_ +#include + #include #include -#include #include #include #include @@ -49,152 +50,15 @@ struct __SecPolicy { CFDictionaryRef _options; }; -/*! - @enum Policy Check Keys - @discussion Keys that represent various checks that can be done in a trust - policy. - @constant kSecPolicyCheckCriticalExtensions Ensure that no certificate in the chain has any critical extensions that we do not understand. - @constant kSecPolicyCheckIdLinkage Check that all the certificates in the chain that have a SubjectId, match the AuthorityId of the certificate they sign. This check is optional, in that if either certificate is missing the required extension the check succeeds. - @constant kSecPolicyCheckBasicConstraints Fails if the basic constraints for the certificate chain are not met, this allows for basic constraints to be non critical and doesn't require every CA certificate to have a basic constraints extension, and allows for leaf certificates to have basic constraints extensions. - @constant kSecPolicyCheckExtendedKeyUsage @@@ - @constant kSecPolicyCheckIdLinkage Fails if the AuthorityKeyID -> SubjectKeyID chaining isn't right. - @constant kSecPolicyCheckKeyUsage @@@ - @constant kSecPolicyCheckWeakIntermediates Fails if any certificates in the chain (other than the leaf and root) have a too small key size. - @constant kSecPolicyCheckWeakLeaf Fails if the leaf has a too small key size. - @constant kSecPolicyCheckWeakRoot Fails if the root has a too small key size. - @constant kSecPolicyCheckKeySize Fails if any certificates in the chain have key size smaller than the policy allows. - @constant kSecPolicyCheckSignatureHashAlgorithms Fails if any certificates in the chain use a hash algorithm disallowed by the policy. - @constant kSecPolicyCheckNonEmptySubject Perform the following check: RFC 3280, 4.1.2.6, says that an empty subject name can only appear in a leaf cert, and only if subjectAltName is present and marked critical. - @constant kSecPolicyCheckQualifiedCertStatements Perform the following check: RFC 3739: if this cert has a Qualified Cert Statements extension, and it's Critical, make sure we understand all of the extension's statementIds. - @constant kSecPolicyCheckValidIntermediates Fails if any certificates in the chain are not valid at the verify time other than the leaf and the root. - @constant kSecPolicyCheckValidLeaf Fails if the leaf certificate is not valid at the verify time. - @constant kSecPolicyCheckValidRoot Fails if the root certificate is not valid at the verify time. - @constant kSecPolicyCheckAnchorTrusted @@@. - @constant kSecPolicyCheckAnchorSHA1 @@@. - @constant kSecPolicyCheckAnchorSHA256 @@@. - @constant kSecPolicyCheckAnchorApple @@@. - @constant kSecPolicyCheckSSLHostname @@@. - @constant kSecPolicyCheckEmail @@@. - @constant kSecPolicyCheckIssuerCommonName @@@. - @constant kSecPolicyCheckSubjectCommonNamePrefix @@@. - @constant kSecPolicyCheckChainLength @@@. - @constant kSecPolicyCheckNotValidBefore @@@. - @constant kSecPolicyCheckEAPTrustedServerNames @@@. - @constant kSecPolicyCheckBasicCertificateProcessing @@@. - @constant kSecPolicyCheckExtendedValidation @@@. - @constant kSecPolicyCheckRevocation Perform a revocation check. - @constant kSecPolicyCheckRevocationResponseRequired Require positive response for revocation check. Use of thise constant indicates that the policy should "fail closed" in case of missing revocation information. - @constant kSecPolicyCheckRevocationOCSP Use OCSP to perform revocation check. - @constant kSecPolicyCheckRevocationCRL Use CRL to perform revocation check. - @constant kSecPolicyCheckRevocationAny Use any available method (OCSP or CRL) to perform revocation check. - @constant kSecPolicyCheckRevocationOnline Force an "online" OCSP check. - @constant kSecPolicyCheckNoNetworkAccess @@@. - @constant kSecPolicyCheckBlackListedLeaf @@@. - @constant kSecPolicyCheckUsageConstraints @@@. - @constant kSecPolicyCheckSystemTrustedWeakHash Check whether the leaf or intermediates are using a weak hash in chains that end with a system-trusted anchor. - @constant kSecPolicyCheckSystemTrustedWeakKey Check whether the leaf or intermediates are using a weak key in chains that end with a system-trusted anchor. - @constant kSecPolicyCheckIntermediateOrganization Fails if any (non-leaf and non-root) certificates in the chain do not have a matching Organization string. - @constant kSecPolicyCheckIntermediateCountry Fails if any (non-leaf and non-root) certificates in the chain do not have a matching Country string. - @constant kSecPolicyCheckPinningRequired Fails if the binary Info plist required pinning but no pinning policies were used. -*/ -extern const CFStringRef kSecPolicyCheckBasicConstraints; -extern const CFStringRef kSecPolicyCheckCriticalExtensions; -extern const CFStringRef kSecPolicyCheckExtendedKeyUsage; -extern const CFStringRef kSecPolicyCheckIdLinkage; -extern const CFStringRef kSecPolicyCheckWeakIntermediates; -extern const CFStringRef kSecPolicyCheckWeakLeaf; -extern const CFStringRef kSecPolicyCheckWeakRoot; -extern const CFStringRef kSecPolicyCheckKeySize; -extern const CFStringRef kSecPolicyCheckSignatureHashAlgorithms; -extern const CFStringRef kSecPolicyCheckKeyUsage; -extern const CFStringRef kSecPolicyCheckNonEmptySubject; -extern const CFStringRef kSecPolicyCheckQualifiedCertStatements; -extern const CFStringRef kSecPolicyCheckValidIntermediates; -extern const CFStringRef kSecPolicyCheckValidLeaf; -extern const CFStringRef kSecPolicyCheckValidRoot; -extern const CFStringRef kSecPolicyCheckAnchorTrusted; -extern const CFStringRef kSecPolicyCheckAnchorSHA1; -extern const CFStringRef kSecPolicyCheckAnchorSHA256; -extern const CFStringRef kSecPolicyCheckAnchorApple; -extern const CFStringRef kSecPolicyCheckSSLHostname; -extern const CFStringRef kSecPolicyCheckEmail; -extern const CFStringRef kSecPolicyCheckIssuerCommonName; -extern const CFStringRef kSecPolicyCheckSubjectCommonName; -extern const CFStringRef kSecPolicyCheckSubjectCommonNameTEST; -extern const CFStringRef kSecPolicyCheckSubjectOrganization; -extern const CFStringRef kSecPolicyCheckSubjectOrganizationalUnit; -extern const CFStringRef kSecPolicyCheckSubjectCommonNamePrefix; -extern const CFStringRef kSecPolicyCheckChainLength; -extern const CFStringRef kSecPolicyCheckNotValidBefore; -extern const CFStringRef kSecPolicyCheckEAPTrustedServerNames; -extern const CFStringRef kSecPolicyCheckCertificatePolicy; -extern const CFStringRef kSecPolicyCheckBasicCertificateProcessing; -extern const CFStringRef kSecPolicyCheckExtendedValidation; -extern const CFStringRef kSecPolicyCheckRevocation; -extern const CFStringRef kSecPolicyCheckRevocationResponseRequired; -extern const CFStringRef kSecPolicyCheckRevocationOCSP; -extern const CFStringRef kSecPolicyCheckRevocationCRL; -extern const CFStringRef kSecPolicyCheckRevocationAny; -extern const CFStringRef kSecPolicyCheckRevocationOnline; -extern const CFStringRef kSecPolicyCheckNoNetworkAccess; -extern const CFStringRef kSecPolicyCheckBlackListedLeaf; -extern const CFStringRef kSecPolicyCheckBlackListedKey; -extern const CFStringRef kSecPolicyCheckGrayListedLeaf; -extern const CFStringRef kSecPolicyCheckLeafMarkerOid; -extern const CFStringRef kSecPolicyCheckLeafMarkerOidWithoutValueCheck; -extern const CFStringRef kSecPolicyCheckLeafMarkersProdAndQA; -extern const CFStringRef kSecPolicyCheckIntermediateMarkerOid; -extern const CFStringRef kSecPolicyCheckIntermediateSPKISHA256; -extern const CFStringRef kSecPolicyCheckIntermediateEKU; -extern const CFStringRef kSecPolicyCheckGrayListedKey; -extern const CFStringRef kSecPolicyCheckCertificateTransparency; -extern const CFStringRef kSecPolicyCheckUsageConstraints; -extern const CFStringRef kSecPolicyCheckSystemTrustedWeakHash; -extern const CFStringRef kSecPolicyCheckSystemTrustedWeakKey; -extern const CFStringRef kSecPolicyCheckIntermediateOrganization; -extern const CFStringRef kSecPolicyCheckIntermediateCountry; -extern const CFStringRef kSecPolicyCheckPinningRequired; - -/* Special option for checking Apple Anchors */ -extern const CFStringRef kSecPolicyAppleAnchorIncludeTestRoots; - -/* Special option for checking Prod and QA Markers */ -extern const CFStringRef kSecPolicyLeafMarkerProd; -extern const CFStringRef kSecPolicyLeafMarkerQA; - SecPolicyRef SecPolicyCreate(CFStringRef oid, CFStringRef name, CFDictionaryRef options); CFDictionaryRef SecPolicyGetOptions(SecPolicyRef policy); -void SecPolicySetOptionsValue(SecPolicyRef policy, CFStringRef key, CFTypeRef value); -void SecPolicySetName(SecPolicyRef policy, CFStringRef policyName); xpc_object_t SecPolicyArrayCopyXPCArray(CFArrayRef policies, CFErrorRef *error); -CFArrayRef SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies, CFErrorRef *error); CFArrayRef SecPolicyArrayCreateDeserialized(CFArrayRef serializedPolicies); CFArrayRef SecPolicyArrayCreateSerialized(CFArrayRef policies); -/* - * MARK: SecPolicyCheckCert functions - */ -bool SecPolicyCheckCertKeyUsage(SecCertificateRef cert, CFTypeRef pvcValue); -bool SecPolicyCheckCertExtendedKeyUsage(SecCertificateRef cert, CFTypeRef pvcValue); -bool SecPolicyCheckCertNonEmptySubject(SecCertificateRef cert, CFTypeRef pvcValue); -bool SecPolicyCheckCertSSLHostname(SecCertificateRef cert, CFTypeRef pvcValue); -bool SecPolicyCheckCertEmail(SecCertificateRef cert, CFTypeRef pvcValue); -bool SecPolicyCheckCertSubjectCommonNamePrefix(SecCertificateRef cert, CFTypeRef pvcValue); -bool SecPolicyCheckCertSubjectCommonName(SecCertificateRef cert, CFTypeRef pvcValue); -bool SecPolicyCheckCertSubjectCommonNameTEST(SecCertificateRef cert, CFTypeRef pvcValue); -bool SecPolicyCheckCertNotValidBefore(SecCertificateRef cert, CFTypeRef pvcValue); -bool SecPolicyCheckCertSubjectOrganization(SecCertificateRef cert, CFTypeRef pvcValue); -bool SecPolicyCheckCertSubjectOrganizationalUnit(SecCertificateRef cert, CFTypeRef pvcValue); -bool SecPolicyCheckCertEAPTrustedServerNames(SecCertificateRef cert, CFTypeRef pvcValue); -bool SecPolicyCheckCertLeafMarkerOid(SecCertificateRef cert, CFTypeRef pvcValue); -bool SecPolicyCheckCertLeafMarkerOidWithoutValueCheck(SecCertificateRef cert, CFTypeRef pvcValue); -bool SecPolicyCheckCertSignatureHashAlgorithms(SecCertificateRef cert, CFTypeRef pvcValue); -bool SecPolicyCheckCertSubjectCountry(SecCertificateRef cert, CFTypeRef pvcValue); - - /* * MARK: SecLeafPVC functions */ diff --git a/OSX/sec/Security/SecPolicyLeafCallbacks.c b/OSX/sec/Security/SecPolicyLeafCallbacks.c index c8c4f6d7..bad7f8ca 100644 --- a/OSX/sec/Security/SecPolicyLeafCallbacks.c +++ b/OSX/sec/Security/SecPolicyLeafCallbacks.c @@ -27,12 +27,14 @@ #include #include +#include #include #include #include +#include #include #include -#include +#include /* * MARK: SecPolicyCheckCert Functions @@ -44,7 +46,7 @@ typedef bool (*SecPolicyCheckCertFunction)(SecCertificateRef cert, CFTypeRef pvc /* This one is different from SecPolicyCheckCriticalExtensions because that one is an empty stub. The CriticalExtensions check is done in SecPolicyCheckBasicCertificateProcessing. */ -static bool SecPolicyCheckCertCriticalExtensions(SecCertificateRef cert, CFTypeRef __unused pvcValue) { +bool SecPolicyCheckCertCriticalExtensions(SecCertificateRef cert, CFTypeRef __unused pvcValue) { if (SecCertificateHasUnknownCriticalExtension(cert)) { /* Certificate contains one or more unknown critical extensions. */ return false; @@ -152,14 +154,6 @@ bool SecPolicyCheckCertNonEmptySubject(SecCertificateRef cert, CFTypeRef __unuse return true; } - -/* This one is different from SecPolicyCheckQualifiedCertStatements because - both are empty stubs. */ -static bool SecPolicyCheckCertQualifiedCertStatements(SecCertificateRef __unused cert, - CFTypeRef __unused pvcValue) { - return true; -} - /* We have a wildcard reference identifier that looks like "*." followed by 2 or more labels. Use CFNetwork's function for determining if those labels comprise a top-level domain. We need to dlopen since CFNetwork is a client of ours. */ @@ -345,7 +339,7 @@ bool SecPolicyCheckCertEmail(SecCertificateRef cert, CFTypeRef pvcValue) { return match; } -static bool SecPolicyCheckCertValidLeaf(SecCertificateRef cert, CFTypeRef pvcValue) { +bool SecPolicyCheckCertTemporalValidity(SecCertificateRef cert, CFTypeRef pvcValue) { CFAbsoluteTime verifyTime = CFDateGetAbsoluteTime(pvcValue); if (!SecCertificateIsValid(cert, verifyTime)) { /* Leaf certificate has expired. */ @@ -557,6 +551,22 @@ bool SecPolicyCheckCertLeafMarkerOidWithoutValueCheck(SecCertificateRef cert, return false; } +/* + * The value is a dictionary. The dictionary contains keys indicating + * whether the value is for Prod or QA. The values are the same as + * in the options dictionary for SecPolicyCheckLeafMarkerOid. + */ +bool SecPolicyCheckCertLeafMarkersProdAndQA(SecCertificateRef cert, CFTypeRef pvcValue) +{ + CFTypeRef prodValue = CFDictionaryGetValue(pvcValue, kSecPolicyLeafMarkerProd); + + if (!SecPolicyCheckCertLeafMarkerOid(cert, prodValue)) { + bool result = false; + return result; + } + return true; +} + static CFSetRef copyCertificatePolicies(SecCertificateRef cert) { CFMutableSetRef policies = NULL; policies = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks); @@ -586,7 +596,7 @@ static bool checkPolicyOidData(SecCertificateRef cert , CFDataRef oid) { /* This one is different from SecPolicyCheckCertificatePolicyOid because that one checks the whole chain. (And uses policy_set_t...) */ -static bool SecPolicyCheckCertCertificatePolicyOid(SecCertificateRef cert, CFTypeRef pvcValue) { +bool SecPolicyCheckCertCertificatePolicy(SecCertificateRef cert, CFTypeRef pvcValue) { CFTypeRef value = pvcValue; bool result = false; @@ -603,7 +613,7 @@ static bool SecPolicyCheckCertCertificatePolicyOid(SecCertificateRef cert, CFTyp return result; } -static bool SecPolicyCheckCertWeak(SecCertificateRef cert, CFTypeRef __unused pvcValue) { +bool SecPolicyCheckCertWeakKeySize(SecCertificateRef cert, CFTypeRef __unused pvcValue) { if (cert && SecCertificateIsWeakKey(cert)) { /* Leaf certificate has a weak key. */ return false; @@ -611,7 +621,7 @@ static bool SecPolicyCheckCertWeak(SecCertificateRef cert, CFTypeRef __unused pv return true; } -static bool SecPolicyCheckCertKeySize(SecCertificateRef cert, CFTypeRef pvcValue) { +bool SecPolicyCheckCertKeySize(SecCertificateRef cert, CFTypeRef pvcValue) { CFDictionaryRef keySizes = pvcValue; if (!SecCertificateIsAtLeastMinKeySize(cert, keySizes)) { return false; @@ -619,6 +629,22 @@ static bool SecPolicyCheckCertKeySize(SecCertificateRef cert, CFTypeRef pvcValue return true; } +bool SecPolicyCheckCertWeakSignature(SecCertificateRef cert, CFTypeRef __unused pvcValue) { + bool result = true; + CFMutableSetRef disallowedHashes = CFSetCreateMutable(NULL, 3, &kCFTypeSetCallBacks); + if (!disallowedHashes) { + return result; + } + CFSetAddValue(disallowedHashes, kSecSignatureDigestAlgorithmMD2); + CFSetAddValue(disallowedHashes, kSecSignatureDigestAlgorithmMD4); + CFSetAddValue(disallowedHashes, kSecSignatureDigestAlgorithmMD5); + if (!SecPolicyCheckCertSignatureHashAlgorithms(cert, disallowedHashes)) { + result = false; + } + CFReleaseSafe(disallowedHashes); + return result; +} + static CFStringRef convertSignatureHashAlgorithm(SecSignatureHashAlgorithm algorithmEnum) { const void *digests[] = { kSecSignatureDigestAlgorithmUnknown, kSecSignatureDigestAlgorithmMD2, @@ -649,69 +675,15 @@ static CFDictionaryRef SecLeafPVCCopyCallbacks(void) { CFMutableDictionaryRef leafCallbacks = NULL; leafCallbacks = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, NULL); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckCriticalExtensions, - SecPolicyCheckCertCriticalExtensions); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckKeyUsage, - SecPolicyCheckCertKeyUsage); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckExtendedKeyUsage, - SecPolicyCheckCertExtendedKeyUsage); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckNonEmptySubject, - SecPolicyCheckCertNonEmptySubject); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckQualifiedCertStatements, - SecPolicyCheckCertQualifiedCertStatements); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckSSLHostname, - SecPolicyCheckCertSSLHostname); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckEmail, - SecPolicyCheckCertEmail); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckValidLeaf, - SecPolicyCheckCertValidLeaf); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckSubjectCommonNamePrefix, - SecPolicyCheckCertSubjectCommonNamePrefix); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckSubjectCommonName, - SecPolicyCheckCertSubjectCommonName); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckNotValidBefore, - SecPolicyCheckCertNotValidBefore); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckSubjectOrganization, - SecPolicyCheckCertSubjectOrganization); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckSubjectOrganizationalUnit, - SecPolicyCheckCertSubjectOrganizationalUnit); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckEAPTrustedServerNames, - SecPolicyCheckCertEAPTrustedServerNames); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckSubjectCommonNameTEST, - SecPolicyCheckCertSubjectCommonNameTEST); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckLeafMarkerOid, - SecPolicyCheckCertLeafMarkerOid); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckLeafMarkerOidWithoutValueCheck, - SecPolicyCheckCertLeafMarkerOidWithoutValueCheck); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckCertificatePolicy, - SecPolicyCheckCertCertificatePolicyOid); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckWeakLeaf, - SecPolicyCheckCertWeak); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckKeySize, - SecPolicyCheckCertKeySize); - CFDictionaryAddValue(leafCallbacks, - kSecPolicyCheckSignatureHashAlgorithms, - SecPolicyCheckCertSignatureHashAlgorithms); + +#undef POLICYCHECKMACRO +#define __PC_ADD_CHECK_(NAME) +#define __PC_ADD_CHECK_O(NAME) CFDictionaryAddValue(leafCallbacks, \ +kSecPolicyCheck##NAME, SecPolicyCheckCert##NAME); + +#define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) \ +__PC_ADD_CHECK_##LEAFONLY(NAME) +#include "SecPolicyChecks.list" return leafCallbacks; } @@ -797,8 +769,8 @@ static void SecLeafPVCValidateKey(const void *key, const void *value, return; } - /* kSecPolicyCheckValidLeaf is special */ - if (CFEqual(key, kSecPolicyCheckValidLeaf)) { + /* kSecPolicyCheckTemporalValidity is special */ + if (CFEqual(key, kSecPolicyCheckTemporalValidity)) { CFDateRef verifyDate = CFDateCreate(NULL, pvc->verifyTime); if(!fcn(pvc->leaf, verifyDate)) { SecLeafPVCSetResult(pvc, key, 0, kCFBooleanFalse); diff --git a/OSX/sec/Security/SecRecoveryKey.m b/OSX/sec/Security/SecRecoveryKey.m index 261800e6..cf47781b 100644 --- a/OSX/sec/Security/SecRecoveryKey.m +++ b/OSX/sec/Security/SecRecoveryKey.m @@ -125,7 +125,7 @@ SecRKCreateRecoveryKeyWithError(NSString *masterKey, NSError **error) return NULL; } - return (__bridge SecRecoveryKey *)rk; + return (SecRecoveryKey *) CFBridgingRelease(rk); } static CFDataRef diff --git a/OSX/sec/Security/SecSCEP.c b/OSX/sec/Security/SecSCEP.c index d436bbc5..05ab7634 100644 --- a/OSX/sec/Security/SecSCEP.c +++ b/OSX/sec/Security/SecSCEP.c @@ -246,7 +246,7 @@ out: CFDataRef SecSCEPGenerateCertificateRequest(CFArrayRef subject, CFDictionaryRef parameters, - SecKeyRef publicKey, SecKeyRef privateKey, + SecKeyRef __unused publicKey, SecKeyRef privateKey, SecIdentityRef signer, CFTypeRef recipients) { CFDataRef csr = NULL; @@ -257,6 +257,8 @@ SecSCEPGenerateCertificateRequest(CFArrayRef subject, CFDictionaryRef parameters SecCertificateRef recipient = NULL; CFDataRef msgtype_value_data = NULL; CFDataRef msgtype_oid_data = NULL; + SecKeyRef realPublicKey = NULL; + SecKeyRef recipientKey = NULL; if (CFGetTypeID(recipients) == SecCertificateGetTypeID()) { recipient = (SecCertificateRef)recipients; @@ -272,7 +274,16 @@ SecSCEPGenerateCertificateRequest(CFArrayRef subject, CFDictionaryRef parameters } require(recipient, out); - require(csr = SecGenerateCertificateRequest(subject, parameters, publicKey, privateKey), out); + /* We don't support EC recipients for SCEP yet. */ +#if TARGET_OS_IPHONE + recipientKey = SecCertificateCopyPublicKey(recipient); +#else + recipientKey = SecCertificateCopyPublicKey_ios(recipient); +#endif + require(SecKeyGetAlgorithmId(recipientKey) == kSecRSAAlgorithmID, out); + + require(realPublicKey = SecKeyCopyPublicKey(privateKey), out); + require(csr = SecGenerateCertificateRequest(subject, parameters, realPublicKey, privateKey), out); require(enveloped_data = CFDataCreateMutable(kCFAllocatorDefault, 0), out); require_noerr(SecCMSCreateEnvelopedData(recipient, parameters, csr, enveloped_data), out); CFReleaseNull(csr); @@ -281,7 +292,7 @@ SecSCEPGenerateCertificateRequest(CFArrayRef subject, CFDictionaryRef parameters &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); /* generate a transaction id: hex encoded pubkey hash */ - CFDataRef public_key_hash = pubkeyhash(publicKey); + CFDataRef public_key_hash = pubkeyhash(realPublicKey); CFDataRef public_key_hash_hex = hexencode(public_key_hash); CFReleaseSafe(public_key_hash); CFDataRef transid_oid_data = scep_oid(transId); @@ -311,7 +322,7 @@ SecSCEPGenerateCertificateRequest(CFArrayRef subject, CFDictionaryRef parameters self_signed_identity = signer; CFRetain(self_signed_identity); } else { - self_signed_identity = SecSCEPCreateTemporaryIdentity(publicKey, privateKey); + self_signed_identity = SecSCEPCreateTemporaryIdentity(realPublicKey, privateKey); /* Add our temporary cert to the keychain for CMS decryption of the reply. If we happened to have picked an existing UUID @@ -331,19 +342,26 @@ SecSCEPGenerateCertificateRequest(CFArrayRef subject, CFDictionaryRef parameters out: - CFReleaseSafe(simple_attr); CFReleaseSafe(msgtype_oid_data); CFReleaseSafe(msgtype_value_data); CFReleaseSafe(self_signed_identity); CFReleaseSafe(enveloped_data); CFReleaseSafe(csr); + CFReleaseNull(realPublicKey); + CFReleaseSafe(recipientKey); return signed_request; } +CFDataRef +SecSCEPCertifyRequest(CFDataRef request, SecIdentityRef ca_identity, CFDataRef serialno, bool pend_request) { + return SecSCEPCertifyRequestWithAlgorithms(request, ca_identity, serialno, pend_request, NULL, NULL); +} + CFDataRef -SecSCEPCertifyRequest(CFDataRef request, SecIdentityRef ca_identity, CFDataRef serialno, bool pend_request) +SecSCEPCertifyRequestWithAlgorithms(CFDataRef request, SecIdentityRef ca_identity, CFDataRef serialno, bool pend_request, + CFStringRef hashingAlgorithm, CFStringRef encryptionAlgorithm) { CFDictionaryRef simple_attr = NULL; SecCertificateRef ca_certificate = NULL; @@ -363,7 +381,7 @@ SecSCEPCertifyRequest(CFDataRef request, SecIdentityRef ca_identity, CFDataRef s SecKeyRef tbsPublicKey = NULL; CFMutableDataRef encrypted_content = NULL; SecCertificateRef recipient = NULL; - CFDictionaryRef parameters = NULL; + CFMutableDictionaryRef parameters = NULL; require_noerr(SecIdentityCopyCertificate(ca_identity, &ca_certificate), out); #if TARGET_OS_IPHONE @@ -420,17 +438,28 @@ SecSCEPCertifyRequest(CFDataRef request, SecIdentityRef ca_identity, CFDataRef s require(cert_msg = CFDataCreateMutable(kCFAllocatorDefault, 0), out); if (!pend_request) { + /* We can't yet support EC recipients for SCEP, so reject now. */ + require (SecKeyGetAlgorithmId(tbsPublicKey) == kSecRSAAlgorithmID, out); + /* sign cert */ - cert = SecIdentitySignCertificate(ca_identity, serialno, - tbsPublicKey, subject, extensions); + cert = SecIdentitySignCertificateWithAlgorithm(ca_identity, serialno, + tbsPublicKey, subject, extensions, hashingAlgorithm); /* degenerate cms with cert */ require (cert_pkcs7 = SecCMSCreateCertificatesOnlyMessage(cert), out); CFReleaseNull(cert); /* envelope for client */ - require_noerr(SecCMSCreateEnvelopedData(signer_cert, NULL, cert_pkcs7, cert_msg), out); + CFDictionaryRef encryption_params = NULL; + if (encryptionAlgorithm) { + encryption_params = CFDictionaryCreate(NULL, (const void **)&kSecCMSBulkEncryptionAlgorithm, + (const void **)&encryptionAlgorithm, 1, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + } + require_noerr(SecCMSCreateEnvelopedData(signer_cert, encryption_params, cert_pkcs7, cert_msg), out); CFReleaseNull(cert_pkcs7); + CFReleaseNull(encryption_params); } CFDataRef pki_status_oid = scep_oid(pkiStatus); @@ -445,9 +474,12 @@ SecSCEPCertifyRequest(CFDataRef request, SecIdentityRef ca_identity, CFDataRef s /* sign with ra/ca cert and add attributes */ signed_reply = CFDataCreateMutable(kCFAllocatorDefault, 0); - const void *signing_params[] = { kSecCMSCertChainMode }; - const void *signing_params_vals[] = { kSecCMSCertChainModeNone }; - parameters = CFDictionaryCreate(kCFAllocatorDefault, signing_params, signing_params_vals, array_size(signing_params), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + parameters = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(parameters, kSecCMSCertChainMode, kSecCMSCertChainModeNone); + if (hashingAlgorithm) { + CFDictionaryAddValue(parameters, kSecCMSSignHashAlgorithm, hashingAlgorithm); + } require_noerr_action(SecCMSCreateSignedData(ca_identity, cert_msg, parameters, simple_attr, signed_reply), out, CFReleaseNull(signed_reply)); out: diff --git a/OSX/sec/Security/SecSCEP.h b/OSX/sec/Security/SecSCEP.h index b173b57f..b7029f0f 100644 --- a/OSX/sec/Security/SecSCEP.h +++ b/OSX/sec/Security/SecSCEP.h @@ -44,7 +44,8 @@ SecSCEPCreateTemporaryIdentity(SecKeyRef publicKey, SecKeyRef privateKey); @abstract generate a scep certificate request blob, to be presented to a scep server @param subject distinguished name to be put in the request - @param parameters additional information such as challenge and extensions + @param parameters additional information such as challenge and extensions (see SecCMS.h and + SecCertificateRequest.h for supported keys) @param publicKey public key to be certified @param privateKey accompanying private key signing the request (proof of possession) @param signer identity to sign scep request with, if NULL the keypair to be @@ -69,6 +70,21 @@ SecSCEPGenerateCertificateRequest(CFArrayRef subject, CFDictionaryRef parameters CFDataRef SecSCEPCertifyRequest(CFDataRef request, SecIdentityRef ca_identity, CFDataRef serialno, bool pend_request) CF_RETURNS_RETAINED; +/*! + @function SecSCEPCertifyRequestWithAlgorithms + @abstract take a SCEP request and issue a cert + @param request the request; the ra/ca identity needed to decrypt it needs to be + in the keychain. + @param ca_identity to sign the csr + @param serialno encoded serial number for cert to be issued + @param pend_request don't issue cert now + @param hashingAlgorithm hashing algorithm to use, see SecCMS.h + @param encryptionAlgorithm encryption algorithm to use, see SecCMS.h + */ +CFDataRef +SecSCEPCertifyRequestWithAlgorithms(CFDataRef request, SecIdentityRef ca_identity, CFDataRef serialno, bool pend_request, + CFStringRef hashingAlgorithm, CFStringRef encryptionAlgorithm) CF_RETURNS_RETAINED; + /*! @function SecSCEPVerifyReply @abstract validate a reply for a sent request and retrieve the issued diff --git a/OSX/sec/Security/SecTrust.c b/OSX/sec/Security/SecTrust.c index a4c839a7..618d0941 100644 --- a/OSX/sec/Security/SecTrust.c +++ b/OSX/sec/Security/SecTrust.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2006-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -37,12 +36,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -57,6 +58,7 @@ #include #include #include +#include #include "SecRSAKey.h" #include @@ -65,6 +67,8 @@ #include +#pragma clang diagnostic ignored "-Wformat=2" + #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v); SEC_CONST_DECL (kSecCertificateDetailSHA1Digest, "SHA1Digest"); @@ -103,7 +107,7 @@ struct __SecTrust { CFArrayRef _SCTs; CFArrayRef _trustedLogs; CFDateRef _verifyDate; - SecCertificatePathRef _chain; + CFArrayRef _chain; SecKeyRef _publicKey; CFArrayRef _details; CFDictionaryRef _info; @@ -393,8 +397,32 @@ OSStatus SecTrustCopyCustomAnchorCertificates(SecTrustRef trust, } }); - *anchors = anchorsArray; - return errSecSuccess; + *anchors = anchorsArray; + return errSecSuccess; +} + +// Return false on error, true on success. +static bool to_bool_error_request(enum SecXPCOperation op, CFErrorRef *error) { + __block bool result = false; + securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) { + result = !(error && *error); + return true; + }); + return result; +} + +Boolean SecTrustFlushResponseCache(CFErrorRef *error) { + CFErrorRef localError = NULL; + os_activity_t activity = os_activity_create("SecTrustFlushResponseCache", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); + bool result = TRUSTD_XPC(sec_ocsp_cache_flush, to_bool_error_request, &localError); + os_release(activity); + if (error) { + *error = localError; + } else if (localError) { + CFRelease(localError); + } + return result; } OSStatus SecTrustSetOCSPResponse(SecTrustRef trust, CFTypeRef responseData) { @@ -522,6 +550,7 @@ OSStatus SecTrustSetPinningPolicyName(SecTrustRef trust, CFStringRef policyName) CFArrayForEach(trust->_policies, ^(const void *value) { SecPolicyRef policy = (SecPolicyRef)value; SecPolicySetName(policy, policyName); + secinfo("SecPinningDb", "Set %@ as name on all policies", policyName); }); }); return errSecSuccess; @@ -762,13 +791,7 @@ Boolean SecTrustIsExpiredOnly(SecTrustRef trust) { CFIndex count = (detail) ? CFDictionaryGetCount(detail) : 0; require(count <= 1, out); if (count) { - CFStringRef key = CFSTR("ValidIntermediates"); - if (ix == 0) { - key = CFSTR("ValidLeaf"); - } else if (ix == pathLength-1) { - key = CFSTR("ValidRoot"); - } - CFBooleanRef valid = (CFBooleanRef)CFDictionaryGetValue(detail, key); + CFBooleanRef valid = (CFBooleanRef)CFDictionaryGetValue(detail, kSecPolicyCheckTemporalValidity); require(isBoolean(valid) && CFEqual(valid, kCFBooleanFalse), out); foundExpired = true; } @@ -870,10 +893,10 @@ static void cert_trust_dump(SecTrustRef trust) { secerror("leaf \"%@\"", name); secerror(": result = %d", (int) trust->_trustResult); if (trust->_chain) { - CFIndex ix, count = SecCertificatePathGetCount(trust->_chain); + CFIndex ix, count = CFArrayGetCount(trust->_chain); CFMutableArrayRef chain = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks); for (ix = 0; ix < count; ix++) { - SecCertificateRef cert = SecCertificatePathGetCertificateAtIndex(trust->_chain, ix); + SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(trust->_chain, ix); if (cert) { CFArrayAppendValue(chain, cert); } @@ -922,7 +945,7 @@ OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *result) { if (trustResult != kSecTrustResultProceed && trustResult != kSecTrustResultUnspecified) { CFStringRef failureDesc = SecTrustCopyFailureDescription(trust); - secerror("%{public}@", failureDesc); + secerror("Trust evaluate failure:%{public}@", failureDesc); CFRelease(failureDesc); } @@ -934,6 +957,244 @@ OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *result) { return status; } +static CFStringRef SecTrustCopyChainSummary(SecTrustRef trust) { + CFMutableStringRef summary = CFStringCreateMutable(NULL, 0); + __block CFArrayRef chain = NULL; + dispatch_sync(trust->_trustQueue, ^{ + chain = trust->_chain; + }); + CFIndex ix, count = CFArrayGetCount(chain); + for (ix = 0; ix < count; ix++) { + if (ix != 0) { CFStringAppend(summary, CFSTR(",")); } + CFStringRef certSummary = SecCertificateCopySubjectSummary((SecCertificateRef)CFArrayGetValueAtIndex(chain, ix)); + CFStringAppendFormat(summary, NULL, CFSTR("\"%@\""), certSummary); + CFReleaseNull(certSummary); + } + return summary; +} + +typedef enum { + kSecTrustErrorSubTypeRevoked, + kSecTrustErrorSubTypeKeySize, + kSecTrustErrorSubTypeWeakHash, + kSecTrustErrorSubTypeDenied, + kSecTrustErrorSubTypeCompliance, + kSecTrustErrorSubTypePinning, + kSecTrustErrorSubTypeTrust, + kSecTrustErrorSubTypeUsage, + kSecTrustErrorSubTypeName, + kSecTrustErrorSubTypeExpired, + kSecTrustErrorSubTypeInvalid, +} SecTrustErrorSubType; + +#define SecCopyTrustString(KEY) SecFrameworkCopyLocalizedString(KEY, CFSTR("Trust")) + +struct checkmap_entry_s { + SecTrustErrorSubType type; + OSStatus status; + const CFStringRef errorKey; + +}; +typedef struct checkmap_entry_s checkmap_entry_t; + +const checkmap_entry_t checkmap[] = { +#undef POLICYCHECKMACRO +#define __PC_SUBTYPE_ kSecTrustErrorSubTypeInvalid +#define __PC_SUBTYPE_N kSecTrustErrorSubTypeName +#define __PC_SUBTYPE_E kSecTrustErrorSubTypeExpired +#define __PC_SUBTYPE_S kSecTrustErrorSubTypeKeySize +#define __PC_SUBTYPE_H kSecTrustErrorSubTypeWeakHash +#define __PC_SUBTYPE_U kSecTrustErrorSubTypeUsage +#define __PC_SUBTYPE_P kSecTrustErrorSubTypePinning +#define __PC_SUBTYPE_V kSecTrustErrorSubTypeRevoked +#define __PC_SUBTYPE_T kSecTrustErrorSubTypeTrust +#define __PC_SUBTYPE_C kSecTrustErrorSubTypeCompliance +#define __PC_SUBTYPE_D kSecTrustErrorSubTypeDenied +#define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) \ +{ __PC_SUBTYPE_##SUBTYPE , OSSTATUS, SEC_TRUST_ERROR_##NAME }, +#include "SecPolicyChecks.list" +}; + +static OSStatus SecTrustCopyErrorStrings(SecTrustRef trust, + CFStringRef * CF_RETURNS_RETAINED simpleError, + CFStringRef * CF_RETURNS_RETAINED fullError) { + if (!simpleError || !fullError) { + return errSecParam; + } + __block CFArrayRef details = NULL; + dispatch_sync(trust->_trustQueue, ^{ + details = CFRetainSafe(trust->_details); + }); + if (!details) + return errSecInternal; + + /* We need to map the policy check constants to indexes into our checkmap table. */ + static dispatch_once_t onceToken; + static CFArrayRef policyChecks = NULL; + dispatch_once(&onceToken, ^{ + CFMutableArrayRef _policyChecks = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + #undef POLICYCHECKMACRO + #define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, ERRORSTRING) \ + CFArrayAppendValue(_policyChecks, kSecPolicyCheck##NAME); + #include "SecPolicyChecks.list" + policyChecks = _policyChecks; + }); + + /* Build the errors for each cert in the detailed results array */ + __block CFMutableStringRef fullMutableError = CFStringCreateMutable(NULL, 0); + __block SecTrustErrorSubType simpleErrorSubType = kSecTrustErrorSubTypeInvalid; + __block OSStatus simpleErrorStatus = errSecInternalError; + __block CFIndex simpleErrorCertIndex = kCFNotFound; + __block CFIndex ix; + CFIndex count = CFArrayGetCount(details); + for (ix = 0; ix < count; ix++) { + CFDictionaryRef perCertDetails = (CFDictionaryRef)CFArrayGetValueAtIndex(details, ix); + if (CFDictionaryGetCount(perCertDetails) == 0) { continue; } // no errors on this cert + + /* Get the cert summary and start the full error details string for this cert */ + CFStringRef certSummary = SecCertificateCopySubjectSummary(SecTrustGetCertificateAtIndex(trust, ix)); + CFStringRef format = SecCopyTrustString(SEC_TRUST_CERTIFICATE_ERROR); + CFStringAppendFormat(fullMutableError, NULL, format, + ix, certSummary); + CFReleaseNull(certSummary); + CFReleaseNull(format); + + /* Figure out the errors */ + __block bool firstError = true; + CFDictionaryForEach(perCertDetails, ^(const void *key, const void * __unused value) { + CFIndex policyCheckIndex = CFArrayGetFirstIndexOfValue(policyChecks, CFRangeMake(0, CFArrayGetCount(policyChecks)), key); + if (policyCheckIndex == kCFNotFound) { return; } + /* Keep track of the highest priority error encountered during this evaluation. + * If multiple certs have errors of the same subtype we keep the lowest indexed cert. */ + if (simpleErrorSubType > checkmap[policyCheckIndex].type) { + simpleErrorSubType = checkmap[policyCheckIndex].type; + simpleErrorCertIndex = ix; + simpleErrorStatus = checkmap[policyCheckIndex].status; + } + /* Add this error to the full error */ + if (!firstError) { CFStringAppend(fullMutableError, CFSTR(", ")); } + CFStringRef errorString = SecCopyTrustString(checkmap[policyCheckIndex].errorKey); + CFStringAppend(fullMutableError, errorString); + CFReleaseNull(errorString); + firstError = false; + }); + CFStringAppend(fullMutableError, CFSTR(";")); + } + CFReleaseNull(details); + + /* Build the simple error */ + if (simpleErrorCertIndex == kCFNotFound) { simpleErrorCertIndex = 0; } + CFStringRef format = NULL; + CFStringRef certSummary = SecCertificateCopySubjectSummary(SecTrustGetCertificateAtIndex(trust, simpleErrorCertIndex)); + switch (simpleErrorSubType) { + case kSecTrustErrorSubTypeRevoked: { + format = SecCopyTrustString(SEC_TRUST_ERROR_SUBTYPE_REVOKED); + break; + } + case kSecTrustErrorSubTypeKeySize: { + format = SecCopyTrustString(SEC_TRUST_ERROR_SUBTYPE_KEYSIZE); + break; + } + case kSecTrustErrorSubTypeWeakHash: { + format = SecCopyTrustString(SEC_TRUST_ERROR_SUBTYPE_WEAKHASH); + break; + } + case kSecTrustErrorSubTypeDenied: { + format = SecCopyTrustString(SEC_TRUST_ERROR_SUBTYPE_DENIED); + break; + } + case kSecTrustErrorSubTypeCompliance: { + format = SecCopyTrustString(SEC_TRUST_ERROR_SUBTYPE_COMPLIANCE); + break; + } + case kSecTrustErrorSubTypeExpired: { + format = SecCopyTrustString(SEC_TRUST_ERROR_SUBTYPE_EXPIRED); + break; + } + case kSecTrustErrorSubTypeTrust: { + format = SecCopyTrustString(SEC_TRUST_ERROR_SUBTYPE_TRUST); + break; + } + case kSecTrustErrorSubTypeName: { + format = SecCopyTrustString(SEC_TRUST_ERROR_SUBTYPE_NAME); + break; + } + case kSecTrustErrorSubTypeUsage: { + format = SecCopyTrustString(SEC_TRUST_ERROR_SUBTYPE_USAGE); + break; + } + case kSecTrustErrorSubTypePinning: { + format = SecCopyTrustString(SEC_TRUST_ERROR_SUBTYPE_PINNING); + CFAssignRetained(certSummary, SecTrustCopyChainSummary(trust)); + break; + } + default: { + format = SecCopyTrustString(SEC_TRUST_ERROR_SUBTYPE_INVALID); + break; + } + } + if (format && certSummary) { + *simpleError = CFStringCreateWithFormat(NULL, NULL, format, certSummary); + } + CFReleaseNull(format); + CFReleaseNull(certSummary); + *fullError = fullMutableError; + return simpleErrorStatus; +} + +static CFErrorRef SecTrustCopyError(SecTrustRef trust) { + if (!trust) { return NULL; } + (void)SecTrustEvaluateIfNecessary(trust); + OSStatus status = errSecSuccess; + __block SecTrustResultType trustResult = kSecTrustResultInvalid; + dispatch_sync(trust->_trustQueue, ^{ + trustResult = trust->_trustResult; + }); + if (trustResult == kSecTrustResultProceed || trustResult == kSecTrustResultUnspecified) { + return NULL; + } + + CFStringRef detailedError = NULL; + CFStringRef simpleError = NULL; + status = SecTrustCopyErrorStrings(trust, &simpleError, &detailedError); + CFDictionaryRef userInfo = CFDictionaryCreate(NULL, (const void **)&kCFErrorLocalizedDescriptionKey, + (const void **)&detailedError, 1, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFErrorRef underlyingError = CFErrorCreate(NULL, kCFErrorDomainOSStatus, status, userInfo); + CFReleaseNull(userInfo); + CFReleaseNull(detailedError); + + const void *keys[] = { kCFErrorLocalizedDescriptionKey, kCFErrorUnderlyingErrorKey }; + const void *values[] = { simpleError, underlyingError }; + userInfo = CFDictionaryCreate(NULL, keys, values, 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFErrorRef error = CFErrorCreate(NULL, kCFErrorDomainOSStatus, status, userInfo); + CFReleaseNull(userInfo); + CFReleaseNull(simpleError); + return error; +} + +bool SecTrustEvaluateWithError(SecTrustRef trust, CFErrorRef *error) { + SecTrustResultType trustResult = kSecTrustResultInvalid; + OSStatus status = SecTrustEvaluate(trust, &trustResult); + if (status == errSecSuccess && (trustResult == kSecTrustResultProceed || trustResult == kSecTrustResultUnspecified)) { + if (error) { + *error = NULL; + } + return true; + } + if (error) { + if (status != errSecSuccess) { + *error = SecCopyLastError(status); + } else { + *error = SecTrustCopyError(trust); + } + } + return false; +} + OSStatus SecTrustEvaluateAsync(SecTrustRef trust, dispatch_queue_t queue, SecTrustCallback result) { @@ -1051,14 +1312,36 @@ static bool SecXPCDictionarySetDataArray(xpc_object_t message, const char *key, return true; } -static bool SecXPCDictionaryCopyChainOptional(xpc_object_t message, const char *key, SecCertificatePathRef *path, CFErrorRef *error) { +static bool SecXPCDictionaryCopyChainOptional(xpc_object_t message, const char *key, CFArrayRef *path, CFErrorRef *error) { xpc_object_t xpc_path = xpc_dictionary_get_value(message, key); + CFMutableArrayRef output = NULL; + size_t count = 0; if (!xpc_path) { *path = NULL; return true; } - *path = SecCertificatePathCreateWithXPCArray(xpc_path, error); - return *path; + require_action_quiet(xpc_get_type(xpc_path) == XPC_TYPE_ARRAY, exit, SecError(errSecDecode, error, CFSTR("xpc_path value is not an array"))); + require_action_quiet(count = xpc_array_get_count(xpc_path), exit, SecError(errSecDecode, error, CFSTR("xpc_path array count == 0"))); + output = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks); + + size_t ix; + for (ix = 0; ix < count; ++ix) { + SecCertificateRef certificate = SecCertificateCreateWithXPCArrayAtIndex(xpc_path, ix, error); + if (certificate) { + CFArrayAppendValue(output, certificate); + CFReleaseNull(certificate); + } else { + CFReleaseNull(output); + break; + } + } + +exit: + if (output) { + *path = output; + return true; + } + return false; } static int SecXPCDictionaryGetNonZeroInteger(xpc_object_t message, const char *key, CFErrorRef *error) { @@ -1074,7 +1357,7 @@ static SecTrustResultType handle_trust_evaluate_xpc(enum SecXPCOperation op, CFA bool keychainsAllowed, CFArrayRef policies, CFArrayRef responses, CFArrayRef SCTs, CFArrayRef trustedLogs, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, CFArrayRef exceptions, - CFArrayRef *details, CFDictionaryRef *info, SecCertificatePathRef *chain, CFErrorRef *error) + CFArrayRef *details, CFDictionaryRef *info, CFArrayRef *chain, CFErrorRef *error) { __block SecTrustResultType tr = kSecTrustResultInvalid; securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) { @@ -1229,8 +1512,7 @@ static OSStatus SecTrustEvaluateIfNecessary(SecTrustRef trust) { the public key from the leaf. */ SecCertificateRef leafCert = (SecCertificateRef)CFArrayGetValueAtIndex(trust->_certificates, 0); CFArrayRef leafCertArray = CFArrayCreate(NULL, (const void**)&leafCert, 1, &kCFTypeArrayCallBacks); - trust->_chain = SecCertificatePathCreateWithCertificates(leafCertArray, NULL); - CFReleaseNull(leafCertArray); + trust->_chain = leafCertArray; if (error) CFReleaseNull(*error); return true; @@ -1322,7 +1604,12 @@ SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust) SecTrustEvaluateIfNecessary(trust); dispatch_sync(trust->_trustQueue, ^{ if (trust->_chain) { - trust->_publicKey = SecCertificatePathCopyPublicKeyAtIndex(trust->_chain, 0); + SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(trust->_chain, 0); +#if TARGET_OS_OSX + trust->_publicKey = SecCertificateCopyPublicKey_ios(cert); +#else + trust->_publicKey = SecCertificateCopyPublicKey(cert); +#endif publicKey = CFRetainSafe(trust->_publicKey); } }); @@ -1338,7 +1625,7 @@ CFIndex SecTrustGetCertificateCount(SecTrustRef trust) { __block CFIndex certCount = 1; dispatch_sync(trust->_trustQueue, ^{ if (trust->_chain) { - certCount = SecCertificatePathGetCount(trust->_chain); + certCount = CFArrayGetCount(trust->_chain); } }); return certCount; @@ -1359,7 +1646,7 @@ SecCertificateRef SecTrustGetCertificateAtIndex(SecTrustRef trust, SecTrustEvaluateIfNecessary(trust); dispatch_sync(trust->_trustQueue, ^{ if (trust->_chain) { - cert = SecCertificatePathGetCertificateAtIndex(trust->_chain, ix); + cert = (SecCertificateRef)CFArrayGetValueAtIndex(trust->_chain, ix); } }); return cert; @@ -1514,21 +1801,19 @@ SecTrustSetOptions(SecTrustRef trustRef, SecTrustOptionFlags options) CFMutableDictionaryRef exception_dictionary = CFDictionaryCreateMutableCopy(NULL, 0, (CFDictionaryRef)CFArrayGetValueAtIndex(old_exceptions, ix)); if (!exception_dictionary) { status = errSecAllocate; goto out; } if ((options & kSecTrustOptionAllowExpired) != 0) { - if (ix == 0) { CFDictionaryAddValue(exception_dictionary, CFSTR("ValidLeaf"), kCFBooleanFalse); } - if (ix == (count - 1)) { CFDictionaryAddValue(exception_dictionary, CFSTR("ValidRoot"), kCFBooleanFalse); } - if (ix > 0 && ix < (count - 1)) { - CFDictionaryAddValue(exception_dictionary, CFSTR("ValidIntermediates"), kCFBooleanFalse); } - } - if ((options & kSecTrustOptionAllowExpiredRoot) != 0) { - if (ix == (count - 1)) { CFDictionaryAddValue(exception_dictionary, CFSTR("ValidRoot"), kCFBooleanFalse); } + CFDictionaryAddValue(exception_dictionary, kSecPolicyCheckTemporalValidity, kCFBooleanFalse); } - if ((options & kSecTrustOptionImplicitAnchors) != 0) { - /* Check that root is self-signed. (Done by trustd for other case.) */ + if ((options & (kSecTrustOptionImplicitAnchors | kSecTrustOptionAllowExpiredRoot)) != 0) { + /* Check that root is self-signed. */ Boolean isSelfSigned = false; SecCertificateRef cert = SecTrustGetCertificateAtIndex(trustRef, ix); if (cert && (errSecSuccess == SecCertificateIsSelfSigned(cert, &isSelfSigned)) && isSelfSigned) { - CFDictionaryAddValue(exception_dictionary, CFSTR("AnchorTrusted"), kCFBooleanFalse); + if ((options & kSecTrustOptionImplicitAnchors) != 0) { + CFDictionaryAddValue(exception_dictionary, kSecPolicyCheckAnchorTrusted, kCFBooleanFalse); + } else if ((options & kSecTrustOptionAllowExpiredRoot) != 0) { + CFDictionaryAddValue(exception_dictionary, kSecPolicyCheckTemporalValidity, kCFBooleanFalse); + } } } CFArrayAppendValue(exceptions, exception_dictionary); @@ -1540,15 +1825,13 @@ SecTrustSetOptions(SecTrustRef trustRef, SecTrustOptionFlags options) &kCFTypeDictionaryValueCallBacks); if (!exception_dictionary) { status = errSecAllocate; goto out; } if ((options & kSecTrustOptionAllowExpired) != 0) { - CFDictionaryAddValue(exception_dictionary, CFSTR("ValidLeaf"), kCFBooleanFalse); - CFDictionaryAddValue(exception_dictionary, CFSTR("ValidIntermediates"), kCFBooleanFalse); - CFDictionaryAddValue(exception_dictionary, CFSTR("ValidRoot"), kCFBooleanFalse); + CFDictionaryAddValue(exception_dictionary, kSecPolicyCheckTemporalValidity, kCFBooleanFalse); } if ((options & kSecTrustOptionAllowExpiredRoot) != 0) { - CFDictionaryAddValue(exception_dictionary, CFSTR("ValidRoot"), kCFBooleanFalse); + CFDictionaryAddValue(exception_dictionary, kSecPolicyCheckValidRoot, kCFBooleanFalse); } if ((options & kSecTrustOptionImplicitAnchors) != 0) { - CFDictionaryAddValue(exception_dictionary, CFSTR("AnchorTrusted"), kCFBooleanFalse); + CFDictionaryAddValue(exception_dictionary, kSecPolicyCheckAnchorTrusted, kCFBooleanFalse); } CFArrayAppendValue(exceptions, exception_dictionary); CFReleaseNull(exception_dictionary); @@ -1586,103 +1869,6 @@ CFArrayRef SecTrustCopyDetailedPropertiesAtIndex(SecTrustRef trust, CFIndex ix) return summary; } -#if 0 - - - -/* Valid chain. - Can be on any non root cert in the chain. - Priority: Top down - Short circuit: Yes (No other errors matter after this one) - Non recoverable error - Trust UI: Invalid certificate chain linkage - Cert UI: Invalid linkage to parent certificate -*/ -CFStringRef kSecPolicyCheckIdLinkage = CFSTR("IdLinkage"); - -/* X.509 required checks. - Can be on any cert in the chain - Priority: Top down - Short circuit: Yes (No other errors matter after this one) - Non recoverable error - Trust UI: (One or more) unsupported critical extensions found. -*/ -/* If we have no names for the extention oids use: - Cert UI: One or more unsupported critical extensions found (Non recoverable error). - Cert UI: Unsupported 'foo', 'bar', baz' critical extensions found. -*/ -CFStringRef kSecPolicyCheckCriticalExtensions = CFSTR("CriticalExtensions"); -/* Cert UI: Unsupported critical Qualified Certificate Statements extension found (Non recoverable error). */ -CFStringRef kSecPolicyCheckQualifiedCertStatements = CFSTR("QualifiedCertStatements"); -/* Cert UI: Certificate has an empty subject (and no critial subjectAltname). */ - -/* Trusted root. - Only apply to the anchor. - Priority: N/A - Short circuit: No (Under discussion) - Recoverable - Trust UI: Root certificate is not trusted (for this policy/app/host/whatever?) - Cert UI: Not a valid anchor -*/ -CFStringRef kSecPolicyCheckAnchorTrusted = CFSTR("AnchorTrusted"); -CFStringRef kSecPolicyCheckAnchorSHA1 = CFSTR("AnchorSHA1"); - -CFStringRef kSecPolicyCheckAnchorApple = CFSTR("AnchorApple"); -CFStringRef kSecPolicyAppleAnchorIncludeTestRoots = CFSTR("AnchorAppleTestRoots"); - -/* Binding. - Only applies to leaf - Priority: N/A - Short Circuit: No - Recoverable - Trust UI: (Hostname|email address) mismatch -*/ -CFStringRef kSecPolicyCheckSSLHostname = CFSTR("SSLHostname"); - -/* Policy specific checks. - Can be on any cert in the chain - Priority: Top down - Short Circuit: No - Recoverable - Trust UI: Certificate chain is not valid for the current policy. - OR: (One or more) certificates in the chain are not valid for the current policy/application -*/ -CFStringRef kSecPolicyCheckNonEmptySubject = CFSTR("NonEmptySubject"); -/* Cert UI: Non CA certificate used as CA. - Cert UI: CA certificate used as leaf. - Cert UI: Cert chain length exceeded. - Cert UI: Basic constraints extension not critical (non fatal). - Cert UI: Leaf certificate has basic constraints extension (non fatal). - */ -CFStringRef kSecPolicyCheckBasicConstraints = CFSTR("BasicConstraints"); -CFStringRef kSecPolicyCheckKeyUsage = CFSTR("KeyUsage"); -CFStringRef kSecPolicyCheckExtendedKeyUsage = CFSTR("ExtendedKeyUsage"); -/* Checks that the issuer of the leaf has exactly one Common Name and that it - matches the specified string. */ -CFStringRef kSecPolicyCheckIssuerCommonName = CFSTR("IssuerCommonName"); -/* Checks that the leaf has exactly one Common Name and that it has the - specified string as a prefix. */ -CFStringRef kSecPolicyCheckSubjectCommonNamePrefix = CFSTR("SubjectCommonNamePrefix"); -/* Check that the certificate chain length matches the specificed CFNumberRef - length. */ -CFStringRef kSecPolicyCheckChainLength = CFSTR("ChainLength"); -CFStringRef kSecPolicyCheckNotValidBefore = CFSTR("NotValidBefore"); - -/* Expiration. - Can be on any cert in the chain - Priority: Top down - Short Circuit: No - Recoverable - Trust UI: One or more certificates have expired or are not valid yet. - OS: The (root|intermediate|leaf) certificate (expired on 'date'|is not valid until 'date') - Cert UI: Certificate (expired on 'date'|is not valid until 'date') -*/ -CFStringRef kSecPolicyCheckValidIntermediates = CFSTR("ValidIntermediates"); -CFStringRef kSecPolicyCheckValidLeaf = CFSTR("ValidLeaf"); -CFStringRef kSecPolicyCheckValidRoot = CFSTR("ValidRoot"); - -#endif - struct TrustFailures { bool badLinkage; bool unknownCritExtn; @@ -1691,6 +1877,7 @@ struct TrustFailures { bool policyFail; bool invalidCert; bool weakKey; + bool weakHash; bool revocation; }; @@ -1713,8 +1900,7 @@ static void applyDetailProperty(const void *_key, const void *_value, purposes. */ if (CFEqual(key, kSecPolicyCheckIdLinkage)) { tf->badLinkage = true; - } else if (CFEqual(key, kSecPolicyCheckCriticalExtensions) - || CFEqual(key, kSecPolicyCheckQualifiedCertStatements)) { + } else if (CFEqual(key, kSecPolicyCheckCriticalExtensions)) { tf->unknownCritExtn = true; } else if (CFEqual(key, kSecPolicyCheckAnchorTrusted) || CFEqual(key, kSecPolicyCheckAnchorSHA1) @@ -1723,14 +1909,12 @@ static void applyDetailProperty(const void *_key, const void *_value, tf->untrustedAnchor = true; } else if (CFEqual(key, kSecPolicyCheckSSLHostname)) { tf->hostnameMismatch = true; - } else if (CFEqual(key, kSecPolicyCheckValidIntermediates) - || CFEqual(key, kSecPolicyCheckValidLeaf) - || CFEqual(key, kSecPolicyCheckValidRoot)) { + } else if (CFEqual(key, kSecPolicyCheckTemporalValidity)) { tf->invalidCert = true; - } else if (CFEqual(key, kSecPolicyCheckWeakIntermediates) - || CFEqual(key, kSecPolicyCheckWeakLeaf) - || CFEqual(key, kSecPolicyCheckWeakRoot)) { + } else if (CFEqual(key, kSecPolicyCheckWeakKeySize)) { tf->weakKey = true; + } else if (CFEqual(key, kSecPolicyCheckWeakSignature)) { + tf->weakHash = true; } else if (CFEqual(key, kSecPolicyCheckRevocation)) { tf->revocation = true; } else @@ -1750,15 +1934,18 @@ static void applyDetailProperty(const void *_key, const void *_value, } } -static void appendError(CFMutableArrayRef properties, CFStringRef error) { - CFStringRef localizedError = SecFrameworkCopyLocalizedString(error, - CFSTR("SecCertificate")); - if (!localizedError) { - //secerror("WARNING: localized error string was not found in Security.framework"); - localizedError = CFRetain(error); +static void appendError(CFMutableArrayRef properties, CFStringRef error, bool localized) { + CFStringRef localizedError = NULL; + if (!error) { + return; + } else if (localized) { + //%%% "SecCertificate" should be changed to "Certificate": rdar://37517120 + localizedError = SecFrameworkCopyLocalizedString(error, CFSTR("SecCertificate")); + } else { + localizedError = (CFStringRef) CFRetainSafe(error); } appendProperty(properties, kSecPropertyTypeError, NULL, NULL, - localizedError); + localizedError, localized); CFReleaseNull(localizedError); } @@ -1773,6 +1960,7 @@ CFArrayRef SecTrustCopyProperties(SecTrustRef trust) return NULL; } SecTrustEvaluateIfNecessary(trust); + bool localized = true; __block CFArrayRef details = NULL; dispatch_sync(trust->_trustQueue, ^{ details = CFRetainSafe(trust->_details); @@ -1797,27 +1985,30 @@ CFArrayRef SecTrustCopyProperties(SecTrustRef trust) /* The badLinkage and unknownCritExtn failures are short circuited, since you can't recover from those errors. */ if (tf.badLinkage) { - appendError(properties, CFSTR("Invalid certificate chain linkage.")); + appendError(properties, CFSTR("Invalid certificate chain linkage."), localized); } else if (tf.unknownCritExtn) { - appendError(properties, CFSTR("One or more unsupported critical extensions found.")); + appendError(properties, CFSTR("One or more unsupported critical extensions found."), localized); } else { if (tf.untrustedAnchor) { - appendError(properties, CFSTR("Root certificate is not trusted.")); + appendError(properties, CFSTR("Root certificate is not trusted."), localized); } if (tf.hostnameMismatch) { - appendError(properties, CFSTR("Hostname mismatch.")); + appendError(properties, CFSTR("Hostname mismatch."), localized); } if (tf.policyFail) { - appendError(properties, CFSTR("Policy requirements not met.")); + appendError(properties, CFSTR("Policy requirements not met."), localized); } if (tf.invalidCert) { - appendError(properties, CFSTR("One or more certificates have expired or are not valid yet.")); + appendError(properties, CFSTR("One or more certificates have expired or are not valid yet."), localized); } if (tf.weakKey) { - appendError(properties, CFSTR("One or more certificates is using a weak key size.")); + appendError(properties, CFSTR("One or more certificates is using a weak key size."), localized); + } + if (tf.weakHash) { + appendError(properties, CFSTR("One or more certificates is using a weak signature algorithm."), localized); } if (tf.revocation) { - appendError(properties, CFSTR("One or more certificates have been revoked.")); + appendError(properties, CFSTR("One or more certificates have been revoked."), localized); } } @@ -1968,68 +2159,82 @@ CFDictionaryRef SecTrustCopyResult(SecTrustRef trust) { return results; } -// Return 0 upon error. -static int to_int_error_request(enum SecXPCOperation op, CFErrorRef *error) { - __block int64_t result = 0; - securityd_send_sync_and_do(op, error, NULL, ^bool(xpc_object_t response, CFErrorRef *error) { - result = xpc_dictionary_get_int64(response, kSecXPCKeyResult); - if (!result) - return SecError(errSecInternal, error, CFSTR("int64 missing in response")); - return true; - }); - return (int)result; +#define do_if_registered(sdp, ...) if (gTrustd && gTrustd->sdp) { return gTrustd->sdp(__VA_ARGS__); } + +static bool xpc_dictionary_entry_is_type(xpc_object_t dictionary, const char *key, xpc_type_t type) { + xpc_object_t value = xpc_dictionary_get_value(dictionary, key); + return value && (xpc_get_type(value) == type); +} + +static uint64_t do_ota_pki_op (enum SecXPCOperation op, CFErrorRef *error) { + uint64_t num = 0; + xpc_object_t message = securityd_create_message(op, error); + if (message) { + xpc_object_t response = securityd_message_with_reply_sync(message, error); + if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_UINT64)) { + num = (int64_t) xpc_dictionary_get_uint64(response, kSecXPCKeyResult); + } + if (response && error && xpc_dictionary_entry_is_type(response, kSecXPCKeyError, XPC_TYPE_DICTIONARY)) { + xpc_object_t xpc_error = xpc_dictionary_get_value(response, kSecXPCKeyError); + if (xpc_error) { + *error = SecCreateCFErrorWithXPCObject(xpc_error); + } + } + xpc_release_safe(message); + xpc_release_safe(response); + } + return num; } + // version 0 -> error, so we need to start at version 1 or later. -OSStatus SecTrustGetOTAPKIAssetVersionNumber(int* versionNumber) -{ - OSStatus result; - os_activity_t trace_activity = os_activity_start("SecTrustGetOTAPKIAssetVersionNumber", OS_ACTIVITY_FLAG_DEFAULT); - result = SecOSStatusWith(^bool(CFErrorRef *error) { - if (!versionNumber) - return SecError(errSecParam, error, CFSTR("versionNumber is NULL")); +uint64_t SecTrustGetTrustStoreVersionNumber(CFErrorRef *error) { + do_if_registered(sec_ota_pki_trust_store_version, error); - return (*versionNumber = TRUSTD_XPC(sec_ota_pki_asset_version, to_int_error_request, error)) != 0; - }); + os_activity_t activity = os_activity_create("SecTrustGetTrustStoreVersionNumber", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); - os_activity_end(trace_activity); - return result; + uint64_t num = do_ota_pki_op(sec_ota_pki_trust_store_version_id, error); + + os_release(activity); + return num; } -#define do_if_registered(sdp, ...) if (gTrustd && gTrustd->sdp) { return gTrustd->sdp(__VA_ARGS__); } +uint64_t SecTrustOTAPKIGetUpdatedAsset(CFErrorRef *error) { + do_if_registered(sec_ota_pki_get_new_asset, error); -static bool xpc_dictionary_entry_is_type(xpc_object_t dictionary, const char *key, xpc_type_t type) -{ - xpc_object_t value = xpc_dictionary_get_value(dictionary, key); + os_activity_t activity = os_activity_create("SecTrustOTAPKIGetUpdatedAsset", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); - return value && (xpc_get_type(value) == type); + uint64_t num = do_ota_pki_op(kSecXPCOpOTAPKIGetNewAsset, error); + + os_release(activity); + return num; } -OSStatus SecTrustOTAPKIGetUpdatedAsset(int* didUpdateAsset) -{ - CFErrorRef error = NULL; - do_if_registered(sec_ota_pki_get_new_asset, &error); +bool SecTrustReportTLSAnalytics(CFStringRef eventName, xpc_object_t eventAttributes, CFErrorRef *error) { + if (!eventName || !eventAttributes) { + return false; + } + do_if_registered(sec_tls_analytics_report, eventName, eventAttributes, error); - int64_t num = 0; - xpc_object_t message = securityd_create_message(kSecXPCOpOTAPKIGetNewAsset, &error); - if (message) - { - xpc_object_t response = securityd_message_with_reply_sync(message, &error); + os_activity_t activity = os_activity_create("SecTrustReportTLSAnalytics", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); - if (response && xpc_dictionary_entry_is_type(response, kSecXPCKeyResult, XPC_TYPE_INT64)) - { - num = (int64_t) xpc_dictionary_get_int64(response, kSecXPCKeyResult); - xpc_release(response); + __block bool result = false; + securityd_send_sync_and_do(kSecXPCOpTLSAnaltyicsReport, error, ^bool(xpc_object_t message, CFErrorRef *block_error) { + if (!SecXPCDictionarySetString(message, kSecTrustEventNameKey, eventName, block_error)) { + return false; } + xpc_dictionary_set_value(message, kSecTrustEventAttributesKey, eventAttributes); + return true; + }, ^bool(xpc_object_t response, CFErrorRef *block_error) { + result = SecXPCDictionaryGetBool(response, kSecXPCKeyResult, block_error); + return true; + }); - xpc_release(message); - } - - if (NULL != didUpdateAsset) - { - *didUpdateAsset = (int)num; - } - return noErr; + os_release(activity); + return result; } /* @@ -2069,8 +2274,7 @@ OSStatus SecTrustEvaluateLeafOnly(SecTrustRef trust, SecTrustResultType *result) &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFMutableArrayRef leafCert = CFArrayCreateMutableCopy(NULL, 1, trust->_certificates); - trust->_chain = SecCertificatePathCreateWithCertificates(leafCert, NULL); - CFReleaseNull(leafCert); + trust->_chain = leafCert; }); SecLeafPVCDelete(&pvc); @@ -2123,7 +2327,7 @@ static void serializeCertificate(const void *value, void *context) { } } -static CFArrayRef SecCertificateArraySerialize(CFArrayRef certificates) { +static CF_RETURNS_RETAINED CFArrayRef SecCertificateArraySerialize(CFArrayRef certificates) { CFMutableArrayRef result = NULL; require_quiet(isArray(certificates), errOut); CFIndex count = CFArrayGetCount(certificates); @@ -2174,10 +2378,10 @@ static CFPropertyListRef SecTrustCopyPlist(SecTrustRef trust) { CFDictionaryAddValue(output, CFSTR(kSecTrustVerifyDateKey), trust->_verifyDate); } if (trust->_chain) { - CFArrayRef serializedChain = SecCertificatePathCreateSerialized(trust->_chain, NULL); - if (serializedChain) { - CFDictionaryAddValue(output, CFSTR(kSecTrustChainKey), serializedChain); - CFRelease(serializedChain); + CFArrayRef serializedCerts = SecCertificateArraySerialize(trust->_chain); + if (serializedCerts) { + CFDictionaryAddValue(output, CFSTR(kSecTrustChainKey), serializedCerts); + CFRelease(serializedCerts); } } if (trust->_details) { @@ -2226,14 +2430,12 @@ out: static OSStatus SecTrustCreateFromPlist(CFPropertyListRef plist, SecTrustRef CF_RETURNS_RETAINED *trust) { OSStatus status = errSecParam; SecTrustRef output = NULL; - CFTypeRef serializedCertificates = NULL, serializedPolicies = NULL, serializedAnchors = NULL, - serializedChain = NULL; + CFTypeRef serializedCertificates = NULL, serializedPolicies = NULL, serializedAnchors = NULL; CFNumberRef trustResultNum = NULL; CFArrayRef certificates = NULL, policies = NULL, anchors = NULL, responses = NULL, - SCTs = NULL, trustedLogs = NULL, details = NULL, exceptions = NULL; + SCTs = NULL, trustedLogs = NULL, details = NULL, exceptions = NULL, chain = NULL; CFDateRef verifyDate = NULL; CFDictionaryRef info = NULL; - SecCertificatePathRef chain = NULL; require_quiet(CFDictionaryGetTypeID() == CFGetTypeID(plist), out); require_quiet(serializedCertificates = CFDictionaryGetValue(plist, CFSTR(kSecTrustCertificatesKey)), out); @@ -2263,10 +2465,9 @@ static OSStatus SecTrustCreateFromPlist(CFPropertyListRef plist, SecTrustRef CF_ if (isDate(verifyDate)) { output->_verifyDate = CFRetainSafe(verifyDate); } - serializedChain = CFDictionaryGetValue(plist, CFSTR(kSecTrustChainKey)); - if (isArray(serializedChain)) { - chain = SecCertificatePathCreateDeserialized(serializedChain, NULL); - output->_chain = chain; + chain = CFDictionaryGetValue(plist, CFSTR(kSecTrustChainKey)); + if (isArray(chain)) { + output->_chain = SecCertificateArrayDeserialize(chain); } details = CFDictionaryGetValue(plist, CFSTR(kSecTrustDetailsKey)); if (isArray(details)) { diff --git a/OSX/sec/Security/SecTrustInternal.h b/OSX/sec/Security/SecTrustInternal.h index 51b174f8..fcb0962e 100644 --- a/OSX/sec/Security/SecTrustInternal.h +++ b/OSX/sec/Security/SecTrustInternal.h @@ -58,6 +58,9 @@ SecKeyRef SecTrustCopyPublicKey_ios(SecTrustRef trust); CFArrayRef SecTrustCopyProperties_ios(SecTrustRef trust); #endif +#define kSecTrustEventNameKey "eventName" +#define kSecTrustEventAttributesKey "eventAttributes" + __END_DECLS #endif /* !_SECURITY_SECTRUSTINTERNAL_H_ */ diff --git a/OSX/sec/Security/SecTrustStatusCodes.c b/OSX/sec/Security/SecTrustStatusCodes.c index 4f9f6d5a..096b3b9e 100644 --- a/OSX/sec/Security/SecTrustStatusCodes.c +++ b/OSX/sec/Security/SecTrustStatusCodes.c @@ -36,53 +36,10 @@ struct resultmap_entry_s { typedef struct resultmap_entry_s resultmap_entry_t; const resultmap_entry_t resultmap[] = { - { CFSTR("SSLHostname"), 0x80012400, /* CSSMERR_APPLETP_HOSTNAME_MISMATCH */}, - { CFSTR("email"), 0x80012418, /* CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND */}, - { CFSTR("IssuerCommonName"), 0x8001243B /* CSSMERR_APPLETP_IDENTIFIER_MISSING */}, - { CFSTR("SubjectCommonName"), 0x8001243B /* CSSMERR_APPLETP_IDENTIFIER_MISSING */}, - { CFSTR("SubjectCommonNamePrefix"), 0x8001243B /* CSSMERR_APPLETP_IDENTIFIER_MISSING */}, - { CFSTR("SubjectCommonNameTEST"), 0x8001243B /* CSSMERR_APPLETP_IDENTIFIER_MISSING */}, - { CFSTR("SubjectOrganization"), 0x8001243B /* CSSMERR_APPLETP_IDENTIFIER_MISSING */}, - { CFSTR("SubjectOrganizationalUnit"), 0x8001243B /* CSSMERR_APPLETP_IDENTIFIER_MISSING */}, - { CFSTR("EAPTrustedServerNames"), 0x80012400 /* CSSMERR_APPLETP_HOSTNAME_MISMATCH */}, - { CFSTR("CertificatePolicy"), 0x80012439 /* CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION */}, - { CFSTR("KeyUsage"), 0x80012406 /* CSSMERR_APPLETP_INVALID_KEY_USAGE */}, - { CFSTR("ExtendedKeyUsage"), 0x80012407 /* CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE */}, - { CFSTR("BasicConstraints"), 0x80012402 /* CSSMERR_APPLETP_NO_BASIC_CONSTRAINTS */}, - { CFSTR("QualifiedCertStatements"), 0x80012438 /* CSSMERR_APPLETP_UNKNOWN_QUAL_CERT_STATEMENT */}, - { CFSTR("IntermediateSPKISHA256"), 0x8001243B /* CSSMERR_APPLETP_IDENTIFIER_MISSING */}, - { CFSTR("IntermediateEKU"), 0x80012407 /* CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE */}, - { CFSTR("AnchorSHA1"), 0x8001212A /* CSSMERR_TP_NOT_TRUSTED */}, - { CFSTR("AnchorSHA256"), 0x8001212A /* CSSMERR_TP_NOT_TRUSTED */}, - { CFSTR("AnchorTrusted"), 0x8001212A /* CSSMERR_TP_NOT_TRUSTED */}, - { CFSTR("AnchorApple"), 0x8001243C /* CSSMERR_APPLETP_CA_PIN_MISMATCH */}, - { CFSTR("NonEmptySubject"), 0x80012437 /* CSSMERR_APPLETP_INVALID_EMPTY_SUBJECT */}, - { CFSTR("IdLinkage"), 0x80012404 /* CSSMERR_APPLETP_INVALID_AUTHORITY_ID */}, - { CFSTR("WeakIntermediates"), 0x80012115 /* CSSMERR_TP_INVALID_CERTIFICATE */}, - { CFSTR("WeakLeaf"), 0x80012115 /* CSSMERR_TP_INVALID_CERTIFICATE */}, - { CFSTR("WeakRoot"), 0x80012115 /* CSSMERR_TP_INVALID_CERTIFICATE */}, - { CFSTR("KeySize"), 0x80010918 /* CSSMERR_CSP_UNSUPPORTED_KEY_SIZE */}, - { CFSTR("SignatureHashAlgorithms"), 0x80010913 /* CSSMERR_CSP_ALGID_MISMATCH */}, - { CFSTR("SystemTrustedWeakHash"), 0x80010955 /* CSSMERR_CSP_INVALID_DIGEST_ALGORITHM */}, - { CFSTR("CriticalExtensions"), 0x80012401 /* CSSMERR_APPLETP_UNKNOWN_CRITICAL_EXTEN */}, - { CFSTR("ChainLength"), 0x80012409 /* CSSMERR_APPLETP_PATH_LEN_CONSTRAINT */}, - { CFSTR("BasicCertificateProcessing"), 0x80012115 /* CSSMERR_TP_INVALID_CERTIFICATE */}, - { CFSTR("ExtendedValidation"), 0x8001212A /* CSSMERR_TP_NOT_TRUSTED */}, - { CFSTR("Revocation"), 0x8001210C /* CSSMERR_TP_CERT_REVOKED */}, - { CFSTR("RevocationResponseRequired"), 0x80012423 /* CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK */}, - { CFSTR("CertificateTransparency"), 0x8001212A /* CSSMERR_TP_NOT_TRUSTED */}, - { CFSTR("BlackListedLeaf"), 0x8001210C /* CSSMERR_TP_CERT_REVOKED */}, - { CFSTR("GrayListedLeaf"), 0x8001212A /* CSSMERR_TP_NOT_TRUSTED */}, - { CFSTR("GrayListedKey"), 0x8001212A /* CSSMERR_TP_NOT_TRUSTED */}, - { CFSTR("BlackListedKey"), 0x8001210C /* CSSMERR_TP_CERT_REVOKED */}, - { CFSTR("CheckLeafMarkerOid"), 0x80012439 /* CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION */}, - { CFSTR("CheckLeafMarkerOidNoValueCheck"), 0x80012439 /* CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION */}, - { CFSTR("CheckIntermediateMarkerOid"), 0x80012439 /* CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION */}, - { CFSTR("UsageConstraints"), 0x80012436 /* CSSMERR_APPLETP_TRUST_SETTING_DENY */}, - { CFSTR("NotValidBefore"), 0x8001210B /* CSSMERR_TP_CERT_NOT_VALID_YET */}, - { CFSTR("ValidIntermediates"), 0x8001210A /* CSSMERR_TP_CERT_EXPIRED */}, - { CFSTR("ValidLeaf"), 0x8001210A /* CSSMERR_TP_CERT_EXPIRED */}, - { CFSTR("ValidRoot"), 0x8001210A /* CSSMERR_TP_CERT_EXPIRED */}, +#undef POLICYCHECKMACRO +#define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) \ +{ CFSTR(#NAME), CSSMERR }, +#include "SecPolicyChecks.list" }; // diff --git a/OSX/sec/Security/SecTrustStore.c b/OSX/sec/Security/SecTrustStore.c index e308ffb6..d070c835 100644 --- a/OSX/sec/Security/SecTrustStore.c +++ b/OSX/sec/Security/SecTrustStore.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2009,2012-2015 Apple Inc. All Rights Reserved. + * Copyright (c) 2007-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -72,7 +72,9 @@ static bool string_data_to_bool_error(enum SecXPCOperation op, SecTrustStoreRef static bool string_data_to_bool_bool_error(enum SecXPCOperation op, SecTrustStoreRef ts, CFDataRef digest, bool *result, CFErrorRef *error) { - return securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) { + os_activity_t activity = os_activity_create("SecTrustStoreContains", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); + bool status = securityd_send_sync_and_do(op, error, ^bool(xpc_object_t message, CFErrorRef *error) { return SecXPCDictionarySetString(message, kSecXPCKeyDomain, (CFStringRef)ts, error) && SecXPCDictionarySetData(message, kSecXPCKeyDigest, digest, error); }, ^bool(xpc_object_t response, CFErrorRef *error) { @@ -80,6 +82,8 @@ static bool string_data_to_bool_bool_error(enum SecXPCOperation op, SecTrustStor *result = xpc_dictionary_get_bool(response, kSecXPCKeyResult); return true; }); + os_release(activity); + return status; } Boolean SecTrustStoreContains(SecTrustStoreRef ts, @@ -88,7 +92,6 @@ Boolean SecTrustStoreContains(SecTrustStoreRef ts, bool ok = false; __block bool contains = false; - os_activity_t trace_activity = os_activity_start("SecTrustStoreContains", OS_ACTIVITY_FLAG_DEFAULT); require(ts, errOut); require(digest = SecCertificateGetSHA1Digest(certificate), errOut); @@ -98,7 +101,6 @@ Boolean SecTrustStoreContains(SecTrustStoreRef ts, }) == errSecSuccess); errOut: - os_activity_end(trace_activity); return ok && contains; } @@ -220,8 +222,9 @@ OSStatus SecTrustStoreRemoveCertificate(SecTrustStoreRef ts, { CFDataRef digest; __block OSStatus status = errSecParam; - - os_activity_t trace_activity = os_activity_start("SecTrustStoreRemoveCertificate", OS_ACTIVITY_FLAG_DEFAULT); + + os_activity_t activity = os_activity_create("SecTrustStoreRemoveCertificate", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); require(ts, errOut); require(digest = SecCertificateGetSHA1Digest(certificate), errOut); require(gTrustd || ts == (SecTrustStoreRef)kSecTrustStoreUserName, errOut); @@ -231,38 +234,27 @@ OSStatus SecTrustStoreRemoveCertificate(SecTrustStoreRef ts, }); errOut: - os_activity_end(trace_activity); + os_release(activity); return status; } -static CFIndex GetOTAAssetVersionNumber() -{ - CFIndex result = 0; - int version = 0; - - if (errSecSuccess == SecTrustGetOTAPKIAssetVersionNumber(&version)) - { - result = version; - } - - return result; -} - - - OSStatus SecTrustStoreGetSettingsVersionNumber(SecTrustSettingsVersionNumber* p_settings_version_number) { - OSStatus status = errSecParam; - if (NULL == p_settings_version_number) - { - return status; + if (NULL == p_settings_version_number) { + return errSecParam; } - - CFIndex versionNumber = GetOTAAssetVersionNumber(); + + OSStatus status = errSecSuccess; + CFErrorRef error = nil; + uint64_t versionNumber = SecTrustGetTrustStoreVersionNumber(&error); *p_settings_version_number = (SecTrustSettingsVersionNumber)versionNumber; - return errSecSuccess; + if (error) { + status = (OSStatus)CFErrorGetCode(error); + } + CFReleaseSafe(error); + return status; } static bool string_to_array_error(enum SecXPCOperation op, SecTrustStoreRef ts, CFArrayRef *trustStoreContents, CFErrorRef *error) @@ -283,7 +275,8 @@ OSStatus SecTrustStoreCopyAll(SecTrustStoreRef ts, CFArrayRef *trustStoreContent __block CFArrayRef results = NULL; OSStatus status = errSecParam; - os_activity_t trace_activity = os_activity_start("SecTrustStoreCopyAll", OS_ACTIVITY_FLAG_DEFAULT); + os_activity_t activity = os_activity_create("SecTrustStoreCopyAll", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); require(ts, errOut); status = SecOSStatusWith(^bool (CFErrorRef *error) { @@ -293,7 +286,7 @@ OSStatus SecTrustStoreCopyAll(SecTrustStoreRef ts, CFArrayRef *trustStoreContent *trustStoreContents = results; errOut: - os_activity_end(trace_activity); + os_release(activity); return status; } @@ -313,7 +306,8 @@ OSStatus SecTrustStoreCopyUsageConstraints(SecTrustStoreRef ts, SecCertificateRe __block CFArrayRef results = NULL; OSStatus status = errSecParam; - os_activity_t trace_activity = os_activity_start("SecTrustStoreCopyUsageConstraints", OS_ACTIVITY_FLAG_DEFAULT); + os_activity_t activity = os_activity_create("SecTrustStoreCopyUsageConstraints", OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_scope(activity); require(ts, errOut); require(certificate, errOut); require(digest = SecCertificateGetSHA1Digest(certificate), errOut); @@ -326,6 +320,6 @@ OSStatus SecTrustStoreCopyUsageConstraints(SecTrustStoreRef ts, SecCertificateRe *usageConstraints = results; errOut: - os_activity_end(trace_activity); + os_release(activity); return status; } diff --git a/OSX/sec/Security/SecuritydXPC.c b/OSX/sec/Security/SecuritydXPC.c index 721659a1..9c9fdfd1 100644 --- a/OSX/sec/Security/SecuritydXPC.c +++ b/OSX/sec/Security/SecuritydXPC.c @@ -42,6 +42,7 @@ const char *kSecXPCKeyUserLabel = "userlabel"; const char *kSecXPCKeyBackup = "backup"; const char *kSecXPCKeyKeybag = "keybag"; const char *kSecXPCKeyUserPassword = "password"; +const char *kSecXPCKeyEMCSBackup = "emcsbackup"; const char *kSecXPCKeyDSID = "dsid"; const char *kSecXPCKeyQuery = "query"; const char *kSecXPCKeyAttributesToUpdate = "attributesToUpdate"; @@ -236,8 +237,8 @@ CFStringRef SOSCCGetOperationDescription(enum SecXPCOperation op) return CFSTR("keychain_restore_syncable"); case sec_keychain_sync_update_message_id: return CFSTR("keychain_sync_update_message"); - case sec_ota_pki_asset_version_id: - return CFSTR("ota_pki_asset_version"); + case sec_ota_pki_trust_store_version_id: + return CFSTR("ota_pki_trust_store_version"); case sec_otr_session_create_remote_id: return CFSTR("otr_session_create_remote"); case sec_otr_session_process_packet_remote_id: @@ -258,6 +259,8 @@ CFStringRef SOSCCGetOperationDescription(enum SecXPCOperation op) return CFSTR("trust_store_copy_all"); case sec_trust_store_copy_usage_constraints_id: return CFSTR("trust_store_copy_usage_constraints"); + case sec_ocsp_cache_flush_id: + return CFSTR("ocsp_cache_flush"); case soscc_EnsurePeerRegistration_id: return CFSTR("EnsurePeerRegistration"); case kSecXPCOpSetEscrowRecord: @@ -298,16 +301,14 @@ CFStringRef SOSCCGetOperationDescription(enum SecXPCOperation op) return CFSTR("copy_parent_certificates"); case sec_item_certificate_exists_id: return CFSTR("certificate_exists"); - case kSecXPCOpCKKSEndpoint: - return CFSTR("CKKSEndpoint"); - case kSecXPCOpSOSEndpoint: - return CFSTR("SOSEndpoint"); - case kSecXPCOpSecuritydXPCServerEndpoint: - return CFSTR("XPCServerEndpoint"); case kSecXPCOpBackupKeybagAdd: return CFSTR("KeybagAdd"); case kSecXPCOpBackupKeybagDelete: return CFSTR("KeybagDelete"); + case kSecXPCOpKeychainControlEndpoint: + return CFSTR("KeychainControlEndpoint"); + case kSecXPCOpTLSAnaltyicsReport: + return CFSTR("TLSAnalyticsReport"); default: return CFSTR("Unknown xpc operation"); } diff --git a/OSX/sec/Security/Tool/SecurityCommands.h b/OSX/sec/Security/Tool/SecurityCommands.h index ee7dfdd0..675393cf 100644 --- a/OSX/sec/Security/Tool/SecurityCommands.h +++ b/OSX/sec/Security/Tool/SecurityCommands.h @@ -183,11 +183,16 @@ SECURITY_COMMAND_IOS("verify-cert", verify_cert, "Verify certificate(s).") SECURITY_COMMAND_IOS("trust-store", trust_store_show_certificates, - "[-p][-f][-s][-v][-t][-k]\n" - " -p Output cert in PEM format.\n" - " -f Show fingerprint (SHA1 digest certificate.)\n" - " -s Show subject.\n" - " -v Show entire certificate in text form.\n" - " -t Show trust settings for certificates.\n" - " -k Show keyid (SHA1 digest of public key)", - "Display user trust store certificates and trust settings.") + "[-p][-f][-s][-v][-t][-k]\n" + " -p Output cert in PEM format.\n" + " -f Show fingerprint (SHA1 digest certificate.)\n" + " -s Show subject.\n" + " -v Show entire certificate in text form.\n" + " -t Show trust settings for certificates.\n" + " -k Show keyid (SHA1 digest of public key)", + "Display user trust store certificates and trust settings.") + +SECURITY_COMMAND("check-trust-update", check_trust_update, + "[-s]\n" + " -s Check for Supplementals (Pinning DB and Trusted CT Logs) update\n", + "Check for data updates for trust and return current version.") diff --git a/OSX/sec/Security/Tool/add_internet_password.c b/OSX/sec/Security/Tool/add_internet_password.c index 3326df88..5758d7bf 100644 --- a/OSX/sec/Security/Tool/add_internet_password.c +++ b/OSX/sec/Security/Tool/add_internet_password.c @@ -159,7 +159,7 @@ int keychain_add_internet_password(int argc, char * const *argv) break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -176,7 +176,7 @@ int keychain_add_internet_password(int argc, char * const *argv) } } else if (argc != 0) - return 2; + return SHOW_USAGE_MESSAGE; result = do_addinternetpassword(keychainName, serverName, securityDomain, accountName, path, port, protocol,authenticationType, passwordData); diff --git a/OSX/sec/Security/Tool/codesign.c b/OSX/sec/Security/Tool/codesign.c index ab01a43b..43e5cda5 100644 --- a/OSX/sec/Security/Tool/codesign.c +++ b/OSX/sec/Security/Tool/codesign.c @@ -333,7 +333,7 @@ extern int codesign_util(int argc, char * const *argv) verbose++; break; default: - return 2; /* Trigger usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -341,7 +341,7 @@ extern int codesign_util(int argc, char * const *argv) argv += optind; if (argc != 1) - return 2; /* Trigger usage message. */ + return SHOW_USAGE_MESSAGE; CFArrayRef sigs = load_code_signatures(argv[0]); require(sigs, out); diff --git a/OSX/sec/Security/Tool/keychain_add.c b/OSX/sec/Security/Tool/keychain_add.c index b8555aec..decf795d 100644 --- a/OSX/sec/Security/Tool/keychain_add.c +++ b/OSX/sec/Security/Tool/keychain_add.c @@ -108,14 +108,14 @@ keychain_add_certificates(int argc, char * const *argv) case 'k': keychainName = optarg; if (*keychainName == '\0') - return 2; + return SHOW_USAGE_MESSAGE; break; case 't': trustSettings = true; break; case '?': default: - return 2; /* Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -123,7 +123,7 @@ keychain_add_certificates(int argc, char * const *argv) argv += optind; if (argc == 0) - return 2; + return SHOW_USAGE_MESSAGE; result = do_add_certificates(keychainName, trustSettings, argc, argv); diff --git a/OSX/sec/Security/Tool/keychain_backup.c b/OSX/sec/Security/Tool/keychain_backup.c index de2582ad..c084dd28 100644 --- a/OSX/sec/Security/Tool/keychain_backup.c +++ b/OSX/sec/Security/Tool/keychain_backup.c @@ -108,7 +108,7 @@ keychain_import(int argc, char * const *argv) password=optarg; break; default: - return 2; /* Trigger usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -117,12 +117,12 @@ keychain_import(int argc, char * const *argv) if(keybag==NULL) { sec_error("-k is required\n"); - return 2; + return SHOW_USAGE_MESSAGE; } if (argc != 1) { sec_error(" is required\n"); - return 2; /* Trigger usage message. */ + return SHOW_USAGE_MESSAGE; } return do_keychain_import(argv[0], keybag, password); @@ -150,7 +150,7 @@ keychain_export(int argc, char * const *argv) password=optarg; break; default: - return 2; /* Trigger usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -159,12 +159,12 @@ keychain_export(int argc, char * const *argv) if(keybag==NULL) { sec_error("-k is required\n"); - return 2; + return SHOW_USAGE_MESSAGE; } if (argc != 1) { sec_error(" is required\n"); - return 2; /* Trigger usage message. */ + return SHOW_USAGE_MESSAGE; } return do_keychain_export(argv[0], keybag, password); diff --git a/OSX/sec/Security/Tool/keychain_find.m b/OSX/sec/Security/Tool/keychain_find.m index 6b7f039c..c396e189 100644 --- a/OSX/sec/Security/Tool/keychain_find.m +++ b/OSX/sec/Security/Tool/keychain_find.m @@ -282,7 +282,7 @@ keychain_find_or_delete_internet_password(Boolean do_delete, int argc, char * co break; case 'g': if (do_delete) - return 2; + return SHOW_USAGE_MESSAGE; get_password = TRUE; break; case 'p': @@ -306,7 +306,7 @@ keychain_find_or_delete_internet_password(Boolean do_delete, int argc, char * co break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -537,7 +537,7 @@ keychain_find_or_delete_generic_password(Boolean do_delete, break; case 'g': if (do_delete) - return 2; + return SHOW_USAGE_MESSAGE; get_password = TRUE; break; case 's': @@ -545,7 +545,7 @@ keychain_find_or_delete_generic_password(Boolean do_delete, break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -608,7 +608,7 @@ keychain_roll_keys(int argc, char * const *argv) { force = true; break; default: - return 2; + return SHOW_USAGE_MESSAGE; } } // argc -= optind; diff --git a/OSX/sec/Security/Tool/pkcs12_util.c b/OSX/sec/Security/Tool/pkcs12_util.c index 1a33b80d..1fc1f145 100644 --- a/OSX/sec/Security/Tool/pkcs12_util.c +++ b/OSX/sec/Security/Tool/pkcs12_util.c @@ -350,7 +350,7 @@ extern int pkcs12_util(int argc, char * const *argv) verbose = true; break; default: - return 2; /* Trigger usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -358,7 +358,7 @@ extern int pkcs12_util(int argc, char * const *argv) argv += optind; if (argc != 1 || !passphrase) - return 2; /* Trigger usage message. */ + return SHOW_USAGE_MESSAGE; filename = argv[0]; array = PKCS12FileCreateArray(filename, passphrase); diff --git a/OSX/sec/Security/Tool/scep.c b/OSX/sec/Security/Tool/scep.c index a254b419..fd9e7a0e 100644 --- a/OSX/sec/Security/Tool/scep.c +++ b/OSX/sec/Security/Tool/scep.c @@ -307,7 +307,7 @@ extern int command_scep(int argc, char * const *argv) scep_capabilities = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingUTF8); break; default: - return 2; /* Trigger usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -315,7 +315,7 @@ extern int command_scep(int argc, char * const *argv) argv += optind; if (argc != 1) - return 2; /* Trigger usage message. */ + return SHOW_USAGE_MESSAGE; CFDataRef scep_request = NULL; CFArrayRef issued_certs = NULL; @@ -520,9 +520,8 @@ extern int command_scep(int argc, char * const *argv) if (scep_subject_alt_name) { fprintf(stderr, "Adding subjectAltName to request\n"); - CFStringRef name = CFSTR("dnsName"); CFDictionaryRef subject_alt_name = CFDictionaryCreate(kCFAllocatorDefault, - (const void **)&name, (const void **)&scep_subject_alt_name, + (const void **)&kSecSubjectAltNameDNSName, (const void **)&scep_subject_alt_name, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(csr_parameters, kSecSubjectAltName, subject_alt_name); } diff --git a/OSX/sec/Security/Tool/show_certificates.c b/OSX/sec/Security/Tool/show_certificates.c index 108885f2..8d7bb967 100644 --- a/OSX/sec/Security/Tool/show_certificates.c +++ b/OSX/sec/Security/Tool/show_certificates.c @@ -53,6 +53,7 @@ #include #include #include +#include #include @@ -172,7 +173,7 @@ int keychain_show_certificates(int argc, char * const *argv) break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -291,6 +292,64 @@ int keychain_show_certificates(int argc, char * const *argv) return result; } +static bool isSettingWithResult(CFDictionaryRef setting, SecTrustSettingsResult result) { + CFNumberRef value = CFDictionaryGetValue(setting, kSecTrustSettingsResult); + if (!isNumberOfType(value, kCFNumberSInt64Type)) { + return false; + } + int64_t setting_result = 0; + if (!CFNumberGetValue(value, kCFNumberSInt64Type, &setting_result) || + (setting_result != result)) { + return false; + } + return true; +} + +static bool isUnconstrainedSettingWithResult(CFDictionaryRef setting, SecTrustSettingsResult result) { + if (!isDictionary(setting) || (CFDictionaryGetCount(setting) != 1)) { + return false; + } + + return isSettingWithResult(setting, result); +} + +static bool isDenyTrustSetting(CFArrayRef trust_settings) { + if (CFArrayGetCount(trust_settings) != 1) { + return false; + } + + return isUnconstrainedSettingWithResult(CFArrayGetValueAtIndex(trust_settings, 0), + kSecTrustSettingsResultDeny); +} + +static bool isPartialSSLTrustSetting(CFArrayRef trust_settings) { + if (CFArrayGetCount(trust_settings) != 2) { + return false; + } + + /* Second setting is a blanket "Trust" */ + if (!isUnconstrainedSettingWithResult(CFArrayGetValueAtIndex(trust_settings, 1), + kSecTrustSettingsResultTrustRoot) && + !isUnconstrainedSettingWithResult(CFArrayGetValueAtIndex(trust_settings, 1), + kSecTrustSettingsResultTrustAsRoot)) { + return false; + } + + /* First setting is "upspecified" for SSL policy */ + CFDictionaryRef setting = CFArrayGetValueAtIndex(trust_settings, 0); + if (!isDictionary(setting) || (CFDictionaryGetCount(setting) < 2)) { + return false; + } + if (!isSettingWithResult(setting, kSecTrustSettingsResultUnspecified)) { + return false; + } + if (!CFEqualSafe(CFDictionaryGetValue(setting, kSecTrustSettingsPolicy), kSecPolicyAppleSSL)) { + return false; + } + + return true; +} + int trust_store_show_certificates(int argc, char * const *argv) { int ch, result = 0; @@ -326,7 +385,7 @@ int trust_store_show_certificates(int argc, char * const *argv) break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -402,13 +461,27 @@ int trust_store_show_certificates(int argc, char * const *argv) CFReleaseNull(cert); return 1; } - // place-holder until there are actual trust settings - CFStringRef settings = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@"), trust_settings); - char *settingsStr = NULL; - settingsStr = CFStringToCString(settings); - fprintf(stdout, "%s\n", settingsStr); - free(settingsStr); - CFRelease(settings); + + /* These are some trust settings configs used by ManagedConfiguration on iOS */ + if (CFArrayGetCount(trust_settings) == 0) { + /* Full trust */ + fprintf(stdout, "Full trust enabled\n"); + } else if (isDenyTrustSetting(trust_settings)) { + fprintf(stdout, "Administrator blacklisted\n"); + } else if (isPartialSSLTrustSetting(trust_settings)) { + fprintf(stdout, "Partial trust enabled\n"); + } else { + CFStringRef settings = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@"), trust_settings); + if (settings) { + char *settingsStr = CFStringToCString(settings); + if (settingsStr) { + fprintf(stdout, "Unknown trust settings:\n%s\n", settingsStr); + free(settingsStr); + } + CFRelease(settings); + } + } + } printf("*******************************************************\n"); diff --git a/OSX/sec/Security/Tool/spc.c b/OSX/sec/Security/Tool/spc.c index 848811d2..404454d9 100644 --- a/OSX/sec/Security/Tool/spc.c +++ b/OSX/sec/Security/Tool/spc.c @@ -648,7 +648,7 @@ extern int command_spc(int argc, char * const *argv) break; case 'h': default: - return 2; + return SHOW_USAGE_MESSAGE; } } @@ -660,11 +660,11 @@ extern int command_spc(int argc, char * const *argv) // get plist from argv[0] url } else if (argc == 0) { machine_authentication(NULL, NULL); - } else return 2; + } else return SHOW_USAGE_MESSAGE; #endif if (argc != 1) - return 2; + return SHOW_USAGE_MESSAGE; int result = -1; CFDictionaryRef dict = NULL; diff --git a/OSX/sec/Security/Tool/trust_update.m b/OSX/sec/Security/Tool/trust_update.m new file mode 100644 index 00000000..adf5453a --- /dev/null +++ b/OSX/sec/Security/Tool/trust_update.m @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + * + * trust_update.m + */ + +#import + +#import +#import + +#include "SecurityCommands.h" + +static int check_OTA_Supplementals_asset(void) { + CFErrorRef error = NULL; + uint64_t version = SecTrustOTAPKIGetUpdatedAsset(&error); + if (error) { + CFStringRef errorDescription = CFErrorCopyDescription(error); + if (errorDescription) { + char *errMsg = CFStringToCString(errorDescription); + fprintf(stdout, "Update failed: %s\n", errMsg); + if (errMsg) { free(errMsg); } + CFRelease(errorDescription); + } else { + fprintf(stdout, "Update failed: no description\n"); + } + CFRelease(error); + } else { + fprintf(stdout, "Updated succeeded\n"); + } + if (version != 0) { + fprintf(stdout, "Asset Content Version: %llu\n", version); + } else { + return 1; + } + return 0; +} + +int check_trust_update(int argc, char * const *argv) { + int arg; + bool check_trust_supplementals = false; + + if (argc == 1) { + return SHOW_USAGE_MESSAGE; + } + + while ((arg = getopt(argc, argv, "s")) != -1) { + switch(arg) { + case 's': + check_trust_supplementals = true; + break; + case '?': + default: + return SHOW_USAGE_MESSAGE; + } + } + + if (check_trust_supplementals) { + return check_OTA_Supplementals_asset(); + } + return 0; +} diff --git a/OSX/sec/Security/Tool/verify_cert.c b/OSX/sec/Security/Tool/verify_cert.c index 6ecc2aea..76b8dd59 100644 --- a/OSX/sec/Security/Tool/verify_cert.c +++ b/OSX/sec/Security/Tool/verify_cert.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2007,2009-2010,2013-2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2003-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -36,6 +36,8 @@ #include #include +#include "SecurityCommands.h" + CFStringRef policyToConstant(const char *policy); int verify_cert(int argc, char * const *argv); @@ -170,8 +172,7 @@ int verify_cert(int argc, char * const *argv) { SecTrustResultType resultType; if (argc < 2) { - /* Return 2 triggers usage message. */ - return 2; + return SHOW_USAGE_MESSAGE; } optind = 1; diff --git a/OSX/sec/Security/ios_tapi_hacks.h b/OSX/sec/Security/ios_tapi_hacks.h new file mode 100644 index 00000000..1367c4a9 --- /dev/null +++ b/OSX/sec/Security/ios_tapi_hacks.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#ifndef ios_tapi_hack_h +#define ios_tapi_hack_h + +// This file is to work around TAPI's insistence that every exported symbol is in a header file. +// The Security project just simply rejects such ideas, so this is the pressure valve: +// +// One-offs in header files that shouldn't be exported in the real-live iOS Security framework +// can be added here, and TAPI will accept them. +// +// Please don't add anything here. + +#ifndef SECURITY_PROJECT_TAPI_HACKS +#error This header is not for inclusion; it's a nasty hack to get the iOS Security framework to build with TAPI. +#endif + +#include +#include + +CFDataRef SecDistinguishedNameCopyNormalizedContent(CFDataRef distinguished_name); +CFDataRef _SecItemCreatePersistentRef(CFTypeRef iclass, sqlite_int64 rowid, CFDictionaryRef attributes); +CFDictionaryRef SecTokenItemValueCopy(CFDataRef db_value, CFErrorRef *error); +CFArrayRef SecItemCopyParentCertificates_ios(CFDataRef normalizedIssuer, CFArrayRef accessGroups, CFErrorRef *error); +bool SecItemCertificateExists(CFDataRef normalizedIssuer, CFDataRef serialNumber, CFArrayRef accessGroups, CFErrorRef *error); +bool _SecItemParsePersistentRef(CFDataRef persistent_ref, CFStringRef *return_class, + sqlite_int64 *return_rowid, CFDictionaryRef *return_token_attrs); + +// SecItemPriv.h +extern const CFStringRef kSecUseSystemKeychain; + +// securityd_client.h + +typedef struct SecurityClient { +} SecurityClient; + +extern struct securityd *gSecurityd; +extern struct trustd *gTrustd; +extern SecurityClient * SecSecurityClientGet(void); +bool securityd_send_sync_and_do(enum SecXPCOperation op, CFErrorRef *error, + bool (^add_to_message)(xpc_object_t message, CFErrorRef* error), + bool (^handle_response)(xpc_object_t response, CFErrorRef* error)); +XPC_RETURNS_RETAINED xpc_object_t securityd_message_with_reply_sync(xpc_object_t message, CFErrorRef *error); +XPC_RETURNS_RETAINED xpc_object_t securityd_create_message(enum SecXPCOperation op, CFErrorRef *error); +bool securityd_message_no_error(xpc_object_t message, CFErrorRef *error); + +@interface SecuritydXPCClient : NSObject +@end + +void SecAccessGroupsSetCurrent(CFArrayRef accessGroups); +CFArrayRef SecAccessGroupsGetCurrent(void); + +#include +extern os_log_t secLogObjForScope(const char *scope); +extern os_log_t secLogObjForCFScope(CFStringRef scope); +#if TARGET_OS_IOS +void SecSecuritySetMusrMode(bool mode, uid_t uid, int activeUser); +#endif // TARGET_OS_IOS + +void SecServerSetMachServiceName(const char *name); + +#endif /* ios_tapi_hacks_h */ + diff --git a/OSX/sec/Security/oids.c b/OSX/sec/Security/oids.c new file mode 100644 index 00000000..800ffc8e --- /dev/null +++ b/OSX/sec/Security/oids.c @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2005-2009,2011-2016 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +/* + * oids.c - OID consts + * + */ + +#include + +#define OID_ISO_CCITT_DIR_SERVICE 85 +#define OID_DS OID_ISO_CCITT_DIR_SERVICE +#define OID_ATTR_TYPE OID_DS, 4 +#define OID_EXTENSION OID_DS, 29 +#define OID_ISO_STANDARD 40 +#define OID_ISO_MEMBER 42 +#define OID_US OID_ISO_MEMBER, 134, 72 + +#define OID_ISO_IDENTIFIED_ORG 43 +#define OID_OSINET OID_ISO_IDENTIFIED_ORG, 4 +#define OID_GOSIP OID_ISO_IDENTIFIED_ORG, 5 +#define OID_DOD OID_ISO_IDENTIFIED_ORG, 6 +#define OID_OIW OID_ISO_IDENTIFIED_ORG, 14 + +/* From the PKCS Standards */ +#define OID_RSA OID_US, 134, 247, 13 +#define OID_RSA_HASH OID_RSA, 2 +#define OID_RSA_ENCRYPT OID_RSA, 3 +#define OID_PKCS OID_RSA, 1 +#define OID_PKCS_1 OID_PKCS, 1 +#define OID_PKCS_2 OID_PKCS, 2 +#define OID_PKCS_3 OID_PKCS, 3 +#define OID_PKCS_4 OID_PKCS, 4 +#define OID_PKCS_5 OID_PKCS, 5 +#define OID_PKCS_6 OID_PKCS, 6 +#define OID_PKCS_7 OID_PKCS, 7 +#define OID_PKCS_8 OID_PKCS, 8 +#define OID_PKCS_9 OID_PKCS, 9 +#define OID_PKCS_10 OID_PKCS, 10 +#define OID_PKCS_11 OID_PKCS, 11 +#define OID_PKCS_12 OID_PKCS, 12 + +/* ANSI X9.62 */ +#define OID_ANSI_X9_62 OID_US, 206, 61 +#define OID_PUBLIC_KEY_TYPE OID_ANSI_X9_62, 2 +#define OID_EC_CURVE OID_ANSI_X9_62, 3, 1 +#define OID_EC_SIG_TYPE OID_ANSI_X9_62, 4 +#define OID_ECDSA_WITH_SHA2 OID_EC_SIG_TYPE, 3 + +/* Certicom */ +#define OID_CERTICOM OID_ISO_IDENTIFIED_ORG, 132 +#define OID_CERTICOM_EC_CURVE OID_CERTICOM, 0 + +/* ANSI X9.42 */ +#define OID_ANSI_X9_42 OID_US, 206, 62, 2 +#define OID_ANSI_X9_42_SCHEME OID_ANSI_X9_42, 3 +#define OID_ANSI_X9_42_NAMED_SCHEME OID_ANSI_X9_42, 4 + +/* ANSI X9.57 */ +#define OID_ANSI_X9_57 OID_US, 206, 56 +#define OID_ANSI_X9_57_ALGORITHM OID_ANSI_X9_57, 4 + +/* DOD IANA Security related objects. */ +#define OID_IANA OID_DOD, 1, 5 + +/* Kerberos PKINIT */ +#define OID_KERBv5 OID_IANA, 2 +#define OID_KERBv5_PKINIT OID_KERBv5, 3 + +/* DOD IANA Mechanisms. */ +#define OID_MECHANISMS OID_IANA, 5 + +/* PKIX */ +#define OID_PKIX OID_MECHANISMS, 7 +#define OID_PE OID_PKIX, 1 +#define OID_QT OID_PKIX, 2 +#define OID_KP OID_PKIX, 3 +#define OID_OTHER_NAME OID_PKIX, 8 +#define OID_PDA OID_PKIX, 9 +#define OID_QCS OID_PKIX, 11 +#define OID_AD OID_PKIX, 48 +#define OID_AD_OCSP OID_AD, 1 +#define OID_AD_CAISSUERS OID_AD, 2 + +/* ISAKMP */ +#define OID_ISAKMP OID_MECHANISMS, 8 + +/* ETSI */ +#define OID_ETSI 0x04, 0x00 +#define OID_ETSI_QCS 0x04, 0x00, 0x8E, 0x46, 0x01 + +#define OID_OIW_SECSIG OID_OIW, 3 + +#define OID_OIW_ALGORITHM OID_OIW_SECSIG, 2 + +/* NIST defined digest algorithm arc (2, 16, 840, 1, 101, 3, 4, 2) */ +#define OID_NIST_HASHALG 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02 + +/* + * Netscape OIDs. + */ +#define NETSCAPE_BASE_OID 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42 + +/* + * Netscape cert extension. + * + * netscape-cert-extension OBJECT IDENTIFIER ::= + * { 2 16 840 1 113730 1 } + * + * BER = 06 08 60 86 48 01 86 F8 42 01 + */ +#define NETSCAPE_CERT_EXTEN NETSCAPE_BASE_OID, 0x01 + +#define NETSCAPE_CERT_POLICY NETSCAPE_BASE_OID, 0x04 + +/* + * Apple-specific OID bases + */ + +/* + * apple OBJECT IDENTIFIER ::= + * { iso(1) member-body(2) US(840) 113635 } + * + * BER = 06 06 2A 86 48 86 F7 63 + */ +#define APPLE_OID OID_US, 0x86, 0xf7, 0x63 + +/* appleDataSecurity OBJECT IDENTIFIER ::= + * { apple 100 } + * { 1 2 840 113635 100 } + * + * BER = 06 07 2A 86 48 86 F7 63 64 + */ +#define APPLE_ADS_OID APPLE_OID, 0x64 + +/* + * appleSecurityAlgorithm OBJECT IDENTIFIER ::= + * { appleDataSecurity 2 } + * { 1 2 840 113635 100 2 } + * + * BER = 06 08 2A 86 48 86 F7 63 64 02 + */ +#define APPLE_ALG_OID APPLE_ADS_OID, 2 + +/* Entrust OIDs. */ +#define ENTRUST_BASE_OID OID_US, 0x86, 0xf6, 0x7d + +/* + * Entrust cert extension. + * + * entrust-cert-extension OBJECT IDENTIFIER ::= + * { 1 2 840 113533 7 65 } + * + * BER = 06 08 2A 86 48 86 F6 7D 07 41 + */ +#define ENTRUST_CERT_EXTEN ENTRUST_BASE_OID, 0x07, 0x41 + +/* Microsoft OIDs. */ +#define MICROSOFT_BASE_OID OID_DOD, 0x01, 0x04, 0x01, 0x82, 0x37 +#define MICROSOFT_ENROLLMENT_OID MICROSOFT_BASE_OID, 0x14 + +/* Google OIDs: 1.3.6.1.4.1.11129. + */ +#define GOOGLE_BASE_OID OID_DOD, 0x01, 0x04, 0x01, 0xD6, 0x79 +#define GOOGLE_EMBEDDED_SCT_OID GOOGLE_BASE_OID, 0x02, 0x04, 0x02 +#define GOOGLE_OCSP_SCT_OID GOOGLE_BASE_OID, 0x02, 0x04, 0x05 + + +/* Algorithm OIDs. */ +static const DERByte + _oidRsa[] = { OID_PKCS_1, 1 }, + _oidMd2Rsa[] = { OID_PKCS_1, 2 }, + _oidMd4Rsa[] = { OID_PKCS_1, 3 }, + _oidMd5Rsa[] = { OID_PKCS_1, 4 }, + _oidSha1Rsa[] = { OID_PKCS_1, 5 }, + _oidSha256Rsa[] = { OID_PKCS_1, 11 }, /* rfc5754 */ + _oidSha384Rsa[] = { OID_PKCS_1, 12 }, /* rfc5754 */ + _oidSha512Rsa[] = { OID_PKCS_1, 13 }, /* rfc5754 */ + _oidSha224Rsa[] = { OID_PKCS_1, 14 }, /* rfc5754 */ + _oidEcPubKey[] = { OID_PUBLIC_KEY_TYPE, 1 }, + _oidSha1Ecdsa[] = { OID_EC_SIG_TYPE, 1 }, /* rfc3279 */ + _oidSha224Ecdsa[] = { OID_ECDSA_WITH_SHA2, 1 }, /* rfc5758 */ + _oidSha256Ecdsa[] = { OID_ECDSA_WITH_SHA2, 2 }, /* rfc5758 */ + _oidSha384Ecdsa[] = { OID_ECDSA_WITH_SHA2, 3 }, /* rfc5758 */ + _oidSha512Ecdsa[] = { OID_ECDSA_WITH_SHA2, 4 }, /* rfc5758 */ + _oidSha1Dsa[] = { OID_ANSI_X9_57_ALGORITHM, 3 }, + _oidMd2[] = { OID_RSA_HASH, 2 }, + _oidMd4[] = { OID_RSA_HASH, 4 }, + _oidMd5[] = { OID_RSA_HASH, 5 }, + _oidSha1[] = { OID_OIW_ALGORITHM, 26 }, + _oidSha1DsaOIW[] = { OID_OIW_ALGORITHM, 27 }, + _oidSha1DsaCommonOIW[] = { OID_OIW_ALGORITHM, 28 }, + _oidSha1RsaOIW[] = { OID_OIW_ALGORITHM, 29 }, + _oidSha256[] = { OID_NIST_HASHALG, 1 }, + _oidSha384[] = { OID_NIST_HASHALG, 2 }, + _oidSha512[] = { OID_NIST_HASHALG, 3 }, + _oidSha224[] = { OID_NIST_HASHALG, 4 }, + _oidFee[] = { APPLE_ALG_OID, 1 }, + _oidMd5Fee[] = { APPLE_ALG_OID, 3 }, + _oidSha1Fee[] = { APPLE_ALG_OID, 4 }, + _oidEcPrime192v1[] = { OID_EC_CURVE, 1 }, + _oidEcPrime256v1[] = { OID_EC_CURVE, 7 }, + _oidAnsip384r1[] = { OID_CERTICOM_EC_CURVE, 34 }, + _oidAnsip521r1[] = { OID_CERTICOM_EC_CURVE, 35 }; + +const DERItem + oidRsa = { (DERByte *)_oidRsa, + sizeof(_oidRsa) }, + oidMd2Rsa = { (DERByte *)_oidMd2Rsa, + sizeof(_oidMd2Rsa) }, + oidMd4Rsa = { (DERByte *)_oidMd4Rsa, + sizeof(_oidMd4Rsa) }, + oidMd5Rsa = { (DERByte *)_oidMd5Rsa, + sizeof(_oidMd5Rsa) }, + oidSha1Rsa = { (DERByte *)_oidSha1Rsa, + sizeof(_oidSha1Rsa) }, + oidSha256Rsa = { (DERByte *)_oidSha256Rsa, + sizeof(_oidSha256Rsa) }, + oidSha384Rsa = { (DERByte *)_oidSha384Rsa, + sizeof(_oidSha384Rsa) }, + oidSha512Rsa = { (DERByte *)_oidSha512Rsa, + sizeof(_oidSha512Rsa) }, + oidSha224Rsa = { (DERByte *)_oidSha224Rsa, + sizeof(_oidSha224Rsa) }, + oidEcPubKey = { (DERByte *)_oidEcPubKey, + sizeof(_oidEcPubKey) }, + oidSha1Ecdsa = { (DERByte *)_oidSha1Ecdsa, + sizeof(_oidSha1Ecdsa) }, + oidSha224Ecdsa = { (DERByte *)_oidSha224Ecdsa, + sizeof(_oidSha224Ecdsa) }, + oidSha256Ecdsa = { (DERByte *)_oidSha256Ecdsa, + sizeof(_oidSha256Ecdsa) }, + oidSha384Ecdsa = { (DERByte *)_oidSha384Ecdsa, + sizeof(_oidSha384Ecdsa) }, + oidSha512Ecdsa = { (DERByte *)_oidSha512Ecdsa, + sizeof(_oidSha512Ecdsa) }, + oidSha1Dsa = { (DERByte *)_oidSha1Dsa, + sizeof(_oidSha1Dsa) }, + oidMd2 = { (DERByte *)_oidMd2, + sizeof(_oidMd2) }, + oidMd4 = { (DERByte *)_oidMd4, + sizeof(_oidMd4) }, + oidMd5 = { (DERByte *)_oidMd5, + sizeof(_oidMd5) }, + oidSha1 = { (DERByte *)_oidSha1, + sizeof(_oidSha1) }, + oidSha1RsaOIW = { (DERByte *)_oidSha1RsaOIW, + sizeof(_oidSha1RsaOIW) }, + oidSha1DsaOIW = { (DERByte *)_oidSha1DsaOIW, + sizeof(_oidSha1DsaOIW) }, + oidSha1DsaCommonOIW = { (DERByte *)_oidSha1DsaCommonOIW, + sizeof(_oidSha1DsaCommonOIW) }, + oidSha256 = { (DERByte *)_oidSha256, + sizeof(_oidSha256) }, + oidSha384 = { (DERByte *)_oidSha384, + sizeof(_oidSha384) }, + oidSha512 = { (DERByte *)_oidSha512, + sizeof(_oidSha512) }, + oidSha224 = { (DERByte *)_oidSha224, + sizeof(_oidSha224) }, + oidFee = { (DERByte *)_oidFee, + sizeof(_oidFee) }, + oidMd5Fee = { (DERByte *)_oidMd5Fee, + sizeof(_oidMd5Fee) }, + oidSha1Fee = { (DERByte *)_oidSha1Fee, + sizeof(_oidSha1Fee) }, + oidEcPrime192v1 = { (DERByte *)_oidEcPrime192v1, + sizeof(_oidEcPrime192v1) }, + oidEcPrime256v1 = { (DERByte *)_oidEcPrime256v1, + sizeof(_oidEcPrime256v1) }, + oidAnsip384r1 = { (DERByte *)_oidAnsip384r1, + sizeof(_oidAnsip384r1) }, + oidAnsip521r1 = { (DERByte *)_oidAnsip521r1, + sizeof(_oidAnsip521r1) }; + + +/* Extension OIDs. */ +__unused static const DERByte + _oidSubjectKeyIdentifier[] = { OID_EXTENSION, 14 }, + _oidKeyUsage[] = { OID_EXTENSION, 15 }, + _oidPrivateKeyUsagePeriod[] = { OID_EXTENSION, 16 }, + _oidSubjectAltName[] = { OID_EXTENSION, 17 }, + _oidIssuerAltName[] = { OID_EXTENSION, 18 }, + _oidBasicConstraints[] = { OID_EXTENSION, 19 }, + _oidNameConstraints[] = { OID_EXTENSION, 30 }, + _oidCrlDistributionPoints[] = { OID_EXTENSION, 31 }, + _oidCertificatePolicies[] = { OID_EXTENSION, 32 }, + _oidAnyPolicy[] = { OID_EXTENSION, 32, 0 }, + _oidPolicyMappings[] = { OID_EXTENSION, 33 }, + _oidAuthorityKeyIdentifier[] = { OID_EXTENSION, 35 }, + _oidPolicyConstraints[] = { OID_EXTENSION, 36 }, + _oidExtendedKeyUsage[] = { OID_EXTENSION, 37 }, + _oidAnyExtendedKeyUsage[] = { OID_EXTENSION, 37, 0 }, + _oidInhibitAnyPolicy[] = { OID_EXTENSION, 54 }, + _oidAuthorityInfoAccess[] = { OID_PE, 1 }, + _oidSubjectInfoAccess[] = { OID_PE, 11 }, + _oidAdOCSP[] = { OID_AD_OCSP }, + _oidAdCAIssuer[] = { OID_AD_CAISSUERS }, + _oidNetscapeCertType[] = { NETSCAPE_CERT_EXTEN, 1 }, + _oidEntrustVersInfo[] = { ENTRUST_CERT_EXTEN, 0 }, + _oidMSNTPrincipalName[] = { MICROSOFT_ENROLLMENT_OID, 2, 3 }, + /* Policy Qualifier IDs for Internet policy qualifiers. */ + _oidQtCps[] = { OID_QT, 1 }, + _oidQtUNotice[] = { OID_QT, 2 }, + /* X.501 Name IDs. */ + _oidCommonName[] = { OID_ATTR_TYPE, 3 }, + _oidCountryName[] = { OID_ATTR_TYPE, 6 }, + _oidLocalityName[] = { OID_ATTR_TYPE, 7 }, + _oidStateOrProvinceName[] = { OID_ATTR_TYPE, 8 }, + _oidOrganizationName[] = { OID_ATTR_TYPE, 10 }, + _oidOrganizationalUnitName[] = { OID_ATTR_TYPE, 11 }, + _oidDescription[] = { OID_ATTR_TYPE, 13 }, + _oidEmailAddress[] = { OID_PKCS_9, 1 }, + _oidFriendlyName[] = { OID_PKCS_9, 20 }, + _oidLocalKeyId[] = { OID_PKCS_9, 21 }, + _oidExtendedKeyUsageServerAuth[] = { OID_KP, 1 }, + _oidExtendedKeyUsageClientAuth[] = { OID_KP, 2 }, + _oidExtendedKeyUsageCodeSigning[] = { OID_KP, 3 }, + _oidExtendedKeyUsageEmailProtection[] = { OID_KP, 4 }, + _oidExtendedKeyUsageTimeStamping[] = { OID_KP, 8 }, + _oidExtendedKeyUsageOCSPSigning[] = { OID_KP, 9 }, + _oidExtendedKeyUsageIPSec[] = { OID_ISAKMP, 2, 2 }, + _oidExtendedKeyUsageMicrosoftSGC[] = { MICROSOFT_BASE_OID, 10, 3, 3 }, + _oidExtendedKeyUsageNetscapeSGC[] = { NETSCAPE_CERT_POLICY, 1 }, + _oidGoogleEmbeddedSignedCertificateTimestamp[] = {GOOGLE_EMBEDDED_SCT_OID}, + _oidGoogleOCSPSignedCertificateTimestamp[] = {GOOGLE_OCSP_SCT_OID}; + +__unused const DERItem + oidSubjectKeyIdentifier = { (DERByte *)_oidSubjectKeyIdentifier, + sizeof(_oidSubjectKeyIdentifier) }, + oidKeyUsage = { (DERByte *)_oidKeyUsage, + sizeof(_oidKeyUsage) }, + oidPrivateKeyUsagePeriod = { (DERByte *)_oidPrivateKeyUsagePeriod, + sizeof(_oidPrivateKeyUsagePeriod) }, + oidSubjectAltName = { (DERByte *)_oidSubjectAltName, + sizeof(_oidSubjectAltName) }, + oidIssuerAltName = { (DERByte *)_oidIssuerAltName, + sizeof(_oidIssuerAltName) }, + oidBasicConstraints = { (DERByte *)_oidBasicConstraints, + sizeof(_oidBasicConstraints) }, + oidNameConstraints = { (DERByte *)_oidNameConstraints, + sizeof(_oidNameConstraints) }, + oidCrlDistributionPoints = { (DERByte *)_oidCrlDistributionPoints, + sizeof(_oidCrlDistributionPoints) }, + oidCertificatePolicies = { (DERByte *)_oidCertificatePolicies, + sizeof(_oidCertificatePolicies) }, + oidAnyPolicy = { (DERByte *)_oidAnyPolicy, + sizeof(_oidAnyPolicy) }, + oidPolicyMappings = { (DERByte *)_oidPolicyMappings, + sizeof(_oidPolicyMappings) }, + oidAuthorityKeyIdentifier = { (DERByte *)_oidAuthorityKeyIdentifier, + sizeof(_oidAuthorityKeyIdentifier) }, + oidPolicyConstraints = { (DERByte *)_oidPolicyConstraints, + sizeof(_oidPolicyConstraints) }, + oidExtendedKeyUsage = { (DERByte *)_oidExtendedKeyUsage, + sizeof(_oidExtendedKeyUsage) }, + oidAnyExtendedKeyUsage = { (DERByte *)_oidAnyExtendedKeyUsage, + sizeof(_oidAnyExtendedKeyUsage) }, + oidInhibitAnyPolicy = { (DERByte *)_oidInhibitAnyPolicy, + sizeof(_oidInhibitAnyPolicy) }, + oidAuthorityInfoAccess = { (DERByte *)_oidAuthorityInfoAccess, + sizeof(_oidAuthorityInfoAccess) }, + oidSubjectInfoAccess = { (DERByte *)_oidSubjectInfoAccess, + sizeof(_oidSubjectInfoAccess) }, + oidAdOCSP = { (DERByte *)_oidAdOCSP, + sizeof(_oidAdOCSP) }, + oidAdCAIssuer = { (DERByte *)_oidAdCAIssuer, + sizeof(_oidAdCAIssuer) }, + oidNetscapeCertType = { (DERByte *)_oidNetscapeCertType, + sizeof(_oidNetscapeCertType) }, + oidEntrustVersInfo = { (DERByte *)_oidEntrustVersInfo, + sizeof(_oidEntrustVersInfo) }, + oidMSNTPrincipalName = { (DERByte *)_oidMSNTPrincipalName, + sizeof(_oidMSNTPrincipalName) }, + /* Policy Qualifier IDs for Internet policy qualifiers. */ + oidQtCps = { (DERByte *)_oidQtCps, + sizeof(_oidQtCps) }, + oidQtUNotice = { (DERByte *)_oidQtUNotice, + sizeof(_oidQtUNotice) }, + /* X.501 Name IDs. */ + oidCommonName = { (DERByte *)_oidCommonName, + sizeof(_oidCommonName) }, + oidCountryName = { (DERByte *)_oidCountryName, + sizeof(_oidCountryName) }, + oidLocalityName = { (DERByte *)_oidLocalityName, + sizeof(_oidLocalityName) }, + oidStateOrProvinceName = { (DERByte *)_oidStateOrProvinceName, + sizeof(_oidStateOrProvinceName) }, + oidOrganizationName = { (DERByte *)_oidOrganizationName, + sizeof(_oidOrganizationName) }, + oidOrganizationalUnitName = { (DERByte *)_oidOrganizationalUnitName, + sizeof(_oidOrganizationalUnitName) }, + oidDescription = { (DERByte *)_oidDescription, + sizeof(_oidDescription) }, + oidEmailAddress = { (DERByte *)_oidEmailAddress, + sizeof(_oidEmailAddress) }, + oidFriendlyName = { (DERByte *)_oidFriendlyName, + sizeof(_oidFriendlyName) }, + oidLocalKeyId = { (DERByte *)_oidLocalKeyId, + sizeof(_oidLocalKeyId) }, + oidExtendedKeyUsageServerAuth = { (DERByte *)_oidExtendedKeyUsageServerAuth, + sizeof(_oidExtendedKeyUsageServerAuth) }, + oidExtendedKeyUsageClientAuth = { (DERByte *)_oidExtendedKeyUsageClientAuth, + sizeof(_oidExtendedKeyUsageClientAuth) }, + oidExtendedKeyUsageCodeSigning = { (DERByte *)_oidExtendedKeyUsageCodeSigning, + sizeof(_oidExtendedKeyUsageCodeSigning) }, + oidExtendedKeyUsageEmailProtection = { (DERByte *)_oidExtendedKeyUsageEmailProtection, + sizeof(_oidExtendedKeyUsageEmailProtection) }, + oidExtendedKeyUsageTimeStamping = { (DERByte *)_oidExtendedKeyUsageTimeStamping, + sizeof(_oidExtendedKeyUsageTimeStamping) }, + oidExtendedKeyUsageOCSPSigning = { (DERByte *)_oidExtendedKeyUsageOCSPSigning, + sizeof(_oidExtendedKeyUsageOCSPSigning) }, + oidExtendedKeyUsageIPSec = { (DERByte *)_oidExtendedKeyUsageIPSec, + sizeof(_oidExtendedKeyUsageIPSec) }, + oidExtendedKeyUsageMicrosoftSGC = { (DERByte *)_oidExtendedKeyUsageMicrosoftSGC, + sizeof(_oidExtendedKeyUsageMicrosoftSGC) }, + oidExtendedKeyUsageNetscapeSGC = { (DERByte *)_oidExtendedKeyUsageNetscapeSGC, + sizeof(_oidExtendedKeyUsageNetscapeSGC) }, + oidGoogleEmbeddedSignedCertificateTimestamp + = { (DERByte *)_oidGoogleEmbeddedSignedCertificateTimestamp, + sizeof(_oidGoogleEmbeddedSignedCertificateTimestamp) }, + oidGoogleOCSPSignedCertificateTimestamp + = { (DERByte *)_oidGoogleOCSPSignedCertificateTimestamp, + sizeof(_oidGoogleOCSPSignedCertificateTimestamp) }; + + + diff --git a/OSX/sec/Security/p12import.c b/OSX/sec/Security/p12import.c index 9afaf3b8..e4c0e36a 100644 --- a/OSX/sec/Security/p12import.c +++ b/OSX/sec/Security/p12import.c @@ -21,7 +21,7 @@ * @APPLE_LICENSE_HEADER_END@ */ -#include +#include #include #include #include diff --git a/OSX/sec/Security/so_01_serverencryption.c b/OSX/sec/Security/so_01_serverencryption.c index fb637de8..2f928996 100644 --- a/OSX/sec/Security/so_01_serverencryption.c +++ b/OSX/sec/Security/so_01_serverencryption.c @@ -124,6 +124,7 @@ static void tests(void) ok(CFEqualSafe(testData, decrypted), "round trip"); + CFReleaseNull(full_key); CFReleaseNull(cert); CFReleaseNull(certInArray); CFReleaseNull(trust); diff --git a/OSX/sec/SecurityTool/KeychainCheck.h b/OSX/sec/SecurityTool/KeychainCheck.h new file mode 100644 index 00000000..746832ae --- /dev/null +++ b/OSX/sec/SecurityTool/KeychainCheck.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + * + */ + +#import + +@interface KeychainCheck : NSObject + +@end diff --git a/OSX/sec/SecurityTool/KeychainCheck.m b/OSX/sec/SecurityTool/KeychainCheck.m new file mode 100644 index 00000000..3786207d --- /dev/null +++ b/OSX/sec/SecurityTool/KeychainCheck.m @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + * + */ + +#import "KeychainCheck.h" +#import "SFKeychainControl.h" +#import "builtin_commands.h" +#import "SOSControlHelper.h" +#import "SOSTypes.h" +#import "CKKSControlProtocol.h" +#import +#import + +@interface KeychainCheck () + +- (void)checkKeychain; +- (void)cleanKeychain; + +@end + +@implementation KeychainCheck { + NSXPCConnection* _connection; +} + +- (instancetype)initWithEndpoint:(xpc_endpoint_t)endpoint +{ + if (self = [super init]) { + NSXPCListenerEndpoint* listenerEndpoint = [[NSXPCListenerEndpoint alloc] init]; + [listenerEndpoint _setEndpoint:endpoint]; + _connection = [[NSXPCConnection alloc] initWithListenerEndpoint:listenerEndpoint]; + if (!_connection) { + return nil; + } + + NSXPCInterface* interface = [NSXPCInterface interfaceWithProtocol:@protocol(SFKeychainControl)]; + _connection.remoteObjectInterface = interface; + [_connection resume]; + } + + return self; +} + +- (void)checkKeychain +{ + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + [[_connection remoteObjectProxyWithErrorHandler:^(NSError* error) { + NSLog(@"failed to communicate with server with error: %@", error); + dispatch_semaphore_signal(semaphore); + }] rpcFindCorruptedItemsWithReply:^(NSArray* corruptedItems, NSError* error) { + if (error) { + NSLog(@"error searching keychain: %@", error.localizedDescription); + } + + if (corruptedItems.count > 0) { + NSLog(@"found %d corrupted items", (int)corruptedItems.count); + } + else { + NSLog(@"no corrupted items found"); + } + + dispatch_semaphore_signal(semaphore); + }]; + + if (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)) { + NSLog(@"timed out trying to communicate with server"); + } +} + +- (void)cleanKeychain +{ + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + [[_connection remoteObjectProxyWithErrorHandler:^(NSError* error) { + NSLog(@"failed to communicate with server with error: %@", error); + dispatch_semaphore_signal(semaphore); + }] rpcDeleteCorruptedItemsWithReply:^(bool success, NSError* error) { + if (success) { + NSLog(@"successfully cleaned keychain"); + } + else { + NSLog(@"error attempting to clean keychain: %@", error); + } + + dispatch_semaphore_signal(semaphore); + }]; + + if (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)) { + NSLog(@"timed out trying to communicate with server"); + } +} + +@end + +int command_keychain_check(int argc, char* const* argv) +{ + KeychainCheck* keychainCheck = [[KeychainCheck alloc] initWithEndpoint:_SecSecuritydCopyKeychainControlEndpoint(NULL)]; + [keychainCheck checkKeychain]; + return 0; +} + +int command_keychain_cleanup(int argc, char* const* argv) +{ + KeychainCheck* keychainCheck = [[KeychainCheck alloc] initWithEndpoint:_SecSecuritydCopyKeychainControlEndpoint(NULL)]; + [keychainCheck cleanKeychain]; + return 0; +} diff --git a/OSX/sec/SecurityTool/SecurityTool.c b/OSX/sec/SecurityTool/SecurityTool.c index c5cb9750..571a34f9 100644 --- a/OSX/sec/SecurityTool/SecurityTool.c +++ b/OSX/sec/SecurityTool/SecurityTool.c @@ -27,6 +27,7 @@ #include "SecInternalReleasePriv.h" #include +#include "SecurityTool/security_tool_commands.h" #include "leaks.h" @@ -228,7 +229,7 @@ usage(void) " -v Be more verbose about what's going on.\n" "%s commands are:\n", getprogname(), getprogname()); help(0, NULL); - return 2; + return SHOW_USAGE_MESSAGE; } /* Execute a single command. */ diff --git a/OSX/sec/SecurityTool/builtin_commands.h b/OSX/sec/SecurityTool/builtin_commands.h index 4e6415c5..e09dfa8b 100644 --- a/OSX/sec/SecurityTool/builtin_commands.h +++ b/OSX/sec/SecurityTool/builtin_commands.h @@ -60,3 +60,11 @@ SECURITY_COMMAND("watchdog", command_watchdog, " check-period \n" " graceful-exit-time \n", "Show current watchdog parameters or set an individual parameter") + +SECURITY_COMMAND("keychain-check", command_keychain_check, + "", + "check the status of your keychain to determine if there are any items we can't decrypt") + +SECURITY_COMMAND("keychain-cleanup", command_keychain_cleanup, + "", + "attempt to remove keychain items we can no longer decrypt") diff --git a/OSX/sec/SecurityTool/digest_calc.c b/OSX/sec/SecurityTool/digest_calc.c index ed682a22..09bb7af0 100644 --- a/OSX/sec/SecurityTool/digest_calc.c +++ b/OSX/sec/SecurityTool/digest_calc.c @@ -45,7 +45,7 @@ extern int command_digest(int argc, char * const *argv) char data [getpagesize()]; if (argc < 3) - return 2; /* Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; if (strcasecmp("sha1", argv[1]) == 0) { @@ -64,7 +64,7 @@ extern int command_digest(int argc, char * const *argv) } else - return 2; /* Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; ccdigest_di_decl(di, ctx); ccdigest_init(di, ctx); diff --git a/OSX/sec/SecurityTool/entitlements.plist b/OSX/sec/SecurityTool/entitlements.plist index f54560d2..ab650a4a 100644 --- a/OSX/sec/SecurityTool/entitlements.plist +++ b/OSX/sec/SecurityTool/entitlements.plist @@ -15,5 +15,7 @@ application-identifier com.apple.security + com.apple.private.keychain.keychaincontrol + diff --git a/OSX/sec/SecurityTool/sos.m b/OSX/sec/SecurityTool/sos.m index a57ad86c..33558c8b 100644 --- a/OSX/sec/SecurityTool/sos.m +++ b/OSX/sec/SecurityTool/sos.m @@ -34,6 +34,7 @@ #import #import #import +#import #import #import @@ -48,18 +49,15 @@ @implementation SOSStatus -- (instancetype) initWithEndpoint:(xpc_endpoint_t)endpoint +- (instancetype) init { if ((self = [super init]) == NULL) return NULL; NSXPCInterface *interface = [NSXPCInterface interfaceWithProtocol:@protocol(SOSControlProtocol)]; _SOSControlSetupInterface(interface); - NSXPCListenerEndpoint *listenerEndpoint = [[NSXPCListenerEndpoint alloc] init]; - [listenerEndpoint _setEndpoint:endpoint]; - - self.connection = [[NSXPCConnection alloc] initWithListenerEndpoint:listenerEndpoint]; + self.connection = [[NSXPCConnection alloc] initWithMachServiceName:@(kSecuritydSOSServiceName) options:0]; if (self.connection == NULL) return NULL; @@ -146,11 +144,7 @@ command_sos_stats(__unused int argc, __unused char * const * argv) @autoreleasepool { int option_index = 0, ch; - xpc_endpoint_t endpoint = _SecSecuritydCopySOSStatusEndpoint(NULL); - if (endpoint == NULL) - errx(1, "no SOS endpoint"); - - SOSStatus *control = [[SOSStatus alloc] initWithEndpoint:endpoint]; + SOSStatus *control = [[SOSStatus alloc] init]; bool asPlist = false; struct option long_options[] = @@ -170,7 +164,7 @@ command_sos_stats(__unused int argc, __unused char * const * argv) default: { usage("sos-stats", long_options); - return 2; + return SHOW_USAGE_MESSAGE; } } } @@ -216,16 +210,12 @@ command_sos_control(__unused int argc, __unused char * const * argv) default: { usage("sos-control", long_options); - return 2; + return SHOW_USAGE_MESSAGE; } } } - xpc_endpoint_t endpoint = _SecSecuritydCopySOSStatusEndpoint(NULL); - if (endpoint == NULL) - errx(1, "no SOS endpoint"); - - SOSStatus *control = [[SOSStatus alloc] initWithEndpoint:endpoint]; + SOSStatus *control = [[SOSStatus alloc] init]; if (control == NULL) errx(1, "no SOS control object"); @@ -294,13 +284,7 @@ command_sos_control(__unused int argc, __unused char * const * argv) int command_watchdog(int argc, char* const * argv) { - xpc_endpoint_t endpoint = _SecSecuritydCopySOSStatusEndpoint(NULL); - if (!endpoint) { - errx(1, "no SOS endpoint"); - return 0; - } - - SOSStatus* control = [[SOSStatus alloc] initWithEndpoint:endpoint]; + SOSStatus* control = [[SOSStatus alloc] init]; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); if (argc < 3) { diff --git a/OSX/sec/SharedWebCredential/swcagent.m b/OSX/sec/SharedWebCredential/swcagent.m index 3466a748..a4cad0c8 100644 --- a/OSX/sec/SharedWebCredential/swcagent.m +++ b/OSX/sec/SharedWebCredential/swcagent.m @@ -47,7 +47,7 @@ #include #endif -#if TARGET_OS_IPHONE && !TARGET_OS_NANO +#if TARGET_OS_IPHONE && !TARGET_OS_WATCH #include #include @@ -270,7 +270,7 @@ static CFStringRef SWCAGetOperationDescription(enum SWCAXPCOperation op) } } -#if !TARGET_IPHONE_SIMULATOR && TARGET_OS_IPHONE && !TARGET_OS_NANO +#if !TARGET_IPHONE_SIMULATOR && TARGET_OS_IPHONE && !TARGET_OS_WATCH static dispatch_once_t sWBUInitializeOnce = 0; static void * sWBULibrary = NULL; static WBUAutoFillGetEnabledDataClasses_f sWBUAutoFillGetEnabledDataClasses_f = NULL; @@ -301,7 +301,7 @@ static bool SWCAIsAutofillEnabled(void) #if TARGET_IPHONE_SIMULATOR // Assume the setting's on in the simulator: WBUAutoFillGetEnabledDataClasses call failing in the Simulator return true; -#elif TARGET_OS_IPHONE && !TARGET_OS_NANO +#elif TARGET_OS_IPHONE && !TARGET_OS_WATCH OSStatus status = _SecWBUEnsuredInitialized(); if (status) { return false; } WBSAutoFillDataClasses autofill = sWBUAutoFillGetEnabledDataClasses_f(); diff --git a/OSX/sec/ipc/client.c b/OSX/sec/ipc/client.c index 58272aa6..b3f158cc 100644 --- a/OSX/sec/ipc/client.c +++ b/OSX/sec/ipc/client.c @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include #include @@ -101,7 +103,7 @@ SecSecurityClientGet(void) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - gClient.task = NULL, + gClient.task = NULL; gClient.accessGroups = SecServerCopyAccessGroups(); gClient.allowSystemKeychain = true; gClient.allowSyncBubbleKeychain = true; @@ -150,6 +152,15 @@ static const char *securityd_service_name(void) { return kSecuritydXPCServiceName; } +static uid_t target_uid = -1; + +void +_SecSetSecuritydTargetUID(uid_t uid) +{ + target_uid = uid; +} + + static xpc_connection_t securityd_create_connection(const char *name, uint64_t flags) { const char *serviceName = name; if (!serviceName) { @@ -161,6 +172,9 @@ static xpc_connection_t securityd_create_connection(const char *name, uint64_t f const char *description = xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION); secnotice("xpc", "got event: %s", description); }); + if (target_uid != (uid_t)-1) { + xpc_connection_set_target_uid(connection, target_uid); + } xpc_connection_resume(connection); return connection; } @@ -196,21 +210,23 @@ static xpc_connection_t trustd_connection(void) { } static bool is_trust_operation(enum SecXPCOperation op) { - switch (op) { - case sec_trust_store_contains_id: - case sec_trust_store_set_trust_settings_id: - case sec_trust_store_remove_certificate_id: - case sec_trust_evaluate_id: - case sec_trust_store_copy_all_id: - case sec_trust_store_copy_usage_constraints_id: - case sec_ota_pki_asset_version_id: + switch (op) { + case sec_trust_store_contains_id: + case sec_trust_store_set_trust_settings_id: + case sec_trust_store_remove_certificate_id: + case sec_trust_evaluate_id: + case sec_trust_store_copy_all_id: + case sec_trust_store_copy_usage_constraints_id: + case sec_ocsp_cache_flush_id: + case sec_ota_pki_trust_store_version_id: case kSecXPCOpOTAGetEscrowCertificates: case kSecXPCOpOTAPKIGetNewAsset: - return true; - default: - break; - } - return false; + case kSecXPCOpTLSAnaltyicsReport: + return true; + default: + break; + } + return false; } static xpc_connection_t securityd_connection_for_operation(enum SecXPCOperation op) { @@ -310,7 +326,9 @@ bool securityd_message_no_error(xpc_object_t message, CFErrorRef *error) { #if TARGET_OS_IPHONE secdebug("xpc", "Talking to securityd failed with error: %@", localError); #else +#if !defined(NDEBUG) uint64_t operation = xpc_dictionary_get_uint64(message, kSecXPCKeyOperation); +#endif secdebug("xpc", "Talking to %s failed with error: %@", (is_trust_operation((enum SecXPCOperation)operation)) ? "trustd" : "secd", localError); #endif @@ -325,7 +343,7 @@ bool securityd_message_no_error(xpc_object_t message, CFErrorRef *error) { bool securityd_send_sync_and_do(enum SecXPCOperation op, CFErrorRef *error, bool (^add_to_message)(xpc_object_t message, CFErrorRef* error), - bool (^handle_response)(xpc_object_t response, CFErrorRef* error)) { + bool (^handle_response)(xpc_object_t _Nonnull response, CFErrorRef* error)) { xpc_object_t message = securityd_create_message(op, error); bool ok = false; if (message) { @@ -461,16 +479,11 @@ _SecSecuritydCopyEndpoint(enum SecXPCOperation op, CFErrorRef *error) XPC_RETURNS_RETAINED xpc_endpoint_t _SecSecuritydCopyCKKSEndpoint(CFErrorRef *error) { - return _SecSecuritydCopyEndpoint(kSecXPCOpCKKSEndpoint, error); + return NULL; } XPC_RETURNS_RETAINED xpc_endpoint_t -_SecSecuritydCopySOSStatusEndpoint(CFErrorRef *error) +_SecSecuritydCopyKeychainControlEndpoint(CFErrorRef* error) { - return _SecSecuritydCopyEndpoint(kSecXPCOpSOSEndpoint, error); + return _SecSecuritydCopyEndpoint(kSecXPCOpKeychainControlEndpoint, error); } - - - - -/* vi:set ts=4 sw=4 et: */ diff --git a/OSX/sec/ipc/client_endpoint.m b/OSX/sec/ipc/client_endpoint.m index a846d682..b9957cc7 100644 --- a/OSX/sec/ipc/client_endpoint.m +++ b/OSX/sec/ipc/client_endpoint.m @@ -32,21 +32,20 @@ @implementation SecuritydXPCClient @synthesize connection = _connection; -- (instancetype) initWithEndpoint:(xpc_endpoint_t)endpoint +- (instancetype) init { if ((self = [super init])) { NSXPCInterface *interface = [NSXPCInterface interfaceWithProtocol:@protocol(SecuritydXPCProtocol)]; - NSXPCListenerEndpoint *listenerEndpoint = [[NSXPCListenerEndpoint alloc] init]; - [listenerEndpoint _setEndpoint:endpoint]; - - self.connection = [[NSXPCConnection alloc] initWithListenerEndpoint:listenerEndpoint]; + self.connection = [[NSXPCConnection alloc] initWithMachServiceName:@(kSecuritydGeneralServiceName) options:0]; if (self.connection == NULL) { return NULL; } self.connection.remoteObjectInterface = interface; [SecuritydXPCClient configureSecuritydXPCProtocol: self.connection.remoteObjectInterface]; + + [self.connection resume]; } return self; @@ -148,40 +147,16 @@ id SecuritydXPCProxyObject(void (^rpcErrorHandler)(NSError static SecuritydXPCClient* rpc; static dispatch_once_t onceToken; - static CFErrorRef cferror = NULL; - static dispatch_queue_t queue; - __block SecuritydXPCClient *result = nil; dispatch_once(&onceToken, ^{ - queue = dispatch_queue_create("SecuritydXPCProxyObject", DISPATCH_QUEUE_SERIAL); - }); - - dispatch_sync(queue, ^{ - if (rpc) { - result = rpc; - return; - } - - xpc_endpoint_t endpoint = _SecSecuritydCopyEndpoint(kSecXPCOpSecuritydXPCServerEndpoint, &cferror); - if (endpoint == NULL) { - return; - } - rpc = [[SecuritydXPCClient alloc] initWithEndpoint:endpoint]; - rpc.connection.invalidationHandler = ^{ - dispatch_sync(queue, ^{ - rpc = nil; - }); - }; - [rpc.connection resume]; - - result = rpc; + rpc = [[SecuritydXPCClient alloc] init]; }); - if (result == NULL) { - rpcErrorHandler((__bridge NSError *)cferror); + if (rpc == NULL) { + rpcErrorHandler([NSError errorWithDomain:@"securityd" code:-1 userInfo:@{ NSLocalizedDescriptionKey : @"Could not create SecuritydXPCClient" }]); return NULL; } else { - return [result.connection remoteObjectProxyWithErrorHandler: rpcErrorHandler]; + return [rpc.connection remoteObjectProxyWithErrorHandler: rpcErrorHandler]; } } diff --git a/OSX/sec/ipc/com.apple.secd.plist b/OSX/sec/ipc/com.apple.secd.plist index 2837c47d..c3470d0f 100644 --- a/OSX/sec/ipc/com.apple.secd.plist +++ b/OSX/sec/ipc/com.apple.secd.plist @@ -14,12 +14,20 @@ com.apple.secd MachServices + com.apple.security.octagon + com.apple.secd com.apple.securityd.xpc com.apple.securityd.aps + com.apple.securityd.ckks + + com.apple.securityd.general + + com.apple.securityd.sos + ProgramArguments diff --git a/OSX/sec/ipc/com.apple.securityd.plist b/OSX/sec/ipc/com.apple.securityd.plist index 4cc3c7ce..5de57431 100644 --- a/OSX/sec/ipc/com.apple.securityd.plist +++ b/OSX/sec/ipc/com.apple.securityd.plist @@ -19,10 +19,18 @@ com.apple.securityd MachServices + com.apple.security.octagon + com.apple.securityd com.apple.securityd.aps + com.apple.securityd.ckks + + com.apple.securityd.general + + com.apple.securityd.sos + ProgramArguments diff --git a/OSX/sec/ipc/securityd_client.h b/OSX/sec/ipc/securityd_client.h index 15f45496..4ed50430 100644 --- a/OSX/sec/ipc/securityd_client.h +++ b/OSX/sec/ipc/securityd_client.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2009,2012-2015 Apple Inc. All Rights Reserved. + * Copyright (c) 2007-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -31,15 +31,11 @@ #include #ifndef MINIMIZE_INCLUDES # include -# include #else typedef struct __SecTrustStore *SecTrustStoreRef; # ifndef _SECURITY_SECCERTIFICATE_H_ typedef struct __SecCertificate *SecCertificateRef; # endif // _SECURITY_SECCERTIFICATE_H_ -# ifndef _SECURITY_SECCERTIFICATEPATH_H_ -typedef struct SecCertificatePath *SecCertificatePathRef; -# endif // _SECURITY_SECCERTIFICATEPATH_H_ #endif // MINIMIZE_INCLUDES #if TARGET_HAS_KEYSTORE @@ -70,6 +66,9 @@ typedef struct SecCertificatePath *SecCertificatePathRef; #define kTrustdXPCServiceName "com.apple.trustd" #endif // *** END TARGET_OS_OSX *** +#define kSecuritydGeneralServiceName "com.apple.securityd.general" +#define kSecuritydSOSServiceName "com.apple.securityd.sos" + // // MARK: XPC Information. // @@ -85,6 +84,7 @@ extern const char *kSecXPCKeyUserLabel; extern const char *kSecXPCKeyBackup; extern const char *kSecXPCKeyKeybag; extern const char *kSecXPCKeyUserPassword; +extern const char *kSecXPCKeyEMCSBackup; extern const char *kSecXPCKeyDSID; extern const char *kSecXPCKeyViewName; extern const char *kSecXPCKeyViewActionCode; @@ -180,11 +180,11 @@ enum SecXPCOperation { sec_item_backup_set_confirmed_manifest_id, sec_item_backup_restore_id, sec_keychain_sync_update_message_id, - sec_ota_pki_asset_version_id, + sec_ota_pki_trust_store_version_id, sec_otr_session_create_remote_id, sec_otr_session_process_packet_remote_id, - kSecXPCOpOTAPKIGetNewAsset, - kSecXPCOpOTAGetEscrowCertificates, + kSecXPCOpOTAPKIGetNewAsset, + kSecXPCOpOTAGetEscrowCertificates, kSecXPCOpProcessUnlockNotification, kSecXPCOpProcessSyncWithAllPeers, kSecXPCOpRollKeys, @@ -243,7 +243,7 @@ enum SecXPCOperation { kSecXPCOpCopyViewUnawarePeerInfo, kSecXPCOpCopyEngineState, kSecXPCOpCopyMyPeerInfo, - kSecXPCOpAccountSetToNew, + kSecXPCOpAccountSetToNew, kSecXPCOpSetNewPublicBackupKey, kSecXPCOpSetBagForAllSlices, kSecXPCOpWaitForInitialSync, @@ -276,6 +276,7 @@ enum SecXPCOperation { kSecXPCOpDeleteUserView, sec_trust_store_copy_all_id, sec_trust_store_copy_usage_constraints_id, + sec_ocsp_cache_flush_id, sec_delete_items_with_access_groups_id, kSecXPCOpIsThisDeviceLastBackup, sec_keychain_backup_keybag_uuid_id, @@ -285,11 +286,10 @@ enum SecXPCOperation { kSecXPCOpSendToPeerIsPending, sec_item_copy_parent_certificates_id, sec_item_certificate_exists_id, - kSecXPCOpCKKSEndpoint, - kSecXPCOpSOSEndpoint, - kSecXPCOpSecuritydXPCServerEndpoint, kSecXPCOpBackupKeybagAdd, kSecXPCOpBackupKeybagDelete, + kSecXPCOpKeychainControlEndpoint, + kSecXPCOpTLSAnaltyicsReport, }; @@ -327,7 +327,7 @@ struct securityd { bool (*sec_item_delete_all)(CFErrorRef* error); CFArrayRef (*sec_item_copy_parent_certificates)(CFDataRef normalizedIssuer, CFArrayRef accessGroups, CFErrorRef *error); bool (*sec_item_certificate_exists)(CFDataRef normalizedIssuer, CFDataRef serialNumber, CFArrayRef accessGroups, CFErrorRef *error); - CFDataRef (*sec_keychain_backup)(SecurityClient *client, CFDataRef keybag, CFDataRef passcode, CFErrorRef* error); + CFDataRef (*sec_keychain_backup)(SecurityClient *client, CFDataRef keybag, CFDataRef passcode, bool emcs, CFErrorRef* error); bool (*sec_keychain_restore)(CFDataRef backup, SecurityClient *client, CFDataRef keybag, CFDataRef passcode, CFErrorRef* error); CFDictionaryRef (*sec_keychain_backup_syncable)(CFDictionaryRef backup_in, CFDataRef keybag, CFDataRef passcode, CFErrorRef* error); bool (*sec_keychain_restore_syncable)(CFDictionaryRef backup, CFDataRef keybag, CFDataRef passcode, CFErrorRef* error); @@ -337,7 +337,7 @@ struct securityd { bool (*sec_item_backup_restore)(CFStringRef backupName, CFStringRef peerID, CFDataRef keybag, CFDataRef secret, CFDataRef backup, CFErrorRef *error); CFDataRef (*sec_otr_session_create_remote)(CFDataRef publicPeerId, CFErrorRef* error); bool (*sec_otr_session_process_packet_remote)(CFDataRef sessionData, CFDataRef inputPacket, CFDataRef* outputSessionData, CFDataRef* outputPacket, bool *readyForMessages, CFErrorRef* error); - bool (*soscc_TryUserCredentials)(CFStringRef user_label, CFDataRef user_password, CFErrorRef *error); + bool (*soscc_TryUserCredentials)(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error); bool (*soscc_SetUserCredentials)(CFStringRef user_label, CFDataRef user_password, CFErrorRef *error); bool (*soscc_SetUserCredentialsAndDSID)(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error); bool (*soscc_CanAuthenticate)(CFErrorRef *error); @@ -437,12 +437,14 @@ struct trustd { bool (*sec_trust_store_set_trust_settings)(SecTrustStoreRef ts, SecCertificateRef certificate, CFTypeRef trustSettingsDictOrArray, CFErrorRef* error); bool (*sec_trust_store_remove_certificate)(SecTrustStoreRef ts, CFDataRef digest, CFErrorRef* error); bool (*sec_truststore_remove_all)(SecTrustStoreRef ts, CFErrorRef* error); - SecTrustResultType (*sec_trust_evaluate)(CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, bool keychainsAllowed, CFArrayRef policies, CFArrayRef responses, CFArrayRef SCTs, CFArrayRef trustedLogs, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, CFArrayRef exceptions, CFArrayRef *details, CFDictionaryRef *info, SecCertificatePathRef *chain, CFErrorRef *error); - int (*sec_ota_pki_asset_version)(CFErrorRef* error); + SecTrustResultType (*sec_trust_evaluate)(CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, bool keychainsAllowed, CFArrayRef policies, CFArrayRef responses, CFArrayRef SCTs, CFArrayRef trustedLogs, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, CFArrayRef exceptions, CFArrayRef *details, CFDictionaryRef *info, CFArrayRef *chain, CFErrorRef *error); + uint64_t (*sec_ota_pki_trust_store_version)(CFErrorRef* error); CFArrayRef (*ota_CopyEscrowCertificates)(uint32_t escrowRootType, CFErrorRef* error); - int (*sec_ota_pki_get_new_asset)(CFErrorRef* error); + uint64_t (*sec_ota_pki_get_new_asset)(CFErrorRef* error); bool (*sec_trust_store_copy_all)(SecTrustStoreRef ts, CFArrayRef *trustStoreContents, CFErrorRef *error); bool (*sec_trust_store_copy_usage_constraints)(SecTrustStoreRef ts, CFDataRef digest, CFArrayRef *usageConstraints, CFErrorRef *error); + bool (*sec_ocsp_cache_flush)(CFErrorRef *error); + bool (*sec_tls_analytics_report)(CFStringRef event_name, xpc_object_t tls_analytics_attributes, CFErrorRef *error); }; extern struct trustd *gTrustd; @@ -470,11 +472,11 @@ XPC_RETURNS_RETAINED xpc_endpoint_t _SecSecuritydCopyEndpoint(enum SecXPCOperati #import typedef void (^SecBoolNSErrorCallback) (bool, NSError*); -@protocol SecuritydXPCCallbackProtocol +@protocol SecuritydXPCCallbackProtocol - (void)callCallback: (bool) result error:(NSError*) error; @end -@protocol SecuritydXPCProtocol +@protocol SecuritydXPCProtocol - (void) SecItemAddAndNotifyOnSync:(NSDictionary*) attributes syncCallback:(id) callback complete:(void (^) (NSDictionary* opDictResult, NSArray* opArrayResult, NSError* operror)) complete; diff --git a/OSX/sec/ipc/server.c b/OSX/sec/ipc/server.c index 9e6a40aa..aa203e73 100644 --- a/OSX/sec/ipc/server.c +++ b/OSX/sec/ipc/server.c @@ -26,13 +26,14 @@ #include #include #include +#include #include #include #include #include #include #include -#include /* For SecItemDeleteAll */ +#include #include #include #include @@ -59,8 +60,11 @@ #include #include #include +#include #include +#include +#include "keychain/ot/OctagonControlServer.h" #include #include @@ -478,15 +482,30 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, break; } case sec_delete_all_id: - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, _SecItemDeleteAll(&error)); + { + bool retval = false; +#if TARGET_OS_IPHONE + /* buddy is temporary allowed to do this */ + CFStringRef applicationIdentifier = SecTaskCopyApplicationIdentifier(client.task); + bool isBuddy = applicationIdentifier && + CFEqual(applicationIdentifier, CFSTR("com.apple.purplebuddy")); + + if (isBuddy || EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateDeleteAll, &error)) + { + retval = _SecItemDeleteAll(&error); + } +#endif + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, retval); break; + } case sec_keychain_backup_id: { if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) { CFDataRef keybag = NULL, passcode = NULL; if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyKeybag, &keybag, &error)) { if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyUserPassword, &passcode, &error)) { - CFDataRef backup = _SecServerKeychainCreateBackup(&client, keybag, passcode, &error); + bool emcs = SecXPCDictionaryGetBool(event, kSecXPCKeyEMCSBackup, NULL); + CFDataRef backup = _SecServerKeychainCreateBackup(&client, keybag, passcode, emcs, &error); if (backup) { int fd = SecXPCDictionaryDupFileDescriptor(event, kSecXPCKeyFileDescriptor, NULL); if (fd < 0) { @@ -801,9 +820,9 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } case kSecXPCOpTryUserCredentials: if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { - with_label_and_password(event, ^(CFStringRef label, CFDataRef password) { + with_label_and_password_and_dsid(event, ^(CFStringRef label, CFDataRef password, CFStringRef dsid) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, - SOSCCTryUserCredentials_Server(label, password, &error)); + SOSCCTryUserCredentials_Server(label, password, dsid, &error)); }); } break; @@ -974,6 +993,7 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, CFStringRef peerID = SecXPCDictionaryCopyString(event, kSecXPCKeyDeviceID, &error); CFDataRef message = SecXPCDictionaryCopyData(event, kSecXPCKeyIDSMessage, &error); xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRequestSyncWithPeerOverKVS_Server(peerID, message, &error)); + CFReleaseNull(message); CFReleaseNull(peerID); } break; @@ -1373,7 +1393,7 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, CFArrayRef viewSet = SecXPCDictionaryCopyArray(event, kSecXPCKeyArray, &error); if (viewSet) { CFBooleanRef result = SOSCCPeersHaveViewsEnabled_Server(viewSet, &error); - if (result) { + if (result != NULL) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result != kCFBooleanFalse); } } @@ -1595,43 +1615,6 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result); } break; - case kSecXPCOpCKKSEndpoint: { - if(EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateCKKS, &error)) { - xpc_endpoint_t endpoint = SecServerCreateCKKSEndpoint(); - if (endpoint) { - xpc_dictionary_set_value(replyMessage, kSecXPCKeyEndpoint, endpoint); - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, true); - xpc_release(endpoint); - } else { - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false); - } - } - break; - } - case kSecXPCOpSOSEndpoint: { - if(EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { - xpc_endpoint_t endpoint = SOSCCCreateSOSEndpoint_server(&error); - if (endpoint) { - xpc_dictionary_set_value(replyMessage, kSecXPCKeyEndpoint, endpoint); - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, true); - xpc_release(endpoint); - } else { - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false); - } - } - break; - } - case kSecXPCOpSecuritydXPCServerEndpoint: { - xpc_endpoint_t endpoint = SecCreateSecuritydXPCServerEndpoint(&error); - if (endpoint) { - xpc_dictionary_set_value(replyMessage, kSecXPCKeyEndpoint, endpoint); - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, true); - xpc_release(endpoint); - } else { - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false); - } - break; - } case kSecXPCOpBackupKeybagAdd: { if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementBackupTableOperations, &error)) { CFDataRef keybag = NULL, passcode = NULL; @@ -1676,7 +1659,6 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } deleted = _SecServerBackupKeybagDelete(attributes, deleteAll, &error); } - CFReleaseNull(resolvedAgrp); CFReleaseNull(attributes); } } @@ -1685,6 +1667,19 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; } + case kSecXPCOpKeychainControlEndpoint: { + if(EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainControl, &error)) { + xpc_endpoint_t endpoint = SecServerCreateKeychainControlEndpoint(); + if (endpoint) { + xpc_dictionary_set_value(replyMessage, kSecXPCKeyEndpoint, endpoint); + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, true); + xpc_release(endpoint); + } else { + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false); + } + } + break; + } default: break; } @@ -1887,6 +1882,11 @@ int main(int argc, char *argv[]) securityd_init_server(); securityd_xpc_init(serviceName); + SecCreateSecuritydXPCServer(); + CKKSControlServerInitialize(); + SOSControlServerInitialize(); + OctagonControlServerInitialize(); + // 13B104+Roots:Device never moved past spinner after using approval to ENABLE icdp #if TARGET_OS_EMBEDDED securityd_soscc_lock_hack(); diff --git a/OSX/sec/ipc/server_endpoint.m b/OSX/sec/ipc/server_endpoint.m index 2ad415ad..4e9cb906 100644 --- a/OSX/sec/ipc/server_endpoint.m +++ b/OSX/sec/ipc/server_endpoint.m @@ -119,24 +119,19 @@ // Responsible for bringing up new SecuritydXPCServer objects, and configuring them with their remote connection @interface SecuritydXPCServerListener : NSObject @property (retain,nonnull) NSXPCListener *listener; -- (xpc_endpoint_t)xpcControlEndpoint; @end @implementation SecuritydXPCServerListener -(instancetype)init { if((self = [super init])){ - self.listener = [NSXPCListener anonymousListener]; + self.listener = [[NSXPCListener alloc] initWithMachServiceName:@(kSecuritydGeneralServiceName)]; self.listener.delegate = self; [self.listener resume]; } return self; } -- (xpc_endpoint_t)xpcControlEndpoint { - return [self.listener.endpoint _endpoint]; -} - - (BOOL)listener:(__unused NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection { // Anyone is allowed to get a connection to securityd, except if you have kSecEntitlementKeychainDeny entitlement @@ -157,14 +152,16 @@ } @end -XPC_RETURNS_RETAINED xpc_endpoint_t SecCreateSecuritydXPCServerEndpoint(CFErrorRef *error) +void +SecCreateSecuritydXPCServer(void) { static SecuritydXPCServerListener* listener = NULL; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - listener = [[SecuritydXPCServerListener alloc] init]; + @autoreleasepool { + listener = [[SecuritydXPCServerListener alloc] init]; + } }); - return [listener xpcControlEndpoint]; } id SecCreateLocalSecuritydXPCServer(void) { diff --git a/OSX/sec/ipc/server_security_helpers.h b/OSX/sec/ipc/server_security_helpers.h index 180d3aea..7f99e901 100644 --- a/OSX/sec/ipc/server_security_helpers.h +++ b/OSX/sec/ipc/server_security_helpers.h @@ -30,7 +30,7 @@ CFTypeRef SecCreateLocalCFSecuritydXPCServer(void); void SecAddLocalSecuritydXPCFakeEntitlement(CFStringRef entitlement, CFTypeRef value); void SecResetLocalSecuritydXPCFakeEntitlements(void); -XPC_RETURNS_RETAINED xpc_endpoint_t SecCreateSecuritydXPCServerEndpoint(CFErrorRef *error); +void SecCreateSecuritydXPCServer(void); void fill_security_client(SecurityClient * client, const uid_t uid, audit_token_t auditToken); CFArrayRef SecTaskCopyAccessGroups(SecTaskRef task); diff --git a/OSX/sec/ipc/server_xpc.m b/OSX/sec/ipc/server_xpc.m index 1c7a42cd..15f2d9e7 100644 --- a/OSX/sec/ipc/server_xpc.m +++ b/OSX/sec/ipc/server_xpc.m @@ -26,8 +26,10 @@ #include #include #include +#include #if OCTAGON +#include "keychain/ckks/CloudKitCategories.h" #include // If your callbacks might pass back a CK error, you should use the XPCSanitizeError() spi on all branches at this layer. // Otherwise, XPC might crash on the other side if they haven't linked CloudKit.framework. @@ -45,6 +47,20 @@ #include "keychain/ckks/CKKSViewManager.h" +@interface SecOSTransactionHolder : NSObject +@property os_transaction_t transaction; +- (instancetype)init:(os_transaction_t)transaction; +@end + +@implementation SecOSTransactionHolder +- (instancetype)init:(os_transaction_t)transaction { + if((self = [super init])) { + _transaction = transaction; + } + return self; +} +@end + @implementation SecuritydXPCServer (SecuritydXPCProtocol) - (void) SecItemAddAndNotifyOnSync:(NSDictionary*) attributes @@ -65,6 +81,11 @@ return; } +#if OCTAGON + // Wait a bit for CKKS initialization in case of daemon start, but don't bail if it isn't up + [[CKKSViewManager manager].completedSecCKKSInitialize wait:10]; +#endif + if(attributes[(id)kSecAttrDeriveSyncIDFromItemAttributes] || attributes[(id)kSecAttrPCSPlaintextServiceIdentifier] || attributes[(id)kSecAttrPCSPlaintextPublicKey] || @@ -81,14 +102,16 @@ CFTypeRef cfresult = NULL; NSMutableDictionary* callbackQuery = [attributes mutableCopy]; + + // We probably need to figure out how to call os_transaction_needs_more_time on this transaction, but as this callback passes through C code, it's quite difficult + SecOSTransactionHolder* callbackTransaction = [[SecOSTransactionHolder alloc] init:os_transaction_create("com.apple.securityd.SecItemAddAndNotifyOnSync-callback")]; callbackQuery[@"f_ckkscallback"] = ^void (bool didSync, CFErrorRef syncerror) { - [callback callCallback: didSync error: (__bridge NSError*)syncerror]; + [callback callCallback:didSync error:XPCSanitizeError((__bridge NSError*)syncerror)]; + callbackTransaction.transaction = nil; }; _SecItemAdd((__bridge CFDictionaryRef) callbackQuery, &_client, &cfresult, &cferror); - //TODO: ensure cferror can transit xpc - // SecItemAdd returns Some CF Object, but NSXPC is pretty adamant that everything be a specific NS type. Split it up here: if(!cfresult) { complete(NULL, NULL, (__bridge NSError *)(cferror)); @@ -141,90 +164,33 @@ return; } - __block SecDbItemRef newItem = NULL; - __block SecDbItemRef oldItem = NULL; - - bool ok = kc_with_dbt(false, &cferror, ^bool (SecDbConnectionRef dbt) { - // Use a DB transaction to gain synchronization with all CKKS zones. - return kc_transaction_type(dbt, kSecDbExclusiveRemoteCKKSTransactionType, &cferror, ^bool { - Query *q = query_create_with_limit( (__bridge CFDictionaryRef) @{ - (__bridge NSString *)kSecValuePersistentRef : newItemPersistentRef, - (__bridge NSString *)kSecAttrAccessGroup : accessGroup, - }, - NULL, - 1, - &cferror); - if(cferror) { - secerror("couldn't create query for new item pref: %@", cferror); - return false; - } - - if(!SecDbItemQuery(q, NULL, dbt, &cferror, ^(SecDbItemRef item, bool *stop) { - newItem = CFRetainSafe(item); - })) { - query_destroy(q, NULL); - secerror("couldn't run query for new item pref: %@", cferror); - return false; - } - - if(!query_destroy(q, &cferror)) { - secerror("couldn't destroy query for new item pref: %@", cferror); - return false; - }; - - if(oldCurrentItemPersistentRef) { - q = query_create_with_limit( (__bridge CFDictionaryRef) @{ - (__bridge NSString *)kSecValuePersistentRef : oldCurrentItemPersistentRef, - (__bridge NSString *)kSecAttrAccessGroup : accessGroup, - }, - NULL, - 1, - &cferror); - if(cferror) { - secerror("couldn't create query: %@", cferror); - return false; - } - - if(!SecDbItemQuery(q, NULL, dbt, &cferror, ^(SecDbItemRef item, bool *stop) { - oldItem = CFRetainSafe(item); - })) { - query_destroy(q, NULL); - secerror("couldn't run query for old item pref: %@", cferror); - return false; - } - - if(!query_destroy(q, &cferror)) { - secerror("couldn't destroy query for old item pref: %@", cferror); - return false; - }; - } - - CKKSViewManager* manager = [CKKSViewManager manager]; - if(!manager) { - secerror("SecItemSetCurrentItemAcrossAllDevices: no view manager?"); - cferror = (CFErrorRef) CFBridgingRetain([NSError errorWithDomain:@"securityd" code:errSecInternalError userInfo:@{NSLocalizedDescriptionKey: @"No view manager, cannot forward request"}]); - return false; - } - [manager setCurrentItemForAccessGroup:newItem - hash:newItemSHA1 - accessGroup:accessGroup - identifier:identifier - viewHint:viewHint - replacing:oldItem - hash:oldItemSHA1 - complete:complete]; - return true; - }); - }); - - CFReleaseNull(newItem); - CFReleaseNull(oldItem); - - if(!ok) { - secnotice("ckks", "SecItemSetCurrentItemAcrossAllDevices failed due to: %@", cferror); - complete((__bridge NSError*) cferror); +#if OCTAGON + // Wait a bit for CKKS initialization in case of daemon start, and bail it doesn't come up + if([[CKKSViewManager manager].completedSecCKKSInitialize wait:10] != 0) { + secerror("SecItemSetCurrentItemAcrossAllDevices: CKKSViewManager not initialized?"); + complete([NSError errorWithDomain:CKKSErrorDomain code:CKKSNotInitialized description:@"CKKS not yet initialized"]); + return; } - CFReleaseNull(cferror); +#endif + + CKKSViewManager* manager = [CKKSViewManager manager]; + if(!manager) { + secerror("SecItemSetCurrentItemAcrossAllDevices: no view manager?"); + complete([NSError errorWithDomain:CKKSErrorDomain + code:CKKSNotInitialized + description:@"No view manager, cannot forward request"]); + return; + } + + [manager setCurrentItemForAccessGroup:newItemPersistentRef + hash:newItemSHA1 + accessGroup:accessGroup + identifier:identifier + viewHint:viewHint + replacing:oldCurrentItemPersistentRef + hash:oldItemSHA1 + complete:complete]; + return; #else // ! OCTAGON xpcComplete([NSError errorWithDomain:@"securityd" code:errSecParam userInfo:@{NSLocalizedDescriptionKey: @"SecItemSetCurrentItemAcrossAllDevices not implemented on this platform"}]); #endif // OCTAGON @@ -264,6 +230,13 @@ return; } + // Wait a bit for CKKS initialization in case of daemon start, and bail it doesn't come up + if([[CKKSViewManager manager].completedSecCKKSInitialize wait:10] != 0) { + secerror("SecItemFetchCurrentItemAcrossAllDevices: CKKSViewManager not initialized?"); + complete(NULL, [NSError errorWithDomain:CKKSErrorDomain code:CKKSNotInitialized description:@"CKKS not yet initialized"]); + return; + } + [[CKKSViewManager manager] getCurrentItemForAccessGroup:accessGroup identifier:identifier viewHint:viewHint @@ -275,9 +248,11 @@ return; } - // Find the persisent ref and return it. - secnotice("ckkscurrent", "CKKS believes current item UUID for (%@,%@) is %@. Looking up persistent ref...", accessGroup, identifier, uuid); - [self findItemPersistentRefByUUID:uuid complete:complete]; + // Find the persistent ref and return it. + secinfo("ckkscurrent", "CKKS believes current item UUID for (%@,%@) is %@. Looking up persistent ref...", accessGroup, identifier, uuid); + [self findItemPersistentRefByUUID:uuid + extraLoggingString:[NSString stringWithFormat:@"%@,%@", accessGroup, identifier] + complete:complete]; }]; #else // ! OCTAGON xpcComplete(NULL, [NSError errorWithDomain:@"securityd" code:errSecParam userInfo:@{NSLocalizedDescriptionKey: @"SecItemFetchCurrentItemAcrossAllDevices not implemented on this platform"}]); @@ -285,6 +260,7 @@ } -(void)findItemPersistentRefByUUID:(NSString*)uuid + extraLoggingString:(NSString*)loggingStr complete:(void (^) (NSData* persistentref, NSError* operror))xpcComplete { // The calling client might not handle CK types well. Sanitize! @@ -329,9 +305,9 @@ } if(result && !cferror) { - secnotice("ckkscurrent", "Found current item for (%@)", uuid); + secinfo("ckkscurrent", "Found current item for (%@: %@)", loggingStr, uuid); } else { - secerror("ckkscurrent: No current item for (%@): %@ %@", uuid, result, cferror); + secerror("ckkscurrent: No current item for (%@,%@): %@ %@", loggingStr, uuid, result, cferror); } complete((__bridge NSData*) result, (__bridge NSError*) cferror); diff --git a/OSX/sec/os_log/com.apple.securityd.plist b/OSX/sec/os_log/com.apple.securityd.plist index bc357ec6..3d7b7702 100644 --- a/OSX/sec/os_log/com.apple.securityd.plist +++ b/OSX/sec/os_log/com.apple.securityd.plist @@ -31,5 +31,34 @@ 2d + circleOps + + Default-Privacy-Setting + Public + Enabled + True + Persist + True + TTL + 14 + Development + + Enabled + True + Persist + True + TTL + 14 + + Debug + + Enabled + True + Persist + True + TTL + 14 + + diff --git a/OSX/sec/securityd/OTATrustUtilities.c b/OSX/sec/securityd/OTATrustUtilities.c deleted file mode 100644 index 8b4f990f..00000000 --- a/OSX/sec/securityd/OTATrustUtilities.c +++ /dev/null @@ -1,1519 +0,0 @@ -/* - * Copyright (c) 2003-2004,2006-2010,2013-2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - * - * OTATrustUtilities.c - */ - -#include "OTATrustUtilities.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "SecFramework.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//#define VERBOSE_LOGGING 1 - -#if VERBOSE_LOGGING - -static void TestOTALog(const char* sz, ...) -{ - va_list va; - va_start(va, sz); - - FILE* fp = fopen("/tmp/secd_OTAUtil.log", "a"); - if (NULL != fp) - { - vfprintf(fp, sz, va); - fclose(fp); - } - va_end(va); -} - -static void TestOTAResourceLog(const char *msg, - CFStringRef resourceName, - CFStringRef resourceType, - CFStringRef subDirName, - CFURLRef url) -{ - CFStringRef tmpStr = NULL; - CFIndex maxLength = 0; - char *buf = NULL; - - tmpStr = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, - CFSTR("%s (name=%@, type=%@, subdir=%@), url=%@"), - msg, resourceName, resourceType, subDirName, url); - if (tmpStr) { - maxLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength(tmpStr), kCFStringEncodingUTF8) + 1; - buf = (char*) malloc(maxLength); - } else { - TestOTALog("TestOTAResourceLog: failed to create string of length %ld\n", (long)maxLength); - } - if (buf) { - if (CFStringGetCString(tmpStr, buf, (CFIndex)maxLength, kCFStringEncodingUTF8)) { - TestOTALog("%s\n", buf); - } - free(buf); - } - CFReleaseSafe(tmpStr); -} - -#else - -#define TestOTALog(sz, ...) -#define TestOTAResourceLog(msg, resourceName, resourceType, subDirName, url) - -#endif - - -//#define NEW_LOCATION 1 - -#if NEW_LOCATION -static const char* kBaseAssetDirectory = "/var/OTAPKI/Assets"; -#else -static const char* kBaseAssetDirectory = "/var/Keychains/Assets"; -#endif - -static const char* kVersionDirectoryNamePrefix = "Version_"; -static const char* kNumberString = "%d"; - -struct index_record -{ - unsigned char hash[CC_SHA1_DIGEST_LENGTH]; - uint32_t offset; -}; -typedef struct index_record index_record; - - -struct _OpaqueSecOTAPKI -{ - CFRuntimeBase _base; - CFSetRef _blackListSet; - CFSetRef _grayListSet; - CFDictionaryRef _allowList; - CFArrayRef _trustedCTLogs; - CFArrayRef _pinningList; - CFArrayRef _escrowCertificates; - CFArrayRef _escrowPCSCertificates; - CFDictionaryRef _evPolicyToAnchorMapping; - CFDictionaryRef _anchorLookupTable; - const char* _anchorTable; - const char* _assetPath; - int _assetVersion; - const char* _validUpdateSnapshot; - const char* _validDatabaseSnapshot; - CFIndex _validSnapshotVersion; - CFIndex _validSnapshotFormat; -}; - -CFGiblisFor(SecOTAPKI) - -static CF_RETURNS_RETAINED CFStringRef SecOTAPKICopyFormatDescription(CFTypeRef cf, CFDictionaryRef formatOptions) -{ - SecOTAPKIRef otapkiRef = (SecOTAPKIRef)cf; - return CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR(""), otapkiRef->_assetVersion); -} - -static void SecOTAPKIDestroy(CFTypeRef cf) -{ - SecOTAPKIRef otapkiref = (SecOTAPKIRef)cf; - - CFReleaseNull(otapkiref->_blackListSet); - CFReleaseNull(otapkiref->_grayListSet); - CFReleaseNull(otapkiref->_escrowCertificates); - CFReleaseNull(otapkiref->_escrowPCSCertificates); - - CFReleaseNull(otapkiref->_evPolicyToAnchorMapping); - CFReleaseNull(otapkiref->_anchorLookupTable); - - CFReleaseNull(otapkiref->_trustedCTLogs); - CFReleaseNull(otapkiref->_pinningList); - - if (otapkiref->_anchorTable) { - free((void *)otapkiref->_anchorTable); - otapkiref->_anchorTable = NULL; - } - if (otapkiref->_assetPath) { - free((void *)otapkiref->_assetPath); - otapkiref->_assetPath = NULL; - } - if (otapkiref->_validUpdateSnapshot) { - free((void *)otapkiref->_validUpdateSnapshot); - otapkiref->_validUpdateSnapshot = NULL; - } - if (otapkiref->_validDatabaseSnapshot) { - free((void *)otapkiref->_validDatabaseSnapshot); - otapkiref->_validDatabaseSnapshot = NULL; - } -} - -static CFDataRef SecOTACopyFileContents(const char *path) -{ - CFMutableDataRef data = NULL; - int fd = open(path, O_RDONLY, 0666); - - if (fd == -1) - { - goto badFile; - } - - off_t fsize = lseek(fd, 0, SEEK_END); - if (fsize == (off_t)-1) - { - goto badFile; - } - - if (fsize > (off_t)INT32_MAX) - { - goto badFile; - } - - data = CFDataCreateMutable(kCFAllocatorDefault, (CFIndex)fsize); - if (NULL == data) - { - goto badFile; - } - - CFDataSetLength(data, (CFIndex)fsize); - void *buf = CFDataGetMutableBytePtr(data); - if (NULL == buf) - { - goto badFile; - } - - off_t total_read = 0; - while (total_read < fsize) - { - ssize_t bytes_read; - - bytes_read = pread(fd, buf, (size_t)(fsize - total_read), total_read); - if (bytes_read == -1) - { - goto badFile; - } - if (bytes_read == 0) - { - goto badFile; - } - total_read += bytes_read; - } - - close(fd); - return data; - -badFile: - if (fd != -1) - { - close(fd); - } - - if (data) - { - CFRelease(data); - } - - return NULL; -} - -static Boolean PathExists(const char* path, size_t* pFileSize) -{ - const char *checked_path = (path) ? path : ""; - TestOTALog("In PathExists: checking path \"%s\"\n", checked_path); - Boolean result = false; - struct stat sb; - - if (NULL != pFileSize) - { - *pFileSize = 0; - } - - int stat_result = stat(checked_path, &sb); - result = (stat_result == 0); - - - if (result) - { - TestOTALog("In PathExists: stat returned 0 for \"%s\"\n", checked_path); - if (S_ISDIR(sb.st_mode)) - { - TestOTALog("In PathExists: \"%s\" is a directory\n", checked_path); - // It is a directory - ; - } - else - { - TestOTALog("In PathExists: \"%s\" is a file\n", checked_path); - // It is a file - if (NULL != pFileSize) - { - *pFileSize = (size_t)sb.st_size; - } - } - } -#if VERBOSE_LOGGING - else - { - const char *stat_prefix = "In PathExists: stat error"; - TestOTALog("%s %d for \"%s\"\n", stat_prefix, stat_result, checked_path); - int local_errno = errno; - switch(local_errno) - { - case EACCES: - TestOTALog("%s EACCES\n", stat_prefix); - break; - - case EBADF: - TestOTALog("%s EBADF\n", stat_prefix); - break; - - case EFAULT: - TestOTALog("%s EFAULT\n", stat_prefix); - break; - - case ELOOP: - TestOTALog("%s ELOOP\n", stat_prefix); - break; - - case ENAMETOOLONG: - TestOTALog("%s ENAMETOOLONG\n", stat_prefix); - break; - - case ENOENT: - TestOTALog("%s ENOENT (missing?)\n", stat_prefix); - break; - - case ENOMEM: - TestOTALog("%s ENOMEM\n", stat_prefix); - break; - - case ENOTDIR: - TestOTALog("%s ENOTDIR\n", stat_prefix); - break; - - case EOVERFLOW: - TestOTALog("%s EOVERFLOW\n", stat_prefix); - break; - - default: - TestOTALog("%s %d\n", stat_prefix, local_errno); - break; - } - } -#endif // #if VERBOSE_LOGGING - - return result; -} - -static int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) -{ - int rv = remove(fpath); - return rv; -} - -static int rmrf(char *path) -{ - const char* p1 = NULL; - char path_buffer[PATH_MAX]; - memset(path_buffer, 0, sizeof(path_buffer)); - - p1 = realpath(path, path_buffer); - if (p1 && !strncmp(path, p1, PATH_MAX)) - { - return nftw(path, unlink_cb, 64, FTW_DEPTH | FTW_PHYS); - } - return -1; -} - - -static CFStringRef kSecSystemTrustStoreBundlePath = CFSTR("/System/Library/Security/Certificates.bundle"); - -CFGiblisGetSingleton(CFBundleRef, SecSystemTrustStoreGetBundle, bundle, ^{ - CFStringRef bundlePath = NULL; -#if TARGET_IPHONE_SIMULATOR - char *simulatorRoot = getenv("SIMULATOR_ROOT"); - if (simulatorRoot) - bundlePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s%@"), simulatorRoot, kSecSystemTrustStoreBundlePath); -#endif - if (!bundlePath) - bundlePath = CFRetainSafe(kSecSystemTrustStoreBundlePath); - TestOTAResourceLog("SecSystemTrustStoreGetBundle", bundlePath, NULL, NULL, NULL); - CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, bundlePath, kCFURLPOSIXPathStyle, true); - *bundle = (url) ? CFBundleCreate(kCFAllocatorDefault, url) : NULL; - CFReleaseSafe(url); - CFReleaseSafe(bundlePath); -}) - -static CFURLRef SecSystemTrustStoreCopyResourceURL(CFStringRef resourceName, - CFStringRef resourceType, CFStringRef subDirName) -{ - CFURLRef url = NULL; - CFBundleRef bundle = SecSystemTrustStoreGetBundle(); - TestOTALog("SecSystemTrustStoreCopyResourceURL: bundle = %p\n", (void*)bundle); - if (bundle) { - url = CFBundleCopyResourceURL(bundle, resourceName, - resourceType, subDirName); - if (!url) { - secwarning("resource: %@.%@ in %@ not found", resourceName, - resourceType, subDirName); - } - } - if (!url) { - TestOTAResourceLog("SecSystemTrustStoreCopyResourceURL: unable to get URL!", - resourceName, resourceType, subDirName, url); - } else { - TestOTAResourceLog("SecSystemTrustStoreCopyResourceURL: got URL from bundle", - resourceName, resourceType, subDirName, url); - } - return url; -} - -static CFDataRef SecSystemTrustStoreCopyResourceContents(CFStringRef resourceName, - CFStringRef resourceType, CFStringRef subDirName) -{ - CFURLRef url = SecSystemTrustStoreCopyResourceURL(resourceName, resourceType, subDirName); - CFDataRef data = NULL; - if (url) { - SInt32 error; - if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, - url, &data, NULL, NULL, &error)) { - secwarning("read: %ld", (long) error); - } - CFRelease(url); - } - TestOTALog("SecSystemTrustStoreCopyResourceContents: data = %p\n", data); - return data; -} - -static CFPropertyListRef CFPropertyListCopyFromAsset(const char *ota_assets_path, CFStringRef asset) -{ - CFPropertyListRef plist = NULL; - // Check to see if the .plist file is in the asset location - CFDataRef xmlData = NULL; - if (ota_assets_path) { - CFStringRef filePath = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s/%@.%@"), ota_assets_path, asset, CFSTR("plist")); - CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, filePath, kCFURLPOSIXPathStyle, false); - - plist = CFPropertyListReadFromFile(url); - CFReleaseSafe(url); - CFReleaseSafe(filePath); - } - - if (!plist) { - // no OTA asset file, so use the file in the system trust store bundle - xmlData = SecSystemTrustStoreCopyResourceContents(asset, CFSTR("plist"), NULL); - - if (xmlData) { - plist = CFPropertyListCreateWithData(kCFAllocatorDefault, xmlData, kCFPropertyListImmutable, NULL, NULL); - CFRelease(xmlData); - } - } - - return plist; -} - -static CFSetRef CFSetCreateFromPropertyList(CFPropertyListRef plist) -{ - CFSetRef result = NULL; - - if (plist) { - CFMutableSetRef tempSet = NULL; - if (CFGetTypeID(plist) == CFArrayGetTypeID()) { - tempSet = CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks); - if (NULL == tempSet) { - return result; - } - CFArrayRef array = (CFArrayRef)plist; - CFIndex num_keys = CFArrayGetCount(array); - for (CFIndex idx = 0; idx < num_keys; idx++) { - CFDataRef data = (CFDataRef)CFArrayGetValueAtIndex(array, idx); - CFSetAddValue(tempSet, data); - } - } - else { - return result; - } - - if (NULL != tempSet) { - result = tempSet; - } - } - return result; -} - -static const char* InitOTADirectory(int* pAssetVersion) -{ - TestOTALog("In InitOTADirectory\n"); - const char* result = NULL; - - char buffer[PATH_MAX]; - DIR *dp; - struct dirent *ep; - int version = 0; - int current_version = 0; - int system_asset_version = 0; - CFIndex asset_number = 0; - - // Look in the system trust store for an AssetVersion.plist file. - // This is needed to ensure that a software update did not put down - // a version of the trust store that is greater than the OTA assets. - - CFDataRef assetVersionData = SecSystemTrustStoreCopyResourceContents(CFSTR("AssetVersion"), CFSTR("plist"), NULL); - if (NULL != assetVersionData) - { - CFPropertyListFormat propFormat; - CFDictionaryRef versionPlist = CFPropertyListCreateWithData(kCFAllocatorDefault, assetVersionData, 0, &propFormat, NULL); - if (NULL != versionPlist && CFDictionaryGetTypeID() == CFGetTypeID(versionPlist)) - { - CFNumberRef versionNumber = (CFNumberRef)CFDictionaryGetValue(versionPlist, (const void *)CFSTR("VersionNumber")); - if (NULL != versionNumber) - { - CFNumberGetValue(versionNumber, kCFNumberCFIndexType, &asset_number); - system_asset_version = (int)asset_number; - } - } - CFReleaseSafe(versionPlist); - CFReleaseSafe(assetVersionData); - } - - // Now check to see if the OTA asset directory exists. - // If it does, get the greatest asset number in the OTA asset directory. - - bool assetDirectoryExists = PathExists(kBaseAssetDirectory, NULL); - if (assetDirectoryExists) - { - TestOTALog("InitOTADirectory: \"%s\" exists\n", kBaseAssetDirectory); - dp = opendir (kBaseAssetDirectory); - if (NULL != dp) - { - TestOTALog("InitOTADirectory: opendir sucessfully open \"%s\"\n", kBaseAssetDirectory); - while ((ep = readdir(dp))) - { - TestOTALog("InitOTADirectory: processing name \"%s\"\n", ep->d_name); - if (strstr(ep->d_name, kVersionDirectoryNamePrefix)) - { - TestOTALog("InitOTADirectory: \"%s\" matches\n", ep->d_name); - memset(buffer, 0, sizeof(buffer)); - snprintf(buffer, sizeof(buffer), "%s%s", kVersionDirectoryNamePrefix, kNumberString); -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wformat-nonliteral" - sscanf(ep->d_name, buffer, &version); -#pragma clang diagnostic pop - - TestOTALog("InitOTADirectory: version = %d\n", version); - - if (current_version > 0) - { - if (version > current_version) - { - // There is more than one Version_ directory. - // Delete the one with the smaller version number - memset(buffer, 0, sizeof(buffer)); - snprintf(buffer, sizeof(buffer), "%s/%s%d", kBaseAssetDirectory, kVersionDirectoryNamePrefix, current_version); - if (PathExists(buffer, NULL)) - { - rmrf(buffer); - } - current_version = version; - } - } - else - { - current_version = version; - } - } - } - closedir(dp); - } - else - { - TestOTALog("InitOTADirectory: opendir failed to open %s\n", kBaseAssetDirectory); - } - } - else - { - TestOTALog("InitOTADirectory: PathExists returned false for %s\n", kBaseAssetDirectory); - } - - // Check to see which version number is greater. - // If the current_version is greater then the OTA asset is newer. - // If the system_asset_version is greater than the system asset is newer. - if (current_version > system_asset_version) - { - // The OTA asset is newer than the system asset number - memset(buffer, 0, sizeof(buffer)); - TestOTALog("InitOTADirectory: current_version = %d\n", current_version); - snprintf(buffer, sizeof(buffer), "%s/%s%d", kBaseAssetDirectory, kVersionDirectoryNamePrefix, current_version); - size_t length = strlen(buffer); - char* temp_str = (char*)malloc(length + 1); - memset(temp_str, 0, (length + 1)); - strncpy(temp_str, buffer, length); - result = temp_str; - } - else - { - // The system asset number is newer than the OTA asset number - current_version = system_asset_version; - if (NULL != result) - { - free((void *)result); - } - result = NULL; - } - - if (NULL != pAssetVersion) - { - *pAssetVersion = current_version; - } - return result; -} - -static CF_RETURNS_RETAINED CFSetRef InitializeBlackList(const char* path_ptr) -{ - CFPropertyListRef plist = CFPropertyListCopyFromAsset(path_ptr, CFSTR("Blocked")); - CFSetRef result = CFSetCreateFromPropertyList(plist); - CFReleaseSafe(plist); - - return result; -} - -static CF_RETURNS_RETAINED CFSetRef InitializeGrayList(const char* path_ptr) -{ - CFPropertyListRef plist = CFPropertyListCopyFromAsset(path_ptr, CFSTR("GrayListedKeys")); - CFSetRef result = CFSetCreateFromPropertyList(plist); - CFReleaseSafe(plist); - - return result; -} - -static CF_RETURNS_RETAINED CFArrayRef InitializePinningList(const char* path_ptr) -{ - CFPropertyListRef list = CFPropertyListCopyFromAsset(path_ptr, CFSTR("CertificatePinning")); - - if (isArray(list)) { - return list; - } else { - CFReleaseNull(list); - return NULL; - } -} - -static CF_RETURNS_RETAINED CFDictionaryRef InitializeAllowList(const char* path_ptr) -{ - CFPropertyListRef allowList = CFPropertyListCopyFromAsset(path_ptr, CFSTR("Allowed")); - - if (allowList && (CFGetTypeID(allowList) == CFDictionaryGetTypeID())) { - return allowList; - } else { - CFReleaseNull(allowList); - return NULL; - } -} - -static CF_RETURNS_RETAINED CFArrayRef InitializeTrustedCTLogs(const char* path_ptr) -{ - CFPropertyListRef trustedCTLogs = CFPropertyListCopyFromAsset(path_ptr, CFSTR("TrustedCTLogs")); - - if (trustedCTLogs && (CFGetTypeID(trustedCTLogs) == CFArrayGetTypeID())) { - return trustedCTLogs; - } else { - CFReleaseNull(trustedCTLogs); - return NULL; - } -} - -static CF_RETURNS_RETAINED CFDictionaryRef InitializeEVPolicyToAnchorDigestsTable(const char* path_ptr) -{ - CFDictionaryRef result = NULL; - CFPropertyListRef evroots = CFPropertyListCopyFromAsset(path_ptr, CFSTR("EVRoots")); - - if (evroots) { - if (CFGetTypeID(evroots) == CFDictionaryGetTypeID()) { - /* @@@ Ensure that each dictionary key is a dotted list of digits, - each value is an NSArrayRef and each element in the array is a - 20 byte digest. */ - result = (CFDictionaryRef)evroots; - } - else { - secwarning("EVRoot.plist is wrong type."); - CFRelease(evroots); - } - } - - return result; -} - -static CFIndex InitializeValidSnapshotVersion(CFIndex *outFormat) -{ - CFIndex validVersion = 0; - CFIndex validFormat = 0; - CFDataRef validVersionData = SecSystemTrustStoreCopyResourceContents(CFSTR("ValidUpdate"), CFSTR("plist"), NULL); - if (NULL != validVersionData) - { - CFPropertyListFormat propFormat; - CFDictionaryRef versionPlist = CFPropertyListCreateWithData(kCFAllocatorDefault, validVersionData, 0, &propFormat, NULL); - if (NULL != versionPlist && CFDictionaryGetTypeID() == CFGetTypeID(versionPlist)) - { - CFNumberRef versionNumber = (CFNumberRef)CFDictionaryGetValue(versionPlist, (const void *)CFSTR("Version")); - if (NULL != versionNumber) - { - CFNumberGetValue(versionNumber, kCFNumberCFIndexType, &validVersion); - } - CFNumberRef formatNumber = (CFNumberRef)CFDictionaryGetValue(versionPlist, (const void *)CFSTR("Format")); - if (NULL != formatNumber) - { - CFNumberGetValue(formatNumber, kCFNumberCFIndexType, &validFormat); - } - } - CFReleaseSafe(versionPlist); - CFReleaseSafe(validVersionData); - } - if (outFormat) { - *outFormat = validFormat; - } - return validVersion; -} - -static const char* InitializeValidSnapshotData(CFStringRef filename_str) -{ - char *result = NULL; - const char *base_error_str = "could not get valid snapshot"; - - CFURLRef valid_url = SecSystemTrustStoreCopyResourceURL(filename_str, CFSTR("sqlite3"), NULL); - if (NULL == valid_url) { - secerror("%s", base_error_str); - } else { - CFStringRef valid_str = CFURLCopyFileSystemPath(valid_url, kCFURLPOSIXPathStyle); - char file_path_buffer[PATH_MAX]; - memset(file_path_buffer, 0, PATH_MAX); - if (NULL == valid_str) { - secerror("%s path", base_error_str); - } else { - const char *valid_cstr = CFStringGetCStringPtr(valid_str, kCFStringEncodingUTF8); - if (NULL == valid_cstr) { - if (CFStringGetCString(valid_str, file_path_buffer, PATH_MAX, kCFStringEncodingUTF8)) { - valid_cstr = file_path_buffer; - } - } - if (NULL == valid_cstr) { - secerror("%s path as UTF8 string", base_error_str); - } else { - asprintf(&result, "%s", valid_cstr); - } - } - CFReleaseSafe(valid_str); - } - CFReleaseSafe(valid_url); - if (result && !PathExists(result, NULL)) { - free(result); - result = NULL; - } - return (const char*)result; -} - -static const char* InitializeValidUpdateSnapshot() -{ - return InitializeValidSnapshotData(CFSTR("update-full")); -} - -static const char* InitializeValidDatabaseSnapshot() -{ - return InitializeValidSnapshotData(CFSTR("valid")); -} - -static void* MapFile(const char* path, int* out_fd, size_t* out_file_size) -{ - void* result = NULL; - void* temp_result = NULL; - if (NULL == path || NULL == out_fd || NULL == out_file_size) - { - return result; - } - - *out_fd = -1; - *out_file_size = 0; - - - *out_fd = open(path, O_RDONLY, 0666); - - if (*out_fd == -1) - { - return result; - } - - off_t fsize = lseek(*out_fd, 0, SEEK_END); - if (fsize == (off_t)-1) - { - return result; - } - - if (fsize > (off_t)INT32_MAX) - { - close(*out_fd); - *out_fd = -1; - return result; - } - - size_t malloc_size = (size_t)fsize; - - temp_result = malloc(malloc_size); - if (NULL == temp_result) - { - close(*out_fd); - *out_fd = -1; - return result; - } - - *out_file_size = malloc_size; - - off_t total_read = 0; - while (total_read < fsize) - { - ssize_t bytes_read; - - bytes_read = pread(*out_fd, temp_result, (size_t)(fsize - total_read), total_read); - if (bytes_read == -1) - { - free(temp_result); - temp_result = NULL; - close(*out_fd); - *out_fd = -1; - return result; - } - if (bytes_read == 0) - { - free(temp_result); - temp_result = NULL; - close(*out_fd); - *out_fd = -1; - return result; - } - total_read += bytes_read; - } - - if (NULL != temp_result) - { - result = temp_result; - } - - return result; -} - -static void UnMapFile(void* mapped_data, size_t data_size) -{ -#pragma unused(mapped_data, data_size) - if (NULL != mapped_data) - { - free((void *)mapped_data); - mapped_data = NULL; - } -} - -static bool InitializeAnchorTable(const char* path_ptr, CFDictionaryRef* pLookupTable, const char** ppAnchorTable) -{ - - bool result = false; - - if (NULL == pLookupTable || NULL == ppAnchorTable) - { - return result; - } - - *pLookupTable = NULL; - *ppAnchorTable = NULL;; - - const char* dir_path = NULL; - CFDataRef cert_index_file_data = NULL; - char file_path_buffer[PATH_MAX]; - CFURLRef table_data_url = NULL; - CFStringRef table_data_cstr_path = NULL; - const char* table_data_path = NULL; - const index_record* pIndex = NULL; - size_t index_offset = 0; - size_t index_data_size = 0; - CFMutableDictionaryRef anchorLookupTable = NULL; - uint32_t offset_int_value = 0; - CFNumberRef index_offset_value = NULL; - CFDataRef index_hash = NULL; - CFMutableArrayRef offsets = NULL; - Boolean release_offset = false; - - char* local_anchorTable = NULL; - size_t local_anchorTableSize = 0; - int local_anchorTable_fd = -1; - - // ------------------------------------------------------------------------ - // First determine if there are asset files at /var/Keychains. If there - // are files use them for the trust table. Otherwise, use the files in the - // Security.framework bundle. - // - // The anchor table file is mapped into memory. This SHOULD be OK as the - // size of the data is around 250K. - // ------------------------------------------------------------------------ - dir_path = path_ptr; - - if (NULL != dir_path) - { - // There is a set of OTA asset files - memset(file_path_buffer, 0, PATH_MAX); - snprintf(file_path_buffer, PATH_MAX, "%s/certsIndex.data", dir_path); - cert_index_file_data = SecOTACopyFileContents(file_path_buffer); - - if (NULL != cert_index_file_data) - { - memset(file_path_buffer, 0, PATH_MAX); - snprintf(file_path_buffer, PATH_MAX, "%s/certsTable.data", dir_path); - local_anchorTable = (char *)MapFile(file_path_buffer, &local_anchorTable_fd, &local_anchorTableSize); - } - - free((void *)dir_path); - dir_path = NULL; - } - - // Check to see if kAnchorTable was indeed set - if (NULL == local_anchorTable) - { - // local_anchorTable is still NULL so the asset in the system trust store bundle needs to be used. - CFReleaseSafe(cert_index_file_data); - cert_index_file_data = SecSystemTrustStoreCopyResourceContents(CFSTR("certsIndex"), CFSTR("data"), NULL); - if (!cert_index_file_data) { - secerror("could not find certsIndex"); - } - table_data_url = SecSystemTrustStoreCopyResourceURL(CFSTR("certsTable"), CFSTR("data"), NULL); - if (!table_data_url) { - secerror("could not find certsTable"); - } - - if (NULL != table_data_url) - { - table_data_cstr_path = CFURLCopyFileSystemPath(table_data_url, kCFURLPOSIXPathStyle); - if (NULL != table_data_cstr_path) - { - memset(file_path_buffer, 0, PATH_MAX); - table_data_path = CFStringGetCStringPtr(table_data_cstr_path, kCFStringEncodingUTF8); - if (NULL == table_data_path) - { - if (CFStringGetCString(table_data_cstr_path, file_path_buffer, PATH_MAX, kCFStringEncodingUTF8)) - { - table_data_path = file_path_buffer; - } - } - local_anchorTable = (char *)MapFile(table_data_path, &local_anchorTable_fd, &local_anchorTableSize); - CFReleaseSafe(table_data_cstr_path); - } - } - CFReleaseSafe(table_data_url); - } - - if (NULL == local_anchorTable || NULL == cert_index_file_data) - { - // we are in trouble - if (NULL != local_anchorTable) - { - UnMapFile(local_anchorTable, local_anchorTableSize); - local_anchorTable = NULL; - local_anchorTableSize = 0; - } - CFReleaseSafe(cert_index_file_data); - return result; - } - - // ------------------------------------------------------------------------ - // Now that the locations of the files are known and the table file has - // been mapped into memory, create a dictionary that maps the SHA1 hash of - // normalized issuer to the offset in the mapped anchor table file which - // contains a index_record to the correct certificate - // ------------------------------------------------------------------------ - pIndex = (const index_record*)CFDataGetBytePtr(cert_index_file_data); - index_data_size = CFDataGetLength(cert_index_file_data); - - anchorLookupTable = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - - for (index_offset = index_data_size; index_offset > 0; index_offset -= sizeof(index_record), pIndex++) - { - offset_int_value = pIndex->offset; - - index_offset_value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &offset_int_value); - index_hash = CFDataCreate(kCFAllocatorDefault, pIndex->hash, CC_SHA1_DIGEST_LENGTH); - - // see if the dictionary already has this key - release_offset = false; - offsets = (CFMutableArrayRef)CFDictionaryGetValue(anchorLookupTable, index_hash); - if (NULL == offsets) - { - offsets = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - release_offset = true; - } - - // Add the offset - CFArrayAppendValue(offsets, index_offset_value); - - // set the key value pair in the dictionary - CFDictionarySetValue(anchorLookupTable, index_hash, offsets); - - CFRelease(index_offset_value); - CFRelease(index_hash); - if (release_offset) - { - CFRelease(offsets); - } - } - - CFRelease(cert_index_file_data); - - if (NULL != anchorLookupTable && NULL != local_anchorTable) - { - *pLookupTable = anchorLookupTable; - *ppAnchorTable = local_anchorTable; - result = true; - } - else - { - CFReleaseSafe(anchorLookupTable); - if (NULL != local_anchorTable) - { - UnMapFile(local_anchorTable, local_anchorTableSize); - //munmap(kAnchorTable, local_anchorTableSize); - local_anchorTable = NULL; - local_anchorTableSize = 0; - } - } - - return result; -} - -static void InitializeEscrowCertificates(const char* path_ptr, CFArrayRef *escrowRoots, CFArrayRef *escrowPCSRoots) -{ - CFDataRef file_data = NULL; - - const char* dir_path = path_ptr; - if (NULL == dir_path) - { - file_data = SecSystemTrustStoreCopyResourceContents(CFSTR("AppleESCertificates"), CFSTR("plist"), NULL); - } - else - { - char buffer[1024]; - memset(buffer, 0, 1024); - snprintf(buffer, 1024, "%s/AppleESCertificates.plist", dir_path); - file_data = SecOTACopyFileContents(buffer); - } - - if (NULL != file_data) - { - CFPropertyListFormat propFormat; - CFDictionaryRef certsDictionary = CFPropertyListCreateWithData(kCFAllocatorDefault, file_data, 0, &propFormat, NULL); - if (NULL != certsDictionary && CFDictionaryGetTypeID() == CFGetTypeID((CFTypeRef)certsDictionary)) - { - CFArrayRef certs = (CFArrayRef)CFDictionaryGetValue(certsDictionary, CFSTR("ProductionEscrowKey")); - if (NULL != certs && CFArrayGetTypeID() == CFGetTypeID((CFTypeRef)certs) && CFArrayGetCount(certs) > 0) - { - *escrowRoots = CFArrayCreateCopy(kCFAllocatorDefault, certs); - } - CFArrayRef pcs_certs = (CFArrayRef)CFDictionaryGetValue(certsDictionary, CFSTR("ProductionPCSEscrowKey")); - if (NULL != pcs_certs && CFArrayGetTypeID() == CFGetTypeID((CFTypeRef)pcs_certs) && CFArrayGetCount(pcs_certs) > 0) - { - *escrowPCSRoots = CFArrayCreateCopy(kCFAllocatorDefault, pcs_certs); - } - } - CFReleaseSafe(certsDictionary); - CFRelease(file_data); - } - -} - - -static SecOTAPKIRef SecOTACreate() -{ - TestOTALog("In SecOTACreate\n"); - - SecOTAPKIRef otapkiref = NULL; - - otapkiref = CFTypeAllocate(SecOTAPKI, struct _OpaqueSecOTAPKI , kCFAllocatorDefault); - - if (NULL == otapkiref) - { - return otapkiref; - } - - // Make sure that if this routine has to bail that the clean up - // will do the right thing - otapkiref->_blackListSet = NULL; - otapkiref->_grayListSet = NULL; - otapkiref->_allowList = NULL; - otapkiref->_trustedCTLogs = NULL; - otapkiref->_pinningList = NULL; - otapkiref->_escrowCertificates = NULL; - otapkiref->_escrowPCSCertificates = NULL; - otapkiref->_evPolicyToAnchorMapping = NULL; - otapkiref->_anchorLookupTable = NULL; - otapkiref->_anchorTable = NULL; - otapkiref->_assetPath = NULL; - otapkiref->_assetVersion = 0; - otapkiref->_validUpdateSnapshot = NULL; - otapkiref->_validDatabaseSnapshot = NULL; - otapkiref->_validSnapshotVersion = 0; - otapkiref->_validSnapshotFormat = 0; - - // Start off by getting the correct asset directory info - int asset_version = 0; - const char* path_ptr = InitOTADirectory(&asset_version); - otapkiref->_assetPath = path_ptr; - otapkiref->_assetVersion = asset_version; - - TestOTALog("SecOTACreate: asset_path = \"%s\"\n", (path_ptr) ? path_ptr : ""); - TestOTALog("SecOTACreate: asset_version = %d\n", asset_version); - - // Get the set of black listed keys - CFSetRef blackKeysSet = InitializeBlackList(path_ptr); - if (NULL == blackKeysSet) - { - CFReleaseNull(otapkiref); - return otapkiref; - } - otapkiref->_blackListSet = blackKeysSet; - - // Get the set of gray listed keys - CFSetRef grayKeysSet = InitializeGrayList(path_ptr); - if (NULL == grayKeysSet) - { - CFReleaseNull(otapkiref); - return otapkiref; - } - otapkiref->_grayListSet = grayKeysSet; - - // Get the allow list dictionary - // (now loaded lazily in SecOTAPKICopyAllowList) - - // Get the trusted Certificate Transparency Logs - otapkiref->_trustedCTLogs = InitializeTrustedCTLogs(path_ptr); - - // Get the pinning list - otapkiref->_pinningList = InitializePinningList(path_ptr); - - // Get the valid update snapshot version and format - CFIndex update_format = 0; - otapkiref->_validSnapshotVersion = InitializeValidSnapshotVersion(&update_format); - otapkiref->_validSnapshotFormat = update_format; - - // Get the valid update snapshot path (if it exists, NULL otherwise) - otapkiref->_validUpdateSnapshot = InitializeValidUpdateSnapshot(); - - // Get the valid database snapshot path (if it exists, NULL otherwise) - otapkiref->_validDatabaseSnapshot = InitializeValidDatabaseSnapshot(); - - CFArrayRef escrowCerts = NULL; - CFArrayRef escrowPCSCerts = NULL; - InitializeEscrowCertificates(path_ptr, &escrowCerts, &escrowPCSCerts); - if (NULL == escrowCerts || NULL == escrowPCSCerts) - { - CFReleaseNull(escrowCerts); - CFReleaseNull(escrowPCSCerts); - CFReleaseNull(otapkiref); - return otapkiref; - } - otapkiref->_escrowCertificates = escrowCerts; - otapkiref->_escrowPCSCertificates = escrowPCSCerts; - - // Get the mapping of EV Policy OIDs to Anchor digest - CFDictionaryRef evOidToAnchorDigestMap = InitializeEVPolicyToAnchorDigestsTable(path_ptr); - if (NULL == evOidToAnchorDigestMap) - { - CFReleaseNull(otapkiref); - return otapkiref; - } - otapkiref->_evPolicyToAnchorMapping = evOidToAnchorDigestMap; - - CFDictionaryRef anchorLookupTable = NULL; - const char* anchorTablePtr = NULL; - - if (!InitializeAnchorTable(path_ptr, &anchorLookupTable, &anchorTablePtr)) - { - CFReleaseSafe(anchorLookupTable); - if (anchorTablePtr) { - free((void *)anchorTablePtr); - } - CFReleaseNull(otapkiref); - return otapkiref; - } - otapkiref->_anchorLookupTable = anchorLookupTable; - otapkiref->_anchorTable = anchorTablePtr; - return otapkiref; -} - -static dispatch_once_t kInitializeOTAPKI = 0; -static const char* kOTAQueueLabel = "com.apple.security.OTAPKIQueue"; -static dispatch_queue_t kOTAQueue; -static SecOTAPKIRef kCurrentOTAPKIRef = NULL; - -SecOTAPKIRef SecOTAPKICopyCurrentOTAPKIRef() -{ - __block SecOTAPKIRef result = NULL; - dispatch_once(&kInitializeOTAPKI, - ^{ - kOTAQueue = dispatch_queue_create(kOTAQueueLabel, NULL); - kCurrentOTAPKIRef = SecOTACreate(); - }); - - dispatch_sync(kOTAQueue, - ^{ - result = kCurrentOTAPKIRef; - CFRetainSafe(result); - }); - return result; -} - - -CFSetRef SecOTAPKICopyBlackListSet(SecOTAPKIRef otapkiRef) -{ - CFSetRef result = NULL; - if (NULL == otapkiRef) - { - return result; - } - - result = otapkiRef->_blackListSet; - CFRetainSafe(result); - return result; -} - - -CFSetRef SecOTAPKICopyGrayList(SecOTAPKIRef otapkiRef) -{ - CFSetRef result = NULL; - if (NULL == otapkiRef) - { - return result; - } - - result = otapkiRef->_grayListSet; - CFRetainSafe(result); - return result; -} - -CFDictionaryRef SecOTAPKICopyAllowList(SecOTAPKIRef otapkiRef) -{ - CFDictionaryRef result = NULL; - if (NULL == otapkiRef) - { - return result; - } - - result = otapkiRef->_allowList; - if (!result) { - result = InitializeAllowList(otapkiRef->_assetPath); - otapkiRef->_allowList = result; - } - - CFRetainSafe(result); - return result; -} - -CFArrayRef SecOTAPKICopyAllowListForAuthKeyID(SecOTAPKIRef otapkiRef, CFStringRef authKeyID) -{ - // %%% temporary performance optimization: - // only load dictionary if we know an allow list exists for this key - const CFStringRef keyIDs[3] = { - CFSTR("7C724B39C7C0DB62A54F9BAA183492A2CA838259"), - CFSTR("65F231AD2AF7F7DD52960AC702C10EEFA6D53B11"), - CFSTR("D2A716207CAFD9959EEB430A19F2E0B9740EA8C7") - }; - CFArrayRef result = NULL; - bool hasAllowList = false; - CFIndex count = (sizeof(keyIDs) / sizeof(keyIDs[0])); - for (CFIndex ix=0; ix_trustedCTLogs; - CFRetainSafe(result); - return result; -} - -CFArrayRef SecOTAPKICopyPinningList(SecOTAPKIRef otapkiRef) { - CFArrayRef result = NULL; - if (NULL == otapkiRef) - { - return result; - } - - result = otapkiRef->_pinningList; - CFRetainSafe(result); - return result; -} - - -/* Returns an array of certificate data (CFDataRef) */ -CFArrayRef SecOTAPKICopyEscrowCertificates(uint32_t escrowRootType, SecOTAPKIRef otapkiRef) -{ - CFMutableArrayRef result = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - if (NULL == otapkiRef) { - return result; - } - - switch (escrowRootType) { - // Note: we shouldn't be getting called to return baseline roots, - // since this function vends production roots by definition. - case kSecCertificateBaselineEscrowRoot: - case kSecCertificateProductionEscrowRoot: - case kSecCertificateBaselineEscrowBackupRoot: - case kSecCertificateProductionEscrowBackupRoot: - if (otapkiRef->_escrowCertificates) { - CFArrayRef escrowCerts = otapkiRef->_escrowCertificates; - CFArrayAppendArray(result, escrowCerts, CFRangeMake(0, CFArrayGetCount(escrowCerts))); - } - break; - case kSecCertificateBaselineEscrowEnrollmentRoot: - case kSecCertificateProductionEscrowEnrollmentRoot: - if (otapkiRef->_escrowCertificates) { - // for enrollment purposes, exclude the v100 root - static const unsigned char V100EscrowRoot[] = { - 0x65,0x5C,0xB0,0x3C,0x39,0x3A,0x32,0xA6,0x0B,0x96, - 0x40,0xC0,0xCA,0x73,0x41,0xFD,0xC3,0x9E,0x96,0xB3 - }; - CFArrayRef escrowCerts = otapkiRef->_escrowCertificates; - CFIndex idx, count = CFArrayGetCount(escrowCerts); - for (idx=0; idx < count; idx++) { - CFDataRef tmpData = (CFDataRef) CFArrayGetValueAtIndex(escrowCerts, idx); - SecCertificateRef tmpCert = (tmpData) ? SecCertificateCreateWithData(NULL, tmpData) : NULL; - CFDataRef sha1Hash = (tmpCert) ? SecCertificateGetSHA1Digest(tmpCert) : NULL; - const uint8_t *dp = (sha1Hash) ? CFDataGetBytePtr(sha1Hash) : NULL; - if (!(dp && !memcmp(V100EscrowRoot, dp, sizeof(V100EscrowRoot))) && tmpData) { - CFArrayAppendValue(result, tmpData); - } - CFReleaseSafe(tmpCert); - } - } - break; - case kSecCertificateBaselinePCSEscrowRoot: - case kSecCertificateProductionPCSEscrowRoot: - if (otapkiRef->_escrowPCSCertificates) { - CFArrayRef escrowPCSCerts = otapkiRef->_escrowPCSCertificates; - CFArrayAppendArray(result, escrowPCSCerts, CFRangeMake(0, CFArrayGetCount(escrowPCSCerts))); - } - break; - default: - break; - } - - return result; -} - - -CFDictionaryRef SecOTAPKICopyEVPolicyToAnchorMapping(SecOTAPKIRef otapkiRef) -{ - CFDictionaryRef result = NULL; - if (NULL == otapkiRef) - { - return result; - } - - result = otapkiRef->_evPolicyToAnchorMapping; - CFRetainSafe(result); - return result; -} - - -CFDictionaryRef SecOTAPKICopyAnchorLookupTable(SecOTAPKIRef otapkiRef) -{ - CFDictionaryRef result = NULL; - if (NULL == otapkiRef) - { - return result; - } - - result = otapkiRef->_anchorLookupTable; - CFRetainSafe(result); - return result; -} - -const char* SecOTAPKIGetAnchorTable(SecOTAPKIRef otapkiRef) -{ - const char* result = NULL; - if (NULL == otapkiRef) - { - return result; - } - - result = otapkiRef->_anchorTable; - return result; -} - -const char* SecOTAPKIGetValidUpdateSnapshot(SecOTAPKIRef otapkiRef) -{ - const char* result = NULL; - if (NULL == otapkiRef) - { - return result; - } - - result = otapkiRef->_validUpdateSnapshot; - return result; -} - -const char* SecOTAPKIGetValidDatabaseSnapshot(SecOTAPKIRef otapkiRef) -{ - const char* result = NULL; - if (NULL == otapkiRef) - { - return result; - } - - result = otapkiRef->_validDatabaseSnapshot; - return result; -} - -CFIndex SecOTAPKIGetValidSnapshotVersion(SecOTAPKIRef otapkiRef) -{ - CFIndex result = 0; - if (NULL == otapkiRef) - { - return result; - } - - result = otapkiRef->_validSnapshotVersion; - return result; -} - -CFIndex SecOTAPKIGetValidSnapshotFormat(SecOTAPKIRef otapkiRef) -{ - CFIndex result = 0; - if (NULL == otapkiRef) - { - return result; - } - - result = otapkiRef->_validSnapshotFormat; - return result; -} - -int SecOTAPKIGetAssetVersion(SecOTAPKIRef otapkiRef) -{ - int result = 0; - if (NULL == otapkiRef) - { - return result; - } - - result = otapkiRef->_assetVersion; - return result; -} - -void SecOTAPKIRefreshData() -{ - TestOTALog("In SecOTAPKIRefreshData\n"); - SecOTAPKIRef new_otaPKRef = SecOTACreate(); - dispatch_sync(kOTAQueue, - ^{ - CFReleaseSafe(kCurrentOTAPKIRef); - kCurrentOTAPKIRef = new_otaPKRef; - }); -} - -/* Returns an array of certificate data (CFDataRef) */ -CFArrayRef SecOTAPKICopyCurrentEscrowCertificates(uint32_t escrowRootType, CFErrorRef* error) -{ - CFArrayRef result = NULL; - - SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef(); - if (NULL == otapkiref) - { - SecError(errSecInternal, error, CFSTR("Unable to get the current OTAPKIRef")); - return result; - } - - result = SecOTAPKICopyEscrowCertificates(escrowRootType, otapkiref); - CFRelease(otapkiref); - - if (NULL == result) - { - SecError(errSecInternal, error, CFSTR("Could not get escrow certificates from the current OTAPKIRef")); - } - return result; -} - -int SecOTAPKIGetCurrentAssetVersion(CFErrorRef* error) -{ - int result = 0; - - SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef(); - if (NULL == otapkiref) - { - SecError(errSecInternal, error, CFSTR("Unable to get the current OTAPKIRef")); - return result; - } - - result = otapkiref->_assetVersion; - return result; -} - -int SecOTAPKISignalNewAsset(CFErrorRef* error) -{ - TestOTALog("SecOTAPKISignalNewAsset has been called!\n"); - SecOTAPKIRefreshData(); - return 1; -} diff --git a/OSX/sec/securityd/OTATrustUtilities.h b/OSX/sec/securityd/OTATrustUtilities.h index 6240d158..9494478b 100644 --- a/OSX/sec/securityd/OTATrustUtilities.h +++ b/OSX/sec/securityd/OTATrustUtilities.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2004,2006-2010,2013-2014 Apple Inc. All Rights Reserved. + * Copyright (c) 2003-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -35,6 +35,9 @@ __BEGIN_DECLS // Opaque type that holds the data for a specific version of the OTA PKI assets typedef struct _OpaqueSecOTAPKI *SecOTAPKIRef; +// Returns a boolean for whether the current instance is the system trustd +bool SecOTAPKIIsSystemTrustd(void); + // Get a reference to the current OTA PKI asset data // Caller is responsible for releasing the returned SecOTAPKIRef CF_EXPORT @@ -65,10 +68,10 @@ CFArrayRef SecOTAPKICopyAllowListForAuthKeyID(SecOTAPKIRef otapkiRef, CFStringRe CF_EXPORT CFArrayRef SecOTAPKICopyTrustedCTLogs(SecOTAPKIRef otapkiRef); -// Accessor to retrieve a copy of the current pinning list. -// Caller is responsible for releasing the returned CFArrayRef +// Accessor to retrieve the path of the current pinning list. +// Caller is responsible for releasing the returned CFURLRef CF_EXPORT -CFArrayRef SecOTAPKICopyPinningList(SecOTAPKIRef otapkiRef); +CFURLRef SecOTAPKICopyPinningList(SecOTAPKIRef otapkiRef); // Accessor to retrieve the array of Escrow certificates. // Caller is responsible for releasing the returned CFArrayRef @@ -116,27 +119,46 @@ CFIndex SecOTAPKIGetValidSnapshotVersion(SecOTAPKIRef otapkiRef); CF_EXPORT CFIndex SecOTAPKIGetValidSnapshotFormat(SecOTAPKIRef otapkiRef); -// Accessor to retrieve the current OTA PKI asset version number +// Accessor to retrieve the OTAPKI trust store version +// Note: Trust store is not mutable by assets CF_EXPORT -int SecOTAPKIGetAssetVersion(SecOTAPKIRef otapkiRef); +uint64_t SecOTAPKIGetTrustStoreVersion(SecOTAPKIRef otapkiRef); -// Signal that a new OTA PKI asset version is available. This call -// will update the current SecOTAPKIRef to now reference the latest -// asset data +// Accessor to retrieve the OTAPKI asset version CF_EXPORT -void SecOTAPKIRefreshData(void); +uint64_t SecOTAPKIGetAssetVersion(SecOTAPKIRef otapkiRef); + +#if __OBJC__ +// SPI to return the current sampling rate for the event name +// This rate is actually n where we sample 1 out of every n +NSNumber *SecOTAPKIGetSamplingRateForEvent(SecOTAPKIRef otapkiRef, NSString *eventName); +#endif // __OBJC__ + +CFArrayRef SecOTAPKICopyAppleCertificateAuthorities(SecOTAPKIRef otapkiRef); // SPI to return the array of currently trusted Escrow certificates CF_EXPORT CFArrayRef SecOTAPKICopyCurrentEscrowCertificates(uint32_t escrowRootType, CFErrorRef* error); +// SPI to return the current OTA PKI trust store version +// Note: Trust store is not mutable by assets +CF_EXPORT +uint64_t SecOTAPKIGetCurrentTrustStoreVersion(CFErrorRef* CF_RETURNS_RETAINED error); + // SPI to return the current OTA PKI asset version CF_EXPORT -int SecOTAPKIGetCurrentAssetVersion(CFErrorRef* error); +uint64_t SecOTAPKIGetCurrentAssetVersion(CFErrorRef* error); + +// SPI to reset the current OTA PKI asset version to the version shipped +// with the system +CF_EXPORT +uint64_t SecOTAPKIResetCurrentAssetVersion(CFErrorRef* CF_RETURNS_RETAINED error); -// SPI to signal securityd to get a new set of trust data +// SPI to signal trustd to get a new set of trust data +// Always returns the current asset version. Returns an error with +// a reason if the update was not successful. CF_EXPORT -int SecOTAPKISignalNewAsset(CFErrorRef* error); +uint64_t SecOTAPKISignalNewAsset(CFErrorRef* CF_RETURNS_RETAINED error); __END_DECLS diff --git a/OSX/sec/securityd/OTATrustUtilities.m b/OSX/sec/securityd/OTATrustUtilities.m new file mode 100644 index 00000000..31f0bad9 --- /dev/null +++ b/OSX/sec/securityd/OTATrustUtilities.m @@ -0,0 +1,1797 @@ +/* + * Copyright (c) 2003-2018 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + * + * OTATrustUtilities.m + */ + +#import +#include "OTATrustUtilities.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "SecFramework.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !TARGET_OS_BRIDGE +#import +#import +#include +#include +#include +#import +#endif + +#if TARGET_OS_OSX +#import +#endif + +static inline bool isNSNumber(id nsType) { + return nsType && [nsType isKindOfClass:[NSNumber class]]; +} + +static inline bool isNSDictionary(id nsType) { + return nsType && [nsType isKindOfClass:[NSDictionary class]]; +} + +static inline bool isNSArray(id nsType) { + return nsType && [nsType isKindOfClass:[NSArray class]]; +} + +#define SECURITYD_ROLE_ACCOUNT 64 +#define ROOT_ACCOUNT 0 + +bool SecOTAPKIIsSystemTrustd() { + static bool result = false; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ +#ifdef NO_SERVER + // Test app running as securityd +#elif TARGET_OS_IPHONE + if (getuid() == SECURITYD_ROLE_ACCOUNT) +#else + if (getuid() == ROOT_ACCOUNT) +#endif + { + result = true; + } + }); + return result; +} + +/* MARK: - */ +/* MARK: System Trust Store */ +static CFStringRef kSecSystemTrustStoreBundlePath = CFSTR("/System/Library/Security/Certificates.bundle"); + +CFGiblisGetSingleton(CFBundleRef, SecSystemTrustStoreGetBundle, bundle, ^{ + CFStringRef bundlePath = NULL; +#if TARGET_OS_SIMULATOR + char *simulatorRoot = getenv("SIMULATOR_ROOT"); + if (simulatorRoot) + bundlePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s%@"), simulatorRoot, kSecSystemTrustStoreBundlePath); +#endif + if (!bundlePath) + bundlePath = CFRetainSafe(kSecSystemTrustStoreBundlePath); + CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, bundlePath, kCFURLPOSIXPathStyle, true); + *bundle = (url) ? CFBundleCreate(kCFAllocatorDefault, url) : NULL; + CFReleaseSafe(url); + CFReleaseSafe(bundlePath); +}) + +static CFURLRef SecSystemTrustStoreCopyResourceURL(CFStringRef resourceName, + CFStringRef resourceType, CFStringRef subDirName) { + CFURLRef url = NULL; + CFBundleRef bundle = SecSystemTrustStoreGetBundle(); + if (bundle) { + url = CFBundleCopyResourceURL(bundle, resourceName, + resourceType, subDirName); + } + if (!url) { + secwarning("resource: %@.%@ in %@ not found", resourceName, + resourceType, subDirName); + } + return url; +} + +static NSURL *SecSystemTrustStoreCopyResourceNSURL(NSString *resourceFileName) { + CFBundleRef bundle = SecSystemTrustStoreGetBundle(); + if (!bundle) { + return NULL; + } + NSURL *resourceDir = CFBridgingRelease(CFBundleCopyResourcesDirectoryURL(bundle)); + if (!resourceDir) { + return NULL; + } + NSURL *fileURL = [NSURL URLWithString:resourceFileName + relativeToURL:resourceDir]; + if (!fileURL) { + secwarning("resource: %@ not found", resourceFileName); + } + return fileURL; +} + +static CFDataRef SecSystemTrustStoreCopyResourceContents(CFStringRef resourceName, + CFStringRef resourceType, CFStringRef subDirName) { + CFURLRef url = SecSystemTrustStoreCopyResourceURL(resourceName, resourceType, subDirName); + CFDataRef data = NULL; + if (url) { + SInt32 error; + if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, + url, &data, NULL, NULL, &error)) { + secwarning("read: %ld", (long) error); + } + CFRelease(url); + } + return data; +} + +/* MARK: - */ +/* MARK: MobileAsset Updates */ +// MARK: Forward Declarations +static uint64_t GetAssetVersion(void); +#if !TARGET_OS_BRIDGE +static BOOL UpdateFromAsset(NSURL *localURL, NSNumber *asset_version); +#endif + +// MARK: Constants +NSString *kOTATrustContentVersionKey = @"MobileAssetContentVersion"; +NSString *kOTATrustContextFilename = @"OTAPKIContext.plist"; +NSString *kOTATrustTrustedCTLogsFilename = @"TrustedCTLogs.plist"; +NSString *kOTATrustAnalyticsSamplingRatesFilename = @"AnalyticsSamplingRates.plist"; +NSString *kOTATrustAppleCertifcateAuthoritiesFilename = @"AppleCertificateAuthorities.plist"; + +#if !TARGET_OS_BRIDGE +const NSString *OTATrustMobileAssetType = @"com.apple.MobileAsset.PKITrustSupplementals"; +#define kOTATrustMobileAssetNotification "com.apple.MobileAsset.PKITrustSupplementals.cached-metadata-updated" +#define kOTATrustOnDiskAssetNotification "com.apple.trustd.asset-updated" +const NSUInteger OTATrustMobileAssetCompatibilityVersion = 1; +#define kOTATrustDefaultUpdatePeriod 60*60*12 // 12 hours +#define kOTATrustMinimumUpdatePeriod 60*5 // 5 min + +#if TARGET_OS_OSX +const CFStringRef kSecSUPrefDomain = CFSTR("com.apple.SoftwareUpdate"); +const CFStringRef kSecSUScanPrefConfigDataInstallKey = CFSTR("ConfigDataInstall"); +#endif + +// MARK: Helper functions +typedef enum { + OTATrustLogLevelDebug, + OTATrustLogLevelInfo, + OTATrustLogLevelNotice, + OTATrustLogLevelError, +} OTATrustLogLevel; + +static void MakeOTATrustError(NSError **error, OTATrustLogLevel level, OSStatus errCode, NSString *format,...) NS_FORMAT_FUNCTION(4,5); + +static void LogLocally(OTATrustLogLevel level, NSString *errorString) { + switch (level) { + case OTATrustLogLevelDebug: + secdebug("OTATrust", "%@", errorString); + break; + case OTATrustLogLevelInfo: + secinfo("OTATrust", "%@", errorString); + break; + case OTATrustLogLevelNotice: + secnotice("OTATrust", "%@", errorString); + break; + case OTATrustLogLevelError: + secerror("OTATrust: %@", errorString); + break; + } +} + +static void LogRemotely(OTATrustLogLevel level, NSError **error) { +#if ENABLE_TRUSTD_ANALYTICS + /* only report errors and notices */ + if (error && level == OTATrustLogLevelError) { + [[TrustdHealthAnalytics logger] logResultForEvent:TrustdHealthAnalyticsEventOTAPKIEvent hardFailure:YES result:*error]; + } else if (error && level == OTATrustLogLevelNotice) { + [[TrustdHealthAnalytics logger] logResultForEvent:TrustdHealthAnalyticsEventOTAPKIEvent hardFailure:NO result:*error]; + } +#endif // ENABLE_TRUSTD_ANALYTICS +} + +static void MakeOTATrustError(NSError **error, OTATrustLogLevel level, OSStatus errCode, NSString *format,...) { + va_list args; + va_start(args, format); + NSString *formattedString = nil; + if (format) { + formattedString = [[NSString alloc] initWithFormat:format arguments:args]; + } + if (error) { + NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init]; + if (format) { + [userInfo setObject:formattedString forKey:NSLocalizedDescriptionKey]; + } + + *error = [NSError errorWithDomain:NSOSStatusErrorDomain + code:errCode + userInfo:userInfo]; + } + + LogLocally(level, formattedString); + LogRemotely(level, error); + va_end(args); +} + +static BOOL CanCheckMobileAsset(void) { + BOOL result = YES; +#if TARGET_OS_OSX + /* Check the user's SU preferences to determine if "Install system data files" is off */ + if (!CFPreferencesSynchronize(kSecSUPrefDomain, kCFPreferencesAnyUser, kCFPreferencesCurrentHost)) { + secerror("OTATrust: unable to synchronize SoftwareUpdate prefs"); + return NO; + } + + id value = nil; + if (CFPreferencesAppValueIsForced(kSecSUScanPrefConfigDataInstallKey, kSecSUPrefDomain)) { + value = CFBridgingRelease(CFPreferencesCopyAppValue(kSecSUScanPrefConfigDataInstallKey, kSecSUPrefDomain)); + } else { + value = CFBridgingRelease(CFPreferencesCopyValue(kSecSUScanPrefConfigDataInstallKey, kSecSUPrefDomain, + kCFPreferencesAnyUser, kCFPreferencesCurrentHost)); + } + if (isNSNumber(value)) { + result = [value boolValue]; + } + + if (!result) { secnotice("OTATrust", "User has disabled system data installation."); } + + /* MobileAsset.framework isn't mastered into the BaseSystem. Check that the MA classes are linked. */ + if (![ASAssetQuery class] || ![ASAsset class] || ![MAAssetQuery class] || ![MAAsset class]) { + secnotice("OTATrust", "Weak-linked MobileAsset framework missing."); + result = NO; + } +#endif + return result; +} + +static BOOL ShouldUpdateWithAsset(NSNumber *asset_version) { + if (![asset_version isKindOfClass:[NSNumber class]]) { + return NO; + } + CFErrorRef error = nil; + uint64_t current_version = SecOTAPKIGetCurrentAssetVersion(&error); + if (error) { + CFReleaseNull(error); + return NO; + } + if ([asset_version compare:[NSNumber numberWithUnsignedLongLong:current_version]] == NSOrderedDescending) { + return YES; + } + return NO; +} + +static bool verify_create_path(const char *path) { + int ret = mkpath_np(path, 0755); + if (!(ret == 0 || ret == EEXIST)) { + secerror("could not create path: %s (%s)", path, strerror(ret)); + return false; + } + return true; +} + +// MARK: File management functions +static NSURL *GetAssetFileURL(NSString *filename) { + /* Make sure the /Library/Keychains directory is there */ +#if TARGET_OS_IPHONE + NSURL *keychainsDirectory = CFBridgingRelease(SecCopyURLForFileInKeychainDirectory(nil)); +#else + NSURL *keychainsDirectory = [NSURL fileURLWithFileSystemRepresentation:"/Library/Keychains/" isDirectory:YES relativeToURL:nil]; +#endif + NSURL *directory = [keychainsDirectory URLByAppendingPathComponent:@"SupplementalsAssets/" isDirectory:YES]; + if (!verify_create_path([directory fileSystemRepresentation])) { + return nil; + } + + if (filename) { + return [directory URLByAppendingPathComponent:filename]; + } else { + return directory; + } +} + +static void DeleteFileWithName(NSString *filename) { + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSError *error = nil; + [fileManager removeItemAtURL:GetAssetFileURL(filename) error:&error]; + if (error) { + secerror("OTATrust: failed to remove %@: %@", filename, error); + } +} + +static void DeleteAssetFromDisk(void) { + if (SecOTAPKIIsSystemTrustd()) { + DeleteFileWithName(kOTATrustContextFilename); + DeleteFileWithName(kOTATrustTrustedCTLogsFilename); + DeleteFileWithName(kOTATrustAnalyticsSamplingRatesFilename); + DeleteFileWithName(kOTATrustAppleCertifcateAuthoritiesFilename); + } +} + +static BOOL WriteAssetVersionToDisk(NSNumber *asset_version) { + if (SecOTAPKIIsSystemTrustd()) { + NSError *error = nil; + NSDictionary *version_dict = @{ kOTATrustContentVersionKey : asset_version }; + [version_dict writeToURL:GetAssetFileURL(kOTATrustContextFilename) error:&error]; + if (error) { + secerror("OTATrust: unable to write asset version to disk: %@", error); + LogRemotely(OTATrustLogLevelError, &error); + return NO; + } + return YES; + } + return NO; +} + + +static BOOL CopyFileToDisk(NSString *filename, NSURL *localURL) { + if (SecOTAPKIIsSystemTrustd()) { + NSFileManager * fileManager = [NSFileManager defaultManager]; + NSError *error = nil; + [fileManager copyItemAtURL:localURL toURL:GetAssetFileURL(filename) error:&error]; + if (error) { + secerror("OTATrust: unable to write CT logs to disk: %@", error); + LogRemotely(OTATrustLogLevelError, &error); + return NO; + } + return YES; + } + return NO; +} + +// MARK: Fetch and Update Functions +#if TARGET_OS_IPHONE +static NSNumber *UpdateAndPurgeAsset(MAAsset *asset, NSNumber *asset_version, NSError **error) { + if (SecPinningDbUpdateFromURL((__bridge CFURLRef)[asset getLocalFileUrl]) && + UpdateFromAsset([asset getLocalFileUrl], asset_version)) { + secnotice("OTATrust", "finished update to version %@ from installed asset. purging asset.", asset_version); +#if ENABLE_TRUSTD_ANALYTICS + [[TrustdHealthAnalytics logger] logSuccessForEventNamed:TrustdHealthAnalyticsEventOTAPKIEvent]; +#endif // ENABLE_TRUSTD_ANALYTICS + [asset purge:^(MAPurgeResult purge_result) { + if (purge_result != MAPurgeSucceeded) { + secerror("OTATrust: purge failed: %ld", (long)purge_result); + } + }]; + return asset_version; + } else { + MakeOTATrustError(error, OTATrustLogLevelError, errSecCallbackFailed, + @"Failed to install new asset version %@ from %@", asset_version, [asset getLocalFileUrl]); + return nil; + } +} + +static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) { + if (!CanCheckMobileAsset()) { + MakeOTATrustError(error, OTATrustLogLevelNotice, errSecServiceNotAvailable, + @"MobileAsset disabled, skipping check."); + return NO; + } + + __block NSNumber *updated_version = nil; + __block dispatch_semaphore_t done = wait ? dispatch_semaphore_create(0) : nil; + __block NSError *ma_error = nil; + secnotice("OTATrust", "begin MobileAsset query for catalog"); + [MAAsset startCatalogDownload:(NSString *)OTATrustMobileAssetType then:^(MADownLoadResult result) { + if (result != MADownloadSucceesful) { + MakeOTATrustError(&ma_error, OTATrustLogLevelError, errSecInternal, + @"failed to download catalog: %ld", (long)result); + return; + } + MAAssetQuery *query = [[MAAssetQuery alloc] initWithType:(NSString *)OTATrustMobileAssetType]; + [query augmentResultsWithState:true]; + + secnotice("OTATrust", "begin MobileAsset metadata sync request"); + MAQueryResult queryResult = [query queryMetaDataSync]; + if (queryResult != MAQuerySucceesful) { + MakeOTATrustError(&ma_error, OTATrustLogLevelError, errSecInternal, + @"failed to query MobileAsset metadata: %ld", (long)queryResult); + return; + } + + if (!query.results) { + MakeOTATrustError(&ma_error, OTATrustLogLevelError, errSecInternal, + @"no results in MobileAsset query"); + return; + } + + bool began_async_job = false; + for (MAAsset *asset in query.results) { + /* Check Compatibility Version against this software version */ + NSNumber *compatibilityVersion = [asset assetProperty:@"_CompatibilityVersion"]; + if (!isNSNumber(compatibilityVersion) || + [compatibilityVersion unsignedIntegerValue] != OTATrustMobileAssetCompatibilityVersion) { + MakeOTATrustError(&ma_error, OTATrustLogLevelNotice, errSecIncompatibleVersion, + @"skipping asset because Compatibility Version doesn't match %@", compatibilityVersion); + continue; + } + /* Check Content Version agains the current content version */ + NSNumber *asset_version = [asset assetProperty:@"_ContentVersion"]; + if (!ShouldUpdateWithAsset(asset_version)) { + MakeOTATrustError(&ma_error, OTATrustLogLevelNotice, errSecDuplicateItem, + @"skipping asset because we already have _ContentVersion %@ (or newer)", asset_version); + continue; + } + + switch (asset.state) { + default: + MakeOTATrustError(&ma_error, OTATrustLogLevelError, errSecInternal, + @"unknown asset state %ld", (long)asset.state); + continue; + case MAInstalled: + /* The asset is already in the cache, get it from disk. */ + secdebug("OTATrust", "OTATrust asset already installed"); + updated_version = UpdateAndPurgeAsset(asset, asset_version, &ma_error); + break; + case MAUnknown: + MakeOTATrustError(&ma_error, OTATrustLogLevelError, errSecInternal, + @"asset is unknown"); + continue; + case MADownloading: + secnotice("OTATrust", "asset is downloading"); + /* fall through */ + case MANotPresent: + secnotice("OTATrust", "begin download of OTATrust asset"); + began_async_job = true; + [asset startDownload:^(MADownLoadResult downloadResult) { + if (downloadResult != MADownloadSucceesful) { + MakeOTATrustError(&ma_error, OTATrustLogLevelError, errSecInternal, + @"failed to download asset: %ld", (long)downloadResult); + return; + } + updated_version = UpdateAndPurgeAsset(asset, asset_version, &ma_error); + if (wait) { + dispatch_semaphore_signal(done); + } + }]; + break; + } /* switch (asset.state) */ + } /* for (MAAsset.. */ + if (wait && !began_async_job) { + dispatch_semaphore_signal(done); + } + }]; /* [MAAsset startCatalogDownload: ] */ + + /* If the caller is waiting for a response, wait up to one minute for the update to complete. + * If the MAAsset callback does not complete in that time, report a timeout. + * If the MAAsset callback completes and did not successfully update, it should report an error; + * forward that error to the caller. + * If the MAAsset callback completes and did not update and did not provide an error; report + * an unknown error. */ + BOOL result = NO; + if (wait) { + if (dispatch_semaphore_wait(done, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60)) != 0) { + MakeOTATrustError(error, OTATrustLogLevelError, errSecNetworkFailure, + @"Failed to get asset metadata within 1 minute."); + } else { + result = (updated_version != nil); + if (error && ma_error) { + *error = ma_error; + } else if (!result) { + MakeOTATrustError(error, OTATrustLogLevelError, errSecInternalComponent, + @"Unknown error occurred."); + } + } + } + return result; +} +#else /* !TARGET_OS_IPHONE */ +/* MobileAssetV2 fails on macOS, so use V1 */ +static NSNumber *UpdateAndPurgeAsset(ASAsset *asset, NSNumber *asset_version, NSError ** error) { + if (SecPinningDbUpdateFromURL((__bridge CFURLRef)[asset localURL]) && + UpdateFromAsset([asset localURL], asset_version)) { + secnotice("OTATrust", "finished update to version %@ from installed asset. purging asset.", asset_version); +#if ENABLE_TRUSTD_ANALYTICS + [[TrustdHealthAnalytics logger] logSuccessForEventNamed:TrustdHealthAnalyticsEventOTAPKIEvent]; +#endif // ENABLE_TRUSTD_ANALYTICS + [asset purge:^(NSError *ma_error) { + if (error) { + secerror("OTATrust: purge failed %@", ma_error); + } + }]; + return asset_version; + } else { + MakeOTATrustError(error, OTATrustLogLevelError, errSecCallbackFailed, + @"Failed to install new asset version %@ from %@", asset_version, [asset localURL]); + return nil; + } +} + +static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) { + if (!CanCheckMobileAsset()) { + MakeOTATrustError(error, OTATrustLogLevelNotice, errSecServiceNotAvailable, + @"MobileAsset disabled, skipping check."); + return NO; + } + + ASAssetQuery *query = [[ASAssetQuery alloc] initWithAssetType:(NSString *)OTATrustMobileAssetType]; + [query setQueriesLocalAssetInformationOnly:isLocalOnly]; // Omitting this leads to a notifcation loop. + NSArray*query_results = [query runQueryAndReturnError:error]; + if (!query_results) { + if (error) { + secerror("OTATrust: asset query failed: %@", *error); + LogRemotely(OTATrustLogLevelError, error); + } + return NO; + } + + __block NSNumber *updated_version = nil; + __block NSError *handler_error = nil; + __block dispatch_semaphore_t done = wait ? dispatch_semaphore_create(0) : nil; + bool began_async_job = false; + for (ASAsset *asset in query_results) { + NSDictionary *attributes = [asset attributes]; + + NSNumber *compatibilityVersion = [attributes objectForKey:ASAttributeCompatibilityVersion]; + if (!isNSNumber(compatibilityVersion) || + [compatibilityVersion unsignedIntegerValue] != OTATrustMobileAssetCompatibilityVersion) { + MakeOTATrustError(error, OTATrustLogLevelNotice, errSecIncompatibleVersion, + @"skipping asset because Compatibility Version doesn't match %@", compatibilityVersion); + continue; + } + + NSNumber *contentVersion = [attributes objectForKey:ASAttributeContentVersion]; + if (!ShouldUpdateWithAsset(contentVersion)) { + MakeOTATrustError(error, OTATrustLogLevelNotice, errSecDuplicateItem, + @"skipping asset because we already have _ContentVersion %@ (or newer)", contentVersion); + continue; + } + + ASProgressHandler OTATrustHandler = ^(NSDictionary *state, NSError *progressError){ + NSString *operationState = nil; + if (progressError) { + MakeOTATrustError(&handler_error, OTATrustLogLevelError, errSecInternal, + @"OTATrust: asset download error: %@", progressError); + if (wait) { + dispatch_semaphore_signal(done); + } + return; + } + + if (!state) { + MakeOTATrustError(&handler_error, OTATrustLogLevelError, errSecInternal, + @"OTATrust: no asset state in progress handler"); + if (wait) { + dispatch_semaphore_signal(done); + } + return; + } + + operationState = [state objectForKey:ASStateOperation]; + secdebug("OTATrust", "Asset state is %@", operationState); + + if (operationState && [operationState isEqualToString:ASOperationCompleted]) { + updated_version = UpdateAndPurgeAsset(asset, contentVersion, &handler_error); + if (wait) { + dispatch_semaphore_signal(done); + } + } + /* Other states keep calling our progress handler until so don't signal */ + }; + + switch ([asset state]) { + case ASAssetStateNotPresent: + secdebug("OTATrust", "OTATrust asset needs to be downloaded"); + asset.progressHandler= OTATrustHandler; + asset.userInitiatedDownload = YES; + [asset beginDownloadWithOptions:@{ASDownloadOptionPriority : ASDownloadPriorityNormal}]; + began_async_job = true; + break; + case ASAssetStateInstalled: + /* The asset is already in the cache, get it from disk. */ + secdebug("OTATrust", "OTATrust asset already installed"); + updated_version = UpdateAndPurgeAsset(asset, contentVersion, error); + break; + case ASAssetStatePaused: + secdebug("OTATrust", "OTATrust asset download paused"); + asset.progressHandler = OTATrustHandler; + asset.userInitiatedDownload = YES; + if (![asset resumeDownloadAndReturnError:error]) { + if (error) { + secerror("OTATrust: failed to resume download of asset: %@", *error); + LogRemotely(OTATrustLogLevelError, error); + } + } else { + began_async_job = true; + } + break; + case ASAssetStateDownloading: + secdebug("OTATrust", "OTATrust asset downloading"); + asset.progressHandler = OTATrustHandler; + asset.userInitiatedDownload = YES; + began_async_job = true; + break; + default: + MakeOTATrustError(error, OTATrustLogLevelError, errSecInternal, + @"unhandled asset state %ld", (long)asset.state); + continue; + } + } + + /* If the caller is waiting for a response, wait up to one minute for the update to complete. + * If the OTATrustHandler does not complete in the time, report a timeout. + * If the OTATrustHandler completes and did not successfully update and it reported an error; + * forward that error to the caller. */ + BOOL result = (updated_version != nil); + if (wait && began_async_job) { + if (dispatch_semaphore_wait(done, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60)) != 0) { + MakeOTATrustError(error, OTATrustLogLevelError, errSecNetworkFailure, + @"Failed to get asset metadata within 1 minute."); + } else { + /* finished an async job, update the result */ + result = (updated_version != nil); + if (error && handler_error) { + *error = handler_error; + } + } + } + + /* If we failed and don't know why, report an unknown error */ + if (!result && error && (*error == NULL)) { + MakeOTATrustError(error, OTATrustLogLevelError, errSecInternalComponent, + @"Unknown error occurred."); + } + return result; +} +#endif /* !TARGET_OS_IPHONE */ + +static void InitializeOTATrustAsset(dispatch_queue_t queue) { + /* Only the "system" trustd does updates */ + if (SecOTAPKIIsSystemTrustd()) { + /* Asynchronously ask MobileAsset for most recent asset. */ + dispatch_async(queue, ^{ + secnotice("OTATrust", "Initial check with MobileAsset for newer PKITrustSupplementals asset"); + (void)DownloadOTATrustAsset(NO, NO, nil); + }); + + /* Register for changes in our asset */ + if (CanCheckMobileAsset()) { + int out_token = 0; + notify_register_dispatch(kOTATrustMobileAssetNotification, &out_token, queue, ^(int __unused token) { + secnotice("OTATrust", "Got notification about a new PKITrustSupplementals asset from mobileassetd."); + (void)DownloadOTATrustAsset(YES, NO, nil); + }); + } + } else { + /* Register for changes signaled by the system trustd */ + secnotice("OTATrust", "Intializing listener for Asset changes from system trustd."); + int out_token = 0; + notify_register_dispatch(kOTATrustOnDiskAssetNotification, &out_token, queue, ^(int __unused token) { + secnotice("OTATrust", "Got notification about a new PKITrustSupplementals asset from system trustd."); + UpdateFromAsset(GetAssetFileURL(nil), [NSNumber numberWithUnsignedLongLong:GetAssetVersion()]); + }); + } +} + +static void TriggerPeriodicOTATrustAssetChecks(dispatch_queue_t queue) { + if (SecOTAPKIIsSystemTrustd()) { + static sec_action_t action; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"com.apple.security"]; + NSNumber *updateDeltas = [defaults valueForKey:@"PKITrustSupplementalsUpdatePeriod"]; + int delta = kOTATrustDefaultUpdatePeriod; + if (isNSNumber(updateDeltas)) { + delta = [updateDeltas intValue]; + if (delta < kOTATrustMinimumUpdatePeriod) { + delta = kOTATrustMinimumUpdatePeriod; + } + } + secnotice("OTATrust", "Setting periodic update delta to %d seconds", delta); + action = sec_action_create_with_queue(queue,"OTATrust", delta); + sec_action_set_handler(action, ^{ + (void)DownloadOTATrustAsset(NO, NO, nil); + }); + }); + sec_action_perform(action); + } +} +#endif /* !TARGET_OS_BRIDGE */ + +/* MARK: - */ +/* MARK: Initialization functions */ +static CFPropertyListRef CFPropertyListCopyFromSystem(CFStringRef asset) { + CFPropertyListRef plist = NULL; + CFDataRef xmlData = SecSystemTrustStoreCopyResourceContents(asset, CFSTR("plist"), NULL); + + if (xmlData) { + plist = CFPropertyListCreateWithData(kCFAllocatorDefault, xmlData, kCFPropertyListImmutable, NULL, NULL); + CFRelease(xmlData); + } + + return plist; +} + +static uint64_t GetSystemVersion(CFStringRef key) { + uint64_t system_version = 0; + int64_t asset_number = 0; + + CFDataRef assetVersionData = SecSystemTrustStoreCopyResourceContents(CFSTR("AssetVersion"), CFSTR("plist"), NULL); + if (NULL != assetVersionData) { + CFPropertyListFormat propFormat; + CFDictionaryRef versionPlist = CFPropertyListCreateWithData(kCFAllocatorDefault, assetVersionData, 0, &propFormat, NULL); + if (NULL != versionPlist && CFDictionaryGetTypeID() == CFGetTypeID(versionPlist)) { + CFNumberRef versionNumber = (CFNumberRef)CFDictionaryGetValue(versionPlist, (const void *)key); + if (NULL != versionNumber){ + CFNumberGetValue(versionNumber, kCFNumberSInt64Type, &asset_number); + if (asset_number < 0) { // Not valid + asset_number = 0; + } + system_version = (uint64_t)asset_number; + } + } + CFReleaseSafe(versionPlist); + CFReleaseSafe(assetVersionData); + } + + return system_version; +} + +static bool ShouldInitializeWithAsset(void) { + uint64_t system_version = GetSystemVersion((__bridge CFStringRef)kOTATrustContentVersionKey); + uint64_t asset_version = GetAssetVersion(); + + if (asset_version > system_version) { + secnotice("OTATrust", "Using asset v%llu instead of system v%llu", asset_version, system_version); + return true; + } + return false; +} + +static CFSetRef CFSetCreateFromPropertyList(CFPropertyListRef plist) { + CFSetRef result = NULL; + + if (plist) { + CFMutableSetRef tempSet = NULL; + if (CFGetTypeID(plist) == CFArrayGetTypeID()) { + tempSet = CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks); + if (NULL == tempSet) { + return result; + } + CFArrayRef array = (CFArrayRef)plist; + CFIndex num_keys = CFArrayGetCount(array); + for (CFIndex idx = 0; idx < num_keys; idx++) { + CFDataRef data = (CFDataRef)CFArrayGetValueAtIndex(array, idx); + CFSetAddValue(tempSet, data); + } + } else { + return result; + } + + result = tempSet; + } + return result; +} + +static CF_RETURNS_RETAINED CFSetRef InitializeBlackList() { + CFPropertyListRef plist = CFPropertyListCopyFromSystem(CFSTR("Blocked")); + CFSetRef result = CFSetCreateFromPropertyList(plist); + CFReleaseSafe(plist); + + return result; +} + +static CF_RETURNS_RETAINED CFSetRef InitializeGrayList() { + CFPropertyListRef plist = CFPropertyListCopyFromSystem(CFSTR("GrayListedKeys")); + CFSetRef result = CFSetCreateFromPropertyList(plist); + CFReleaseSafe(plist); + + return result; +} + +static CF_RETURNS_RETAINED CFURLRef InitializePinningList() { + return SecSystemTrustStoreCopyResourceURL(CFSTR("CertificatePinning"), CFSTR("plist"), NULL); +} + +static CF_RETURNS_RETAINED CFDictionaryRef InitializeAllowList() { + CFPropertyListRef allowList = CFPropertyListCopyFromSystem(CFSTR("Allowed")); + + if (allowList && (CFGetTypeID(allowList) == CFDictionaryGetTypeID())) { + return allowList; + } else { + CFReleaseNull(allowList); + return NULL; + } +} + +static CF_RETURNS_RETAINED CFArrayRef InitializeTrustedCTLogs() { + NSArray *trustedCTLogs = nil; +#if !TARGET_OS_BRIDGE + if (ShouldInitializeWithAsset()) { + trustedCTLogs = [NSArray arrayWithContentsOfURL:GetAssetFileURL(kOTATrustTrustedCTLogsFilename)]; + if (!isNSArray(trustedCTLogs)) { + DeleteAssetFromDisk(); + } + } +#endif + if (!isNSArray(trustedCTLogs)) { + trustedCTLogs = [NSArray arrayWithContentsOfURL:SecSystemTrustStoreCopyResourceNSURL(kOTATrustTrustedCTLogsFilename)]; + } + if (isNSArray(trustedCTLogs)) { + return CFBridgingRetain(trustedCTLogs); + } + return NULL; +} + +static CF_RETURNS_RETAINED CFDictionaryRef InitializeEVPolicyToAnchorDigestsTable() { + CFDictionaryRef result = NULL; + CFPropertyListRef evroots = CFPropertyListCopyFromSystem(CFSTR("EVRoots")); + + if (evroots) { + if (CFGetTypeID(evroots) == CFDictionaryGetTypeID()) { + /* @@@ Ensure that each dictionary key is a dotted list of digits, + each value is an NSArrayRef and each element in the array is a + 20 byte digest. */ + result = (CFDictionaryRef)evroots; + } + else { + secwarning("EVRoot.plist is wrong type."); + CFRelease(evroots); + } + } + + return result; +} + +static CFIndex InitializeValidSnapshotVersion(CFIndex *outFormat) { + CFIndex validVersion = 0; + CFIndex validFormat = 0; + CFDataRef validVersionData = SecSystemTrustStoreCopyResourceContents(CFSTR("ValidUpdate"), CFSTR("plist"), NULL); + if (NULL != validVersionData) + { + CFPropertyListFormat propFormat; + CFDictionaryRef versionPlist = CFPropertyListCreateWithData(kCFAllocatorDefault, validVersionData, 0, &propFormat, NULL); + if (NULL != versionPlist && CFDictionaryGetTypeID() == CFGetTypeID(versionPlist)) + { + CFNumberRef versionNumber = (CFNumberRef)CFDictionaryGetValue(versionPlist, (const void *)CFSTR("Version")); + if (NULL != versionNumber) + { + CFNumberGetValue(versionNumber, kCFNumberCFIndexType, &validVersion); + } + CFNumberRef formatNumber = (CFNumberRef)CFDictionaryGetValue(versionPlist, (const void *)CFSTR("Format")); + if (NULL != formatNumber) + { + CFNumberGetValue(formatNumber, kCFNumberCFIndexType, &validFormat); + } + } + CFReleaseSafe(versionPlist); + CFReleaseSafe(validVersionData); + } + if (outFormat) { + *outFormat = validFormat; + } + return validVersion; +} + +static Boolean PathExists(const char* path, size_t* pFileSize) { + const char *checked_path = (path) ? path : ""; + Boolean result = false; + struct stat sb; + + if (NULL != pFileSize) { + *pFileSize = 0; + } + + int stat_result = stat(checked_path, &sb); + result = (stat_result == 0); + + if (result && !S_ISDIR(sb.st_mode)) { + // It is a file + if (NULL != pFileSize) { + *pFileSize = (size_t)sb.st_size; + } + } + + return result; +} + +static const char* InitializeValidSnapshotData(CFStringRef filename_str) { + char *result = NULL; + const char *base_error_str = "could not get valid snapshot"; + + CFURLRef valid_url = SecSystemTrustStoreCopyResourceURL(filename_str, CFSTR("sqlite3"), NULL); + if (NULL == valid_url) { + secerror("%s", base_error_str); + } else { + CFStringRef valid_str = CFURLCopyFileSystemPath(valid_url, kCFURLPOSIXPathStyle); + char file_path_buffer[PATH_MAX]; + memset(file_path_buffer, 0, PATH_MAX); + if (NULL == valid_str) { + secerror("%s path", base_error_str); + } else { + const char *valid_cstr = CFStringGetCStringPtr(valid_str, kCFStringEncodingUTF8); + if (NULL == valid_cstr) { + if (CFStringGetCString(valid_str, file_path_buffer, PATH_MAX, kCFStringEncodingUTF8)) { + valid_cstr = file_path_buffer; + } + } + if (NULL == valid_cstr) { + secerror("%s path as UTF8 string", base_error_str); + } else { + asprintf(&result, "%s", valid_cstr); + } + } + CFReleaseSafe(valid_str); + } + CFReleaseSafe(valid_url); + if (result && !PathExists(result, NULL)) { + free(result); + result = NULL; + } + return (const char*)result; +} + +static const char* InitializeValidDatabaseSnapshot() { + return InitializeValidSnapshotData(CFSTR("valid")); +} + +static const uint8_t* MapFile(const char* path, size_t* out_file_size) { + int rtn, fd; + const uint8_t *buf = NULL; + struct stat sb; + size_t size = 0; + + if (NULL == path || NULL == out_file_size) { + return NULL; + } + + *out_file_size = 0; + + fd = open(path, O_RDONLY); + if (fd < 0) { return NULL; } + rtn = fstat(fd, &sb); + if (rtn || (sb.st_size > (off_t) ((UINT32_MAX >> 1)-1))) { + close(fd); + return NULL; + } + size = (size_t)sb.st_size; + + buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); + if (!buf || buf == MAP_FAILED) { + secerror("unable to map %s (errno %d)", path, errno); + close(fd); + return NULL; + } + + close(fd); + *out_file_size = size; + return buf; +} + +static void UnMapFile(void* mapped_data, size_t data_size) { + if (!mapped_data) { + return; + } + int rtn = munmap(mapped_data, data_size); + if (rtn != 0) { + secerror("unable to unmap %ld bytes at %p (error %d)", data_size, mapped_data, rtn); + } +} + +struct index_record { + unsigned char hash[CC_SHA1_DIGEST_LENGTH]; + uint32_t offset; +}; +typedef struct index_record index_record; + +static bool InitializeAnchorTable(CFDictionaryRef* pLookupTable, const char** ppAnchorTable) { + + bool result = false; + + if (NULL == pLookupTable || NULL == ppAnchorTable) { + return result; + } + + *pLookupTable = NULL; + *ppAnchorTable = NULL;; + + CFDataRef cert_index_file_data = NULL; + char file_path_buffer[PATH_MAX]; + CFURLRef table_data_url = NULL; + CFStringRef table_data_cstr_path = NULL; + const char* table_data_path = NULL; + const index_record* pIndex = NULL; + size_t index_offset = 0; + size_t index_data_size = 0; + CFMutableDictionaryRef anchorLookupTable = NULL; + uint32_t offset_int_value = 0; + CFNumberRef index_offset_value = NULL; + CFDataRef index_hash = NULL; + CFMutableArrayRef offsets = NULL; + Boolean release_offset = false; + + char* local_anchorTable = NULL; + size_t local_anchorTableSize = 0; + + // local_anchorTable is still NULL so the asset in the system trust store bundle needs to be used. + CFReleaseSafe(cert_index_file_data); + cert_index_file_data = SecSystemTrustStoreCopyResourceContents(CFSTR("certsIndex"), CFSTR("data"), NULL); + if (!cert_index_file_data) { + secerror("could not find certsIndex"); + } + table_data_url = SecSystemTrustStoreCopyResourceURL(CFSTR("certsTable"), CFSTR("data"), NULL); + if (!table_data_url) { + secerror("could not find certsTable"); + } + + if (NULL != table_data_url) { + table_data_cstr_path = CFURLCopyFileSystemPath(table_data_url, kCFURLPOSIXPathStyle); + if (NULL != table_data_cstr_path) { + memset(file_path_buffer, 0, PATH_MAX); + table_data_path = CFStringGetCStringPtr(table_data_cstr_path, kCFStringEncodingUTF8); + if (NULL == table_data_path) { + if (CFStringGetCString(table_data_cstr_path, file_path_buffer, PATH_MAX, kCFStringEncodingUTF8)) { + table_data_path = file_path_buffer; + } + } + local_anchorTable = (char *)MapFile(table_data_path, &local_anchorTableSize); + CFReleaseSafe(table_data_cstr_path); + } + } + CFReleaseSafe(table_data_url); + + if (NULL == local_anchorTable || NULL == cert_index_file_data) { + // we are in trouble + if (NULL != local_anchorTable) { + UnMapFile(local_anchorTable, local_anchorTableSize); + local_anchorTable = NULL; + local_anchorTableSize = 0; + } + CFReleaseSafe(cert_index_file_data); + return result; + } + + // ------------------------------------------------------------------------ + // Now that the locations of the files are known and the table file has + // been mapped into memory, create a dictionary that maps the SHA1 hash of + // normalized issuer to the offset in the mapped anchor table file which + // contains a index_record to the correct certificate + // ------------------------------------------------------------------------ + pIndex = (const index_record*)CFDataGetBytePtr(cert_index_file_data); + index_data_size = CFDataGetLength(cert_index_file_data); + + anchorLookupTable = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + for (index_offset = index_data_size; index_offset > 0; index_offset -= sizeof(index_record), pIndex++) { + offset_int_value = pIndex->offset; + + index_offset_value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &offset_int_value); + index_hash = CFDataCreate(kCFAllocatorDefault, pIndex->hash, CC_SHA1_DIGEST_LENGTH); + + // see if the dictionary already has this key + release_offset = false; + offsets = (CFMutableArrayRef)CFDictionaryGetValue(anchorLookupTable, index_hash); + if (NULL == offsets) { + offsets = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); + release_offset = true; + } + + // Add the offset + CFArrayAppendValue(offsets, index_offset_value); + + // set the key value pair in the dictionary + CFDictionarySetValue(anchorLookupTable, index_hash, offsets); + + CFRelease(index_offset_value); + CFRelease(index_hash); + if (release_offset) { + CFRelease(offsets); + } + } + + CFRelease(cert_index_file_data); + + if (NULL != anchorLookupTable && NULL != local_anchorTable) { + *pLookupTable = anchorLookupTable; + *ppAnchorTable = local_anchorTable; + result = true; + } else { + CFReleaseSafe(anchorLookupTable); + if (NULL != local_anchorTable) { + UnMapFile(local_anchorTable, local_anchorTableSize); + local_anchorTable = NULL; + local_anchorTableSize = 0; + } + } + + return result; +} + +static void InitializeEscrowCertificates(CFArrayRef *escrowRoots, CFArrayRef *escrowPCSRoots) { + CFDataRef file_data = SecSystemTrustStoreCopyResourceContents(CFSTR("AppleESCertificates"), CFSTR("plist"), NULL); + + if (NULL == file_data) { + return; + } + + CFPropertyListFormat propFormat; + CFDictionaryRef certsDictionary = CFPropertyListCreateWithData(kCFAllocatorDefault, file_data, 0, &propFormat, NULL); + if (NULL != certsDictionary && CFDictionaryGetTypeID() == CFGetTypeID((CFTypeRef)certsDictionary)) { + CFArrayRef certs = (CFArrayRef)CFDictionaryGetValue(certsDictionary, CFSTR("ProductionEscrowKey")); + if (NULL != certs && CFArrayGetTypeID() == CFGetTypeID((CFTypeRef)certs) && CFArrayGetCount(certs) > 0) { + *escrowRoots = CFArrayCreateCopy(kCFAllocatorDefault, certs); + } + CFArrayRef pcs_certs = (CFArrayRef)CFDictionaryGetValue(certsDictionary, CFSTR("ProductionPCSEscrowKey")); + if (NULL != pcs_certs && CFArrayGetTypeID() == CFGetTypeID((CFTypeRef)pcs_certs) && CFArrayGetCount(pcs_certs) > 0) { + *escrowPCSRoots = CFArrayCreateCopy(kCFAllocatorDefault, pcs_certs); + } + } + CFReleaseSafe(certsDictionary); + CFRelease(file_data); +} + +static CF_RETURNS_RETAINED CFDictionaryRef InitializeEventSamplingRates() { + NSDictionary *analyticsSamplingRates = nil; + NSDictionary *eventSamplingRates = nil; +#if !TARGET_OS_BRIDGE + if (ShouldInitializeWithAsset()) { + analyticsSamplingRates = [NSDictionary dictionaryWithContentsOfURL:GetAssetFileURL(kOTATrustAnalyticsSamplingRatesFilename)]; + if (!isNSDictionary(analyticsSamplingRates)) { + DeleteAssetFromDisk(); + } + eventSamplingRates = analyticsSamplingRates[@"Events"]; + } +#endif + if (!isNSDictionary(eventSamplingRates)) { + analyticsSamplingRates = [NSDictionary dictionaryWithContentsOfURL:SecSystemTrustStoreCopyResourceNSURL(kOTATrustAnalyticsSamplingRatesFilename)]; + } + if (isNSDictionary(analyticsSamplingRates)) { + eventSamplingRates = analyticsSamplingRates[@"Events"]; + if (isNSDictionary(eventSamplingRates)) { + return CFBridgingRetain(eventSamplingRates); + } + } + return NULL; +} + +static CF_RETURNS_RETAINED CFArrayRef InitializeAppleCertificateAuthorities() { + NSArray *appleCAs = nil; +#if !TARGET_OS_BRIDGE + if (ShouldInitializeWithAsset()) { + appleCAs = [NSArray arrayWithContentsOfURL:GetAssetFileURL(kOTATrustAppleCertifcateAuthoritiesFilename)]; + if (!isNSArray(appleCAs)) { + DeleteAssetFromDisk(); + } + } +#endif + if (!isNSArray(appleCAs)) { + appleCAs = [NSArray arrayWithContentsOfURL:SecSystemTrustStoreCopyResourceNSURL(kOTATrustAppleCertifcateAuthoritiesFilename)]; + } + if (isNSArray(appleCAs)) { + return CFBridgingRetain(appleCAs); + } + return NULL; +} + +/* MARK: - */ +/* MARK: SecOTA */ + +/* We keep track of one OTAPKI reference */ +static SecOTAPKIRef kCurrentOTAPKIRef = NULL; +/* This queue is for making changes to the OTAPKI reference */ +static dispatch_queue_t kOTAQueue = NULL; +/* This queue is for fetching changes to the OTAPKI reference or otherwise doing maintenance activities */ +static dispatch_queue_t kOTABackgroundQueue = NULL; + +struct _OpaqueSecOTAPKI { + CFRuntimeBase _base; + CFSetRef _blackListSet; + CFSetRef _grayListSet; + CFDictionaryRef _allowList; + CFArrayRef _trustedCTLogs; + CFURLRef _pinningList; + CFArrayRef _escrowCertificates; + CFArrayRef _escrowPCSCertificates; + CFDictionaryRef _evPolicyToAnchorMapping; + CFDictionaryRef _anchorLookupTable; + const char* _anchorTable; + uint64_t _trustStoreVersion; + const char* _validDatabaseSnapshot; + CFIndex _validSnapshotVersion; + CFIndex _validSnapshotFormat; + uint64_t _assetVersion; + CFDictionaryRef _eventSamplingRates; + CFArrayRef _appleCAs; +}; + +CFGiblisFor(SecOTAPKI) + +static CF_RETURNS_RETAINED CFStringRef SecOTAPKICopyFormatDescription(CFTypeRef cf, CFDictionaryRef formatOptions) { + SecOTAPKIRef otapkiRef = (SecOTAPKIRef)cf; + return CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR(""), + otapkiRef->_trustStoreVersion, otapkiRef->_assetVersion); +} + +static void SecOTAPKIDestroy(CFTypeRef cf) { + SecOTAPKIRef otapkiref = (SecOTAPKIRef)cf; + + CFReleaseNull(otapkiref->_blackListSet); + CFReleaseNull(otapkiref->_grayListSet); + CFReleaseNull(otapkiref->_escrowCertificates); + CFReleaseNull(otapkiref->_escrowPCSCertificates); + + CFReleaseNull(otapkiref->_evPolicyToAnchorMapping); + CFReleaseNull(otapkiref->_anchorLookupTable); + + CFReleaseNull(otapkiref->_trustedCTLogs); + CFReleaseNull(otapkiref->_pinningList); + CFReleaseNull(otapkiref->_eventSamplingRates); + CFReleaseNull(otapkiref->_appleCAs); + + if (otapkiref->_anchorTable) { + free((void *)otapkiref->_anchorTable); + otapkiref->_anchorTable = NULL; + } + if (otapkiref->_validDatabaseSnapshot) { + free((void *)otapkiref->_validDatabaseSnapshot); + otapkiref->_validDatabaseSnapshot = NULL; + } +} + +static uint64_t GetSystemTrustStoreVersion(void) { + return GetSystemVersion(CFSTR("VersionNumber")); +} + +static uint64_t GetAssetVersion(void) { + @autoreleasepool { + /* Get system asset version */ + uint64_t version = GetSystemVersion((__bridge CFStringRef)kOTATrustContentVersionKey); + +#if !TARGET_OS_BRIDGE + uint64_t asset_version = 0; + NSDictionary *OTAPKIContext = [NSDictionary dictionaryWithContentsOfURL:GetAssetFileURL(kOTATrustContextFilename)]; + if (isNSDictionary(OTAPKIContext)) { + NSNumber *tmpNumber = OTAPKIContext[kOTATrustContentVersionKey]; + if (isNSNumber(tmpNumber)) { + asset_version = [tmpNumber unsignedLongLongValue]; + } + } + + if (asset_version > version) { + return asset_version; + } else { + /* Delete old data */ + DeleteAssetFromDisk(); + } +#endif + return version; + } +} + +static SecOTAPKIRef SecOTACreate() { + + SecOTAPKIRef otapkiref = NULL; + + otapkiref = CFTypeAllocate(SecOTAPKI, struct _OpaqueSecOTAPKI , kCFAllocatorDefault); + + if (NULL == otapkiref) { + return otapkiref; + } + + // Make sure that if this routine has to bail that the clean up + // will do the right thing + memset(otapkiref, 0, sizeof(*otapkiref)); + + // Start off by getting the trust store version + otapkiref->_trustStoreVersion = GetSystemTrustStoreVersion(); + + // Get the set of black listed keys + CFSetRef blackKeysSet = InitializeBlackList(); + if (NULL == blackKeysSet) { + CFReleaseNull(otapkiref); + return otapkiref; + } + otapkiref->_blackListSet = blackKeysSet; + + // Get the set of gray listed keys + CFSetRef grayKeysSet = InitializeGrayList(); + if (NULL == grayKeysSet) { + CFReleaseNull(otapkiref); + return otapkiref; + } + otapkiref->_grayListSet = grayKeysSet; + + // Get the allow list dictionary + // (now loaded lazily in SecOTAPKICopyAllowList) + + // Get the trusted Certificate Transparency Logs + otapkiref->_trustedCTLogs = InitializeTrustedCTLogs(); + + // Get the pinning list + otapkiref->_pinningList = InitializePinningList(); + + // Get the Event Sampling Rates + otapkiref->_eventSamplingRates = InitializeEventSamplingRates(); + + // Get the list of CAs used by Apple + otapkiref->_appleCAs = InitializeAppleCertificateAuthorities(); + + // Get the asset version (after possible reset due to missing asset date) + otapkiref->_assetVersion = GetAssetVersion(); + + // Get the valid update snapshot version and format + CFIndex update_format = 0; + otapkiref->_validSnapshotVersion = InitializeValidSnapshotVersion(&update_format); + otapkiref->_validSnapshotFormat = update_format; + + // Get the valid database snapshot path (if it exists, NULL otherwise) + otapkiref->_validDatabaseSnapshot = InitializeValidDatabaseSnapshot(); + + CFArrayRef escrowCerts = NULL; + CFArrayRef escrowPCSCerts = NULL; + InitializeEscrowCertificates(&escrowCerts, &escrowPCSCerts); + if (NULL == escrowCerts || NULL == escrowPCSCerts) { + CFReleaseNull(escrowCerts); + CFReleaseNull(escrowPCSCerts); + CFReleaseNull(otapkiref); + return otapkiref; + } + otapkiref->_escrowCertificates = escrowCerts; + otapkiref->_escrowPCSCertificates = escrowPCSCerts; + + // Get the mapping of EV Policy OIDs to Anchor digest + CFDictionaryRef evOidToAnchorDigestMap = InitializeEVPolicyToAnchorDigestsTable(); + if (NULL == evOidToAnchorDigestMap) { + CFReleaseNull(otapkiref); + return otapkiref; + } + otapkiref->_evPolicyToAnchorMapping = evOidToAnchorDigestMap; + + CFDictionaryRef anchorLookupTable = NULL; + const char* anchorTablePtr = NULL; + + if (!InitializeAnchorTable(&anchorLookupTable, &anchorTablePtr)) { + CFReleaseSafe(anchorLookupTable); + if (anchorTablePtr) { + free((void *)anchorTablePtr); + } + CFReleaseNull(otapkiref); + return otapkiref; + } + otapkiref->_anchorLookupTable = anchorLookupTable; + otapkiref->_anchorTable = anchorTablePtr; + +#if !TARGET_OS_BRIDGE + /* Initialize our update handling */ + InitializeOTATrustAsset(kOTABackgroundQueue); +#endif + + return otapkiref; +} + +SecOTAPKIRef SecOTAPKICopyCurrentOTAPKIRef() { + __block SecOTAPKIRef result = NULL; + static dispatch_once_t kInitializeOTAPKI = 0; + dispatch_once(&kInitializeOTAPKI, ^{ + @autoreleasepool { + kOTAQueue = dispatch_queue_create("com.apple.security.OTAPKIQueue", NULL); + dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, + QOS_CLASS_BACKGROUND, 0); + attr = dispatch_queue_attr_make_with_autorelease_frequency(attr, DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM); + kOTABackgroundQueue = dispatch_queue_create("com.apple.security.OTAPKIBackgroundQueue", attr); + kCurrentOTAPKIRef = SecOTACreate(); + if (!kOTAQueue || !kOTABackgroundQueue) { + secerror("Failed to create OTAPKI Queues. May crash later."); + } + } + }); + + dispatch_sync(kOTAQueue, ^{ + result = kCurrentOTAPKIRef; + CFRetainSafe(result); + }); + return result; +} + +#if !TARGET_OS_BRIDGE +static BOOL UpdateFromAsset(NSURL *localURL, NSNumber *asset_version) { + if (!localURL || !asset_version) { + secerror("OTATrust: missing url and version for downloaded asset"); + return NO; + } + __block NSArray *newTrustedCTLogs = NULL; + __block uint64_t version = [asset_version unsignedLongLongValue]; + __block NSDictionary *newAnalyticsSamplingRates = NULL; + __block NSArray *newAppleCAs = NULL; + + NSURL *TrustedCTLogsFileLoc = [NSURL URLWithString:kOTATrustTrustedCTLogsFilename + relativeToURL:localURL]; + newTrustedCTLogs = [NSArray arrayWithContentsOfURL:TrustedCTLogsFileLoc]; + if (!newTrustedCTLogs) { + secerror("OTATrust: unable to create TrustedCTLogs from asset file: %@", TrustedCTLogsFileLoc); + return NO; + } + + NSURL *AnalyticsSamplingRatesFileLoc = [NSURL URLWithString:kOTATrustAnalyticsSamplingRatesFilename + relativeToURL:localURL]; + newAnalyticsSamplingRates = [NSDictionary dictionaryWithContentsOfURL:AnalyticsSamplingRatesFileLoc]; + if (!newAnalyticsSamplingRates) { + secerror("OTATrust: unable to create AnalyticsSamplingRates from asset file: %@", AnalyticsSamplingRatesFileLoc); + return NO; + } + + NSURL *AppleCAsFileLoc = [NSURL URLWithString:kOTATrustAppleCertifcateAuthoritiesFilename + relativeToURL:localURL]; + newAppleCAs = [NSArray arrayWithContentsOfURL:AppleCAsFileLoc]; + if (!newAppleCAs) { + secerror("OTATrust: unable to create AppleCAs from asset file: %@", AppleCAsFileLoc); + return NO; + } + + /* Update the Current OTAPKIRef with the new data */ + dispatch_sync(kOTAQueue, ^{ + secnotice("OTATrust", "updating asset version from %llu to %llu", kCurrentOTAPKIRef->_assetVersion, version); + CFRetainAssign(kCurrentOTAPKIRef->_trustedCTLogs, (__bridge CFArrayRef)newTrustedCTLogs); + CFRetainAssign(kCurrentOTAPKIRef->_eventSamplingRates, (__bridge CFDictionaryRef)newAnalyticsSamplingRates); + CFRetainAssign(kCurrentOTAPKIRef->_appleCAs, (__bridge CFArrayRef)newAppleCAs); + kCurrentOTAPKIRef->_assetVersion = version; + }); + + /* Write the data to disk (so that we don't have to re-download the asset on re-launch) */ + DeleteAssetFromDisk(); + if (CopyFileToDisk(kOTATrustTrustedCTLogsFilename, TrustedCTLogsFileLoc) && + CopyFileToDisk(kOTATrustAnalyticsSamplingRatesFilename, AnalyticsSamplingRatesFileLoc) && + CopyFileToDisk(kOTATrustAppleCertifcateAuthoritiesFilename, AppleCAsFileLoc) && + WriteAssetVersionToDisk(asset_version)) { + /* If we successfully updated the "asset" on disk, signal the other trustds to pick up the changes */ + notify_post(kOTATrustOnDiskAssetNotification); + } + + return YES; +} +#endif // !TARGET_OS_BRIDGE + + +CFSetRef SecOTAPKICopyBlackListSet(SecOTAPKIRef otapkiRef) { + if (NULL == otapkiRef) { + return NULL; + } + + return CFRetainSafe(otapkiRef->_blackListSet); +} + + +CFSetRef SecOTAPKICopyGrayList(SecOTAPKIRef otapkiRef) { + if (NULL == otapkiRef) { + return NULL; + } + + return CFRetainSafe(otapkiRef->_grayListSet); +} + +CFDictionaryRef SecOTAPKICopyAllowList(SecOTAPKIRef otapkiRef) { + if (NULL == otapkiRef) { + return NULL; + } + + CFDictionaryRef result = otapkiRef->_allowList; + if (!result) { + result = InitializeAllowList(); + otapkiRef->_allowList = result; + } + + return CFRetainSafe(result); +} + +CFArrayRef SecOTAPKICopyAllowListForAuthKeyID(SecOTAPKIRef otapkiRef, CFStringRef authKeyID) { + // %%% temporary performance optimization: + // only load dictionary if we know an allow list exists for this key + const CFStringRef keyIDs[3] = { + CFSTR("7C724B39C7C0DB62A54F9BAA183492A2CA838259"), + CFSTR("65F231AD2AF7F7DD52960AC702C10EEFA6D53B11"), + CFSTR("D2A716207CAFD9959EEB430A19F2E0B9740EA8C7") + }; + CFArrayRef result = NULL; + bool hasAllowList = false; + CFIndex count = (sizeof(keyIDs) / sizeof(keyIDs[0])); + for (CFIndex ix=0; ix_trustedCTLogs; + CFRetainSafe(result); + return result; +} + +CFURLRef SecOTAPKICopyPinningList(SecOTAPKIRef otapkiRef) { + if (NULL == otapkiRef) { + return NULL; + } + + return CFRetainSafe(otapkiRef->_pinningList); +} + + +/* Returns an array of certificate data (CFDataRef) */ +CFArrayRef SecOTAPKICopyEscrowCertificates(uint32_t escrowRootType, SecOTAPKIRef otapkiRef) { + CFMutableArrayRef result = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); + if (NULL == otapkiRef) { + return result; + } + + switch (escrowRootType) { + // Note: we shouldn't be getting called to return baseline roots, + // since this function vends production roots by definition. + case kSecCertificateBaselineEscrowRoot: + case kSecCertificateProductionEscrowRoot: + case kSecCertificateBaselineEscrowBackupRoot: + case kSecCertificateProductionEscrowBackupRoot: + if (otapkiRef->_escrowCertificates) { + CFArrayRef escrowCerts = otapkiRef->_escrowCertificates; + CFArrayAppendArray(result, escrowCerts, CFRangeMake(0, CFArrayGetCount(escrowCerts))); + } + break; + case kSecCertificateBaselineEscrowEnrollmentRoot: + case kSecCertificateProductionEscrowEnrollmentRoot: + if (otapkiRef->_escrowCertificates) { + // for enrollment purposes, exclude the v100 root + static const unsigned char V100EscrowRoot[] = { + 0x65,0x5C,0xB0,0x3C,0x39,0x3A,0x32,0xA6,0x0B,0x96, + 0x40,0xC0,0xCA,0x73,0x41,0xFD,0xC3,0x9E,0x96,0xB3 + }; + CFArrayRef escrowCerts = otapkiRef->_escrowCertificates; + CFIndex idx, count = CFArrayGetCount(escrowCerts); + for (idx=0; idx < count; idx++) { + CFDataRef tmpData = (CFDataRef) CFArrayGetValueAtIndex(escrowCerts, idx); + SecCertificateRef tmpCert = (tmpData) ? SecCertificateCreateWithData(NULL, tmpData) : NULL; + CFDataRef sha1Hash = (tmpCert) ? SecCertificateGetSHA1Digest(tmpCert) : NULL; + const uint8_t *dp = (sha1Hash) ? CFDataGetBytePtr(sha1Hash) : NULL; + if (!(dp && !memcmp(V100EscrowRoot, dp, sizeof(V100EscrowRoot))) && tmpData) { + CFArrayAppendValue(result, tmpData); + } + CFReleaseSafe(tmpCert); + } + } + break; + case kSecCertificateBaselinePCSEscrowRoot: + case kSecCertificateProductionPCSEscrowRoot: + if (otapkiRef->_escrowPCSCertificates) { + CFArrayRef escrowPCSCerts = otapkiRef->_escrowPCSCertificates; + CFArrayAppendArray(result, escrowPCSCerts, CFRangeMake(0, CFArrayGetCount(escrowPCSCerts))); + } + break; + default: + break; + } + + return result; +} + + +CFDictionaryRef SecOTAPKICopyEVPolicyToAnchorMapping(SecOTAPKIRef otapkiRef) { + if (NULL == otapkiRef) { + return NULL; + } + + return CFRetainSafe(otapkiRef->_evPolicyToAnchorMapping); +} + + +CFDictionaryRef SecOTAPKICopyAnchorLookupTable(SecOTAPKIRef otapkiRef) { + if (NULL == otapkiRef) { + return NULL; + } + + return CFRetainSafe(otapkiRef->_anchorLookupTable); +} + +const char* SecOTAPKIGetAnchorTable(SecOTAPKIRef otapkiRef) { + if (NULL == otapkiRef) { + return NULL; + } + + return otapkiRef->_anchorTable; +} + +const char* SecOTAPKIGetValidDatabaseSnapshot(SecOTAPKIRef otapkiRef) { + if (NULL == otapkiRef) { + return NULL; + } + + return otapkiRef->_validDatabaseSnapshot; +} + +CFIndex SecOTAPKIGetValidSnapshotVersion(SecOTAPKIRef otapkiRef) { + if (NULL == otapkiRef) { + return 0; + } + + return otapkiRef->_validSnapshotVersion; +} + +CFIndex SecOTAPKIGetValidSnapshotFormat(SecOTAPKIRef otapkiRef) { + if (NULL == otapkiRef) { + return 0; + } + + return otapkiRef->_validSnapshotFormat; +} + +uint64_t SecOTAPKIGetTrustStoreVersion(SecOTAPKIRef otapkiRef) { + if (NULL == otapkiRef) { + return 0; + } + + return otapkiRef->_trustStoreVersion; +} + +uint64_t SecOTAPKIGetAssetVersion(SecOTAPKIRef otapkiRef) { + if (NULL == otapkiRef) { + return 0; + } + + return otapkiRef->_assetVersion; +} + +NSNumber *SecOTAPKIGetSamplingRateForEvent(SecOTAPKIRef otapkiRef, NSString *eventName) { + if (NULL == otapkiRef) { + return nil; + } + +#if !TARGET_OS_BRIDGE + /* Trigger periodic background MA checks in system trustd + * We also check on trustd launch and listen for notifications. */ + TriggerPeriodicOTATrustAssetChecks(kOTABackgroundQueue); +#endif + + if (otapkiRef->_eventSamplingRates) { + CFTypeRef value = CFDictionaryGetValue(otapkiRef->_eventSamplingRates, (__bridge CFStringRef)eventName); + if (isNumberOfType(value, kCFNumberSInt64Type)) { + return (__bridge NSNumber *)value; + } + } + return nil; +} + +CFArrayRef SecOTAPKICopyAppleCertificateAuthorities(SecOTAPKIRef otapkiRef) { + if (NULL == otapkiRef) { + return NULL; + } + +#if !TARGET_OS_BRIDGE + /* Trigger periodic background MA checks in system trustd + * We also check on trustd launch and listen for notifications. */ + TriggerPeriodicOTATrustAssetChecks(kOTABackgroundQueue); +#endif + + return CFRetainSafe(otapkiRef->_appleCAs); +} + +/* Returns an array of certificate data (CFDataRef) */ +CFArrayRef SecOTAPKICopyCurrentEscrowCertificates(uint32_t escrowRootType, CFErrorRef* error) { + SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef(); + if (NULL == otapkiref) { + SecError(errSecInternal, error, CFSTR("Unable to get the current OTAPKIRef")); + return NULL; + } + + CFArrayRef result = SecOTAPKICopyEscrowCertificates(escrowRootType, otapkiref); + CFRelease(otapkiref); + + if (NULL == result) { + SecError(errSecInternal, error, CFSTR("Could not get escrow certificates from the current OTAPKIRef")); + } + return result; +} + +uint64_t SecOTAPKIGetCurrentTrustStoreVersion(CFErrorRef* error){ + SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef(); + if (NULL == otapkiref) { + SecError(errSecInternal, error, CFSTR("Unable to get the current OTAPKIRef")); + return 0; + } + + return otapkiref->_trustStoreVersion; +} + +uint64_t SecOTAPKIGetCurrentAssetVersion(CFErrorRef* error) { + SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef(); + if (NULL == otapkiref) { + SecError(errSecInternal, error, CFSTR("Unable to get the current OTAPKIRef")); + return 0; + } + + return otapkiref->_assetVersion; +} + +uint64_t SecOTAPKIResetCurrentAssetVersion(CFErrorRef* error) { + uint64_t system_version = GetSystemVersion((__bridge CFStringRef)kOTATrustContentVersionKey); + + dispatch_sync(kOTAQueue, ^{ + kCurrentOTAPKIRef->_assetVersion = system_version; + }); + +#if !TARGET_OS_BRIDGE + DeleteAssetFromDisk(); +#endif + return system_version; +} + +uint64_t SecOTAPKISignalNewAsset(CFErrorRef* error) { +#if !TARGET_OS_BRIDGE + if (SecOTAPKIIsSystemTrustd()) { + NSError *nserror = nil; + if (!DownloadOTATrustAsset(NO, YES, &nserror) && error) { + *error = CFRetainSafe((__bridge CFErrorRef)nserror); + } + } else { + SecError(errSecServiceNotAvailable, error, CFSTR("This function may ony be performed by the system trustd.")); + } + return GetAssetVersion(); +#else + SecError(errSecUnsupportedService, error, CFSTR("This function is not available on this platform")); + return GetAssetVersion(); +#endif +} diff --git a/OSX/sec/securityd/Regressions/SOSAccountTesting.h b/OSX/sec/securityd/Regressions/SOSAccountTesting.h index fee51336..47805102 100644 --- a/OSX/sec/securityd/Regressions/SOSAccountTesting.h +++ b/OSX/sec/securityd/Regressions/SOSAccountTesting.h @@ -252,12 +252,13 @@ static void accounts_agree_internal(char *label, SOSAccount* left, SOSAccount* r if (leftFullPeer) CFSetAddValue(allowed_identities, SOSFullPeerInfoGetPeerInfo(leftFullPeer)); + CFReleaseNull(leftFullPeer); - SOSFullPeerInfoRef rightFullPeer = [right.trust CopyAccountIdentityPeerInfo]; if (rightFullPeer) CFSetAddValue(allowed_identities, SOSFullPeerInfoGetPeerInfo(rightFullPeer)); + CFReleaseNull(rightFullPeer); unretired_peers_is_subset(label, leftPeers, allowed_identities); @@ -541,8 +542,10 @@ static inline void FeedChangesTo(CFMutableDictionaryRef changes, SOSAccount* acc secnotice("changes", " %@", key); }); - if(CFDictionaryGetCount(account_pending_messages) == 0) + if(CFDictionaryGetCount(account_pending_messages) == 0) { + CFReleaseNull(account_pending_messages); return; + } __block CFMutableArrayRef handled = NULL; [acct performTransaction:^(SOSAccountTransaction * _Nonnull txn) { @@ -719,7 +722,7 @@ static inline SOSAccount* CreateAccountForLocalChanges(CFStringRef name, CFStrin CFStringRef randomSerial = CFStringCreateRandomHexWithLength(8); CFStringRef randomDevID = CFStringCreateRandomHexWithLength(16); SOSAccount* retval = CreateAccountForLocalChangesWithStartingAttributes(name, data_source_name, SOSPeerInfo_iOS, randomSerial, - kCFBooleanTrue, kCFBooleanTrue, kCFBooleanTrue, SOSTransportMessageTypeIDSV2, randomDevID); + kCFBooleanTrue, kCFBooleanTrue, kCFBooleanTrue, SOSTransportMessageTypeKVS, randomDevID); CFReleaseNull(randomSerial); CFReleaseNull(randomDevID); @@ -988,7 +991,7 @@ static inline bool SOSTestJoinThroughPiggyBack(CFDataRef cfpassword, CFStringRef static inline SOSAccount* SOSTestCreateAccountAsSerialClone(CFStringRef name, SOSPeerInfoDeviceClass devClass, CFStringRef serial, CFStringRef idsID) { - return CreateAccountForLocalChangesWithStartingAttributes(name, CFSTR("TestSource"), devClass, serial, kCFBooleanTrue, kCFBooleanTrue, kCFBooleanTrue, SOSTransportMessageTypeIDSV2, idsID); + return CreateAccountForLocalChangesWithStartingAttributes(name, CFSTR("TestSource"), devClass, serial, kCFBooleanTrue, kCFBooleanTrue, kCFBooleanTrue, SOSTransportMessageTypeKVS, idsID); } static inline bool SOSTestMakeGhostInCircle(CFStringRef name, SOSPeerInfoDeviceClass devClass, CFStringRef serial, CFStringRef idsID, diff --git a/OSX/sec/securityd/Regressions/SOSTransportTestTransports.m b/OSX/sec/securityd/Regressions/SOSTransportTestTransports.m index 2adcb1d3..bd9449b3 100644 --- a/OSX/sec/securityd/Regressions/SOSTransportTestTransports.m +++ b/OSX/sec/securityd/Regressions/SOSTransportTestTransports.m @@ -46,6 +46,18 @@ CFMutableArrayRef message_transports = NULL; return self; } +-(void)dealloc { + if(self) { + CFReleaseNull(self->_changes); + CFReleaseNull(self->_circleName); + } +} + +- (void)setChanges:(CFMutableDictionaryRef)changes +{ + CFRetainAssign(self->_changes, changes); +} + -(bool) SOSTransportKeyParameterHandleKeyParameterChanges:(CKKeyParameterTest*) transport data:(CFDataRef) data err:(CFErrorRef) error { SOSAccount* acct = transport.account; @@ -268,7 +280,7 @@ bool SOSTransportCircleTestRemovePendingChange(SOSCircleStorageTransportTest* tr return SOSAccountHandleRetirementMessages(self.account, circle_retirement_messages_table, error); } --(CFArrayRef) handleCircleMessagesAndReturnHandledCopy:(CFMutableDictionaryRef) circle_circle_messages_table err:(CFErrorRef *)error +-(CFArrayRef)CF_RETURNS_RETAINED handleCircleMessagesAndReturnHandledCopy:(CFMutableDictionaryRef) circle_circle_messages_table err:(CFErrorRef *)error { CFMutableArrayRef handledKeys = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); CFDictionaryForEach(circle_circle_messages_table, ^(const void *key, const void *value) { @@ -320,6 +332,11 @@ SOSAccount* SOSTransportCircleTestGetAccount(SOSCircleStorageTransportTest* tran return self; } +- (void)setChanges:(CFMutableDictionaryRef)changes +{ + CFRetainAssign(self->_changes, changes); +} + -(CFIndex) SOSTransportMessageGetTransportType { return kKVSTest; @@ -445,15 +462,17 @@ static bool sendToPeer(SOSMessageKVSTest* transport, CFStringRef circleName, CFS if (peerID) { SOSEngineWithPeerID((SOSEngineRef)transport.engine, peerID, error, ^(SOSPeerRef peer, SOSCoderRef coder, SOSDataSourceRef dataSource, SOSTransactionRef txn, bool *forceSaveState) { - SOSEnginePeerMessageSentBlock sent = NULL; + SOSEnginePeerMessageSentCallback* sentCallback = NULL; CFDataRef message_to_send = NULL; - bool ok = SOSPeerCoderSendMessageIfNeeded([transport SOSTransportMessageGetAccount], (SOSEngineRef)transport.engine, txn, peer, coder, &message_to_send, peerID, false, &sent, error); + bool ok = SOSPeerCoderSendMessageIfNeeded([transport SOSTransportMessageGetAccount], (SOSEngineRef)transport.engine, txn, peer, coder, &message_to_send, peerID, false, &sentCallback, error); if (message_to_send) { CFDictionaryRef peer_dict = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, peerID, message_to_send, NULL); CFDictionarySetValue(SOSTransportMessageKVSTestGetChanges(transport), (__bridge CFStringRef)self->circleName, peer_dict); - SOSPeerCoderConsume(&sent, ok); + SOSEngineMessageCallCallback(sentCallback, ok); CFReleaseSafe(peer_dict); } + + SOSEngineFreeMessageCallback(sentCallback); CFReleaseSafe(message_to_send); }); } @@ -842,15 +861,16 @@ void SOSAccountUpdateTestTransports(SOSAccount* account, CFDictionaryRef gestalt } -static SOSCircleRef SOSAccountEnsureCircleTest(SOSAccount* a, CFStringRef name, CFStringRef accountName) +static CF_RETURNS_RETAINED SOSCircleRef SOSAccountEnsureCircleTest(SOSAccount* a, CFStringRef name, CFStringRef accountName) { CFErrorRef localError = NULL; SOSAccountTrustClassic *trust = a.trust; - SOSCircleRef circle = [a.trust getCircle:&localError]; + SOSCircleRef circle = CFRetainSafe([a.trust getCircle:&localError]); if(!circle || isSOSErrorCoded(localError, kSOSErrorIncompatibleCircle)){ secnotice("circle", "Error retrieving the circle: %@", localError); CFReleaseNull(localError); + CFReleaseNull(circle); circle = SOSCircleCreate(kCFAllocatorDefault, name, &localError); if (circle){ @@ -883,7 +903,7 @@ bool SOSAccountEnsureFactoryCirclesTest(SOSAccount* a, CFStringRef accountName) CFStringRef circle_name = SOSDataSourceFactoryCopyName(a.factory); if(!circle_name) return result; - SOSAccountEnsureCircleTest(a, (CFStringRef)circle_name, accountName); + CFReleaseSafe(SOSAccountEnsureCircleTest(a, (CFStringRef)circle_name, accountName)); CFReleaseNull(circle_name); result = true; diff --git a/OSX/sec/securityd/Regressions/secd-01-items.m b/OSX/sec/securityd/Regressions/secd-01-items.m index a829dc49..80596f4c 100644 --- a/OSX/sec/securityd/Regressions/secd-01-items.m +++ b/OSX/sec/securityd/Regressions/secd-01-items.m @@ -77,6 +77,7 @@ int secd_01_items(int argc, char *const *argv) kSecAttrPort, kSecAttrProtocol, kSecAttrAuthenticationType, + kSecReturnData, kSecValueData }; const void *values[] = { @@ -86,6 +87,7 @@ int secd_01_items(int argc, char *const *argv) eighty, CFSTR("http"), CFSTR("dflt"), + kCFBooleanTrue, pwdata }; diff --git a/OSX/sec/securityd/Regressions/secd-155-otr-negotiation-monitor.m b/OSX/sec/securityd/Regressions/secd-155-otr-negotiation-monitor.m index 7508b9de..e02bc0fa 100644 --- a/OSX/sec/securityd/Regressions/secd-155-otr-negotiation-monitor.m +++ b/OSX/sec/securityd/Regressions/secd-155-otr-negotiation-monitor.m @@ -50,7 +50,7 @@ static bool SOSAccountIsThisPeerIDMe(SOSAccount* account, CFStringRef peerID) { return myPeerID && CFEqualSafe(myPeerID, peerID); } -static void ids_test_sync(SOSAccount* alice_account, SOSAccount* bob_account){ +__unused static void ids_test_sync(SOSAccount* alice_account, SOSAccount* bob_account){ CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); __block bool SyncingCompletedOverIDS = false; @@ -375,7 +375,7 @@ static void tests(void) ok(SOSAccountEnsurePeerRegistration(bob_account, NULL), "ensure peer registration - bob"); - ids_test_sync(alice_account, bob_account); + // ids_test_sync(alice_account, bob_account); } int secd_155_otr_negotiation_monitor(int argc, char *const *argv) diff --git a/OSX/sec/securityd/Regressions/secd-20-keychain_upgrade.m b/OSX/sec/securityd/Regressions/secd-20-keychain_upgrade.m index 3e758520..a333f310 100644 --- a/OSX/sec/securityd/Regressions/secd-20-keychain_upgrade.m +++ b/OSX/sec/securityd/Regressions/secd-20-keychain_upgrade.m @@ -78,6 +78,7 @@ keychain_upgrade(bool musr, const char *dbname) (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccount : @"system-label-me", (id)kSecUseSystemKeychain : (id)kCFBooleanTrue, + (id)kSecValueData : [NSData dataWithBytes:"some data" length:9], }, NULL); is(res, 0, "SecItemAdd(system)"); #endif @@ -89,6 +90,7 @@ keychain_upgrade(bool musr, const char *dbname) res = SecItemAdd((CFDictionaryRef)@{ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccount : @"user-label-me", + (id)kSecValueData : [NSData dataWithBytes:"some data" length:9], }, NULL); is(res, 0, "SecItemAdd(user)"); diff --git a/OSX/sec/securityd/Regressions/secd-21-transmogrify.m b/OSX/sec/securityd/Regressions/secd-21-transmogrify.m index 00eeca6a..9ede92db 100644 --- a/OSX/sec/securityd/Regressions/secd-21-transmogrify.m +++ b/OSX/sec/securityd/Regressions/secd-21-transmogrify.m @@ -79,6 +79,7 @@ secd_21_transmogrify(int argc, char *const *argv) res = SecItemAdd((CFDictionaryRef)@{ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccount : @"user-label-me", + (id)kSecValueData : [NSData dataWithBytes:"password" length:8] }, NULL); is(res, 0, "SecItemAdd(user)"); @@ -108,6 +109,7 @@ secd_21_transmogrify(int argc, char *const *argv) (id)kSecAttrAccount : @"user-label-me", (id)kSecUseSystemKeychain : (id)kCFBooleanTrue, (id)kSecReturnAttributes : (id)kCFBooleanTrue, + (id)kSecReturnData : @(YES) }, (CFTypeRef *)&result); is(res, 0, "SecItemCopyMatching(system)"); @@ -115,6 +117,9 @@ secd_21_transmogrify(int argc, char *const *argv) if (isDictionary(result)) { NSData *data = ((__bridge NSDictionary *)result)[@"musr"]; ok([data isEqual:(__bridge id)SecMUSRGetSystemKeychainUUID()], "item is system keychain"); + + NSData* passwordData = [(__bridge NSDictionary*)result valueForKey:(id)kSecValueData]; + ok([passwordData isEqual:[NSData dataWithBytes:"password" length:8]], "no data found in transmogrified item"); } else { ok(0, "returned item is: %@", result); } @@ -129,6 +134,7 @@ secd_21_transmogrify(int argc, char *const *argv) (id)kSecAttrAccessGroup : @"com.apple.ProtectedCloudStorage", (id)kSecAttrAccessible : (id)kSecAttrAccessibleAfterFirstUnlock, (id)kSecAttrAccount : @"pcs-label-me", + (id)kSecValueData : [NSData dataWithBytes:"some data" length:9], }, &client, NULL, NULL); is(res, true, "SecItemAdd(user)"); @@ -136,10 +142,12 @@ secd_21_transmogrify(int argc, char *const *argv) (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccount : @"pcs-label-me", (id)kSecReturnAttributes : (id)kCFBooleanTrue, + (id)kSecReturnData : @(YES), }, &client, (CFTypeRef *)&result, &error); is(res, true, "SecItemCopyMatching(system): %@", error); ok(isDictionary(result), "result is dictionary"); + ok([[(__bridge NSDictionary*)result valueForKey:(__bridge id)kSecValueData] isEqual:[NSData dataWithBytes:"some data" length:9]], "retrieved data matches stored data"); /* Check that data are in 502 active user keychain */ ok (CFEqualSafe(((__bridge CFDataRef)((__bridge NSDictionary *)result)[@"musr"]), musr), "not in msr 502"); diff --git a/OSX/sec/securityd/Regressions/secd-36-ks-encrypt.m b/OSX/sec/securityd/Regressions/secd-36-ks-encrypt.m index ed3cb12a..d13d6f3d 100644 --- a/OSX/sec/securityd/Regressions/secd-36-ks-encrypt.m +++ b/OSX/sec/securityd/Regressions/secd-36-ks-encrypt.m @@ -40,6 +40,8 @@ int secd_36_ks_encrypt(int argc, char *const *argv) { plan_tests(8); + secd_test_setup_temp_keychain("secd_36_ks_encrypt", NULL); + keybag_handle_t keybag; keybag_state_t state; CFDictionaryRef data = NULL; @@ -64,7 +66,7 @@ int secd_36_ks_encrypt(int argc, char *const *argv) ok(ac = SecAccessControlCreate(NULL, &error), "SecAccessControlCreate: %@", error); ok(SecAccessControlSetProtection(ac, kSecAttrAccessibleWhenUnlocked, &error), "SecAccessControlSetProtection: %@", error); - ret = ks_encrypt_data(keybag, ac, NULL, data, NULL, &enc, true, &error); + ret = ks_encrypt_data(keybag, ac, NULL, data, (__bridge CFDictionaryRef)@{@"persistref" : @"aaa-bbb-ccc"}, NULL, &enc, true, &error); is(true, ret); CFReleaseNull(ac); @@ -73,10 +75,11 @@ int secd_36_ks_encrypt(int argc, char *const *argv) CFMutableDictionaryRef attributes = NULL; uint32_t version = 0; - ret = ks_decrypt_data(keybag, kAKSKeyOpDecrypt, &ac, NULL, enc, NULL, NULL, &attributes, &version, &error); + ret = ks_decrypt_data(keybag, kAKSKeyOpDecrypt, &ac, NULL, enc, NULL, NULL, &attributes, &version, true, NULL, &error); is(true, ret, "ks_decrypt_data: %@", error); - ok(CFEqual(SecAccessControlGetProtection(ac), kSecAttrAccessibleWhenUnlocked), "AccessControl protection is: %@", SecAccessControlGetProtection(ac)); + CFTypeRef aclProtection = ac ? SecAccessControlGetProtection(ac) : NULL; + ok(aclProtection && CFEqual(aclProtection, kSecAttrAccessibleWhenUnlocked), "AccessControl protection is: %@", aclProtection); CFReleaseNull(ac); } diff --git a/OSX/sec/securityd/Regressions/secd-50-message.m b/OSX/sec/securityd/Regressions/secd-50-message.m index 14d92407..418b8133 100644 --- a/OSX/sec/securityd/Regressions/secd-50-message.m +++ b/OSX/sec/securityd/Regressions/secd-50-message.m @@ -124,6 +124,8 @@ __unused static void testDeltaManifestMessage(const char *test_directive, const CFReleaseNull(error); ok(sentMessage = SOSMessageCreateWithManifests(kCFAllocatorDefault, proposed, base, proposed, true, &error), "sentMessage create: %@", error); + CFReleaseNull(base); + CFReleaseNull(proposed); CFReleaseNull(error); ok(data = SOSMessageCreateData(sentMessage, msgid, &error), "sentMessage data create: %@ .. %@", error, sentMessage); CFReleaseNull(error); @@ -182,6 +184,8 @@ __unused static void testObjectsMessage(const char *test_directive, const char * proposed = SOSManifestCreateWithBytes((const uint8_t *)dv2.digest, dv2.count * SOSDigestSize, &error); CFReleaseNull(error); ok(sentMessage = SOSMessageCreateWithManifests(kCFAllocatorDefault, proposed, base, proposed, true, &error), "sentMessage create: %@", error); + CFReleaseNull(base); + CFReleaseNull(proposed); CFDataRef O0, O1, O2, O3; CFDataRef o0 = CFDataCreate(kCFAllocatorDefault, NULL, 0); O0 = testCopyAddedObject(sentMessage, o0); diff --git a/OSX/sec/securityd/Regressions/secd-52-offering-gencount-reset.m b/OSX/sec/securityd/Regressions/secd-52-offering-gencount-reset.m index 2368bba2..1425ec83 100644 --- a/OSX/sec/securityd/Regressions/secd-52-offering-gencount-reset.m +++ b/OSX/sec/securityd/Regressions/secd-52-offering-gencount-reset.m @@ -159,9 +159,10 @@ static void tests(void) is([alice_account getCircleStatus:&error],kSOSCCNotInCircle,"alice is not in the account (%@)", error); is([bob_account getCircleStatus:&error], kSOSCCNotInCircle,"bob is not in the account (%@)", error); is([carol_account getCircleStatus:&error], kSOSCCInCircle,"carol is in the account (%@)", error); - + CFReleaseNull(gencount); CFReleaseNull(cfpassword); + CFReleaseNull(user_privkey); alice_account = nil; bob_account = nil; carol_account = nil; diff --git a/OSX/sec/securityd/Regressions/secd-55-account-incompatibility.m b/OSX/sec/securityd/Regressions/secd-55-account-incompatibility.m index d4177ade..e5c66d62 100644 --- a/OSX/sec/securityd/Regressions/secd-55-account-incompatibility.m +++ b/OSX/sec/securityd/Regressions/secd-55-account-incompatibility.m @@ -94,7 +94,8 @@ static void tests(void) CFReleaseNull(incompatibleDER); is(ProcessChangesUntilNoChange(changes, alice_account, NULL), 1, "updates"); - + + CFReleaseNull(changes); alice_account = nil; bob_account = nil; carol_account = nil; diff --git a/OSX/sec/securityd/Regressions/secd-60-account-cloud-identity.m b/OSX/sec/securityd/Regressions/secd-60-account-cloud-identity.m index 0554e696..9bd82500 100644 --- a/OSX/sec/securityd/Regressions/secd-60-account-cloud-identity.m +++ b/OSX/sec/securityd/Regressions/secd-60-account-cloud-identity.m @@ -59,6 +59,7 @@ static bool purgeICloudIdentity(SOSAccount* account) { SOSFullPeerInfoRef icfpi = SOSCircleCopyiCloudFullPeerInfoRef([account.trust getCircle:NULL], NULL); if(!icfpi) return false; retval = SOSFullPeerInfoPurgePersistentKey(icfpi, NULL); + CFReleaseNull(icfpi); return retval; } @@ -261,11 +262,16 @@ static void tests(void) CFDataRef public_key_hash = SecKeyCopyPublicKeyHash(publicKey); ok(public_key_hash != NULL, "hash is not null"); + CFReleaseNull(publicKey); + SOSAccount* margaret_account = CreateAccountForLocalChanges(CFSTR("margaret"), CFSTR("TestSource")); ok(SOSAccountAssertUserCredentialsAndUpdate(margaret_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error); ok(SOSAccountJoinCirclesAfterRestore_wTxn(margaret_account, &error), "Carole cloud identity joins (%@)", error); + CFReleaseNull(identityArray); + CFReleaseNull(changes); + CFReleaseNull(error); CFReleaseNull(public_key_hash); CFReleaseNull(cfpassword); CFReleaseNull(privKey); diff --git a/OSX/sec/securityd/Regressions/secd-700-sftm.m b/OSX/sec/securityd/Regressions/secd-700-sftm.m new file mode 100644 index 00000000..49280848 --- /dev/null +++ b/OSX/sec/securityd/Regressions/secd-700-sftm.m @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +// +// secd-700-sftm.m +// + +#import +#import "secd_regressions.h" +#import "SecdTestKeychainUtilities.h" + +#import "keychain/Signin Metrics/SFTransactionMetric.h" + +static void test() +{ + SFTransactionMetric *metric = [[SFTransactionMetric alloc] initWithUUID:@"UUID" category:@"CoreCDP"]; + NSError *error = [[NSError alloc] initWithDomain:@"TestErrorDomain" code:42 userInfo:@{}]; + [metric logError:error]; + + NSDictionary* eventAttributes = @{@"wait for initial sync time" : @"90 s", @"event result" : @"success"}; + [metric logEvent:@"event" eventAttributes:eventAttributes]; + + NSDictionary *query = @{ + (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrLabel : @"TestLabel", + (id)kSecAttrAccessGroup : @"com.apple.security.wiiss", + }; + + [metric timeEvent:@"Adding item to keychain" blockToTime:^{ + CFTypeRef result; + SecItemAdd((__bridge CFDictionaryRef)query, &result); + }]; + + [metric signInCompleted]; +} + +int secd_700_sftm(int argc, char *const *argv) +{ + plan_tests(1); + + secd_test_setup_temp_keychain(__FUNCTION__, NULL); + + test(); + + return 0; +} diff --git a/OSX/sec/securityd/Regressions/secd-76-idstransport.m b/OSX/sec/securityd/Regressions/secd-76-idstransport.m index 5ab0c1aa..164c56f0 100644 --- a/OSX/sec/securityd/Regressions/secd-76-idstransport.m +++ b/OSX/sec/securityd/Regressions/secd-76-idstransport.m @@ -57,7 +57,7 @@ -static int kTestTestCount = 90; +static int kTestTestCount = 73; static void tests() { diff --git a/OSX/sec/securityd/Regressions/secd-81-item-acl-stress.m b/OSX/sec/securityd/Regressions/secd-81-item-acl-stress.m index 54163ddc..921af46b 100644 --- a/OSX/sec/securityd/Regressions/secd-81-item-acl-stress.m +++ b/OSX/sec/securityd/Regressions/secd-81-item-acl-stress.m @@ -202,6 +202,8 @@ static void fillItem(CFMutableDictionaryRef item, uint32_t num) CFDictionarySetValue(item, attr, value); CFReleaseSafe(value); }); + + CFDictionarySetValue(item, kSecValueData, (__bridge CFDataRef)[NSData dataWithBytes:"some data" length:9]); } static void tests(bool isPasscodeSet) diff --git a/OSX/sec/securityd/Regressions/secd-81-item-acl.m b/OSX/sec/securityd/Regressions/secd-81-item-acl.m index a1fb2dae..4db56a5c 100644 --- a/OSX/sec/securityd/Regressions/secd-81-item-acl.m +++ b/OSX/sec/securityd/Regressions/secd-81-item-acl.m @@ -192,6 +192,8 @@ static void fillItem(CFMutableDictionaryRef item, uint32_t num) CFDictionarySetValue(item, attr, value); CFReleaseSafe(value); }); + + CFDictionarySetValue(item, kSecValueData, (__bridge CFDataRef)[NSData dataWithBytes:"some data" length:9]); } #if LA_CONTEXT_IMPLEMENTED @@ -266,7 +268,9 @@ static void item_with_application_password(uint32_t *item_num) CFDictionarySetValue(item, kSecUseCredentialReference, credRefData); ok_status(SecItemAdd(item, NULL), "add local - acl with application password and user present"); LASetErrorCodeBlock(authFailedBlock); + CFDictionarySetValue(item, kSecReturnData, kCFBooleanTrue); is_status(SecItemCopyMatching(item, NULL), errSecAuthFailed, "find local - acl with application password and user present"); + CFDictionaryRemoveValue(item, kSecReturnData); LASetErrorCodeBlock(okBlock); set_app_password(acmContext); ok_status(SecItemDelete(item), "delete local - acl with application password and user present"); diff --git a/OSX/sec/securityd/Regressions/secd60-account-cloud-exposure.m b/OSX/sec/securityd/Regressions/secd60-account-cloud-exposure.m index 23a59fb4..ca6f7fd9 100644 --- a/OSX/sec/securityd/Regressions/secd60-account-cloud-exposure.m +++ b/OSX/sec/securityd/Regressions/secd60-account-cloud-exposure.m @@ -65,9 +65,11 @@ static bool SOSAccountResetCircleToNastyOffering(SOSAccount* account, SecKeyRef SecKeyRef userPub = SecKeyCreatePublicFromPrivate(userPriv); SOSAccountTrustClassic *trust = account.trust; if(!SOSAccountHasCircle(account, error)){ + CFReleaseNull(userPub); return result; } if(![account.trust ensureFullPeerAvailable:(__bridge CFDictionaryRef)(account.gestalt) deviceID:(__bridge CFStringRef)(account.deviceID) backupKey:(__bridge CFDataRef)(account.backup_key) err:error]){ + CFReleaseNull(userPub); return result; } (void) [account.trust resetAllRings:account err:error]; @@ -88,17 +90,22 @@ static bool SOSAccountResetCircleToNastyOffering(SOSAccount* account, SecKeyRef [trust setDepartureCode:kSOSNeverLeftCircle]; result = true; - [trust setTrustedCircle:SOSCircleCopyCircle(kCFAllocatorDefault, circle, error)]; + SOSCircleRef copiedCircle = SOSCircleCopyCircle(kCFAllocatorDefault, circle, error); // I don't think this copy is necessary, but... + [trust setTrustedCircle:copiedCircle]; + CFReleaseNull(copiedCircle); SOSAccountPublishCloudParameters(account, NULL); trust.fullPeerInfo = nil; err_out: - if (result == false) - secerror("error resetting circle (%@) to offering: %@", circle, localError); + if (result == false) { + secerror("error resetting circle (%@) to offering: %@", circle, localError); + } if (localError && error && *error == NULL) { *error = localError; localError = NULL; } + + CFReleaseNull(iCloudfpi); CFReleaseNull(localError); return result; }]; diff --git a/OSX/sec/securityd/Regressions/secd_77_ids_messaging.m b/OSX/sec/securityd/Regressions/secd_77_ids_messaging.m index 862be40d..a23cdabb 100644 --- a/OSX/sec/securityd/Regressions/secd_77_ids_messaging.m +++ b/OSX/sec/securityd/Regressions/secd_77_ids_messaging.m @@ -62,7 +62,7 @@ static bool SOSAccountIsThisPeerIDMe(SOSAccount* account, CFStringRef peerID) { return myPeerID && CFEqualSafe(myPeerID, peerID); } -static void ids_test_sync(SOSAccount* alice_account, SOSAccount* bob_account){ +__unused static void ids_test_sync(SOSAccount* alice_account, SOSAccount* bob_account){ CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); __block bool SyncingCompletedOverIDS = false; @@ -275,7 +275,7 @@ static void tests() ok(SOSAccountEnsurePeerRegistration(bob_account, NULL), "ensure peer registration - bob"); - ids_test_sync(alice_account, bob_account); + //ids_test_sync(alice_account, bob_account); CFReleaseNull(bob_dsid); CFReleaseNull(alice_dsid); diff --git a/OSX/sec/securityd/Regressions/secd_regressions.h b/OSX/sec/securityd/Regressions/secd_regressions.h index 845ccbf1..70a8fe41 100644 --- a/OSX/sec/securityd/Regressions/secd_regressions.h +++ b/OSX/sec/securityd/Regressions/secd_regressions.h @@ -97,5 +97,6 @@ ONE_TEST(secd_200_logstate) ONE_TEST(secd_201_coders) ONE_TEST(secd_202_recoverykey) ONE_TEST(secd_210_keyinterest) +ONE_TEST(secd_700_sftm) DISABLED_ONE_TEST(secd_230_keybagtable) diff --git a/OSX/sec/securityd/SFKeychainControlManager.h b/OSX/sec/securityd/SFKeychainControlManager.h new file mode 100644 index 00000000..52f06c67 --- /dev/null +++ b/OSX/sec/securityd/SFKeychainControlManager.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include + +XPC_RETURNS_RETAINED _Nullable xpc_endpoint_t SecServerCreateKeychainControlEndpoint(void); + +#ifdef __OBJC__ + +#import "SFKeychainControl.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SFKeychainControlManager : NSObject + ++ (instancetype)sharedManager; + +- (NSArray*)findCorruptedItemsWithError:(NSError**)error; +- (bool)deleteCorruptedItemsWithError:(NSError**)error; + +- (nullable xpc_endpoint_t)xpcControlEndpoint; + +NS_ASSUME_NONNULL_END + +@end + +#endif diff --git a/OSX/sec/securityd/SFKeychainControlManager.m b/OSX/sec/securityd/SFKeychainControlManager.m new file mode 100644 index 00000000..ede2edda --- /dev/null +++ b/OSX/sec/securityd/SFKeychainControlManager.m @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import "SFKeychainControlManager.h" +#import "SecCFError.h" +#import "builtin_commands.h" +#import "debugging.h" +#import +#import +#import + +NSString* kSecEntitlementKeychainControl = @"com.apple.private.keychain.keychaincontrol"; + +XPC_RETURNS_RETAINED xpc_endpoint_t SecServerCreateKeychainControlEndpoint(void) +{ + return [[SFKeychainControlManager sharedManager] xpcControlEndpoint]; +} + +@implementation SFKeychainControlManager { + NSXPCListener* _listener; +} + ++ (instancetype)sharedManager +{ + static SFKeychainControlManager* manager = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + manager = [[SFKeychainControlManager alloc] _init]; + }); + + return manager; +} + +- (instancetype)_init +{ + if (self = [super init]) { + _listener = [NSXPCListener anonymousListener]; + _listener.delegate = self; + [_listener resume]; + } + + return self; +} + +- (xpc_endpoint_t)xpcControlEndpoint +{ + return [_listener.endpoint _endpoint]; +} + +- (BOOL)listener:(NSXPCListener*)listener shouldAcceptNewConnection:(NSXPCConnection*)newConnection +{ + NSNumber* entitlementValue = [newConnection valueForEntitlement:kSecEntitlementKeychainControl]; + if (![entitlementValue isKindOfClass:[NSNumber class]] || !entitlementValue.boolValue) { + secerror("SFKeychainControl: Client pid (%d) doesn't have entitlement: %@", newConnection.processIdentifier, kSecEntitlementKeychainControl); + return NO; + } + + NSXPCInterface* interface = [NSXPCInterface interfaceWithProtocol:@protocol(SFKeychainControl)]; + [interface setClass:[NSError class] forSelector:@selector(rpcFindCorruptedItemsWithReply:) argumentIndex:1 ofReply:YES]; + [interface setClass:[NSError class] forSelector:@selector(rpcDeleteCorruptedItemsWithReply:) argumentIndex:1 ofReply:YES]; + newConnection.exportedInterface = interface; + newConnection.exportedObject = self; + [newConnection resume]; + return YES; +} + +- (NSArray*)findCorruptedItemsWithError:(NSError**)error +{ + NSMutableArray* corruptedItems = [[NSMutableArray alloc] init]; + NSMutableArray* underlyingErrors = [[NSMutableArray alloc] init]; + + CFTypeRef genericPasswords = NULL; + NSDictionary* genericPasswordsQuery = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecReturnPersistentRef : @(YES), + (id)kSecAttrNoLegacy : @(YES), + (id)kSecMatchLimit : (id)kSecMatchLimitAll }; + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)genericPasswordsQuery, &genericPasswords); + CFErrorRef genericPasswordError = NULL; + if (status != errSecItemNotFound) { + SecError(status, &genericPasswordError, CFSTR("generic password query failed")); + if (genericPasswordError) { + [underlyingErrors addObject:CFBridgingRelease(genericPasswordError)]; + } + } + + CFTypeRef internetPasswords = NULL; + NSDictionary* internetPasswordsQuery = @{ (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecReturnPersistentRef : @(YES), + (id)kSecAttrNoLegacy : @(YES), + (id)kSecMatchLimit : (id)kSecMatchLimitAll }; + status = SecItemCopyMatching((__bridge CFDictionaryRef)internetPasswordsQuery, &internetPasswords); + CFErrorRef internetPasswordError = NULL; + if (status != errSecItemNotFound) { + SecError(status, &internetPasswordError, CFSTR("internet password query failed")); + if (internetPasswordError) { + [underlyingErrors addObject:CFBridgingRelease(internetPasswordError)]; + } + } + + CFTypeRef keys = NULL; + NSDictionary* keysQuery = @{ (id)kSecClass : (id)kSecClassKey, + (id)kSecReturnPersistentRef : @(YES), + (id)kSecAttrNoLegacy : @(YES), + (id)kSecMatchLimit : (id)kSecMatchLimitAll }; + status = SecItemCopyMatching((__bridge CFDictionaryRef)keysQuery, &keys); + CFErrorRef keyError = NULL; + if (status != errSecItemNotFound) { + if (keyError) { + [underlyingErrors addObject:CFBridgingRelease(keyError)]; + } + } + + CFTypeRef certificates = NULL; + NSDictionary* certificateQuery = @{ (id)kSecClass : (id)kSecClassCertificate, + (id)kSecReturnPersistentRef : @(YES), + (id)kSecAttrNoLegacy : @(YES), + (id)kSecMatchLimit : (id)kSecMatchLimitAll }; + status = SecItemCopyMatching((__bridge CFDictionaryRef)certificateQuery, &certificates); + CFErrorRef certificateError = NULL; + if (status != errSecItemNotFound) { + SecError(status, &certificateError, CFSTR("certificate query failed")); + if (certificateError) { + [underlyingErrors addObject:CFBridgingRelease(certificateError)]; + } + } + + void (^scanArrayForCorruptedItem)(CFTypeRef, NSString*) = ^(CFTypeRef items, NSString* class) { + if ([(__bridge NSArray*)items isKindOfClass:[NSArray class]]) { + NSLog(@"scanning %d %@", (int)CFArrayGetCount(items), class); + for (NSData* persistentRef in (__bridge NSArray*)items) { + NSDictionary* itemQuery = @{ (id)kSecClass : class, + (id)kSecValuePersistentRef : persistentRef, + (id)kSecReturnAttributes : @(YES), + (id)kSecAttrNoLegacy : @(YES) }; + CFTypeRef itemAttributes = NULL; + OSStatus copyStatus = SecItemCopyMatching((__bridge CFDictionaryRef)itemQuery, &itemAttributes); + if (copyStatus != errSecSuccess && status != errSecInteractionNotAllowed) { + [corruptedItems addObject:itemQuery]; + } + } + } + }; + + scanArrayForCorruptedItem(genericPasswords, (id)kSecClassGenericPassword); + scanArrayForCorruptedItem(internetPasswords, (id)kSecClassInternetPassword); + scanArrayForCorruptedItem(keys, (id)kSecClassKey); + scanArrayForCorruptedItem(certificates, (id)kSecClassCertificate); + + if (underlyingErrors.count > 0 && error) { + *error = [NSError errorWithDomain:@"com.apple.security.keychainhealth" code:1 userInfo:@{ NSLocalizedDescriptionKey : [NSString stringWithFormat:@"encountered %d errors searching for corrupted items", (int)underlyingErrors.count], NSUnderlyingErrorKey : underlyingErrors.firstObject, @"searchingErrorCount" : @(underlyingErrors.count) }]; + } + + return corruptedItems; +} + +- (bool)deleteCorruptedItemsWithError:(NSError**)error +{ + NSError* findError = nil; + NSArray* corruptedItems = [self findCorruptedItemsWithError:&findError]; + bool success = findError == nil; + + NSMutableArray* deleteErrors = [[NSMutableArray alloc] init]; + for (NSDictionary* corruptedItem in corruptedItems) { + OSStatus status = SecItemDelete((__bridge CFDictionaryRef)corruptedItem); + if (status != errSecSuccess) { + success = false; + CFErrorRef deleteError = NULL; + SecError(status, &deleteError, CFSTR("failed to delete corrupted item")); + [deleteErrors addObject:CFBridgingRelease(deleteError)]; + } + } + + if (error && (findError || deleteErrors.count > 0)) { + *error = [NSError errorWithDomain:@"com.apple.security.keychainhealth" code:2 userInfo:@{ NSLocalizedDescriptionKey : [NSString stringWithFormat:@"encountered %@ errors searching for corrupted items and %d errors attempting to delete corrupted items", findError.userInfo[@"searchingErrorCount"], (int)deleteErrors.count]}]; + } + + return success; +} + +- (void)rpcFindCorruptedItemsWithReply:(void (^)(NSArray* corruptedItems, NSError* error))reply +{ + NSError* error = nil; + NSArray* corruptedItems = [self findCorruptedItemsWithError:&error]; + reply(corruptedItems, error); +} + +- (void)rpcDeleteCorruptedItemsWithReply:(void (^)(bool success, NSError* error))reply +{ + NSError* error = nil; + bool success = [self deleteCorruptedItemsWithError:&error]; + reply(success, error); +} + +@end diff --git a/OSX/sec/securityd/SOSCloudCircleServer.h b/OSX/sec/securityd/SOSCloudCircleServer.h index c0e0f394..81340ab4 100644 --- a/OSX/sec/securityd/SOSCloudCircleServer.h +++ b/OSX/sec/securityd/SOSCloudCircleServer.h @@ -35,7 +35,7 @@ __BEGIN_DECLS // // MARK: Server versions of our SPI // -bool SOSCCTryUserCredentials_Server(CFStringRef user_label, CFDataRef user_password, CFErrorRef *error); +bool SOSCCTryUserCredentials_Server(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error); bool SOSCCSetUserCredentials_Server(CFStringRef user_label, CFDataRef user_password, CFErrorRef *error); bool SOSCCSetUserCredentialsAndDSID_Server(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error); @@ -191,11 +191,14 @@ void sync_the_last_data_to_kvs(CFTypeRef account, bool waitForeverForSynchroniza bool SOSCCMessageFromPeerIsPending_Server(SOSPeerInfoRef peer, CFErrorRef *error); bool SOSCCSendToPeerIsPending_Server(SOSPeerInfoRef peer, CFErrorRef *error); -XPC_RETURNS_RETAINED xpc_endpoint_t SOSCCCreateSOSEndpoint_server(CFErrorRef *error); void SOSCCPerformWithOctagonSigningKey(void (^action)(SecKeyRef octagonPrivKey, CFErrorRef error)); +void SOSCCPerformWithOctagonSigningPublicKey(void (^action)(SecKeyRef octagonPublicKey, CFErrorRef error)); void SOSCCPerformWithOctagonEncryptionKey(void (^action)(SecKeyRef octagonPrivEncryptionKey, CFErrorRef error)); +void SOSCCPerformWithOctagonEncryptionPublicKey(void (^action)(SecKeyRef octagonPublicEncryptionKey, CFErrorRef error)); +void SOSCCPerformWithAllOctagonKeys(void (^action)(SecKeyRef octagonEncryptionKey, SecKeyRef octagonSigningKey, CFErrorRef error)); void SOSCCPerformWithTrustedPeers(void (^action)(CFSetRef sosPeerInfoRefs, CFErrorRef error)); +void SOSCCPerformWithPeerID(void (^action)(CFStringRef peerID, CFErrorRef error)); void SOSCCResetOTRNegotiation_Server(CFStringRef peerid); void SOSCCPeerRateLimiterSendNextMessage_Server(CFStringRef peerid, CFStringRef accessGroup); diff --git a/OSX/sec/securityd/SOSCloudCircleServer.m b/OSX/sec/securityd/SOSCloudCircleServer.m index b49cb6ee..c70e58dd 100644 --- a/OSX/sec/securityd/SOSCloudCircleServer.m +++ b/OSX/sec/securityd/SOSCloudCircleServer.m @@ -363,7 +363,8 @@ static void SOSCCProcessGestaltUpdate(SCDynamicStoreRef store, CFArrayRef keys, if(txn.account){ CFDictionaryRef gestalt = CreateDeviceGestaltDictionary(store, keys, context); if ([txn.account.trust updateGestalt:txn.account newGestalt:gestalt]) { - notify_post(kSOSCCCircleChangedNotification); + // we used to notify_post(kSOSCCCircleChangedNotification); + secnotice("circleOps", "Changed our peer's gestalt information. This is not a circle change."); } CFReleaseSafe(gestalt); } @@ -454,27 +455,33 @@ static SOSAccount* GetSharedAccount(void) { CFSetRef applicant_additions, CFSetRef applicant_removals) { CFErrorRef pi_error = NULL; SOSPeerInfoRef me = sSharedAccount.peerInfo; - if (!me) { - secerror("Error finding me for change: %@", pi_error); + if(!me) { + secinfo("circleOps", "Change block called with no peerInfo"); + return; + } + + if(!SOSCircleHasPeer(circle, me, NULL)) { + secinfo("circleOps", "Change block called while not in circle"); + return; + } + + // TODO: Figure out why peer_additions isn't right in some cases (like when joining a v2 circle with a v0 peer. + if (CFSetGetCount(peer_additions) != 0) { + secnotice("updates", "Requesting Ensure Peer Registration."); + SOSCloudKeychainRequestEnsurePeerRegistration(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), NULL); } else { - // TODO: Figure out why peer_additions isn't right in some cases (like when joining a v2 circle with a v0 peer. - if (SOSCircleHasPeer(circle, me, NULL) && CFSetGetCount(peer_additions) != 0) { - secnotice("updates", "Requesting Ensure Peer Registration."); - SOSCloudKeychainRequestEnsurePeerRegistration(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), NULL); - } else { - secinfo("updates", "Not requesting Ensure Peer Registration, since it's not needed"); - } - - if (CFSetContainsValue(peer_additions, me)) { - // TODO: Potentially remove from here and move this to the engine - // TODO: We also need to do this when our views change. - CFMutableSetRef peers = SOSCircleCopyPeers(circle, kCFAllocatorDefault); - CFSetRemoveValue(peers, me); - if (!CFSetIsEmpty(peers)) { - SOSCCRequestSyncWithPeers(peers); - } - CFReleaseNull(peers); + secinfo("updates", "Not requesting Ensure Peer Registration, since it's not needed"); + } + + if (CFSetContainsValue(peer_additions, me)) { + // TODO: Potentially remove from here and move this to the engine + // TODO: We also need to do this when our views change. + CFMutableSetRef peers = SOSCircleCopyPeers(circle, kCFAllocatorDefault); + CFSetRemoveValue(peers, me); + if (!CFSetIsEmpty(peers)) { + SOSCCRequestSyncWithPeers(peers); } + CFReleaseNull(peers); } CFReleaseNull(pi_error); @@ -497,6 +504,7 @@ static SOSAccount* GetSharedAccount(void) { CFReleaseNull(localError); CFReleaseNull(removed); } + secnotice("circleOps", "peer counts changed, posting kSOSCCCircleChangedNotification"); notify_post(kSOSCCCircleChangedNotification); } }); @@ -511,10 +519,10 @@ static SOSAccount* GetSharedAccount(void) { CFErrorRef error = NULL; handledKeys = SOSTransportDispatchMessages(txn, changes, &error); - if (!handledKeys) { + if (!handledKeys || error) { secerror("Error handling updates: %@", error); - CFReleaseNull(error); } + CFReleaseNull(error); }); CFReleaseSafe(changes); return handledKeys; @@ -546,12 +554,14 @@ CFTypeRef GetSharedAccountRef(void) } static void do_with_account(void (^action)(SOSAccountTransaction* txn)) { - SOSAccount* account = GetSharedAccount(); + @autoreleasepool { + SOSAccount* account = GetSharedAccount(); - if(account){ - [account performTransaction:^(SOSAccountTransaction * _Nonnull txn) { - action(txn); - }]; + if(account){ + [account performTransaction:^(SOSAccountTransaction * _Nonnull txn) { + action(txn); + }]; + } } } @@ -613,6 +623,7 @@ static bool do_with_account_if_after_first_unlock(CFErrorRef *error, bool (^acti notify_post(kSOSCCCircleChangedNotification); notify_post(kSOSCCViewMembershipChangedNotification); } + CFReleaseNull(cferror); }); }); @@ -723,10 +734,13 @@ CFTypeRef SOSKeychainAccountGetSharedAccount() // Mark: Credential processing // - -bool SOSCCTryUserCredentials_Server(CFStringRef user_label, CFDataRef user_password, CFErrorRef *error) -{ +bool SOSCCTryUserCredentials_Server(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error) { + secnotice("updates", "Trying credentials and dsid (%@) for %@", dsid, user_label); + return do_with_account_if_after_first_unlock(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { + if (dsid != NULL && CFStringCompare(dsid, CFSTR(""), 0) != 0) { + SOSAccountAssertDSID(txn.account, dsid); + } return SOSAccountTryUserCredentials(txn.account, user_label, user_password, block_error); }); } @@ -1226,7 +1240,7 @@ bool SOSCCRemovePeersFromCircle_Server(CFArrayRef peers, CFErrorRef* error) bool SOSCCLoggedOutOfAccount_Server(CFErrorRef *error) { return do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { - secnotice("sosops", "Signed out of account!"); + secnotice("circleOps", "Signed out of account!"); bool waitForeverForSynchronization = true; @@ -1548,7 +1562,7 @@ CFDataRef SOSWrapToBackupSliceKeyBag(SOSBackupSliceKeyBagRef bskb, CFDataRef inp CFMutableDictionaryRef plaintext = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(plaintext, CFSTR("data"), input); - require_quiet(ks_encrypt_data(bskb_handle, access, NULL, plaintext, NULL, &encrypted, false, error), exit); + require_quiet(ks_encrypt_data_legacy(bskb_handle, access, NULL, plaintext, NULL, &encrypted, false, error), exit); exit: CFReleaseNull(bskb); @@ -1788,17 +1802,20 @@ bool SOSCCDeleteEngineState_Server(CFErrorRef* error) SOSPeerInfoRef SOSCCSetNewPublicBackupKey_Server(CFDataRef newPublicBackup, CFErrorRef *error){ __block SOSPeerInfoRef result = NULL; + secnotice("devRecovery", "SOSCCSetNewPublicBackupKey_Server acquiring account lock"); (void) do_with_account_while_unlocked(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { + secnotice("devRecovery", "SOSCCSetNewPublicBackupKey_Server acquired account lock"); if(SOSAccountSetBackupPublicKey(txn,newPublicBackup, error)){ + secnotice("devRecovery", "SOSCCSetNewPublicBackupKey_Server, new public backup is set in account"); [txn restart]; // Finish the transaction to update any changes to the peer info. // Create a copy to be DERed/sent back to client result = SOSPeerInfoCreateCopy(kCFAllocatorDefault, txn.account.peerInfo, block_error); - secdebug("backup", "SOSCCSetNewPublicBackupKey_Server, new public backup is set"); + secnotice("devRecovery", "SOSCCSetNewPublicBackupKey_Server, new public backup is set and pushed"); } else { - secerror("SOSCCSetNewPublicBackupKey_Server, could not set new public backup"); + secnotice("devRecovery", "SOSCCSetNewPublicBackupKey_Server, could not set new public backup"); } return result != NULL; }); @@ -2060,12 +2077,13 @@ SOSPeerInfoRef SOSCCCopyApplication_Server(CFErrorRef *error) { } bool SOSCCCleanupKVSKeys_Server(CFErrorRef *error) { - __block bool result = false; - do_with_account_while_unlocked(error, ^bool(SOSAccountTransaction* txn, CFErrorRef *error) { + bool result = do_with_account_while_unlocked(error, ^bool(SOSAccountTransaction* txn, CFErrorRef *error) { return SOSAccountCleanupAllKVSKeys(txn.account, error); }); + if(result && error && *error) { + CFReleaseNull(*error); + } return result; - } bool SOSCCTestPopulateKVSWithBadKeys_Server(CFErrorRef *error) @@ -2147,7 +2165,7 @@ void SOSCCResetOTRNegotiation_Server(CFStringRef peerid) { CFErrorRef localError = NULL; do_with_account_while_unlocked(&localError, ^bool(SOSAccountTransaction* txn, CFErrorRef *error) { - SOSAccountResetOTRNegotiationCoder(txn, peerid); + SOSAccountResetOTRNegotiationCoder(txn.account, peerid); return true; }); if(localError) @@ -2169,19 +2187,26 @@ void SOSCCPeerRateLimiterSendNextMessage_Server(CFStringRef peerid, CFStringRef } } -XPC_RETURNS_RETAINED xpc_endpoint_t -SOSCCCreateSOSEndpoint_server(CFErrorRef *error) +void SOSCCPerformWithOctagonSigningKey(void (^action)(SecKeyRef octagonPrivSigningKey, CFErrorRef error)) { - SOSAccount* account = (__bridge SOSAccount *)(SOSKeychainAccountGetSharedAccount()); - return [account xpcControlEndpoint]; + CFErrorRef error = NULL; + do_with_account_if_after_first_unlock(&error, ^bool(SOSAccountTransaction *txn, CFErrorRef *err) { + SOSFullPeerInfoRef fpi = txn.account.trust.fullPeerInfo; + SecKeyRef signingKey = SOSFullPeerInfoCopyOctagonSigningKey(fpi, err); + CFErrorRef errorArg = err ? *err : NULL; + action(signingKey, errorArg); + CFReleaseNull(signingKey); + return true; + }); + CFReleaseNull(error); } -void SOSCCPerformWithOctagonSigningKey(void (^action)(SecKeyRef octagonPrivSigningKey, CFErrorRef error)) +void SOSCCPerformWithOctagonSigningPublicKey(void (^action)(SecKeyRef octagonPublicKey, CFErrorRef error)) { CFErrorRef error = NULL; do_with_account_if_after_first_unlock(&error, ^bool(SOSAccountTransaction *txn, CFErrorRef *err) { SOSFullPeerInfoRef fpi = txn.account.trust.fullPeerInfo; - SecKeyRef signingKey = SOSFullPeerInfoCopyOctagonSigningKey(fpi, err); + SecKeyRef signingKey = SOSFullPeerInfoCopyOctagonPublicSigningKey(fpi, err); CFErrorRef errorArg = err ? *err : NULL; action(signingKey, errorArg); CFReleaseNull(signingKey); @@ -2204,6 +2229,52 @@ void SOSCCPerformWithOctagonEncryptionKey(void (^action)(SecKeyRef octagonPrivEn CFReleaseNull(error); } +void SOSCCPerformWithOctagonEncryptionPublicKey(void (^action)(SecKeyRef octagonPublicEncryptionKey, CFErrorRef error)) +{ + CFErrorRef error = NULL; + do_with_account_if_after_first_unlock(&error, ^bool(SOSAccountTransaction *txn, CFErrorRef *err) { + SOSFullPeerInfoRef fpi = txn.account.trust.fullPeerInfo; + SecKeyRef signingKey = SOSFullPeerInfoCopyOctagonPublicEncryptionKey(fpi, err); + CFErrorRef errorArg = err ? *err : NULL; + action(signingKey, errorArg); + CFReleaseNull(signingKey); + return true; + }); + CFReleaseNull(error); +} + +void SOSCCPerformWithAllOctagonKeys(void (^action)(SecKeyRef octagonEncryptionKey, SecKeyRef octagonSigningKey, CFErrorRef error)) +{ + CFErrorRef localError = NULL; + do_with_account_if_after_first_unlock(&localError, ^bool(SOSAccountTransaction *txn, CFErrorRef *err) { + SecKeyRef encryptionKey = NULL; + SecKeyRef signingKey = NULL; + CFErrorRef errorArg = err ? *err : NULL; + + SOSFullPeerInfoRef fpi = txn.account.trust.fullPeerInfo; + require_action_quiet(fpi, fail, secerror("device does not have a peer"); SOSCreateError(kSOSErrorPeerNotFound, CFSTR("No Peer for Account"), NULL, &errorArg)); + + signingKey = SOSFullPeerInfoCopyOctagonSigningKey(fpi, &errorArg); + require_action_quiet(signingKey && !errorArg, fail, secerror("SOSCCPerformWithAllOctagonKeys signing key error: %@", errorArg)); + CFReleaseNull(errorArg); + + encryptionKey = SOSFullPeerInfoCopyOctagonEncryptionKey(fpi, &errorArg); + require_action_quiet(encryptionKey && !errorArg, fail, secerror("SOSCCPerformWithAllOctagonKeys encryption key error: %@", errorArg)); + + action(encryptionKey, signingKey, errorArg); + CFReleaseNull(signingKey); + CFReleaseNull(encryptionKey); + CFReleaseNull(errorArg); + return true; + fail: + action(NULL, NULL, errorArg); + CFReleaseNull(errorArg); + CFReleaseNull(signingKey); + CFReleaseNull(encryptionKey); + return true; + }); + CFReleaseNull(localError); +} void SOSCCPerformWithTrustedPeers(void (^action)(CFSetRef sosPeerInfoRefs, CFErrorRef error)) { CFErrorRef cfAccountError = NULL; @@ -2220,3 +2291,23 @@ void SOSCCPerformWithTrustedPeers(void (^action)(CFSetRef sosPeerInfoRefs, CFErr CFReleaseNull(cfAccountError); } +void SOSCCPerformWithPeerID(void (^action)(CFStringRef peerID, CFErrorRef error)) +{ + CFErrorRef cfAccountError = NULL; + do_with_account_if_after_first_unlock(&cfAccountError, ^bool(SOSAccountTransaction *txn, CFErrorRef *cferror) { + SOSAccount* account = txn.account; + NSString* peerID = nil; + CFErrorRef localError = nil; + + if([account getCircleStatus:nil] == kSOSCCInCircle){ + peerID = [txn.account peerID]; + } + else{ + SOSErrorCreate(kSOSErrorNoCircle, &localError, NULL, CFSTR("Not in circle")); + } + action((__bridge CFStringRef)peerID, localError); + CFReleaseNull(localError); + return true; + }); + CFReleaseNull(cfAccountError); +} diff --git a/OSX/sec/securityd/SecCAIssuerCache.c b/OSX/sec/securityd/SecCAIssuerCache.c index d5f593f7..3481cf58 100644 --- a/OSX/sec/securityd/SecCAIssuerCache.c +++ b/OSX/sec/securityd/SecCAIssuerCache.c @@ -27,6 +27,7 @@ */ #include +#include #include #include #include @@ -186,7 +187,7 @@ static int SecCAIssuerCacheCommitTxn(SecCAIssuerCacheRef this) { static SecCAIssuerCacheRef SecCAIssuerCacheCreate(const char *db_name) { SecCAIssuerCacheRef this; - int s3e; + int s3e = SQLITE_OK; bool create = true; require(this = (SecCAIssuerCacheRef)calloc(sizeof(struct __SecCAIssuerCache), 1), errOut); @@ -237,6 +238,9 @@ static SecCAIssuerCacheRef SecCAIssuerCacheCreate(const char *db_name) { return this; errOut: + if (s3e != SQLITE_OK) { + TrustdHealthAnalyticsLogErrorCodeForDatabase(TACAIssuerCache, TAOperationCreate, TAFatalError, s3e); + } if (this) { if (this->queue) dispatch_release(this->queue); @@ -295,8 +299,9 @@ static void _SecCAIssuerCacheAddCertificate(SecCAIssuerCacheRef this, require_noerr(s3e = sec_sqlite3_reset(this->insertIssuer, s3e), errOut); errOut: - if (s3e) { + if (s3e != SQLITE_OK) { secerror("caissuer cache add failed: %s", sqlite3_errmsg(this->s3h)); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TACAIssuerCache, TAOperationWrite, TAFatalError, s3e); /* TODO: Blow away the cache and create a new db. */ } } @@ -326,9 +331,10 @@ static SecCertificateRef _SecCAIssuerCacheCopyMatching(SecCAIssuerCacheRef this, require_noerr(s3e = sec_sqlite3_reset(this->selectIssuer, s3e), errOut); errOut: - if (s3e) { + if (s3e != SQLITE_OK) { if (s3e != SQLITE_DONE) { secerror("caissuer cache lookup failed: %s", sqlite3_errmsg(this->s3h)); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TACAIssuerCache, TAOperationRead, TAFatalError, s3e); /* TODO: Blow away the cache and create a new db. */ } @@ -355,8 +361,9 @@ static void _SecCAIssuerCacheGC(void *context) { require_noerr(s3e = SecCAIssuerCacheCommitTxn(this), errOut); errOut: - if (s3e) { + if (s3e != SQLITE_OK) { secerror("caissuer cache expire failed: %s", sqlite3_errmsg(this->s3h)); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TACAIssuerCache, TAOperationWrite, TAFatalError, s3e); /* TODO: Blow away the cache and create a new db. */ } } @@ -368,8 +375,9 @@ static void _SecCAIssuerCacheFlush(void *context) { secdebug("caissuercache", "flushing pending changes"); s3e = SecCAIssuerCacheCommitTxn(this); - if (s3e) { + if (s3e != SQLITE_OK) { secerror("caissuer cache flush failed: %s", sqlite3_errmsg(this->s3h)); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TACAIssuerCache, TAOperationWrite, TAFatalError, s3e); /* TODO: Blow away the cache and create a new db. */ } } diff --git a/OSX/sec/securityd/SecCAIssuerRequest.c b/OSX/sec/securityd/SecCAIssuerRequest.c index 6c3fde1e..b187a965 100644 --- a/OSX/sec/securityd/SecCAIssuerRequest.c +++ b/OSX/sec/securityd/SecCAIssuerRequest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2016 Apple Inc. All Rights Reserved. + * Copyright (c) 2009-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -36,7 +36,9 @@ #include #include #include +#include #include +#include #define MAX_CA_ISSUERS 3 #define CA_ISSUERS_REQUEST_THRESHOLD 10 @@ -68,6 +70,10 @@ static bool SecCAIssuerRequestIssue(SecCAIssuerRequestRef request) { SecCAIssuerRequestRelease(request); return true; } + + SecPathBuilderRef builder = (SecPathBuilderRef)request->context; + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder); + while (request->issuerIX < count && request->issuerIX < MAX_CA_ISSUERS) { CFURLRef issuer = CFArrayGetValueAtIndex(request->issuers, request->issuerIX++); @@ -79,6 +85,10 @@ static bool SecCAIssuerRequestIssue(SecCAIssuerRequestRef request) { if (msg) { secinfo("caissuer", "%@", msg); bool done = asynchttp_request(msg, 0, &request->http); + if (analytics) { + /* Count each http request we made */ + analytics->ca_issuer_fetches++; + } CFRelease(msg); if (done == false) { CFRelease(scheme); @@ -123,6 +133,14 @@ static void SecCAIssuerRequestCompleted(asynchttp_t *http, CFTimeInterval maxAge) { /* Cast depends on http being first field in struct SecCAIssuerRequest. */ SecCAIssuerRequestRef request = (SecCAIssuerRequestRef)http; + + SecPathBuilderRef builder = (SecPathBuilderRef)request->context; + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder); + if (analytics) { + /* Add the time this fetch took to complete to the total time */ + analytics->ca_issuer_fetch_time += (mach_absolute_time() - http->start_time); + } + CFDataRef data = (request->http.response ? CFHTTPMessageCopyBody(request->http.response) : NULL); if (data) { @@ -140,8 +158,13 @@ static void SecCAIssuerRequestCompleted(asynchttp_t *http, CFArrayRef certificates = NULL; certificates = SecCMSCertificatesOnlyMessageCopyCertificates(data); /* @@@ Technically these can have more than one certificate */ - if (certificates && CFArrayGetCount(certificates) == 1) { + if (certificates && CFArrayGetCount(certificates) >= 1) { parent = CFRetainSafe((SecCertificateRef)CFArrayGetValueAtIndex(certificates, 0)); + } else if (certificates && CFArrayGetCount(certificates) > 1) { + if (analytics) { + /* Indicate that this trust evaluation encountered a CAIssuer fetch with multiple certs */ + analytics->ca_issuer_multiple_certs = true; + } } CFReleaseNull(certificates); } @@ -170,7 +193,13 @@ static void SecCAIssuerRequestCompleted(asynchttp_t *http, SecCAIssuerRequestRelease(request); return; } + } else if (analytics) { + /* We failed to create a SecCertificateRef from the data we got */ + analytics->ca_issuer_unsupported_data = true; } + } else if (analytics) { + /* We didn't get any data back, so the fetch failed */ + analytics->ca_issuer_fetch_failed++; } secdebug("caissuer", "response: %@ not parent, trying next caissuer", @@ -211,12 +240,22 @@ bool SecCAIssuerCopyParents(SecCertificateRef certificate, dispatch_queue_t queu return true; } + SecPathBuilderRef builder = (SecPathBuilderRef)context; + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder); CFArrayRef parents = SecCAIssuerRequestCacheCopyParents(certificate, issuers); if (parents) { + if (analytics) { + /* We found parents in the cache */ + analytics->ca_issuer_cache_hit = true; + } callback(context, parents); CFReleaseSafe(parents); return true; } + if (analytics) { + /* We're going to have to make a network call */ + analytics->ca_issuer_network = true; + } /* Cache miss, let's issue a network request. */ SecCAIssuerRequestRef request = diff --git a/OSX/sec/securityd/SecCertificateServer.c b/OSX/sec/securityd/SecCertificateServer.c index 7561db85..ea49d9b0 100644 --- a/OSX/sec/securityd/SecCertificateServer.c +++ b/OSX/sec/securityd/SecCertificateServer.c @@ -30,14 +30,13 @@ #include #include -#include +#include #include #include #include #include #include -#include #include #include @@ -239,27 +238,27 @@ exit: ************* SecCertificatePathVC object *************** ********************************************************/ struct SecCertificatePathVC { - CFRuntimeBase _base; - CFIndex count; + CFRuntimeBase _base; + CFIndex count; /* Index of next parent source to search for parents. */ - CFIndex nextParentSource; + CFIndex nextParentSource; - /* Index of last certificate in chain who's signature has been verified. + /* Index of last certificate in chain whose signature has been verified. 0 means nothing has been checked. 1 means the leaf has been verified - against it's issuer, etc. */ - CFIndex lastVerifiedSigner; + against its issuer, etc. */ + CFIndex lastVerifiedSigner; /* Index of first self issued certificate in the chain. -1 mean there is none. 0 means the leaf is self signed. */ - CFIndex selfIssued; + CFIndex selfIssued; /* True iff cert at index selfIssued does in fact self verify. */ - bool isSelfSigned; + bool isSelfSigned; /* True if the root of this path is an anchor. Trustedness of the * anchor is determined by the PVC. */ - bool isAnchored; + bool isAnchored; policy_tree_t policy_tree; uint8_t policy_tree_verification_result; @@ -277,7 +276,12 @@ struct SecCertificatePathVC { bool pathValidated; - SecCertificateVCRef certificates[]; + /* Enumerated value to determine whether CT is required for the leaf + * certificate (because a CA in the path has a require-ct constraint). + * If non-zero, CT is required; value indicates overridable status. */ + SecPathCTPolicy requiresCT; + + SecCertificateVCRef certificates[]; }; CFGiblisWithHashFor(SecCertificatePathVC) @@ -505,13 +509,23 @@ exit: return outCerts; } -SecCertificatePathRef SecCertificatePathVCCopyCertificatePath(SecCertificatePathVCRef path) { - CFArrayRef certs = SecCertificatePathVCCopyCertificates(path); - SecCertificatePathRef newPath = SecCertificatePathCreateWithCertificates(certs, NULL); - CFReleaseNull(certs); - return newPath; +CFArrayRef SecCertificatePathVCCreateSerialized(SecCertificatePathVCRef path) { + CFMutableArrayRef serializedCerts = NULL; + require_quiet(path, exit); + size_t count = path->count; + require_quiet(serializedCerts = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks), exit); + SecCertificatePathVCForEachCertificate(path, ^(SecCertificateRef cert, bool * __unused stop) { + CFDataRef certData = SecCertificateCopyData(cert); + if (certData) { + CFArrayAppendValue(serializedCerts, certData); + CFRelease(certData); + } + }); +exit: + return serializedCerts; } + /* Record the fact that we found our own root cert as our parent certificate. */ void SecCertificatePathVCSetSelfIssued( @@ -593,8 +607,11 @@ CFIndex SecCertificatePathVCGetCount( SecCertificateRef SecCertificatePathVCGetCertificateAtIndex( SecCertificatePathVCRef certificatePath, CFIndex ix) { - check(certificatePath && ix >= 0 && ix < certificatePath->count); - return (certificatePath->certificates[ix])->certificate; + if (!certificatePath || ix < 0 || ix >= certificatePath->count) { + return NULL; + } + SecCertificateVCRef cvc = certificatePath->certificates[ix]; + return cvc ? cvc->certificate : NULL; } void SecCertificatePathVCForEachCertificate(SecCertificatePathVCRef path, void(^operation)(SecCertificateRef certificate, bool *stop)) { @@ -875,6 +892,10 @@ CFAbsoluteTime SecCertificatePathVCGetEarliestNextUpdate(SecCertificatePathVCRef continue; } } + /* Make sure to always skip roots for whom we can't check revocation */ + if (certIX == certCount - 1) { + continue; + } secdebug("rvc", "revocation checking soft failure for cert: %ld", certIX); enu = thisCertNextUpdate; @@ -935,6 +956,18 @@ void SecCertificatePathVCSetIsCT(SecCertificatePathVCRef certificatePath, bool i certificatePath->isCT = isCT; } +SecPathCTPolicy SecCertificatePathVCRequiresCT(SecCertificatePathVCRef certificatePath) { + if (!certificatePath) { return kSecPathCTNotRequired; } + return certificatePath->requiresCT; +} + +void SecCertificatePathVCSetRequiresCT(SecCertificatePathVCRef certificatePath, SecPathCTPolicy requiresCT) { + if (certificatePath->requiresCT > requiresCT) { + return; /* once set, CT policy may be only be changed to a more strict value */ + } + certificatePath->requiresCT = requiresCT; +} + bool SecCertificatePathVCIsAllowlisted(SecCertificatePathVCRef certificatePath) { if (!certificatePath) { return false; } return certificatePath->is_allowlisted; diff --git a/OSX/sec/securityd/SecCertificateServer.h b/OSX/sec/securityd/SecCertificateServer.h index 7b5a1481..7be3affa 100644 --- a/OSX/sec/securityd/SecCertificateServer.h +++ b/OSX/sec/securityd/SecCertificateServer.h @@ -33,7 +33,6 @@ #include #include -#include #include @@ -57,7 +56,8 @@ SecCertificatePathVCRef SecCertificatePathVCCopyFromParent(SecCertificatePathVCR /* Create an array of SecCertificateRefs from a certificate path. */ CFArrayRef SecCertificatePathVCCopyCertificates(SecCertificatePathVCRef path); -SecCertificatePathRef SecCertificatePathVCCopyCertificatePath(SecCertificatePathVCRef path); +/* Create an array of CFDataRefs from a certificate path. */ +CFArrayRef SecCertificatePathVCCreateSerialized(SecCertificatePathVCRef path); /* Record the fact that we found our own root cert as our parent certificate. */ @@ -143,8 +143,16 @@ void SecCertificatePathVCSetIsEV(SecCertificatePathVCRef certificatePath, bool i bool SecCertificatePathVCIsOptionallyEV(SecCertificatePathVCRef certificatePath); /* CT */ +typedef CFIndex SecPathCTPolicy; +enum { + kSecPathCTNotRequired = 0, + kSecPathCTRequiredOverridable = 1, + kSecPathCTRequired = 2 +}; bool SecCertificatePathVCIsCT(SecCertificatePathVCRef certificatePath); void SecCertificatePathVCSetIsCT(SecCertificatePathVCRef certificatePath, bool isCT); +SecPathCTPolicy SecCertificatePathVCRequiresCT(SecCertificatePathVCRef certificatePath); +void SecCertificatePathVCSetRequiresCT(SecCertificatePathVCRef certificatePath, SecPathCTPolicy requiresCT); /* Allowlist */ bool SecCertificatePathVCIsAllowlisted(SecCertificatePathVCRef certificatePath); diff --git a/OSX/sec/securityd/SecCertificateSource.c b/OSX/sec/securityd/SecCertificateSource.c index d954f64c..37c2a788 100644 --- a/OSX/sec/securityd/SecCertificateSource.c +++ b/OSX/sec/securityd/SecCertificateSource.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/OSX/sec/securityd/SecDbItem.c b/OSX/sec/securityd/SecDbItem.c index 2bf7414d..2eaffdae 100644 --- a/OSX/sec/securityd/SecDbItem.c +++ b/OSX/sec/securityd/SecDbItem.c @@ -367,24 +367,25 @@ CFDataRef SecDbItemCopyEncryptedDataToBackup(SecDbItemRef item, uint64_t handle, if (attributes || auth_attributes) { SecAccessControlRef access_control = SecDbItemCopyAccessControl(item, error); if (access_control) { - if (ks_encrypt_data(keybag, access_control, item->credHandle, attributes, auth_attributes, &edata, false, error)) { + if (ks_encrypt_data_legacy(keybag, access_control, item->credHandle, attributes, auth_attributes, &edata, false, error)) { item->_edataState = kSecDbItemEncrypting; } else { seccritical("ks_encrypt_data (db): failed: %@", error ? *error : (CFErrorRef)CFSTR("")); } CFRelease(access_control); } - CFReleaseSafe(attributes); - CFReleaseSafe(auth_attributes); + CFReleaseNull(attributes); + CFReleaseNull(auth_attributes); } + return edata; } -bool SecDbItemEnsureDecrypted(SecDbItemRef item, CFErrorRef *error) { +bool SecDbItemEnsureDecrypted(SecDbItemRef item, bool decryptSecretData, CFErrorRef *error) { // If we haven't yet decrypted the item, make sure we do so now bool result = true; - if (item->_edataState == kSecDbItemEncrypted) { + if (item->_edataState == kSecDbItemEncrypted || (decryptSecretData && item->_edataState == kSecDbItemSecretEncrypted)) { const SecDbAttr *attr = SecDbClassAttrWithKind(item->class, kSecDbEncryptedDataAttr, error); if (attr) { CFDataRef edata = SecDbItemGetCachedValue(item, attr); @@ -392,9 +393,9 @@ bool SecDbItemEnsureDecrypted(SecDbItemRef item, CFErrorRef *error) { return SecError(errSecInternal, error, CFSTR("state= encrypted but edata is NULL")); // Decrypt calls set value a bunch of times which clears our edata and changes our state. item->_edataState = kSecDbItemDecrypting; - result = SecDbItemDecrypt(item, edata, error); + result = SecDbItemDecrypt(item, decryptSecretData, edata, error); if (result) - item->_edataState = kSecDbItemClean; + item->_edataState = decryptSecretData ? kSecDbItemClean : kSecDbItemSecretEncrypted; else item->_edataState = kSecDbItemEncrypted; } @@ -484,8 +485,8 @@ CFTypeRef SecDbItemGetValue(SecDbItemRef item, const SecDbAttr *desc, CFErrorRef if (!desc) return NULL; - if (desc->flags & kSecDbInCryptoDataFlag || desc->flags & kSecDbInAuthenticatedDataFlag) { - if (!SecDbItemEnsureDecrypted(item, error)) + if (desc->flags & kSecDbInCryptoDataFlag || desc->flags & kSecDbInAuthenticatedDataFlag || desc->flags & kSecDbReturnDataFlag) { + if (!SecDbItemEnsureDecrypted(item, desc->flags & kSecDbReturnDataFlag, error)) return NULL; } @@ -754,7 +755,7 @@ keybag_handle_t SecDbItemGetKeybag(SecDbItemRef item) { } bool SecDbItemSetKeybag(SecDbItemRef item, keybag_handle_t keybag, CFErrorRef *error) { - if (!SecDbItemEnsureDecrypted(item, error)) + if (!SecDbItemEnsureDecrypted(item, true, error)) return false; if (item->keybag != keybag) { item->keybag = keybag; @@ -777,9 +778,11 @@ bool SecDbItemSetValue(SecDbItemRef item, const SecDbAttr *desc, CFTypeRef value if (desc->setValue) return desc->setValue(item, desc, value, error); - if (desc->flags & kSecDbInCryptoDataFlag || desc->flags & kSecDbInAuthenticatedDataFlag) - if (!SecDbItemEnsureDecrypted(item, error)) + if (desc->flags & kSecDbInCryptoDataFlag || desc->flags & kSecDbInAuthenticatedDataFlag) { + if (!SecDbItemEnsureDecrypted(item, true, error)) { return false; + } + } bool changed = false; CFTypeRef attr = NULL; @@ -849,7 +852,7 @@ bool SecDbItemSetValue(SecDbItemRef item, const SecDbAttr *desc, CFTypeRef value SecDbItemSetValue(item, SecDbClassAttrWithKind(item->class, kSecDbSHA1Attr, NULL), kCFNull, NULL); if (desc->flags & kSecDbPrimaryKeyFlag) SecDbItemSetValue(item, SecDbClassAttrWithKind(item->class, kSecDbPrimaryKeyAttr, NULL), kCFNull, NULL); - if ((desc->flags & kSecDbInCryptoDataFlag || desc->flags & kSecDbInAuthenticatedDataFlag) && item->_edataState == kSecDbItemClean) + if ((desc->flags & kSecDbInCryptoDataFlag || desc->flags & kSecDbInAuthenticatedDataFlag) && (item->_edataState == kSecDbItemClean || (item->_edataState == kSecDbItemSecretEncrypted && (desc->flags & kSecDbReturnDataFlag) == 0))) SecDbItemSetValue(item, SecDbClassAttrWithKind(item->class, kSecDbEncryptedDataAttr, NULL), kCFNull, NULL); if (desc->flags & kSecDbSHA1ValueInFlag) CFDictionaryRemoveValue(item->attributes, SecDbAttrGetHashName(desc)); @@ -1304,7 +1307,7 @@ static bool SecDbItemIsCorrupt(SecDbItemRef item, bool *is_corrupt, CFErrorRef * CFDataRef storedSHA1 = CFRetainSafe(SecDbItemGetValue(item, sha1attr, &localError)); bool akpu = false; - if (localError || !SecDbItemEnsureDecrypted(item, &localError)) { + if (localError || !SecDbItemEnsureDecrypted(item, true, &localError)) { if (SecErrorGetOSStatus(localError) == errSecDecode) { // We failed to decrypt the item const SecDbAttr *desc = SecDbClassAttrWithKind(item->class, kSecDbAccessControlAttr, &localError); @@ -1380,6 +1383,11 @@ static bool SecDbItemDoInsert(SecDbItemRef item, SecDbConnectionRef dbconn, CFEr bool (^use_attr)(const SecDbAttr *attr) = ^bool(const SecDbAttr *attr) { return (attr->flags & kSecDbInFlag); }; + + if (!SecDbItemEnsureDecrypted(item, true, error)) { + return false; + } + CFStringRef sql = SecDbItemCopyInsertSQL(item, use_attr); __block bool ok = sql; if (sql) { diff --git a/OSX/sec/securityd/SecDbItem.h b/OSX/sec/securityd/SecDbItem.h index c4132de8..97f35f69 100644 --- a/OSX/sec/securityd/SecDbItem.h +++ b/OSX/sec/securityd/SecDbItem.h @@ -132,6 +132,7 @@ enum SecDbItemState { kSecDbItemDecrypting, // Temporary state while we are decrypting so set knows not to blow away the edata. kSecDbItemEncrypting, // Temporary state while we are encrypting so set knows to move to clean. kSecDbItemAlwaysEncrypted, // As kSecDbItemEncrypted, but decryption is never attempted + kSecDbItemSecretEncrypted, // Metadata is clean, but the secret data remains encrypted }; struct SecDbItem { @@ -147,7 +148,7 @@ struct SecDbItem { }; // TODO: Make this a callback to client -bool SecDbItemDecrypt(SecDbItemRef item, CFDataRef edata, CFErrorRef *error); +bool SecDbItemDecrypt(SecDbItemRef item, bool decryptSecretData, CFDataRef edata, CFErrorRef *error); CFTypeID SecDbItemGetTypeID(void); @@ -204,7 +205,7 @@ SecDbItemRef SecDbItemCreateWithPrimaryKey(CFAllocatorRef allocator, const SecDb SecDbItemRef SecDbItemCreateWithRowId(CFAllocatorRef allocator, const SecDbClass *class, sqlite_int64 row_id, keybag_handle_t keybag, CFErrorRef *error); #endif -bool SecDbItemEnsureDecrypted(SecDbItemRef item, CFErrorRef *error); +bool SecDbItemEnsureDecrypted(SecDbItemRef item, bool decryptSecretData, CFErrorRef *error); SecDbItemRef SecDbItemCopyWithUpdates(SecDbItemRef item, CFDictionaryRef updates, CFErrorRef *error); diff --git a/OSX/sec/securityd/SecDbKeychainItem.c b/OSX/sec/securityd/SecDbKeychainItem.c deleted file mode 100644 index 25e042d1..00000000 --- a/OSX/sec/securityd/SecDbKeychainItem.c +++ /dev/null @@ -1,1372 +0,0 @@ -/* - * Copyright (c) 2006-2014 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* - * SecDbKeychainItem.c - CoreFoundation-based constants and functions for - access to Security items (certificates, keys, identities, and - passwords.) - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if USE_KEYSTORE -#include -#include -#include -#include -#include - -#endif /* USE_KEYSTORE */ - -pthread_key_t CURRENT_CONNECTION_KEY; - -// From SecItemServer, should be a acl-check block -bool itemInAccessGroup(CFDictionaryRef item, CFArrayRef accessGroups); - -static keyclass_t kc_parse_keyclass(CFTypeRef value, CFErrorRef *error); -static CFTypeRef kc_encode_keyclass(keyclass_t keyclass); -static CFDataRef kc_copy_protection_data(SecAccessControlRef access_control); -static CFTypeRef kc_copy_protection_from(const uint8_t *der, const uint8_t *der_end); -static CF_RETURNS_RETAINED CFMutableDictionaryRef s3dl_item_v2_decode(CFDataRef plain, CFErrorRef *error); -static CF_RETURNS_RETAINED CFMutableDictionaryRef s3dl_item_v3_decode(CFDataRef plain, CFErrorRef *error); -#if USE_KEYSTORE -static CFDataRef kc_create_auth_data(SecAccessControlRef access_control, CFDictionaryRef auth_attributes); -static bool kc_attribs_key_encrypted_data_from_blob(keybag_handle_t keybag, const SecDbClass *class, const void *blob_data, size_t blob_data_len, SecAccessControlRef access_control, uint32_t version, - CFMutableDictionaryRef *authenticated_attributes, aks_ref_key_t *ref_key, CFDataRef *encrypted_data, CFErrorRef *error); -static CFDataRef kc_copy_access_groups_data(CFArrayRef access_groups, CFErrorRef *error); -#endif - -static const uint8_t* der_decode_plist_with_repair(CFAllocatorRef pl, CFOptionFlags mutability, CFPropertyListRef* cf, CFErrorRef *error, - const uint8_t* der, const uint8_t *der_end, - const uint8_t* (^repairBlock)(CFAllocatorRef allocator, CFOptionFlags mutability, CFPropertyListRef* pl, CFErrorRef *error, - const uint8_t* der, const uint8_t *der_end)); -static const uint8_t* der_decode_dictionary_with_repair(CFAllocatorRef allocator, CFOptionFlags mutability, CFDictionaryRef* dictionary, CFErrorRef *error, - const uint8_t* der, const uint8_t *der_end, - const uint8_t* (^repairBlock)(CFAllocatorRef allocator, CFOptionFlags mutability, CFPropertyListRef* pl, CFErrorRef *error, - const uint8_t* der, const uint8_t *der_end)); -static const uint8_t* der_decode_key_value_with_repair(CFAllocatorRef allocator, CFOptionFlags mutability, CFPropertyListRef* key, CFPropertyListRef* value, CFErrorRef *error, - const uint8_t* der, const uint8_t *der_end, - const uint8_t* (^repairBlock)(CFAllocatorRef allocator, CFOptionFlags mutability, CFPropertyListRef* pl, CFErrorRef *error, - const uint8_t* der, const uint8_t *der_end)); -static const uint8_t* der_decode_array_with_repair(CFAllocatorRef allocator, CFOptionFlags mutability, CFArrayRef* array, CFErrorRef *error, - const uint8_t* der, const uint8_t *der_end, - const uint8_t* (^repairBlock)(CFAllocatorRef allocator, CFOptionFlags mutability, CFPropertyListRef* pl, CFErrorRef *error, - const uint8_t* der, const uint8_t *der_end)); -static const uint8_t* der_decode_set_with_repair(CFAllocatorRef allocator, CFOptionFlags mutability, CFSetRef* set, CFErrorRef *error, - const uint8_t* der, const uint8_t *der_end, - const uint8_t* (^repairBlock)(CFAllocatorRef allocator, CFOptionFlags mutability, CFPropertyListRef* pl, CFErrorRef *error, - const uint8_t* der, const uint8_t *der_end)); - -const uint32_t kUseDefaultIVMask = 1<<31; -const int16_t kIVSizeAESGCM = 12; - -// echo "keychainblobstaticiv" | openssl dgst -sha256 | cut -c1-24 | xargs -I {} echo "0x{}" | xxd -r | xxd -p -i -static const uint8_t gcmIV[kIVSizeAESGCM] = { - 0x1e, 0xa0, 0x5c, 0xa9, 0x98, 0x2e, 0x87, 0xdc, 0xf1, 0x45, 0xe8, 0x24 -}; - -/* Given plainText create and return a CFDataRef containing: - BULK_KEY = RandomKey() - version || keyclass|ACL || KeyStore_WRAP(keyclass, BULK_KEY) || - AES(BULK_KEY, NULL_IV, plainText || padding) - */ -bool ks_encrypt_data(keybag_handle_t keybag, SecAccessControlRef access_control, CFDataRef acm_context, - CFDictionaryRef attributes, CFDictionaryRef authenticated_attributes, CFDataRef *pBlob, bool useDefaultIV, CFErrorRef *error) { - CFMutableDataRef blob = NULL; - CFDataRef ac_data = NULL; - bool ok = true; - //check(keybag >= 0); - - /* Precalculate output blob length. */ - const uint32_t bulkKeySize = 32; /* Use 256 bit AES key for bulkKey. */ - const uint32_t maxKeyWrapOverHead = 8 + 32; - uint8_t bulkKey[bulkKeySize]; - CFMutableDataRef bulkKeyWrapped = CFDataCreateMutable(NULL, 0); - CFDataSetLength(bulkKeyWrapped, bulkKeySize + maxKeyWrapOverHead); - uint32_t key_wrapped_size; - size_t ivLen = 0; - const uint8_t *iv = NULL; - const uint8_t *aad = NULL; // Additional Authenticated Data - ptrdiff_t aadLen = 0; - -#if USE_KEYSTORE - CFDataRef auth_data = NULL; -#endif - - /* If access_control specifies only protection and no ACL, use legacy blob format version 3, - which has better support for sync/backup. Otherwise, force new format v6 unless useDefaultIV is set. */ - bool hasACLConstraints = SecAccessControlGetConstraints(access_control); - const uint32_t version = (hasACLConstraints ? 6 : 3); - CFDataRef plainText = NULL; - if (version < 4) { - CFMutableDictionaryRef attributes_dict = CFDictionaryCreateMutableCopy(NULL, 0, attributes); - if (authenticated_attributes) { - CFDictionaryForEach(authenticated_attributes, ^(const void *key, const void *value) { - CFDictionaryAddValue(attributes_dict, key, value); - }); - } - - if (attributes_dict) { - // Drop the accc attribute for non v6 items during encode. - CFDictionaryRemoveValue(attributes_dict, kSecAttrAccessControl); - plainText = CFPropertyListCreateDERData(kCFAllocatorDefault, attributes_dict, error); - CFRelease(attributes_dict); - } - } else { -#if USE_KEYSTORE - if (attributes) { - plainText = CFPropertyListCreateDERData(kCFAllocatorDefault, attributes, error); - } -#else - CFMutableDictionaryRef attributes_dict = CFDictionaryCreateMutableCopy(NULL, 0, attributes); - if (authenticated_attributes) { - CFDictionaryForEach(authenticated_attributes, ^(const void *key, const void *value) { - CFDictionaryAddValue(attributes_dict, key, value); - }); - } - - if (attributes_dict) { - plainText = CFPropertyListCreateDERData(kCFAllocatorDefault, attributes_dict, error); - CFRelease(attributes_dict); - } -#endif - } - - if (!plainText || CFGetTypeID(plainText) != CFDataGetTypeID() - || access_control == 0) { - ok = SecError(errSecParam, error, CFSTR("ks_encrypt_data: invalid plain text")); - goto out; - } - - size_t ptLen = CFDataGetLength(plainText); - size_t ctLen = ptLen; - size_t tagLen = 16; - keyclass_t actual_class = 0; - - if (SecRandomCopyBytes(kSecRandomDefault, bulkKeySize, bulkKey)) { - ok = SecError(errSecAllocate, error, CFSTR("ks_encrypt_data: SecRandomCopyBytes failed")); - goto out; - } - - /* Extract keyclass from access control. */ - keyclass_t keyclass = kc_parse_keyclass(SecAccessControlGetProtection(access_control), error); - if (!keyclass) - goto out; - -#if USE_KEYSTORE - if (version >= 4) { - auth_data = kc_create_auth_data(access_control, authenticated_attributes); - require_quiet(ok = ks_encrypt_acl(keybag, keyclass, bulkKeySize, bulkKey, bulkKeyWrapped, auth_data, acm_context, access_control, error), out); - } else -#endif - { - /* Encrypt bulkKey. */ - require_quiet(ok = ks_crypt(kAKSKeyOpEncrypt, keybag, - keyclass, bulkKeySize, bulkKey, - &actual_class, bulkKeyWrapped, - error), out); - } - - key_wrapped_size = (uint32_t)CFDataGetLength(bulkKeyWrapped); - UInt8 *cursor; - size_t blobLen = sizeof(version); - uint32_t prot_length = 0; - - if (!hasACLConstraints) { - blobLen += sizeof(actual_class); - } else { - require_quiet(ac_data = kc_copy_protection_data(access_control), out); - prot_length = (uint32_t)CFDataGetLength(ac_data); - blobLen += sizeof(prot_length) + prot_length; - } - - blobLen += sizeof(key_wrapped_size) + key_wrapped_size + ctLen + tagLen; - require_quiet(blob = CFDataCreateMutable(NULL, blobLen), out); - CFDataSetLength(blob, blobLen); - cursor = CFDataGetMutableBytePtr(blob); - - *((uint32_t *)cursor) = useDefaultIV ? (version | kUseDefaultIVMask) : version; - cursor += sizeof(version); - - //secerror("class: %d actual class: %d", keyclass, actual_class); - if (!hasACLConstraints) { - *((keyclass_t *)cursor) = actual_class; - cursor += sizeof(keyclass); - } else { - *((uint32_t *)cursor) = prot_length; - cursor += sizeof(prot_length); - - CFDataGetBytes(ac_data, CFRangeMake(0, prot_length), cursor); - cursor += prot_length; - } - - *((uint32_t *)cursor) = key_wrapped_size; - cursor += sizeof(key_wrapped_size); - - if (useDefaultIV) { - iv = gcmIV; - ivLen = kIVSizeAESGCM; - // AAD is (version || ac_data || key_wrapped_size) - aad = CFDataGetMutableBytePtr(blob); - aadLen = cursor - aad; - } - - memcpy(cursor, CFDataGetBytePtr(bulkKeyWrapped), key_wrapped_size); - cursor += key_wrapped_size; - - /* Encrypt the plainText with the bulkKey. */ - CCCryptorStatus ccerr = CCCryptorGCM(kCCEncrypt, kCCAlgorithmAES128, - bulkKey, bulkKeySize, - iv, ivLen, /* iv */ - aad, aadLen, /* auth data */ - CFDataGetBytePtr(plainText), ptLen, - cursor, - cursor + ctLen, &tagLen); - if (ccerr) { - ok = SecError(errSecInternal, error, CFSTR("ks_encrypt_data: CCCryptorGCM failed: %d"), ccerr); - goto out; - } - if (tagLen != 16) { - ok = SecError(errSecInternal, error, CFSTR("ks_encrypt_data: CCCryptorGCM expected: 16 got: %ld byte tag"), tagLen); - goto out; - } - -out: - memset(bulkKey, 0, sizeof(bulkKey)); - CFReleaseSafe(ac_data); - CFReleaseSafe(bulkKeyWrapped); - CFReleaseSafe(plainText); - if (!ok) { - CFReleaseSafe(blob); - } else { - *pBlob = blob; - } - -#if USE_KEYSTORE - CFReleaseSafe(auth_data); -#endif - return ok; -} - -/* Given cipherText containing: - version || keyclass || KeyStore_WRAP(keyclass, BULK_KEY) || - AES(BULK_KEY, NULL_IV, plainText || padding) - return the plainText. */ -bool ks_decrypt_data(keybag_handle_t keybag, CFTypeRef cryptoOp, SecAccessControlRef *paccess_control, CFDataRef acm_context, - CFDataRef blob, const SecDbClass *db_class, CFArrayRef caller_access_groups, - CFMutableDictionaryRef *attributes_p, uint32_t *version_p, CFErrorRef *error) { - const uint32_t v0KeyWrapOverHead = 8; - CFMutableDataRef bulkKey = CFDataCreateMutable(0, 32); /* Use 256 bit AES key for bulkKey. */ - CFDataSetLength(bulkKey, 32); /* Use 256 bit AES key for bulkKey. */ - bool ok = true; - SecAccessControlRef access_control = NULL; - - if (attributes_p) - *attributes_p = NULL; - if (version_p) - *version_p = 0; - - CFMutableDataRef plainText = NULL; - CFMutableDictionaryRef attributes = NULL; - uint32_t version = 0; - size_t ivLen = 0; - const uint8_t *iv = NULL; - const uint8_t *aad = NULL; // Additional Authenticated Data - ptrdiff_t aadLen = 0; - -#if USE_KEYSTORE - CFMutableDictionaryRef authenticated_attributes = NULL; - CFDataRef caller_access_groups_data = NULL; - CFDataRef ed_data = NULL; - aks_ref_key_t ref_key = NULL; -#if TARGET_OS_IPHONE - check(keybag >= 0); -#else - check((keybag >= 0) || (keybag == session_keybag_handle)); -#endif -#endif - - if (!blob) { - ok = SecError(errSecParam, error, CFSTR("ks_decrypt_data: invalid blob")); - goto out; - } - - size_t blobLen = CFDataGetLength(blob); - const uint8_t *cursor = CFDataGetBytePtr(blob); - keyclass_t keyclass; - - if (blobLen < sizeof(version)) { - ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: Check for underflow (length)")); - goto out; - } - - version = *((uint32_t *)cursor); - if (version & kUseDefaultIVMask) { - version &= ~kUseDefaultIVMask; - iv = gcmIV; - ivLen = kIVSizeAESGCM; - } - - cursor += sizeof(version); - blobLen -= sizeof(version); - - bool hasProtectionData = (version >= 4); - - if (hasProtectionData) { - /* Deserialize SecAccessControl object from the blob. */ - uint32_t prot_length; - - /* - * Parse proto length - */ - - if (blobLen < sizeof(prot_length)) { - ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: Check for underflow (prot_length)")); - goto out; - } - - prot_length = *((uint32_t *)cursor); - cursor += sizeof(prot_length); - blobLen -= sizeof(prot_length); - - /* - * Parse proto itself - */ - - if (blobLen < prot_length) { - ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: Check for underflow (prot)")); - goto out; - } - - CFTypeRef protection = kc_copy_protection_from(cursor, cursor + prot_length); - if (!protection) { - ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: invalid ACL")); - goto out; - } else { - access_control = SecAccessControlCreate(NULL, NULL); - require_quiet(access_control, out); - ok = SecAccessControlSetProtection(access_control, protection, NULL); - CFRelease(protection); - if (!ok) { - SecError(errSecDecode, error, CFSTR("ks_decrypt_data: invalid ACL")); - goto out; - } - } - - cursor += prot_length; - blobLen -= prot_length; - - /* - * Get numeric value of keyclass from the access_control. - */ - keyclass = kc_parse_keyclass(SecAccessControlGetProtection(access_control), error); - if (!keyclass) { - ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: invalid ACL")); - goto out; - } - } else { - if (blobLen < sizeof(keyclass)) { - ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: Check for underflow (keyclass)")); - goto out; - } - - keyclass = *((keyclass_t *)cursor); - -#if USE_KEYSTORE - CFTypeRef protection = kc_encode_keyclass(keyclass & key_class_last); // mask out generation -#else - CFTypeRef protection = kc_encode_keyclass(keyclass); -#endif - require_action_quiet(protection, out, ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: invalid keyclass detected"))); - require_action_quiet(access_control = SecAccessControlCreate(kCFAllocatorDefault, error), out, - ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: SecAccessControlCreate failed"))); - require_action_quiet(SecAccessControlSetProtection(access_control, protection, error), out, - ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: SecAccessControlSetProtection failed"))); - - cursor += sizeof(keyclass); - blobLen -= sizeof(keyclass); - } - - size_t tagLen = 0; - uint32_t wrapped_key_size = 0; - - switch (version) { - case 0: - wrapped_key_size = (uint32_t)CFDataGetLength(bulkKey) + v0KeyWrapOverHead; - break; - case 2: - case 3: - /* DROPTHROUGH */ - /* v2 and v3 have the same crypto, just different dictionary encodings. */ - /* Difference between v3 and v6 is already handled above, so treat v3 as v6. */ - case 4: - case 5: - case 6: - tagLen = 16; - /* DROPTHROUGH */ - case 1: - if (blobLen < sizeof(wrapped_key_size)) { - ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: Check for underflow (wrapped_key_size)")); - goto out; - } - wrapped_key_size = *((uint32_t *)cursor); - - cursor += sizeof(wrapped_key_size); - blobLen -= sizeof(wrapped_key_size); - - break; - default: - ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: invalid version %d"), version); - goto out; - } - - if (blobLen < tagLen + wrapped_key_size) { - ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: Check for underflow (wrapped_key/taglen)")); - goto out; - } - - size_t ctLen = blobLen - tagLen - wrapped_key_size; - - /* - * Pre-version 2 have some additial constraints since it use AES in CBC mode - */ - if (version < 2) { - if (ctLen < kCCBlockSizeAES128) { - ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: Check for underflow (CBC check)")); - goto out; - } - if ((ctLen & 0xF) != 0) { - ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: invalid length on CBC data")); - goto out; - } - } - -#if USE_KEYSTORE - if (hasProtectionData) { - if (caller_access_groups) { - caller_access_groups_data = kc_copy_access_groups_data(caller_access_groups, error); - require_quiet(ok = (caller_access_groups_data != NULL), out); - } - - require_quiet(ok = kc_attribs_key_encrypted_data_from_blob(keybag, db_class, cursor, wrapped_key_size, access_control, version, - &authenticated_attributes, &ref_key, &ed_data, error), out); - if (CFEqual(cryptoOp, kAKSKeyOpDecrypt)) { - require_quiet(ok = ks_decrypt_acl(ref_key, ed_data, bulkKey, acm_context, caller_access_groups_data, access_control, error), out); - } else if (CFEqual(cryptoOp, kAKSKeyOpDelete)) { - require_quiet(ok = ks_delete_acl(ref_key, ed_data, acm_context, caller_access_groups_data, access_control, error), out); - attributes = CFRetainSafe(authenticated_attributes); - goto out; - } else { - ok = SecError(errSecInternal, error, CFSTR("ks_decrypt_data: invalid operation")); - goto out; - } - } else -#endif - { - /* Now unwrap the bulk key using a key in the keybag. */ - require_quiet(ok = ks_crypt(cryptoOp, keybag, - keyclass, wrapped_key_size, cursor, NULL, bulkKey, error), out); - } - - if (iv) { - // AAD is (version || ... [|| key_wrapped_size ]) - aad = CFDataGetBytePtr(blob); - aadLen = cursor - aad; - } - - cursor += wrapped_key_size; - - plainText = CFDataCreateMutable(NULL, ctLen); - if (!plainText) { - ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: failed to allocate data for plain text")); - goto out; - } - CFDataSetLength(plainText, ctLen); - - /* Decrypt the cipherText with the bulkKey. */ - CCCryptorStatus ccerr; - if (tagLen) { - uint8_t tag[tagLen]; - ccerr = CCCryptorGCM(kCCDecrypt, kCCAlgorithmAES128, - CFDataGetBytePtr(bulkKey), CFDataGetLength(bulkKey), - iv, ivLen, /* iv */ - aad, aadLen, /* auth data */ - cursor, ctLen, - CFDataGetMutableBytePtr(plainText), - tag, &tagLen); - if (ccerr) { - /* TODO: Should this be errSecDecode once AppleKeyStore correctly - identifies uuid unwrap failures? */ - /* errSecInteractionNotAllowed; */ - ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: CCCryptorGCM failed: %d"), ccerr); - goto out; - } - if (tagLen != 16) { - ok = SecError(errSecInternal, error, CFSTR("ks_decrypt_data: CCCryptorGCM expected: 16 got: %ld byte tag"), tagLen); - goto out; - } - cursor += ctLen; - if (timingsafe_bcmp(tag, cursor, tagLen)) { - ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: CCCryptorGCM computed tag not same as tag in blob")); - goto out; - } - } else { - size_t ptLen; - ccerr = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, - CFDataGetBytePtr(bulkKey), CFDataGetLength(bulkKey), NULL, cursor, ctLen, - CFDataGetMutableBytePtr(plainText), ctLen, &ptLen); - if (ccerr) { - /* TODO: Should this be errSecDecode once AppleKeyStore correctly - identifies uuid unwrap failures? */ - /* errSecInteractionNotAllowed; */ - ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: CCCrypt failed: %d"), ccerr); - goto out; - } - CFDataSetLength(plainText, ptLen); - } - - if (version < 2) { - attributes = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionaryAddValue(attributes, CFSTR("v_Data"), plainText); - } else if (version < 3) { - attributes = s3dl_item_v2_decode(plainText, error); - } else { - attributes = s3dl_item_v3_decode(plainText, error); - } - - require_action_quiet(attributes, out, { ok = false; secerror("decode v%d failed: %@", version, error ? *error : NULL); }); - -#if USE_KEYSTORE - if (version >= 4 && authenticated_attributes != NULL) { - CFDictionaryForEach(authenticated_attributes, ^(const void *key, const void *value) { - CFDictionaryAddValue(attributes, key, value); - }); - } -#endif - -out: - memset(CFDataGetMutableBytePtr(bulkKey), 0, CFDataGetLength(bulkKey)); - CFReleaseNull(bulkKey); - CFReleaseNull(plainText); - - // Always copy access control data (if present), because if we fail it may indicate why. - if (paccess_control) - *paccess_control = access_control; - else - CFReleaseNull(access_control); - - if (ok) { - if (attributes_p) - CFRetainAssign(*attributes_p, attributes); - if (version_p) - *version_p = version; - } - CFReleaseNull(attributes); -#if USE_KEYSTORE - CFReleaseNull(authenticated_attributes); - CFReleaseNull(caller_access_groups_data); - CFReleaseNull(ed_data); - if (ref_key) aks_ref_key_free(&ref_key); -#endif - return ok; -} - -static keyclass_t kc_parse_keyclass(CFTypeRef value, CFErrorRef *error) { - if (!isString(value)) { - SecError(errSecParam, error, CFSTR("accessible attribute %@ not a string"), value); - } else if (CFEqual(value, kSecAttrAccessibleWhenUnlocked)) { - return key_class_ak; - } else if (CFEqual(value, kSecAttrAccessibleAfterFirstUnlock)) { - return key_class_ck; - } else if (CFEqual(value, kSecAttrAccessibleAlwaysPrivate)) { - return key_class_dk; - } else if (CFEqual(value, kSecAttrAccessibleWhenUnlockedThisDeviceOnly)) { - return key_class_aku; - } else if (CFEqual(value, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly)) { - return key_class_cku; - } else if (CFEqual(value, kSecAttrAccessibleAlwaysThisDeviceOnlyPrivate)) { - return key_class_dku; - } else if (CFEqual(value, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly)) { - return key_class_akpu; - } else { - SecError(errSecParam, error, CFSTR("accessible attribute %@ unknown"), value); - } - return 0; -} - -static CFTypeRef kc_encode_keyclass(keyclass_t keyclass) { - switch (keyclass) { - case key_class_ak: - return kSecAttrAccessibleWhenUnlocked; - case key_class_ck: - return kSecAttrAccessibleAfterFirstUnlock; - case key_class_dk: - return kSecAttrAccessibleAlwaysPrivate; - case key_class_aku: - return kSecAttrAccessibleWhenUnlockedThisDeviceOnly; - case key_class_cku: - return kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly; - case key_class_dku: - return kSecAttrAccessibleAlwaysThisDeviceOnlyPrivate; - case key_class_akpu: - return kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly; - default: - return 0; - } -} - -#if USE_KEYSTORE -static bool kc_attribs_key_encrypted_data_from_blob(keybag_handle_t keybag, const SecDbClass *class, const void *blob_data, size_t blob_data_len, SecAccessControlRef access_control, uint32_t version, - CFMutableDictionaryRef *authenticated_attributes, aks_ref_key_t *ref_key, CFDataRef *encrypted_data, CFErrorRef *error) -{ - CFMutableDictionaryRef acl = NULL; - CFDictionaryRef blob_dict = NULL; - aks_ref_key_t tmp_ref_key = NULL; - CFDataRef key_data = NULL; - CFDataRef ed = NULL; - bool ok = false; - - der_decode_plist(NULL, kCFPropertyListImmutable, (CFPropertyListRef*)&blob_dict, NULL, blob_data, blob_data + blob_data_len); - require_action_quiet(blob_dict, out, SecError(errSecDecode, error, CFSTR("kc_attribs_key_encrypted_data_from_blob: failed to decode 'blob data'"))); - - if (!ks_separate_data_and_key(blob_dict, &ed, &key_data)) { - ed = CFDataCreate(kCFAllocatorDefault, blob_data, blob_data_len); - key_data = CFRetain(ed); - } - require_action_quiet(ed, out, SecError(errSecDecode, error, CFSTR("kc_attribs_key_encrypted_data_from_blob: failed to decode 'encrypted data'"))); - require_action_quiet(key_data, out, SecError(errSecDecode, error, CFSTR("kc_attribs_key_encrypted_data_from_blob: failed to decode 'key data'"))); - - const void *external_data = NULL; - size_t external_data_len = 0; - require_quiet(external_data = ks_ref_key_get_external_data(keybag, key_data, &tmp_ref_key, &external_data_len, error), out); - - CFPropertyListRef external_data_dict = NULL; - der_decode_plist(NULL, kCFPropertyListImmutable, &external_data_dict, NULL, external_data, external_data + external_data_len); - require_action_quiet(external_data_dict, out, SecError(errSecDecode, error, CFSTR("kc_attribs_key_encrypted_data_from_blob: failed to decode 'encrypted data dictionary'"))); - acl = CFDictionaryCreateMutableCopy(NULL, 0, external_data_dict); - SecDbForEachAttrWithMask(class, attr_desc, kSecDbInAuthenticatedDataFlag) { - CFDictionaryRemoveValue(acl, attr_desc->name); - CFTypeRef value = CFDictionaryGetValue(external_data_dict, attr_desc->name); - if (value) { - if (!*authenticated_attributes) - *authenticated_attributes = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - - CFDictionaryAddValue(*authenticated_attributes, attr_desc->name, value); - } - } - CFReleaseSafe(external_data_dict); - - if (acl) { - /* v4 data format used wrong ACL placement, for backward compatibility we have to support both formats */ - if (version == 4) { - SecAccessControlSetConstraints(access_control, acl); - } else { - CFDictionaryRef constraints = CFDictionaryGetValue(acl, kAKSKeyAcl); - require_action_quiet(isDictionary(constraints), out, - SecError(errSecDecode, error, CFSTR("kc_attribs_key_encrypted_data_from_blob: acl missing"))); - SecAccessControlSetConstraints(access_control, constraints); - } - - /* v4/v5 data format usualy does not contain kAKSKeyOpEncrypt, so add kAKSKeyOpEncrypt if is missing */ - if (version < 6) { - SecAccessConstraintRef encryptConstraint = SecAccessControlGetConstraint(access_control, kAKSKeyOpEncrypt); - if (!encryptConstraint) - SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpEncrypt, kCFBooleanTrue, NULL); - } - - } - - if (encrypted_data) - *encrypted_data = CFRetain(ed); - - if (ref_key) { - *ref_key = tmp_ref_key; - tmp_ref_key = NULL; - } - - ok = true; - -out: - if (tmp_ref_key) - aks_ref_key_free(&tmp_ref_key); - CFReleaseSafe(blob_dict); - CFReleaseSafe(key_data); - CFReleaseSafe(ed); - CFReleaseSafe(acl); - - - return ok; -} - -static CFDataRef kc_create_auth_data(SecAccessControlRef access_control, CFDictionaryRef auth_attributes) { - CFDictionaryRef constraints = SecAccessControlGetConstraints(access_control); - CFMutableDictionaryRef auth_data = CFDictionaryCreateMutableCopy(NULL, 0, auth_attributes); - CFDictionarySetValue(auth_data, kAKSKeyAcl, constraints); - CFDataRef encoded = CFPropertyListCreateDERData(kCFAllocatorDefault, auth_data, NULL); - CFReleaseSafe(auth_data); - return encoded; -} - -static CFDataRef kc_copy_access_groups_data(CFArrayRef access_groups, CFErrorRef *error) -{ - size_t ag_size = der_sizeof_plist(access_groups, error); - CFMutableDataRef result = CFDataCreateMutable(kCFAllocatorDefault, 0); - CFDataSetLength(result, ag_size); - if (!der_encode_plist(access_groups, error, CFDataGetMutableBytePtr(result), CFDataGetMutableBytePtr(result) + ag_size)) { - CFRelease(result); - return NULL; - } - else - return result; -} - -#endif /* USE_KEYSTORE */ - -static CFDataRef kc_copy_protection_data(SecAccessControlRef access_control) -{ - CFTypeRef protection = SecAccessControlGetProtection(access_control); - size_t protection_size = der_sizeof_plist(protection, NULL); - CFMutableDataRef result = CFDataCreateMutable(NULL, 0); - CFDataSetLength(result, protection_size); - if (!der_encode_plist(protection, NULL, CFDataGetMutableBytePtr(result), CFDataGetMutableBytePtr(result) + protection_size)) { - CFRelease(result); - return NULL; - } - else - return result; -} - -static CFTypeRef kc_copy_protection_from(const uint8_t *der, const uint8_t *der_end) -{ - CFTypeRef result = NULL; - der_decode_plist(NULL, kCFPropertyListImmutable, &result, NULL, der, der_end); - return result; -} - -/* Return a (mutable) dictionary if plist is a dictionary, return NULL and set error otherwise. Does nothing if plist is already NULL. */ -static CF_RETURNS_RETAINED -CFMutableDictionaryRef dictionaryFromPlist(CFPropertyListRef plist CF_CONSUMED, CFErrorRef *error) { - if (plist && !isDictionary(plist)) { - CFStringRef typeName = CFCopyTypeIDDescription(CFGetTypeID((CFTypeRef)plist)); - SecError(errSecDecode, error, CFSTR("plist is a %@, expecting a dictionary"), typeName); - CFReleaseSafe(typeName); - CFReleaseNull(plist); - } - return (CFMutableDictionaryRef)plist; -} - -static CF_RETURNS_RETAINED -CFMutableDictionaryRef s3dl_item_v2_decode(CFDataRef plain, CFErrorRef *error) { - CFPropertyListRef item; - item = CFPropertyListCreateWithData(0, plain, kCFPropertyListMutableContainers, NULL, error); - return dictionaryFromPlist(item, error); -} - -static const uint8_t* (^s3dl_item_v3_decode_repair_date)(CFAllocatorRef, CFOptionFlags, CFPropertyListRef*, CFErrorRef*, const uint8_t*, const uint8_t*) = - ^const uint8_t*(CFAllocatorRef allocator, CFOptionFlags mutability, CFPropertyListRef* pl, CFErrorRef *error, const uint8_t* der, const uint8_t *der_end) { - if (error && CFEqualSafe(CFErrorGetDomain(*error), sSecDERErrorDomain) && CFErrorGetCode(*error) == kSecDERErrorUnknownEncoding) { - CFAbsoluteTime date = 0; - CFCalendarRef calendar = CFCalendarCreateWithIdentifier(allocator, kCFGregorianCalendar); - CFTimeZoneRef tz = CFTimeZoneCreateWithTimeIntervalFromGMT(allocator, 0); - CFCalendarSetTimeZone(calendar, tz); - CFCalendarComposeAbsoluteTime(calendar, &date, "yMd", 2001, 3, 24); // random date for 15A143: can't recover keychain - CFReleaseSafe(tz); - CFReleaseSafe(calendar); - - *pl = CFDateCreate(allocator, date); - if (NULL != *pl) { - CFReleaseNull(*error); - return der_end; - } - } - return NULL; -}; - -static CF_RETURNS_RETAINED -CFMutableDictionaryRef s3dl_item_v3_decode(CFDataRef plain, CFErrorRef *error) { - CFPropertyListRef item = NULL; - const uint8_t *der_beg = CFDataGetBytePtr(plain); - const uint8_t *der_end = der_beg + CFDataGetLength(plain); - const uint8_t *der = der_decode_plist(0, kCFPropertyListMutableContainers, &item, error, der_beg, der_end); - if (!der && error && CFEqualSafe(CFErrorGetDomain(*error), sSecDERErrorDomain) && CFErrorGetCode(*error) == kSecDERErrorUnknownEncoding) { - CFReleaseNull(*error); - der = der_decode_plist_with_repair(0, kCFPropertyListMutableContainers, &item, error, der_beg, der_end, s3dl_item_v3_decode_repair_date); - } - if (der && der != der_end) { - SecCFCreateError(errSecDecode, kSecErrorDomain, CFSTR("trailing garbage at end of decrypted item"), NULL, error); - CFReleaseNull(item); - } - return dictionaryFromPlist(item, error); -} - -bool s3dl_item_from_data(CFDataRef edata, Query *q, CFArrayRef accessGroups, - CFMutableDictionaryRef *item, SecAccessControlRef *access_control, CFErrorRef *error) { - SecAccessControlRef ac = NULL; - CFDataRef ac_data = NULL; - bool ok = false; - - /* Decrypt and decode the item and check the decoded attributes against the query. */ - uint32_t version = 0; - require_quiet((ok = ks_decrypt_data(q->q_keybag, kAKSKeyOpDecrypt, &ac, q->q_use_cred_handle, edata, q->q_class, - q->q_caller_access_groups, item, &version, error)), out); - if (version < 2) { - goto out; - } - - ac_data = SecAccessControlCopyData(ac); - if (!itemInAccessGroup(*item, accessGroups)) { - secerror("items accessGroup %@ not in %@", - CFDictionaryGetValue(*item, kSecAttrAccessGroup), - accessGroups); - ok = SecError(errSecDecode, error, CFSTR("items accessGroup %@ not in %@"), - CFDictionaryGetValue(*item, kSecAttrAccessGroup), - accessGroups); - CFReleaseNull(*item); - } - - /* AccessControl attribute does not exist in the db, so synthesize it. */ - if (version > 3) - CFDictionarySetValue(*item, kSecAttrAccessControl, ac_data); - - /* TODO: Validate access_control attribute. */ - -out: - if (access_control) - *access_control = CFRetainSafe(ac); - CFReleaseSafe(ac); - CFReleaseSafe(ac_data); - return ok; -} - -/* Infer accessibility and access group for pre-v2 (iOS4.x and earlier) items - being imported from a backup. */ -static bool SecDbItemImportMigrate(SecDbItemRef item, CFErrorRef *error) { - bool ok = true; - CFStringRef agrp = SecDbItemGetCachedValueWithName(item, kSecAttrAccessGroup); - CFStringRef accessible = SecDbItemGetCachedValueWithName(item, kSecAttrAccessible); - - if (!isString(agrp) || !isString(accessible)) - return ok; - if (SecDbItemGetClass(item) == genp_class() && CFEqual(accessible, kSecAttrAccessibleAlwaysPrivate)) { - CFStringRef svce = SecDbItemGetCachedValueWithName(item, kSecAttrService); - if (!isString(svce)) return ok; - if (CFEqual(agrp, CFSTR("apple"))) { - if (CFEqual(svce, CFSTR("AirPort"))) { - ok = SecDbItemSetValueWithName(item, kSecAttrAccessible, kSecAttrAccessibleAfterFirstUnlock, error); - } else if (CFEqual(svce, CFSTR("com.apple.airplay.password"))) { - ok = SecDbItemSetValueWithName(item, kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked, error); - } else if (CFEqual(svce, CFSTR("YouTube"))) { - ok = (SecDbItemSetValueWithName(item, kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked, error) && - SecDbItemSetValueWithName(item, kSecAttrAccessGroup, CFSTR("com.apple.youtube.credentials"), error)); - } else { - CFStringRef desc = SecDbItemGetCachedValueWithName(item, kSecAttrDescription); - if (!isString(desc)) return ok; - if (CFEqual(desc, CFSTR("IPSec Shared Secret")) || CFEqual(desc, CFSTR("PPP Password"))) { - ok = SecDbItemSetValueWithName(item, kSecAttrAccessible, kSecAttrAccessibleAfterFirstUnlock, error); - } - } - } - } else if (SecDbItemGetClass(item) == inet_class() && CFEqual(accessible, kSecAttrAccessibleAlwaysPrivate)) { - if (CFEqual(agrp, CFSTR("PrintKitAccessGroup"))) { - ok = SecDbItemSetValueWithName(item, kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked, error); - } else if (CFEqual(agrp, CFSTR("apple"))) { - CFTypeRef ptcl = SecDbItemGetCachedValueWithName(item, kSecAttrProtocol); - bool is_proxy = false; - if (isNumber(ptcl)) { - SInt32 iptcl; - CFNumberGetValue(ptcl, kCFNumberSInt32Type, &iptcl); - is_proxy = (iptcl == FOUR_CHAR_CODE('htpx') || - iptcl == FOUR_CHAR_CODE('htsx') || - iptcl == FOUR_CHAR_CODE('ftpx') || - iptcl == FOUR_CHAR_CODE('rtsx') || - iptcl == FOUR_CHAR_CODE('xpth') || - iptcl == FOUR_CHAR_CODE('xsth') || - iptcl == FOUR_CHAR_CODE('xptf') || - iptcl == FOUR_CHAR_CODE('xstr')); - } else if (isString(ptcl)) { - is_proxy = (CFEqual(ptcl, kSecAttrProtocolHTTPProxy) || - CFEqual(ptcl, kSecAttrProtocolHTTPSProxy) || - CFEqual(ptcl, kSecAttrProtocolRTSPProxy) || - CFEqual(ptcl, kSecAttrProtocolFTPProxy)); - } - if (is_proxy) - ok = SecDbItemSetValueWithName(item, kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked, error); - } - } - return ok; -} - -bool SecDbItemDecrypt(SecDbItemRef item, CFDataRef edata, CFErrorRef *error) { - bool ok = true; - CFMutableDictionaryRef dict = NULL; - SecAccessControlRef access_control = NULL; - uint32_t version = 0; - - require_quiet(ok = ks_decrypt_data(SecDbItemGetKeybag(item), item->cryptoOp, &access_control, item->credHandle, edata, - item->class, item->callerAccessGroups, &dict, &version, error), out); - - if (version < 2) { - /* Old V4 style keychain backup being imported. */ - ok = SecDbItemSetValueWithName(item, CFSTR("v_Data"), CFDictionaryGetValue(dict, CFSTR("v_Data")), error) && - SecDbItemImportMigrate(item, error); - } else { - ok = dict && SecDbItemSetValues(item, dict, error); - } - - SecAccessControlRef my_access_control = SecDbItemCopyAccessControl(item, error); - if (!my_access_control) { - ok = false; - goto out; - } - - /* Make sure that the protection of ACL in the dictionary (read from DB) matched what we got - back from decoding the data blob. */ - if (!CFEqual(SecAccessControlGetProtection(my_access_control), SecAccessControlGetProtection(access_control))) { - ok = SecError(errSecDecode, error, CFSTR("ACL protection doesn't match the one in blob (%@ : %@)"), - SecAccessControlGetProtection(my_access_control), - SecAccessControlGetProtection(access_control)); - } - CFRelease(my_access_control); - -out: - // If we got protection back from ks_decrypt_data, update the appropriate attribute even if anything else - // (incl. actual decryption) failed. We need to access the protection type even if we are not able to actually - // decrypt the data. - ok = SecDbItemSetAccessControl(item, access_control, NULL) && ok; - - CFReleaseSafe(dict); - CFReleaseSafe(access_control); - return ok; -} - -/* Automagically make a item syncable, based on various attributes. */ -bool SecDbItemInferSyncable(SecDbItemRef item, CFErrorRef *error) -{ - CFStringRef agrp = SecDbItemGetCachedValueWithName(item, kSecAttrAccessGroup); - - if (!isString(agrp)) - return true; - - if (CFEqual(agrp, CFSTR("com.apple.cfnetwork")) && SecDbItemGetClass(item) == inet_class()) { - CFTypeRef srvr = SecDbItemGetCachedValueWithName(item, kSecAttrServer); - CFTypeRef ptcl = SecDbItemGetCachedValueWithName(item, kSecAttrProtocol); - CFTypeRef atyp = SecDbItemGetCachedValueWithName(item, kSecAttrAuthenticationType); - - if (isString(srvr) && isString(ptcl) && isString(atyp)) { - /* This looks like a Mobile Safari Password, make syncable */ - secnotice("item", "Make this item syncable: %@", item); - return SecDbItemSetSyncable(item, true, error); - } - } - - return true; -} - -/* This create a SecDbItem from the item dictionnary that are exported for backups. - Item are stored in the backup as a dictionary containing two keys: - - v_Data: the encrypted data blob - - v_PersistentRef: a persistent Ref. - src_keybag is normally the backup keybag. - dst_keybag is normally the device keybag. - */ -SecDbItemRef SecDbItemCreateWithBackupDictionary(CFAllocatorRef allocator, const SecDbClass *dbclass, CFDictionaryRef dict, keybag_handle_t src_keybag, keybag_handle_t dst_keybag, CFErrorRef *error) -{ - CFDataRef edata = CFDictionaryGetValue(dict, CFSTR("v_Data")); - SecDbItemRef item = NULL; - - if (edata) { - item = SecDbItemCreateWithEncryptedData(kCFAllocatorDefault, dbclass, edata, src_keybag, error); - if (item) - if (!SecDbItemSetKeybag(item, dst_keybag, error)) - CFReleaseNull(item); - } else { - SecError(errSecDecode, error, CFSTR("No v_Data in backup dictionary %@"), dict); - } - - return item; -} - -bool SecDbItemExtractRowIdFromBackupDictionary(SecDbItemRef item, CFDictionaryRef dict, CFErrorRef *error) { - CFDataRef ref = CFDictionaryGetValue(dict, CFSTR("v_PersistentRef")); - if (!ref) - return SecError(errSecDecode, error, CFSTR("No v_PersistentRef in backup dictionary %@"), dict); - - CFStringRef className; - sqlite3_int64 rowid; - if (!_SecItemParsePersistentRef(ref, &className, &rowid, NULL)) - return SecError(errSecDecode, error, CFSTR("v_PersistentRef %@ failed to decode"), ref); - - if (!CFEqual(SecDbItemGetClass(item)->name, className)) - return SecError(errSecDecode, error, CFSTR("v_PersistentRef has unexpected class %@"), className); - - return SecDbItemSetRowId(item, rowid, error); -} - -static CFDataRef SecDbItemCopyDERWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error) { - CFDataRef der = NULL; - CFMutableDictionaryRef dict = SecDbItemCopyPListWithMask(item, mask, error); - if (dict) { - der = CFPropertyListCreateDERData(kCFAllocatorDefault, dict, error); - CFRelease(dict); - } - return der; -} - -static CFTypeRef SecDbItemCopyDigestWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error) { - CFDataRef digest = NULL; - CFDataRef der = SecDbItemCopyDERWithMask(item, mask, error); - if (der) { - digest = CFDataCopySHA1Digest(der, error); - CFRelease(der); - } - return digest; -} - -static CFTypeRef SecDbItemCopySHA256DigestWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error) { - CFDataRef digest = NULL; - CFDataRef der = SecDbItemCopyDERWithMask(item, mask, error); - if (der) { - digest = CFDataCopySHA256Digest(der, error); - CFRelease(der); - } - return digest; -} - -CFTypeRef SecDbKeychainItemCopyPrimaryKey(SecDbItemRef item, const SecDbAttr *attr, CFErrorRef *error) { - return SecDbItemCopyDigestWithMask(item, kSecDbPrimaryKeyFlag, error); -} - -CFTypeRef SecDbKeychainItemCopySHA256PrimaryKey(SecDbItemRef item, CFErrorRef *error) { - return SecDbItemCopySHA256DigestWithMask(item, kSecDbPrimaryKeyFlag, error); -} - -CFTypeRef SecDbKeychainItemCopySHA1(SecDbItemRef item, const SecDbAttr *attr, CFErrorRef *error) { - return SecDbItemCopyDigestWithMask(item, kSecDbInHashFlag, error); -} - -CFTypeRef SecDbKeychainItemCopyEncryptedData(SecDbItemRef item, const SecDbAttr *attr, CFErrorRef *error) { - CFDataRef edata = NULL; - CFMutableDictionaryRef attributes = SecDbItemCopyPListWithMask(item, kSecDbInCryptoDataFlag, error); - CFMutableDictionaryRef auth_attributes = SecDbItemCopyPListWithMask(item, kSecDbInAuthenticatedDataFlag, error); - if (attributes || auth_attributes) { - SecAccessControlRef access_control = SecDbItemCopyAccessControl(item, error); - if (access_control) { - if (ks_encrypt_data(item->keybag, access_control, item->credHandle, attributes, auth_attributes, &edata, true, error)) { - item->_edataState = kSecDbItemEncrypting; - } else if (!error || !*error || CFErrorGetCode(*error) != errSecAuthNeeded || !CFEqualSafe(CFErrorGetDomain(*error), kSecErrorDomain) ) { - seccritical("ks_encrypt_data (db): failed: %@", error ? *error : (CFErrorRef)CFSTR("")); - } - CFRelease(access_control); - } - CFReleaseSafe(attributes); - CFReleaseSafe(auth_attributes); - } - - return edata; -} - -CFTypeRef SecDbKeychainItemCopyCurrentDate(SecDbItemRef item, const SecDbAttr *attr, CFErrorRef *error) { - CFTypeRef value = NULL; - switch (attr->kind) { - case kSecDbDateAttr: - value = CFDateCreate(kCFAllocatorDefault, 0.0); - break; - case kSecDbCreationDateAttr: - case kSecDbModificationDateAttr: - value = CFDateCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent()); - break; - default: - SecError(errSecInternal, error, CFSTR("attr %@ has no default value"), attr->name); - value = NULL; - } - - return value; -} - -SecAccessControlRef SecDbItemCopyAccessControl(SecDbItemRef item, CFErrorRef *error) { - SecAccessControlRef accc = NULL, pdmn = NULL, result = NULL; - CFTypeRef acccData = SecDbItemGetValue(item, SecDbClassAttrWithKind(item->class, kSecDbAccessControlAttr, error), error); - CFTypeRef pdmnValue = SecDbItemGetValue(item, SecDbClassAttrWithKind(item->class, kSecDbAccessAttr, error), error); - - if (!acccData || !pdmnValue) - return NULL; - if (!CFEqual(acccData, kCFNull)) - require_quiet(accc = SecAccessControlCreateFromData(CFGetAllocator(item), acccData, error), out); - - if (!CFEqual(pdmnValue, kCFNull)) { - require_quiet(pdmn = SecAccessControlCreate(CFGetAllocator(item), error), out); - require_quiet(SecAccessControlSetProtection(pdmn, pdmnValue, error), out); - } - - if (accc && pdmn) { - CFTypeRef acccProt = SecAccessControlGetProtection(accc); - CFTypeRef pdmnProt = SecAccessControlGetProtection(pdmn); - if (!acccProt || !pdmnProt || !CFEqual(acccProt, pdmnProt)) { - secerror("SecDbItemCopyAccessControl accc %@ != pdmn %@, setting pdmn to accc value", acccProt, pdmnProt); - __security_simulatecrash(CFSTR("Corrupted item on decrypt accc != pdmn"), __sec_exception_code_CorruptItem); - // Setting pdmn to accc prot value. - require_quiet(SecDbItemSetValue(item, SecDbClassAttrWithKind(item->class, kSecDbAccessAttr, error), acccProt, error), out); - } - } - - if (accc) - CFRetainAssign(result, accc); - else if(pdmn) - CFRetainAssign(result, pdmn); - -out: - CFReleaseSafe(accc); - CFReleaseSafe(pdmn); - - return result; -} - -static const uint8_t* der_decode_plist_with_repair(CFAllocatorRef allocator, CFOptionFlags mutability, - CFPropertyListRef* pl, CFErrorRef *error, - const uint8_t* der, const uint8_t *der_end, - const uint8_t* (^repairBlock)(CFAllocatorRef, CFOptionFlags, CFPropertyListRef*, CFErrorRef*, - const uint8_t*, const uint8_t*)) -{ - if (NULL == der) { - SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Null DER"), NULL, error); - return NULL; - } - - ccder_tag tag; - if (NULL == ccder_decode_tag(&tag, der, der_end)) { - SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown data encoding"), NULL, error); - return NULL; - } - - switch (tag) { - case CCDER_NULL: - return der_decode_null(allocator, mutability, (CFNullRef*)pl, error, der, der_end); - case CCDER_BOOLEAN: - return der_decode_boolean(allocator, mutability, (CFBooleanRef*)pl, error, der, der_end); - case CCDER_OCTET_STRING: - return der_decode_data(allocator, mutability, (CFDataRef*)pl, error, der, der_end); - case CCDER_GENERALIZED_TIME: { - const uint8_t* der_result = der_decode_date(allocator, mutability, (CFDateRef*)pl, error, der, der_end); - if (!der_result) { - der_result = repairBlock(allocator, mutability, pl, error, der, der_end); - } - return der_result; - } - case CCDER_CONSTRUCTED_SEQUENCE: - return der_decode_array_with_repair(allocator, mutability, (CFArrayRef*)pl, error, der, der_end, repairBlock); - case CCDER_UTF8_STRING: - return der_decode_string(allocator, mutability, (CFStringRef*)pl, error, der, der_end); - case CCDER_INTEGER: - return der_decode_number(allocator, mutability, (CFNumberRef*)pl, error, der, der_end); - case CCDER_CONSTRUCTED_SET: - return der_decode_dictionary_with_repair(allocator, mutability, (CFDictionaryRef*)pl, error, der, der_end, repairBlock); - case CCDER_CONSTRUCTED_CFSET: - return der_decode_set_with_repair(allocator, mutability, (CFSetRef*)pl, error, der, der_end, repairBlock); - default: - SecCFDERCreateError(kSecDERErrorUnsupportedDERType, CFSTR("Unsupported DER Type"), NULL, error); - return NULL; - } -} - -static const uint8_t* der_decode_dictionary_with_repair(CFAllocatorRef allocator, CFOptionFlags mutability, - CFDictionaryRef* dictionary, CFErrorRef *error, - const uint8_t* der, const uint8_t *der_end, - const uint8_t* (^repairBlock)(CFAllocatorRef, CFOptionFlags, CFPropertyListRef*, CFErrorRef*, - const uint8_t*, const uint8_t*)) -{ - if (NULL == der) { - SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Null DER"), NULL, error); - return NULL; - } - - const uint8_t *payload_end = 0; - const uint8_t *payload = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SET, &payload_end, der, der_end); - - if (NULL == payload) { - SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown data encoding, expected CCDER_CONSTRUCTED_SET"), NULL, error); - return NULL; - } - - - CFMutableDictionaryRef dict = CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - - if (NULL == dict) { - SecCFDERCreateError(kSecDERErrorAllocationFailure, CFSTR("Failed to create dictionary"), NULL, error); - payload = NULL; - goto exit; - } - - while (payload != NULL && payload < payload_end) { - CFTypeRef key = NULL; - CFTypeRef value = NULL; - - payload = der_decode_key_value_with_repair(allocator, mutability, &key, &value, error, payload, payload_end, repairBlock); - - if (payload) { - CFDictionaryAddValue(dict, key, value); - } - - CFReleaseNull(key); - CFReleaseNull(value); - } - - -exit: - if (payload == payload_end) { - *dictionary = dict; - dict = NULL; - } - - CFReleaseNull(dict); - - return payload; -} - -static const uint8_t* der_decode_key_value_with_repair(CFAllocatorRef allocator, CFOptionFlags mutability, - CFPropertyListRef* key, CFPropertyListRef* value, CFErrorRef *error, - const uint8_t* der, const uint8_t *der_end, - const uint8_t* (^repairBlock)(CFAllocatorRef, CFOptionFlags, CFPropertyListRef*, CFErrorRef*, - const uint8_t*, const uint8_t*)) -{ - const uint8_t *payload_end = 0; - const uint8_t *payload = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &payload_end, der, der_end); - - if (NULL == payload) { - SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown data encoding, expected CCDER_CONSTRUCTED_SEQUENCE"), NULL, error); - return NULL; - } - - CFTypeRef keyObject = NULL; - CFTypeRef valueObject = NULL; - - - payload = der_decode_plist_with_repair(allocator, mutability, &keyObject, error, payload, payload_end, repairBlock); - payload = der_decode_plist_with_repair(allocator, mutability, &valueObject, error, payload, payload_end, repairBlock); - - if (payload != NULL) { - *key = keyObject; - *value = valueObject; - } else { - CFReleaseNull(keyObject); - CFReleaseNull(valueObject); - } - return payload; -} - -static const uint8_t* der_decode_array_with_repair(CFAllocatorRef allocator, CFOptionFlags mutability, - CFArrayRef* array, CFErrorRef *error, - const uint8_t* der, const uint8_t *der_end, - const uint8_t* (^repairBlock)(CFAllocatorRef, CFOptionFlags, CFPropertyListRef*, CFErrorRef*, - const uint8_t*, const uint8_t*)) -{ - if (NULL == der) { - SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Null DER"), NULL, error); - return NULL; - } - - CFMutableArrayRef result = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); - - const uint8_t *elements_end; - const uint8_t *current_element = ccder_decode_sequence_tl(&elements_end, der, der_end); - - while (current_element != NULL && current_element < elements_end) { - CFPropertyListRef element = NULL; - current_element = der_decode_plist_with_repair(allocator, mutability, &element, error, current_element, elements_end, repairBlock); - if (current_element) { - CFArrayAppendValue(result, element); - CFReleaseNull(element); - } - } - - if (current_element) { - *array = result; - result = NULL; - } - - CFReleaseNull(result); - return current_element; -} - -static const uint8_t* der_decode_set_with_repair(CFAllocatorRef allocator, CFOptionFlags mutability, - CFSetRef* set, CFErrorRef *error, - const uint8_t* der, const uint8_t *der_end, - const uint8_t* (^repairBlock)(CFAllocatorRef, CFOptionFlags, CFPropertyListRef*, CFErrorRef*, - const uint8_t*, const uint8_t*)) -{ - if (NULL == der) { - SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Null DER"), NULL, error); - return NULL; - } - - const uint8_t *payload_end = 0; - const uint8_t *payload = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_CFSET, &payload_end, der, der_end); - - if (NULL == payload) { - SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown data encoding, expected CCDER_CONSTRUCTED_CFSET"), NULL, error); - return NULL; - } - - CFMutableSetRef theSet = (set && *set) ? CFSetCreateMutableCopy(allocator, 0, *set) - : CFSetCreateMutable(allocator, 0, &kCFTypeSetCallBacks); - - if (NULL == theSet) { - SecCFDERCreateError(kSecDERErrorAllocationFailure, CFSTR("Failed to create set"), NULL, error); - payload = NULL; - goto exit; - } - - while (payload != NULL && payload < payload_end) { - CFTypeRef value = NULL; - - payload = der_decode_plist_with_repair(allocator, mutability, &value, error, payload, payload_end, repairBlock); - - if (payload) { - CFSetAddValue(theSet, value); - } - CFReleaseNull(value); - } - - -exit: - if (set && payload == payload_end) { - CFTransferRetained(*set, theSet); - } - - CFReleaseNull(theSet); - - return payload; -} diff --git a/OSX/sec/securityd/SecDbKeychainItem.h b/OSX/sec/securityd/SecDbKeychainItem.h index 35ebd36e..c19cd42b 100644 --- a/OSX/sec/securityd/SecDbKeychainItem.h +++ b/OSX/sec/securityd/SecDbKeychainItem.h @@ -35,12 +35,14 @@ __BEGIN_DECLS bool ks_encrypt_data(keybag_handle_t keybag, SecAccessControlRef access_control, CFDataRef acm_context, - CFDictionaryRef attributes, CFDictionaryRef authenticated_attributes, CFDataRef *pBlob, bool useDefaultIV, CFErrorRef *error); -bool ks_decrypt_data(keybag_handle_t keybag, CFTypeRef operation, SecAccessControlRef *paccess_control, CFDataRef acm_context, + CFDictionaryRef secretData, CFDictionaryRef attributes, CFDictionaryRef authenticated_attributes, CFDataRef *pBlob, bool useDefaultIV, CFErrorRef *error); +bool ks_encrypt_data_legacy(keybag_handle_t keybag, SecAccessControlRef access_control, CFDataRef acm_context, + CFDictionaryRef attributes, CFDictionaryRef authenticated_attributes, CFDataRef *pBlob, bool useDefaultIV, CFErrorRef *error); // used for backup +bool ks_decrypt_data(keybag_handle_t keybag, CFTypeRef cryptoOp, SecAccessControlRef *paccess_control, CFDataRef acm_context, CFDataRef blob, const SecDbClass *db_class, CFArrayRef caller_access_groups, - CFMutableDictionaryRef *attributes_p, uint32_t *version_p, CFErrorRef *error); + CFMutableDictionaryRef *attributes_p, uint32_t *version_p, bool decryptSecretData, keyclass_t* outKeyclass, CFErrorRef *error); bool s3dl_item_from_data(CFDataRef edata, Query *q, CFArrayRef accessGroups, - CFMutableDictionaryRef *item, SecAccessControlRef *access_control, CFErrorRef *error); + CFMutableDictionaryRef *item, SecAccessControlRef *access_control, keyclass_t* keyclass, CFErrorRef *error); SecDbItemRef SecDbItemCreateWithBackupDictionary(CFAllocatorRef allocator, const SecDbClass *dbclass, CFDictionaryRef dict, keybag_handle_t src_keybag, keybag_handle_t dst_keybag, CFErrorRef *error); bool SecDbItemExtractRowIdFromBackupDictionary(SecDbItemRef item, CFDictionaryRef dict, CFErrorRef *error); bool SecDbItemInferSyncable(SecDbItemRef item, CFErrorRef *error); @@ -54,6 +56,8 @@ CFTypeRef SecDbKeychainItemCopyEncryptedData(SecDbItemRef item, const SecDbAttr SecAccessControlRef SecDbItemCopyAccessControl(SecDbItemRef item, CFErrorRef *error); bool SecDbItemSetAccessControl(SecDbItemRef item, SecAccessControlRef access_control, CFErrorRef *error); +void SecDbResetMetadataKeys(void); + __END_DECLS #endif /* _SECURITYD_SECKEYCHAINITEM_H_ */ diff --git a/OSX/sec/securityd/SecDbKeychainItem.m b/OSX/sec/securityd/SecDbKeychainItem.m new file mode 100644 index 00000000..1530fd05 --- /dev/null +++ b/OSX/sec/securityd/SecDbKeychainItem.m @@ -0,0 +1,1510 @@ +/* + * Copyright (c) 2006-2014 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * SecDbKeychainItem.c - CoreFoundation-based constants and functions for + access to Security items (certificates, keys, identities, and + passwords.) + */ + +#include + +#import "SecInternalReleasePriv.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#import "SecDbKeychainItemV7.h" + +#if USE_KEYSTORE +#include +#include +#include +#include +#include + +#endif /* USE_KEYSTORE */ + +pthread_key_t CURRENT_CONNECTION_KEY; + +// From SecItemServer, should be a acl-check block +bool itemInAccessGroup(CFDictionaryRef item, CFArrayRef accessGroups); + +static keyclass_t kc_parse_keyclass(CFTypeRef value, CFErrorRef *error); +static CFTypeRef kc_encode_keyclass(keyclass_t keyclass); +static CFDataRef kc_copy_protection_data(SecAccessControlRef access_control); +static CFTypeRef kc_copy_protection_from(const uint8_t *der, const uint8_t *der_end); +static CF_RETURNS_RETAINED CFMutableDictionaryRef s3dl_item_v2_decode(CFDataRef plain, CFErrorRef *error); +static CF_RETURNS_RETAINED CFMutableDictionaryRef s3dl_item_v3_decode(CFDataRef plain, CFErrorRef *error); +#if USE_KEYSTORE +static bool kc_attribs_key_encrypted_data_from_blob(keybag_handle_t keybag, const SecDbClass *class, const void *blob_data, size_t blob_data_len, SecAccessControlRef access_control, uint32_t version, + CFMutableDictionaryRef *authenticated_attributes, aks_ref_key_t *ref_key, CFDataRef *encrypted_data, CFErrorRef *error); +static CFDataRef kc_create_auth_data(SecAccessControlRef access_control, CFDictionaryRef auth_attributes); +static CFDataRef kc_copy_access_groups_data(CFArrayRef access_groups, CFErrorRef *error); +#endif + +static const uint8_t* der_decode_plist_with_repair(CFAllocatorRef pl, CFOptionFlags mutability, CFPropertyListRef* cf, CFErrorRef *error, + const uint8_t* der, const uint8_t *der_end, + const uint8_t* (^repairBlock)(CFAllocatorRef allocator, CFOptionFlags mutability, CFPropertyListRef* pl, CFErrorRef *error, + const uint8_t* der, const uint8_t *der_end)); +static const uint8_t* der_decode_dictionary_with_repair(CFAllocatorRef allocator, CFOptionFlags mutability, CFDictionaryRef* dictionary, CFErrorRef *error, + const uint8_t* der, const uint8_t *der_end, + const uint8_t* (^repairBlock)(CFAllocatorRef allocator, CFOptionFlags mutability, CFPropertyListRef* pl, CFErrorRef *error, + const uint8_t* der, const uint8_t *der_end)); +static const uint8_t* der_decode_key_value_with_repair(CFAllocatorRef allocator, CFOptionFlags mutability, CFPropertyListRef* key, CFPropertyListRef* value, CFErrorRef *error, + const uint8_t* der, const uint8_t *der_end, + const uint8_t* (^repairBlock)(CFAllocatorRef allocator, CFOptionFlags mutability, CFPropertyListRef* pl, CFErrorRef *error, + const uint8_t* der, const uint8_t *der_end)); +static const uint8_t* der_decode_array_with_repair(CFAllocatorRef allocator, CFOptionFlags mutability, CFArrayRef* array, CFErrorRef *error, + const uint8_t* der, const uint8_t *der_end, + const uint8_t* (^repairBlock)(CFAllocatorRef allocator, CFOptionFlags mutability, CFPropertyListRef* pl, CFErrorRef *error, + const uint8_t* der, const uint8_t *der_end)); +static const uint8_t* der_decode_set_with_repair(CFAllocatorRef allocator, CFOptionFlags mutability, CFSetRef* set, CFErrorRef *error, + const uint8_t* der, const uint8_t *der_end, + const uint8_t* (^repairBlock)(CFAllocatorRef allocator, CFOptionFlags mutability, CFPropertyListRef* pl, CFErrorRef *error, + const uint8_t* der, const uint8_t *der_end)); + +const uint32_t kUseDefaultIVMask = 1<<31; +const int16_t kIVSizeAESGCM = 12; + +// echo "keychainblobstaticiv" | openssl dgst -sha256 | cut -c1-24 | xargs -I {} echo "0x{}" | xxd -r | xxd -p -i +static const uint8_t gcmIV[kIVSizeAESGCM] = { + 0x1e, 0xa0, 0x5c, 0xa9, 0x98, 0x2e, 0x87, 0xdc, 0xf1, 0x45, 0xe8, 0x24 +}; + +/* Given plainText create and return a CFDataRef containing: + BULK_KEY = RandomKey() + version || keyclass|ACL || KeyStore_WRAP(keyclass, BULK_KEY) || + AES(BULK_KEY, NULL_IV, plainText || padding) + */ +bool ks_encrypt_data_legacy(keybag_handle_t keybag, SecAccessControlRef access_control, CFDataRef acm_context, + CFDictionaryRef attributes, CFDictionaryRef authenticated_attributes, CFDataRef *pBlob, bool useDefaultIV, CFErrorRef *error) { + CFMutableDataRef blob = NULL; + CFDataRef ac_data = NULL; + bool ok = true; + //check(keybag >= 0); + + /* Precalculate output blob length. */ + const uint32_t bulkKeySize = 32; /* Use 256 bit AES key for bulkKey. */ + const uint32_t maxKeyWrapOverHead = 8 + 32; + uint8_t bulkKey[bulkKeySize]; + CFMutableDataRef bulkKeyWrapped = CFDataCreateMutable(NULL, 0); + CFDataSetLength(bulkKeyWrapped, bulkKeySize + maxKeyWrapOverHead); + uint32_t key_wrapped_size; + size_t ivLen = 0; + const uint8_t *iv = NULL; + const uint8_t *aad = NULL; // Additional Authenticated Data + ptrdiff_t aadLen = 0; + +#if USE_KEYSTORE + CFDataRef auth_data = NULL; +#endif + + /* If access_control specifies only protection and no ACL, use legacy blob format version 3, + which has better support for sync/backup. Otherwise, force new format v6 unless useDefaultIV is set. */ + bool hasACLConstraints = SecAccessControlGetConstraints(access_control); + const uint32_t version = (hasACLConstraints ? 6 : 3); + CFDataRef plainText = NULL; + if (version < 4) { + CFMutableDictionaryRef attributes_dict = CFDictionaryCreateMutableCopy(NULL, 0, attributes); + if (authenticated_attributes) { + CFDictionaryForEach(authenticated_attributes, ^(const void *key, const void *value) { + CFDictionaryAddValue(attributes_dict, key, value); + }); + } + + if (attributes_dict) { + // Drop the accc attribute for non v6 items during encode. + CFDictionaryRemoveValue(attributes_dict, kSecAttrAccessControl); + plainText = CFPropertyListCreateDERData(kCFAllocatorDefault, attributes_dict, error); + CFRelease(attributes_dict); + } + } else { +#if USE_KEYSTORE + if (attributes) { + plainText = CFPropertyListCreateDERData(kCFAllocatorDefault, attributes, error); + } +#else + CFMutableDictionaryRef attributes_dict = CFDictionaryCreateMutableCopy(NULL, 0, attributes); + if (authenticated_attributes) { + CFDictionaryForEach(authenticated_attributes, ^(const void *key, const void *value) { + CFDictionaryAddValue(attributes_dict, key, value); + }); + } + + if (attributes_dict) { + plainText = CFPropertyListCreateDERData(kCFAllocatorDefault, attributes_dict, error); + CFRelease(attributes_dict); + } +#endif + } + + if (!plainText || CFGetTypeID(plainText) != CFDataGetTypeID() + || access_control == 0) { + ok = SecError(errSecParam, error, CFSTR("ks_encrypt_data: invalid plain text")); + goto out; + } + + size_t ptLen = CFDataGetLength(plainText); + size_t ctLen = ptLen; + size_t tagLen = 16; + keyclass_t actual_class = 0; + + if (SecRandomCopyBytes(kSecRandomDefault, bulkKeySize, bulkKey)) { + ok = SecError(errSecAllocate, error, CFSTR("ks_encrypt_data: SecRandomCopyBytes failed")); + goto out; + } + + /* Extract keyclass from access control. */ + keyclass_t keyclass = kc_parse_keyclass(SecAccessControlGetProtection(access_control), error); + if (!keyclass) + goto out; + +#if USE_KEYSTORE + if (version >= 4) { + auth_data = kc_create_auth_data(access_control, authenticated_attributes); + require_quiet(ok = ks_encrypt_acl(keybag, keyclass, bulkKeySize, bulkKey, bulkKeyWrapped, auth_data, acm_context, access_control, error), out); + } else +#endif + { + /* Encrypt bulkKey. */ + require_quiet(ok = ks_crypt(kAKSKeyOpEncrypt, keybag, + keyclass, bulkKeySize, bulkKey, + &actual_class, bulkKeyWrapped, + error), out); + } + + key_wrapped_size = (uint32_t)CFDataGetLength(bulkKeyWrapped); + UInt8 *cursor; + size_t blobLen = sizeof(version); + uint32_t prot_length = 0; + + if (!hasACLConstraints) { + blobLen += sizeof(actual_class); + } else { + require_quiet(ac_data = kc_copy_protection_data(access_control), out); + prot_length = (uint32_t)CFDataGetLength(ac_data); + blobLen += sizeof(prot_length) + prot_length; + } + + blobLen += sizeof(key_wrapped_size) + key_wrapped_size + ctLen + tagLen; + require_quiet(blob = CFDataCreateMutable(NULL, blobLen), out); + CFDataSetLength(blob, blobLen); + cursor = CFDataGetMutableBytePtr(blob); + + *((uint32_t *)cursor) = useDefaultIV ? (version | kUseDefaultIVMask) : version; + cursor += sizeof(version); + + //secerror("class: %d actual class: %d", keyclass, actual_class); + if (!hasACLConstraints) { + *((keyclass_t *)cursor) = actual_class; + cursor += sizeof(keyclass); + } else { + *((uint32_t *)cursor) = prot_length; + cursor += sizeof(prot_length); + + CFDataGetBytes(ac_data, CFRangeMake(0, prot_length), cursor); + cursor += prot_length; + } + + *((uint32_t *)cursor) = key_wrapped_size; + cursor += sizeof(key_wrapped_size); + + if (useDefaultIV) { + iv = gcmIV; + ivLen = kIVSizeAESGCM; + // AAD is (version || ac_data || key_wrapped_size) + aad = CFDataGetMutableBytePtr(blob); + aadLen = cursor - aad; + } + + memcpy(cursor, CFDataGetBytePtr(bulkKeyWrapped), key_wrapped_size); + cursor += key_wrapped_size; + + /* Encrypt the plainText with the bulkKey. */ + CCCryptorStatus ccerr = CCCryptorGCM(kCCEncrypt, kCCAlgorithmAES128, + bulkKey, bulkKeySize, + iv, ivLen, /* iv */ + aad, aadLen, /* auth data */ + CFDataGetBytePtr(plainText), ptLen, + cursor, + cursor + ctLen, &tagLen); + if (ccerr) { + ok = SecError(errSecInternal, error, CFSTR("ks_encrypt_data: CCCryptorGCM failed: %d"), ccerr); + goto out; + } + if (tagLen != 16) { + ok = SecError(errSecInternal, error, CFSTR("ks_encrypt_data: CCCryptorGCM expected: 16 got: %ld byte tag"), tagLen); + goto out; + } + + out: + memset(bulkKey, 0, sizeof(bulkKey)); + CFReleaseSafe(ac_data); + CFReleaseSafe(bulkKeyWrapped); + CFReleaseSafe(plainText); + if (!ok) { + CFReleaseSafe(blob); + } else { + *pBlob = blob; + } + +#if USE_KEYSTORE + CFReleaseSafe(auth_data); +#endif + return ok; +} + +bool ks_encrypt_data(keybag_handle_t keybag, SecAccessControlRef access_control, CFDataRef acm_context, + CFDictionaryRef secretData, CFDictionaryRef attributes, CFDictionaryRef authenticated_attributes, CFDataRef *pBlob, bool useDefaultIV, CFErrorRef *error) { + if (CFDictionaryGetCount(secretData) == 0) { + secerror("SecDbKeychainItem: encrypting item with no secret data"); // not actually making this an error because it seems this is done frequently by third parties + } + + if (keybag != KEYBAG_DEVICE) { + secwarning("ks_encrypt_data: called with non-device keybag - call should be rerouted to ks_encrypt_data_legacy"); + + CFMutableDictionaryRef allAttributes = CFDictionaryCreateMutableCopy(NULL, CFDictionaryGetCount(secretData) + CFDictionaryGetCount(attributes), attributes); + CFDictionaryForEach(secretData, ^(const void *key, const void *value) { + CFDictionaryAddValue(allAttributes, key, value); + }); + bool result = ks_encrypt_data_legacy(keybag, access_control, acm_context, allAttributes, authenticated_attributes, pBlob, useDefaultIV, error); + CFReleaseNull(allAttributes); + return result; + } + + keyclass_t key_class = kc_parse_keyclass(SecAccessControlGetProtection(access_control), error); + if (!key_class) { + return false; + } + + if (SecAccessControlGetConstraints(access_control)) { + NSMutableDictionary* allAttributes = [(__bridge NSDictionary*)attributes mutableCopy]; + [allAttributes addEntriesFromDictionary:(__bridge NSDictionary*)secretData]; + return ks_encrypt_data_legacy(keybag, access_control, acm_context, (__bridge CFDictionaryRef)allAttributes, authenticated_attributes, pBlob, useDefaultIV, error); + } + + bool success = false; + @autoreleasepool { + NSMutableDictionary* metadataAttributes = attributes ? [(__bridge NSDictionary*)attributes mutableCopy] : [NSMutableDictionary dictionary]; + [metadataAttributes addEntriesFromDictionary:(__bridge NSDictionary*)authenticated_attributes]; + metadataAttributes[@"SecAccessControl"] = (__bridge_transfer NSData*)SecAccessControlCopyData(access_control); + + NSString* tamperCheck = [[NSUUID UUID] UUIDString]; // can use the item persistent reference when that starts getting filled in + SecDbKeychainItemV7* item = [[SecDbKeychainItemV7 alloc] initWithSecretAttributes:(__bridge NSDictionary*)secretData metadataAttributes:metadataAttributes tamperCheck:tamperCheck keyclass:key_class]; + + NSError* localError = nil; + NSData* encryptedBlob = [item encryptedBlobWithKeybag:keybag accessControl:access_control acmContext:(__bridge NSData*)acm_context error:&localError]; + if (encryptedBlob) { + NSMutableData* encryptedBlobWithVersion = [NSMutableData dataWithLength:encryptedBlob.length + sizeof(uint32_t)]; + *((uint32_t*)encryptedBlobWithVersion.mutableBytes) = (uint32_t)7; + memcpy((uint32_t*)encryptedBlobWithVersion.mutableBytes + 1, encryptedBlob.bytes, encryptedBlob.length); + *pBlob = (__bridge_retained CFDataRef)encryptedBlobWithVersion; + success = true; + } + else { + if (error) { + *error = (__bridge_retained CFErrorRef)localError; + } + } + } + + return success; +} + +/* Given cipherText containing: + version || keyclass || KeyStore_WRAP(keyclass, BULK_KEY) || + AES(BULK_KEY, NULL_IV, plainText || padding) + return the plainText. */ +bool ks_decrypt_data(keybag_handle_t keybag, CFTypeRef cryptoOp, SecAccessControlRef *paccess_control, CFDataRef acm_context, + CFDataRef blob, const SecDbClass *db_class, CFArrayRef caller_access_groups, + CFMutableDictionaryRef *attributes_p, uint32_t *version_p, bool decryptSecretData, keyclass_t* outKeyclass, CFErrorRef *error) { + const uint32_t v0KeyWrapOverHead = 8; + CFMutableDataRef bulkKey = CFDataCreateMutable(0, 32); /* Use 256 bit AES key for bulkKey. */ + CFDataSetLength(bulkKey, 32); /* Use 256 bit AES key for bulkKey. */ + bool ok = true; + SecAccessControlRef access_control = NULL; + + if (attributes_p) + *attributes_p = NULL; + if (version_p) + *version_p = 0; + + CFMutableDataRef plainText = NULL; + CFMutableDictionaryRef attributes = NULL; + uint32_t version = 0; + size_t ivLen = 0; + const uint8_t *iv = NULL; + const uint8_t *aad = NULL; // Additional Authenticated Data + ptrdiff_t aadLen = 0; + +#if USE_KEYSTORE + CFMutableDictionaryRef authenticated_attributes = NULL; + CFDataRef caller_access_groups_data = NULL; + CFDataRef ed_data = NULL; + aks_ref_key_t ref_key = NULL; +#if TARGET_OS_IPHONE + check(keybag >= 0); +#else + check((keybag >= 0) || (keybag == session_keybag_handle)); +#endif +#endif + + if (!blob) { + ok = SecError(errSecParam, error, CFSTR("ks_decrypt_data: invalid blob")); + goto out; + } + + size_t blobLen = CFDataGetLength(blob); + const uint8_t *cursor = CFDataGetBytePtr(blob); + keyclass_t keyclass; + + if (blobLen < sizeof(version)) { + ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: Check for underflow (length)")); + goto out; + } + + version = *((uint32_t *)cursor); + if (version & kUseDefaultIVMask) { + version &= ~kUseDefaultIVMask; + iv = gcmIV; + ivLen = kIVSizeAESGCM; + } + + cursor += sizeof(version); + blobLen -= sizeof(version); + + bool hasProtectionData = (version >= 4 && version < 7); + + if (version >= 7) { + @autoreleasepool { + NSError* localError = nil; + NSData* encryptedBlob = [NSData dataWithBytes:cursor length:blobLen]; + SecDbKeychainItemV7* item = [[SecDbKeychainItemV7 alloc] initWithData:encryptedBlob decryptionKeybag:keybag error:&localError]; + if (outKeyclass) { + *outKeyclass = item.keyclass; + } + + NSMutableDictionary* itemAttributes = [[item metadataAttributesWithError:&localError] mutableCopy]; + if (itemAttributes && !localError) { + NSData* accessControlData = itemAttributes[@"SecAccessControl"]; + access_control = SecAccessControlCreateFromData(NULL, (__bridge CFDataRef)accessControlData, error); + [itemAttributes removeObjectForKey:@"SecAccessControl"]; + + if (decryptSecretData) { + NSDictionary* secretAttributes = [item secretAttributesWithAcmContext:(__bridge NSData*)acm_context accessControl:access_control callerAccessGroups:(__bridge NSArray*)caller_access_groups error:&localError]; + if (secretAttributes) { + [itemAttributes addEntriesFromDictionary:secretAttributes]; + + if (secretAttributes.count == 0) { + secerror("SecDbKeychainItemV7: item decrypted succussfully, but has no secret data so it's useless"); // not actually making this an error because a bunch of third parties store items with no secret data on purpose + } + } + else { + ok = false; + } + } + + if (ok) { + if (CFEqual(kAKSKeyOpDelete, cryptoOp)) { + ok = [item deleteWithAcmContext:(__bridge NSData*)acm_context accessControl:access_control callerAccessGroups:(__bridge NSArray*)caller_access_groups error:&localError]; + } + + attributes = (__bridge_retained CFMutableDictionaryRef)itemAttributes; + } + } + else { + ok = false; + } + + if (!ok && error) { + *error = (__bridge_retained CFErrorRef)localError; + } + } + goto out; + } + + if (hasProtectionData) { + /* Deserialize SecAccessControl object from the blob. */ + uint32_t prot_length; + + /* + * Parse proto length + */ + + if (blobLen < sizeof(prot_length)) { + ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: Check for underflow (prot_length)")); + goto out; + } + + prot_length = *((uint32_t *)cursor); + cursor += sizeof(prot_length); + blobLen -= sizeof(prot_length); + + /* + * Parse proto itself + */ + + if (blobLen < prot_length) { + ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: Check for underflow (prot)")); + goto out; + } + + CFTypeRef protection = kc_copy_protection_from(cursor, cursor + prot_length); + if (!protection) { + ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: invalid ACL")); + goto out; + } else { + access_control = SecAccessControlCreate(NULL, NULL); + require_quiet(access_control, out); + ok = SecAccessControlSetProtection(access_control, protection, NULL); + CFRelease(protection); + if (!ok) { + SecError(errSecDecode, error, CFSTR("ks_decrypt_data: invalid ACL")); + goto out; + } + } + + cursor += prot_length; + blobLen -= prot_length; + + /* + * Get numeric value of keyclass from the access_control. + */ + keyclass = kc_parse_keyclass(SecAccessControlGetProtection(access_control), error); + if (!keyclass) { + ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: invalid ACL")); + goto out; + } + } else { + if (blobLen < sizeof(keyclass)) { + ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: Check for underflow (keyclass)")); + goto out; + } + + keyclass = *((keyclass_t *)cursor); + +#if USE_KEYSTORE + CFTypeRef protection = kc_encode_keyclass(keyclass & key_class_last); // mask out generation +#else + CFTypeRef protection = kc_encode_keyclass(keyclass); +#endif + require_action_quiet(protection, out, ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: invalid keyclass detected"))); + require_action_quiet(access_control = SecAccessControlCreate(kCFAllocatorDefault, error), out, + ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: SecAccessControlCreate failed"))); + require_action_quiet(SecAccessControlSetProtection(access_control, protection, error), out, + ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: SecAccessControlSetProtection failed"))); + + cursor += sizeof(keyclass); + blobLen -= sizeof(keyclass); + } + + size_t tagLen = 0; + uint32_t wrapped_key_size = 0; + + switch (version) { + case 0: + wrapped_key_size = (uint32_t)CFDataGetLength(bulkKey) + v0KeyWrapOverHead; + break; + case 2: + case 3: + /* DROPTHROUGH */ + /* v2 and v3 have the same crypto, just different dictionary encodings. */ + /* Difference between v3 and v6 is already handled above, so treat v3 as v6. */ + case 4: + case 5: + case 6: + tagLen = 16; + /* DROPTHROUGH */ + case 1: + if (blobLen < sizeof(wrapped_key_size)) { + ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: Check for underflow (wrapped_key_size)")); + goto out; + } + wrapped_key_size = *((uint32_t *)cursor); + + cursor += sizeof(wrapped_key_size); + blobLen -= sizeof(wrapped_key_size); + + break; + default: + ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: invalid version %d"), version); + goto out; + } + + if (blobLen < tagLen + wrapped_key_size) { + ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: Check for underflow (wrapped_key/taglen)")); + goto out; + } + + size_t ctLen = blobLen - tagLen - wrapped_key_size; + + /* + * Pre-version 2 have some additial constraints since it use AES in CBC mode + */ + if (version < 2) { + if (ctLen < kCCBlockSizeAES128) { + ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: Check for underflow (CBC check)")); + goto out; + } + if ((ctLen & 0xF) != 0) { + ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: invalid length on CBC data")); + goto out; + } + } + +#if USE_KEYSTORE + if (hasProtectionData) { + if (caller_access_groups) { + caller_access_groups_data = kc_copy_access_groups_data(caller_access_groups, error); + require_quiet(ok = (caller_access_groups_data != NULL), out); + } + + require_quiet(ok = kc_attribs_key_encrypted_data_from_blob(keybag, db_class, cursor, wrapped_key_size, access_control, version, + &authenticated_attributes, &ref_key, &ed_data, error), out); + if (CFEqual(cryptoOp, kAKSKeyOpDecrypt)) { + require_quiet(ok = ks_decrypt_acl(ref_key, ed_data, bulkKey, acm_context, caller_access_groups_data, access_control, error), out); + } else if (CFEqual(cryptoOp, kAKSKeyOpDelete)) { + require_quiet(ok = ks_delete_acl(ref_key, ed_data, acm_context, caller_access_groups_data, access_control, error), out); + attributes = CFRetainSafe(authenticated_attributes); + goto out; + } else { + ok = SecError(errSecInternal, error, CFSTR("ks_decrypt_data: invalid operation")); + goto out; + } + } else +#endif + { + /* Now unwrap the bulk key using a key in the keybag. */ + require_quiet(ok = ks_crypt(cryptoOp, keybag, + keyclass, wrapped_key_size, cursor, NULL, bulkKey, error), out); + } + + if (iv) { + // AAD is (version || ... [|| key_wrapped_size ]) + aad = CFDataGetBytePtr(blob); + aadLen = cursor - aad; + } + + cursor += wrapped_key_size; + + plainText = CFDataCreateMutable(NULL, ctLen); + if (!plainText) { + ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: failed to allocate data for plain text")); + goto out; + } + CFDataSetLength(plainText, ctLen); + + /* Decrypt the cipherText with the bulkKey. */ + CCCryptorStatus ccerr; + if (tagLen) { + uint8_t tag[tagLen]; + ccerr = CCCryptorGCM(kCCDecrypt, kCCAlgorithmAES128, + CFDataGetBytePtr(bulkKey), CFDataGetLength(bulkKey), + iv, ivLen, /* iv */ + aad, aadLen, /* auth data */ + cursor, ctLen, + CFDataGetMutableBytePtr(plainText), + tag, &tagLen); + if (ccerr) { + /* TODO: Should this be errSecDecode once AppleKeyStore correctly + identifies uuid unwrap failures? */ + /* errSecInteractionNotAllowed; */ + ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: CCCryptorGCM failed: %d"), ccerr); + goto out; + } + if (tagLen != 16) { + ok = SecError(errSecInternal, error, CFSTR("ks_decrypt_data: CCCryptorGCM expected: 16 got: %ld byte tag"), tagLen); + goto out; + } + cursor += ctLen; + if (timingsafe_bcmp(tag, cursor, tagLen)) { + ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: CCCryptorGCM computed tag not same as tag in blob")); + goto out; + } + } else { + size_t ptLen; + ccerr = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, + CFDataGetBytePtr(bulkKey), CFDataGetLength(bulkKey), NULL, cursor, ctLen, + CFDataGetMutableBytePtr(plainText), ctLen, &ptLen); + if (ccerr) { + /* TODO: Should this be errSecDecode once AppleKeyStore correctly + identifies uuid unwrap failures? */ + /* errSecInteractionNotAllowed; */ + ok = SecError(errSecDecode, error, CFSTR("ks_decrypt_data: CCCrypt failed: %d"), ccerr); + goto out; + } + CFDataSetLength(plainText, ptLen); + } + + if (version < 2) { + attributes = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionaryAddValue(attributes, CFSTR("v_Data"), plainText); + } else if (version < 3) { + attributes = s3dl_item_v2_decode(plainText, error); + } else { + attributes = s3dl_item_v3_decode(plainText, error); + } + + require_action_quiet(attributes, out, { ok = false; secerror("decode v%d failed: %@", version, error ? *error : NULL); }); + +#if USE_KEYSTORE + if (version >= 4 && authenticated_attributes != NULL) { + CFDictionaryForEach(authenticated_attributes, ^(const void *key, const void *value) { + CFDictionaryAddValue(attributes, key, value); + }); + } +#endif + +out: + memset(CFDataGetMutableBytePtr(bulkKey), 0, CFDataGetLength(bulkKey)); + CFReleaseNull(bulkKey); + CFReleaseNull(plainText); + + // Always copy access control data (if present), because if we fail it may indicate why. + if (paccess_control) + *paccess_control = access_control; + else + CFReleaseNull(access_control); + + if (ok) { + if (attributes_p) + CFRetainAssign(*attributes_p, attributes); + if (version_p) + *version_p = version; + } + CFReleaseNull(attributes); +#if USE_KEYSTORE + CFReleaseNull(authenticated_attributes); + CFReleaseNull(caller_access_groups_data); + CFReleaseNull(ed_data); + if (ref_key) aks_ref_key_free(&ref_key); +#endif + return ok; +} + +static keyclass_t kc_parse_keyclass(CFTypeRef value, CFErrorRef *error) { + if (!isString(value)) { + SecError(errSecParam, error, CFSTR("accessible attribute %@ not a string"), value); + } else if (CFEqual(value, kSecAttrAccessibleWhenUnlocked)) { + return key_class_ak; + } else if (CFEqual(value, kSecAttrAccessibleAfterFirstUnlock)) { + return key_class_ck; + } else if (CFEqual(value, kSecAttrAccessibleAlwaysPrivate)) { + return key_class_dk; + } else if (CFEqual(value, kSecAttrAccessibleWhenUnlockedThisDeviceOnly)) { + return key_class_aku; + } else if (CFEqual(value, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly)) { + return key_class_cku; + } else if (CFEqual(value, kSecAttrAccessibleAlwaysThisDeviceOnlyPrivate)) { + return key_class_dku; + } else if (CFEqual(value, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly)) { + return key_class_akpu; + } else { + SecError(errSecParam, error, CFSTR("accessible attribute %@ unknown"), value); + } + return 0; +} + +static CFTypeRef kc_encode_keyclass(keyclass_t keyclass) { + switch (keyclass) { + case key_class_ak: + return kSecAttrAccessibleWhenUnlocked; + case key_class_ck: + return kSecAttrAccessibleAfterFirstUnlock; + case key_class_dk: + return kSecAttrAccessibleAlwaysPrivate; + case key_class_aku: + return kSecAttrAccessibleWhenUnlockedThisDeviceOnly; + case key_class_cku: + return kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly; + case key_class_dku: + return kSecAttrAccessibleAlwaysThisDeviceOnlyPrivate; + case key_class_akpu: + return kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly; + default: + return 0; + } +} + +#if USE_KEYSTORE +static bool kc_attribs_key_encrypted_data_from_blob(keybag_handle_t keybag, const SecDbClass *class, const void *blob_data, size_t blob_data_len, SecAccessControlRef access_control, uint32_t version, + CFMutableDictionaryRef *authenticated_attributes, aks_ref_key_t *ref_key, CFDataRef *encrypted_data, CFErrorRef *error) +{ + CFMutableDictionaryRef acl = NULL; + CFDictionaryRef blob_dict = NULL; + aks_ref_key_t tmp_ref_key = NULL; + CFDataRef key_data = NULL; + CFDataRef ed = NULL; + bool ok = false; + + der_decode_plist(NULL, kCFPropertyListImmutable, (CFPropertyListRef*)&blob_dict, NULL, blob_data, blob_data + blob_data_len); + require_action_quiet(blob_dict, out, SecError(errSecDecode, error, CFSTR("kc_attribs_key_encrypted_data_from_blob: failed to decode 'blob data'"))); + + if (!ks_separate_data_and_key(blob_dict, &ed, &key_data)) { + ed = CFDataCreate(kCFAllocatorDefault, blob_data, blob_data_len); + key_data = CFRetain(ed); + } + require_action_quiet(ed, out, SecError(errSecDecode, error, CFSTR("kc_attribs_key_encrypted_data_from_blob: failed to decode 'encrypted data'"))); + require_action_quiet(key_data, out, SecError(errSecDecode, error, CFSTR("kc_attribs_key_encrypted_data_from_blob: failed to decode 'key data'"))); + + const void *external_data = NULL; + size_t external_data_len = 0; + require_quiet(external_data = ks_ref_key_get_external_data(keybag, key_data, &tmp_ref_key, &external_data_len, error), out); + + CFPropertyListRef external_data_dict = NULL; + der_decode_plist(NULL, kCFPropertyListImmutable, &external_data_dict, NULL, external_data, external_data + external_data_len); + require_action_quiet(external_data_dict, out, SecError(errSecDecode, error, CFSTR("kc_attribs_key_encrypted_data_from_blob: failed to decode 'encrypted data dictionary'"))); + acl = CFDictionaryCreateMutableCopy(NULL, 0, external_data_dict); + SecDbForEachAttrWithMask(class, attr_desc, kSecDbInAuthenticatedDataFlag) { + CFDictionaryRemoveValue(acl, attr_desc->name); + CFTypeRef value = CFDictionaryGetValue(external_data_dict, attr_desc->name); + if (value) { + if (!*authenticated_attributes) + *authenticated_attributes = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + CFDictionaryAddValue(*authenticated_attributes, attr_desc->name, value); + } + } + CFReleaseSafe(external_data_dict); + + if (acl) { + /* v4 data format used wrong ACL placement, for backward compatibility we have to support both formats */ + if (version == 4) { + SecAccessControlSetConstraints(access_control, acl); + } else { + CFDictionaryRef constraints = CFDictionaryGetValue(acl, kAKSKeyAcl); + require_action_quiet(isDictionary(constraints), out, + SecError(errSecDecode, error, CFSTR("kc_attribs_key_encrypted_data_from_blob: acl missing"))); + SecAccessControlSetConstraints(access_control, constraints); + } + + /* v4/v5 data format usualy does not contain kAKSKeyOpEncrypt, so add kAKSKeyOpEncrypt if is missing */ + if (version < 6) { + SecAccessConstraintRef encryptConstraint = SecAccessControlGetConstraint(access_control, kAKSKeyOpEncrypt); + if (!encryptConstraint) + SecAccessControlAddConstraintForOperation(access_control, kAKSKeyOpEncrypt, kCFBooleanTrue, NULL); + } + + } + + if (encrypted_data) + *encrypted_data = CFRetain(ed); + + if (ref_key) { + *ref_key = tmp_ref_key; + tmp_ref_key = NULL; + } + + ok = true; + +out: + if (tmp_ref_key) + aks_ref_key_free(&tmp_ref_key); + CFReleaseSafe(blob_dict); + CFReleaseSafe(key_data); + CFReleaseSafe(ed); + CFReleaseSafe(acl); + + + return ok; +} + +static CFDataRef kc_create_auth_data(SecAccessControlRef access_control, CFDictionaryRef auth_attributes) { + CFDictionaryRef constraints = SecAccessControlGetConstraints(access_control); + CFMutableDictionaryRef auth_data = CFDictionaryCreateMutableCopy(NULL, 0, auth_attributes); + CFDictionarySetValue(auth_data, kAKSKeyAcl, constraints); + CFDataRef encoded = CFPropertyListCreateDERData(kCFAllocatorDefault, auth_data, NULL); + CFReleaseSafe(auth_data); + return encoded; +} + +static CFDataRef kc_copy_access_groups_data(CFArrayRef access_groups, CFErrorRef *error) +{ + size_t ag_size = der_sizeof_plist(access_groups, error); + CFMutableDataRef result = CFDataCreateMutable(kCFAllocatorDefault, 0); + CFDataSetLength(result, ag_size); + if (!der_encode_plist(access_groups, error, CFDataGetMutableBytePtr(result), CFDataGetMutableBytePtr(result) + ag_size)) { + CFRelease(result); + return NULL; + } + else + return result; +} + +#endif /* USE_KEYSTORE */ + +static CFDataRef kc_copy_protection_data(SecAccessControlRef access_control) +{ + CFTypeRef protection = SecAccessControlGetProtection(access_control); + size_t protection_size = der_sizeof_plist(protection, NULL); + CFMutableDataRef result = CFDataCreateMutable(NULL, 0); + CFDataSetLength(result, protection_size); + if (!der_encode_plist(protection, NULL, CFDataGetMutableBytePtr(result), CFDataGetMutableBytePtr(result) + protection_size)) { + CFRelease(result); + return NULL; + } + else + return result; +} + +static CFTypeRef kc_copy_protection_from(const uint8_t *der, const uint8_t *der_end) +{ + CFTypeRef result = NULL; + der_decode_plist(NULL, kCFPropertyListImmutable, &result, NULL, der, der_end); + return result; +} + +/* Return a (mutable) dictionary if plist is a dictionary, return NULL and set error otherwise. Does nothing if plist is already NULL. */ +static CF_RETURNS_RETAINED +CFMutableDictionaryRef dictionaryFromPlist(CFPropertyListRef plist CF_CONSUMED, CFErrorRef *error) { + if (plist && !isDictionary(plist)) { + CFStringRef typeName = CFCopyTypeIDDescription(CFGetTypeID((CFTypeRef)plist)); + SecError(errSecDecode, error, CFSTR("plist is a %@, expecting a dictionary"), typeName); + CFReleaseSafe(typeName); + CFReleaseNull(plist); + } + return (CFMutableDictionaryRef)plist; +} + +static CF_RETURNS_RETAINED +CFMutableDictionaryRef s3dl_item_v2_decode(CFDataRef plain, CFErrorRef *error) { + CFPropertyListRef item; + item = CFPropertyListCreateWithData(0, plain, kCFPropertyListMutableContainers, NULL, error); + return dictionaryFromPlist(item, error); +} + +static const uint8_t* (^s3dl_item_v3_decode_repair_date)(CFAllocatorRef, CFOptionFlags, CFPropertyListRef*, CFErrorRef*, const uint8_t*, const uint8_t*) = + ^const uint8_t*(CFAllocatorRef allocator, CFOptionFlags mutability, CFPropertyListRef* pl, CFErrorRef *error, const uint8_t* der, const uint8_t *der_end) { + if (error && CFEqualSafe(CFErrorGetDomain(*error), sSecDERErrorDomain) && CFErrorGetCode(*error) == kSecDERErrorUnknownEncoding) { + CFAbsoluteTime date = 0; + CFCalendarRef calendar = CFCalendarCreateWithIdentifier(allocator, kCFGregorianCalendar); + CFTimeZoneRef tz = CFTimeZoneCreateWithTimeIntervalFromGMT(allocator, 0); + CFCalendarSetTimeZone(calendar, tz); + CFCalendarComposeAbsoluteTime(calendar, &date, "yMd", 2001, 3, 24); // random date for 15A143: can't recover keychain + CFReleaseSafe(tz); + CFReleaseSafe(calendar); + + *pl = CFDateCreate(allocator, date); + if (NULL != *pl) { + CFReleaseNull(*error); + return der_end; + } + } + return NULL; +}; + +static CF_RETURNS_RETAINED +CFMutableDictionaryRef s3dl_item_v3_decode(CFDataRef plain, CFErrorRef *error) { + CFPropertyListRef item = NULL; + const uint8_t *der_beg = CFDataGetBytePtr(plain); + const uint8_t *der_end = der_beg + CFDataGetLength(plain); + const uint8_t *der = der_decode_plist(0, kCFPropertyListMutableContainers, &item, error, der_beg, der_end); + if (!der && error && CFEqualSafe(CFErrorGetDomain(*error), sSecDERErrorDomain) && CFErrorGetCode(*error) == kSecDERErrorUnknownEncoding) { + CFReleaseNull(*error); + der = der_decode_plist_with_repair(0, kCFPropertyListMutableContainers, &item, error, der_beg, der_end, s3dl_item_v3_decode_repair_date); + } + if (der && der != der_end) { + SecCFCreateError(errSecDecode, kSecErrorDomain, CFSTR("trailing garbage at end of decrypted item"), NULL, error); + CFReleaseNull(item); + } + return dictionaryFromPlist(item, error); +} + +bool s3dl_item_from_data(CFDataRef edata, Query *q, CFArrayRef accessGroups, + CFMutableDictionaryRef *item, SecAccessControlRef *access_control, keyclass_t* keyclass, CFErrorRef *error) { + SecAccessControlRef ac = NULL; + CFDataRef ac_data = NULL; + bool ok = false; + + /* Decrypt and decode the item and check the decoded attributes against the query. */ + uint32_t version = 0; + + bool decryptSecretData = false; + if ((q->q_return_type & kSecReturnDataMask) || (q->q_return_type & kSecReturnRefMask)) { + decryptSecretData = true; + } + else if (q->q_match_policy || q->q_match_valid_on_date || q->q_match_trusted_only) { + decryptSecretData = true; + } + + require_quiet((ok = ks_decrypt_data(q->q_keybag, kAKSKeyOpDecrypt, &ac, q->q_use_cred_handle, edata, q->q_class, + q->q_caller_access_groups, item, &version, decryptSecretData, keyclass, error)), out); + if (version < 2) { + goto out; + } + + ac_data = SecAccessControlCopyData(ac); + if (!itemInAccessGroup(*item, accessGroups)) { + secerror("items accessGroup %@ not in %@", + CFDictionaryGetValue(*item, kSecAttrAccessGroup), + accessGroups); + ok = SecError(errSecDecode, error, CFSTR("items accessGroup %@ not in %@"), + CFDictionaryGetValue(*item, kSecAttrAccessGroup), + accessGroups); + CFReleaseNull(*item); + } + + /* AccessControl attribute does not exist in the db, so synthesize it. */ + if (version > 3) + CFDictionarySetValue(*item, kSecAttrAccessControl, ac_data); + + /* TODO: Validate access_control attribute. */ + +out: + if (access_control) + *access_control = CFRetainSafe(ac); + CFReleaseSafe(ac); + CFReleaseSafe(ac_data); + return ok; +} + +/* Infer accessibility and access group for pre-v2 (iOS4.x and earlier) items + being imported from a backup. */ +static bool SecDbItemImportMigrate(SecDbItemRef item, CFErrorRef *error) { + bool ok = true; + CFStringRef agrp = SecDbItemGetCachedValueWithName(item, kSecAttrAccessGroup); + CFStringRef accessible = SecDbItemGetCachedValueWithName(item, kSecAttrAccessible); + + if (!isString(agrp) || !isString(accessible)) + return ok; + if (SecDbItemGetClass(item) == genp_class() && CFEqual(accessible, kSecAttrAccessibleAlwaysPrivate)) { + CFStringRef svce = SecDbItemGetCachedValueWithName(item, kSecAttrService); + if (!isString(svce)) return ok; + if (CFEqual(agrp, CFSTR("apple"))) { + if (CFEqual(svce, CFSTR("AirPort"))) { + ok = SecDbItemSetValueWithName(item, kSecAttrAccessible, kSecAttrAccessibleAfterFirstUnlock, error); + } else if (CFEqual(svce, CFSTR("com.apple.airplay.password"))) { + ok = SecDbItemSetValueWithName(item, kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked, error); + } else if (CFEqual(svce, CFSTR("YouTube"))) { + ok = (SecDbItemSetValueWithName(item, kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked, error) && + SecDbItemSetValueWithName(item, kSecAttrAccessGroup, CFSTR("com.apple.youtube.credentials"), error)); + } else { + CFStringRef desc = SecDbItemGetCachedValueWithName(item, kSecAttrDescription); + if (!isString(desc)) return ok; + if (CFEqual(desc, CFSTR("IPSec Shared Secret")) || CFEqual(desc, CFSTR("PPP Password"))) { + ok = SecDbItemSetValueWithName(item, kSecAttrAccessible, kSecAttrAccessibleAfterFirstUnlock, error); + } + } + } + } else if (SecDbItemGetClass(item) == inet_class() && CFEqual(accessible, kSecAttrAccessibleAlwaysPrivate)) { + if (CFEqual(agrp, CFSTR("PrintKitAccessGroup"))) { + ok = SecDbItemSetValueWithName(item, kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked, error); + } else if (CFEqual(agrp, CFSTR("apple"))) { + CFTypeRef ptcl = SecDbItemGetCachedValueWithName(item, kSecAttrProtocol); + bool is_proxy = false; + if (isNumber(ptcl)) { + SInt32 iptcl; + CFNumberGetValue(ptcl, kCFNumberSInt32Type, &iptcl); + is_proxy = (iptcl == FOUR_CHAR_CODE('htpx') || + iptcl == FOUR_CHAR_CODE('htsx') || + iptcl == FOUR_CHAR_CODE('ftpx') || + iptcl == FOUR_CHAR_CODE('rtsx') || + iptcl == FOUR_CHAR_CODE('xpth') || + iptcl == FOUR_CHAR_CODE('xsth') || + iptcl == FOUR_CHAR_CODE('xptf') || + iptcl == FOUR_CHAR_CODE('xstr')); + } else if (isString(ptcl)) { + is_proxy = (CFEqual(ptcl, kSecAttrProtocolHTTPProxy) || + CFEqual(ptcl, kSecAttrProtocolHTTPSProxy) || + CFEqual(ptcl, kSecAttrProtocolRTSPProxy) || + CFEqual(ptcl, kSecAttrProtocolFTPProxy)); + } + if (is_proxy) + ok = SecDbItemSetValueWithName(item, kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked, error); + } + } + return ok; +} + +bool SecDbItemDecrypt(SecDbItemRef item, bool decryptSecretData, CFDataRef edata, CFErrorRef *error) { + bool ok = true; + CFMutableDictionaryRef dict = NULL; + SecAccessControlRef access_control = NULL; + uint32_t version = 0; + + require_quiet(ok = ks_decrypt_data(SecDbItemGetKeybag(item), item->cryptoOp, &access_control, item->credHandle, edata, + item->class, item->callerAccessGroups, &dict, &version, decryptSecretData, NULL, error), out); + + if (version < 2) { + /* Old V4 style keychain backup being imported. */ + ok = SecDbItemSetValueWithName(item, CFSTR("v_Data"), CFDictionaryGetValue(dict, CFSTR("v_Data")), error) && + SecDbItemImportMigrate(item, error); + } else { + ok = dict && SecDbItemSetValues(item, dict, error); + } + + SecAccessControlRef my_access_control = SecDbItemCopyAccessControl(item, error); + if (!my_access_control) { + ok = false; + goto out; + } + + /* Make sure that the protection of ACL in the dictionary (read from DB) matched what we got + back from decoding the data blob. */ + if (!CFEqual(SecAccessControlGetProtection(my_access_control), SecAccessControlGetProtection(access_control))) { + ok = SecError(errSecDecode, error, CFSTR("ACL protection doesn't match the one in blob (%@ : %@)"), + SecAccessControlGetProtection(my_access_control), + SecAccessControlGetProtection(access_control)); + } + CFRelease(my_access_control); + +out: + // If we got protection back from ks_decrypt_data, update the appropriate attribute even if anything else + // (incl. actual decryption) failed. We need to access the protection type even if we are not able to actually + // decrypt the data. + ok = SecDbItemSetAccessControl(item, access_control, NULL) && ok; + + CFReleaseSafe(dict); + CFReleaseSafe(access_control); + return ok; +} + +/* Automagically make a item syncable, based on various attributes. */ +bool SecDbItemInferSyncable(SecDbItemRef item, CFErrorRef *error) +{ + CFStringRef agrp = SecDbItemGetCachedValueWithName(item, kSecAttrAccessGroup); + + if (!isString(agrp)) + return true; + + if (CFEqual(agrp, CFSTR("com.apple.cfnetwork")) && SecDbItemGetClass(item) == inet_class()) { + CFTypeRef srvr = SecDbItemGetCachedValueWithName(item, kSecAttrServer); + CFTypeRef ptcl = SecDbItemGetCachedValueWithName(item, kSecAttrProtocol); + CFTypeRef atyp = SecDbItemGetCachedValueWithName(item, kSecAttrAuthenticationType); + + if (isString(srvr) && isString(ptcl) && isString(atyp)) { + /* This looks like a Mobile Safari Password, make syncable */ + secnotice("item", "Make this item syncable: %@", item); + return SecDbItemSetSyncable(item, true, error); + } + } + + return true; +} + +/* This create a SecDbItem from the item dictionnary that are exported for backups. + Item are stored in the backup as a dictionary containing two keys: + - v_Data: the encrypted data blob + - v_PersistentRef: a persistent Ref. + src_keybag is normally the backup keybag. + dst_keybag is normally the device keybag. + */ +SecDbItemRef SecDbItemCreateWithBackupDictionary(CFAllocatorRef allocator, const SecDbClass *dbclass, CFDictionaryRef dict, keybag_handle_t src_keybag, keybag_handle_t dst_keybag, CFErrorRef *error) +{ + CFDataRef edata = CFDictionaryGetValue(dict, CFSTR("v_Data")); + SecDbItemRef item = NULL; + + if (edata) { + item = SecDbItemCreateWithEncryptedData(kCFAllocatorDefault, dbclass, edata, src_keybag, error); + if (item) + if (!SecDbItemSetKeybag(item, dst_keybag, error)) + CFReleaseNull(item); + } else { + SecError(errSecDecode, error, CFSTR("No v_Data in backup dictionary %@"), dict); + } + + return item; +} + +bool SecDbItemExtractRowIdFromBackupDictionary(SecDbItemRef item, CFDictionaryRef dict, CFErrorRef *error) { + CFDataRef ref = CFDictionaryGetValue(dict, CFSTR("v_PersistentRef")); + if (!ref) + return SecError(errSecDecode, error, CFSTR("No v_PersistentRef in backup dictionary %@"), dict); + + CFStringRef className; + sqlite3_int64 rowid; + if (!_SecItemParsePersistentRef(ref, &className, &rowid, NULL)) + return SecError(errSecDecode, error, CFSTR("v_PersistentRef %@ failed to decode"), ref); + + if (!CFEqual(SecDbItemGetClass(item)->name, className)) + return SecError(errSecDecode, error, CFSTR("v_PersistentRef has unexpected class %@"), className); + + return SecDbItemSetRowId(item, rowid, error); +} + +static CFDataRef SecDbItemCopyDERWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error) { + CFDataRef der = NULL; + CFMutableDictionaryRef dict = SecDbItemCopyPListWithMask(item, mask, error); + if (dict) { + der = CFPropertyListCreateDERData(kCFAllocatorDefault, dict, error); + CFRelease(dict); + } + return der; +} + +static CFTypeRef SecDbItemCopyDigestWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error) { + CFDataRef digest = NULL; + CFDataRef der = SecDbItemCopyDERWithMask(item, mask, error); + if (der) { + digest = CFDataCopySHA1Digest(der, error); + CFRelease(der); + } + return digest; +} + +static CFTypeRef SecDbItemCopySHA256DigestWithMask(SecDbItemRef item, CFOptionFlags mask, CFErrorRef *error) { + CFDataRef digest = NULL; + CFDataRef der = SecDbItemCopyDERWithMask(item, mask, error); + if (der) { + digest = CFDataCopySHA256Digest(der, error); + CFRelease(der); + } + return digest; +} + +CFTypeRef SecDbKeychainItemCopyPrimaryKey(SecDbItemRef item, const SecDbAttr *attr, CFErrorRef *error) { + return SecDbItemCopyDigestWithMask(item, kSecDbPrimaryKeyFlag, error); +} + +CFTypeRef SecDbKeychainItemCopySHA256PrimaryKey(SecDbItemRef item, CFErrorRef *error) { + return SecDbItemCopySHA256DigestWithMask(item, kSecDbPrimaryKeyFlag, error); +} + +CFTypeRef SecDbKeychainItemCopySHA1(SecDbItemRef item, const SecDbAttr *attr, CFErrorRef *error) { + return SecDbItemCopyDigestWithMask(item, kSecDbInHashFlag, error); +} + +CFTypeRef SecDbKeychainItemCopyEncryptedData(SecDbItemRef item, const SecDbAttr *attr, CFErrorRef *error) { + CFDataRef edata = NULL; + CFMutableDictionaryRef secretStuff = SecDbItemCopyPListWithMask(item, kSecDbReturnDataFlag, error); + CFMutableDictionaryRef attributes = SecDbItemCopyPListWithMask(item, kSecDbInCryptoDataFlag, error); + CFMutableDictionaryRef auth_attributes = SecDbItemCopyPListWithMask(item, kSecDbInAuthenticatedDataFlag, error); + if (secretStuff || attributes || auth_attributes) { + SecAccessControlRef access_control = SecDbItemCopyAccessControl(item, error); + CFDataRef sha1 = SecDbKeychainItemCopySHA1(item, attr, error); + if (access_control && sha1) { + if (!auth_attributes) { + auth_attributes = CFDictionaryCreateMutable(NULL, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + } + CFDictionarySetValue(auth_attributes, kSecAttrSHA1, sha1); + + CFDictionaryForEach(secretStuff, ^(const void *key, const void *value) { + CFDictionaryRemoveValue(attributes, key); + CFDictionaryRemoveValue(auth_attributes, key); + }); + + if (ks_encrypt_data(item->keybag, access_control, item->credHandle, secretStuff, attributes, auth_attributes, &edata, true, error)) { + item->_edataState = kSecDbItemEncrypting; + } else if (!error || !*error || CFErrorGetCode(*error) != errSecAuthNeeded || !CFEqualSafe(CFErrorGetDomain(*error), kSecErrorDomain) ) { + seccritical("ks_encrypt_data (db): failed: %@", error ? *error : (CFErrorRef)CFSTR("")); + } + CFRelease(access_control); + } + CFReleaseNull(secretStuff); + CFReleaseNull(attributes); + CFReleaseNull(auth_attributes); + CFReleaseNull(sha1); + } + + return edata; +} + +CFTypeRef SecDbKeychainItemCopyCurrentDate(SecDbItemRef item, const SecDbAttr *attr, CFErrorRef *error) { + CFTypeRef value = NULL; + switch (attr->kind) { + case kSecDbDateAttr: + value = CFDateCreate(kCFAllocatorDefault, 0.0); + break; + case kSecDbCreationDateAttr: + case kSecDbModificationDateAttr: + value = CFDateCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent()); + break; + default: + SecError(errSecInternal, error, CFSTR("attr %@ has no default value"), attr->name); + value = NULL; + } + + return value; +} + +SecAccessControlRef SecDbItemCopyAccessControl(SecDbItemRef item, CFErrorRef *error) { + SecAccessControlRef accc = NULL, pdmn = NULL, result = NULL; + CFTypeRef acccData = SecDbItemGetValue(item, SecDbClassAttrWithKind(item->class, kSecDbAccessControlAttr, error), error); + CFTypeRef pdmnValue = SecDbItemGetValue(item, SecDbClassAttrWithKind(item->class, kSecDbAccessAttr, error), error); + + if (!acccData || !pdmnValue) + return NULL; + if (!CFEqual(acccData, kCFNull)) + require_quiet(accc = SecAccessControlCreateFromData(CFGetAllocator(item), acccData, error), out); + + if (!CFEqual(pdmnValue, kCFNull)) { + require_quiet(pdmn = SecAccessControlCreate(CFGetAllocator(item), error), out); + require_quiet(SecAccessControlSetProtection(pdmn, pdmnValue, error), out); + } + + if (accc && pdmn) { + CFTypeRef acccProt = SecAccessControlGetProtection(accc); + CFTypeRef pdmnProt = SecAccessControlGetProtection(pdmn); + if (!acccProt || !pdmnProt || !CFEqual(acccProt, pdmnProt)) { + secerror("SecDbItemCopyAccessControl accc %@ != pdmn %@, setting pdmn to accc value", acccProt, pdmnProt); + __security_simulatecrash(CFSTR("Corrupted item on decrypt accc != pdmn"), __sec_exception_code_CorruptItem); + // Setting pdmn to accc prot value. + require_quiet(SecDbItemSetValue(item, SecDbClassAttrWithKind(item->class, kSecDbAccessAttr, error), acccProt, error), out); + } + } + + if (accc) + CFRetainAssign(result, accc); + else if(pdmn) + CFRetainAssign(result, pdmn); + +out: + CFReleaseSafe(accc); + CFReleaseSafe(pdmn); + + return result; +} + +static const uint8_t* der_decode_plist_with_repair(CFAllocatorRef allocator, CFOptionFlags mutability, + CFPropertyListRef* pl, CFErrorRef *error, + const uint8_t* der, const uint8_t *der_end, + const uint8_t* (^repairBlock)(CFAllocatorRef, CFOptionFlags, CFPropertyListRef*, CFErrorRef*, + const uint8_t*, const uint8_t*)) +{ + if (NULL == der) { + SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Null DER"), NULL, error); + return NULL; + } + + ccder_tag tag; + if (NULL == ccder_decode_tag(&tag, der, der_end)) { + SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown data encoding"), NULL, error); + return NULL; + } + + switch (tag) { + case CCDER_NULL: + return der_decode_null(allocator, mutability, (CFNullRef*)pl, error, der, der_end); + case CCDER_BOOLEAN: + return der_decode_boolean(allocator, mutability, (CFBooleanRef*)pl, error, der, der_end); + case CCDER_OCTET_STRING: + return der_decode_data(allocator, mutability, (CFDataRef*)pl, error, der, der_end); + case CCDER_GENERALIZED_TIME: { + const uint8_t* der_result = der_decode_date(allocator, mutability, (CFDateRef*)pl, error, der, der_end); + if (!der_result) { + der_result = repairBlock(allocator, mutability, pl, error, der, der_end); + } + return der_result; + } + case CCDER_CONSTRUCTED_SEQUENCE: + return der_decode_array_with_repair(allocator, mutability, (CFArrayRef*)pl, error, der, der_end, repairBlock); + case CCDER_UTF8_STRING: + return der_decode_string(allocator, mutability, (CFStringRef*)pl, error, der, der_end); + case CCDER_INTEGER: + return der_decode_number(allocator, mutability, (CFNumberRef*)pl, error, der, der_end); + case CCDER_CONSTRUCTED_SET: + return der_decode_dictionary_with_repair(allocator, mutability, (CFDictionaryRef*)pl, error, der, der_end, repairBlock); + case CCDER_CONSTRUCTED_CFSET: + return der_decode_set_with_repair(allocator, mutability, (CFSetRef*)pl, error, der, der_end, repairBlock); + default: + SecCFDERCreateError(kSecDERErrorUnsupportedDERType, CFSTR("Unsupported DER Type"), NULL, error); + return NULL; + } +} + +static const uint8_t* der_decode_dictionary_with_repair(CFAllocatorRef allocator, CFOptionFlags mutability, + CFDictionaryRef* dictionary, CFErrorRef *error, + const uint8_t* der, const uint8_t *der_end, + const uint8_t* (^repairBlock)(CFAllocatorRef, CFOptionFlags, CFPropertyListRef*, CFErrorRef*, + const uint8_t*, const uint8_t*)) +{ + if (NULL == der) { + SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Null DER"), NULL, error); + return NULL; + } + + const uint8_t *payload_end = 0; + const uint8_t *payload = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SET, &payload_end, der, der_end); + + if (NULL == payload) { + SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown data encoding, expected CCDER_CONSTRUCTED_SET"), NULL, error); + return NULL; + } + + + CFMutableDictionaryRef dict = CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + if (NULL == dict) { + SecCFDERCreateError(kSecDERErrorAllocationFailure, CFSTR("Failed to create dictionary"), NULL, error); + payload = NULL; + goto exit; + } + + while (payload != NULL && payload < payload_end) { + CFTypeRef key = NULL; + CFTypeRef value = NULL; + + payload = der_decode_key_value_with_repair(allocator, mutability, &key, &value, error, payload, payload_end, repairBlock); + + if (payload) { + CFDictionaryAddValue(dict, key, value); + } + + CFReleaseNull(key); + CFReleaseNull(value); + } + + +exit: + if (payload == payload_end) { + *dictionary = dict; + dict = NULL; + } + + CFReleaseNull(dict); + + return payload; +} + +static const uint8_t* der_decode_key_value_with_repair(CFAllocatorRef allocator, CFOptionFlags mutability, + CFPropertyListRef* key, CFPropertyListRef* value, CFErrorRef *error, + const uint8_t* der, const uint8_t *der_end, + const uint8_t* (^repairBlock)(CFAllocatorRef, CFOptionFlags, CFPropertyListRef*, CFErrorRef*, + const uint8_t*, const uint8_t*)) +{ + const uint8_t *payload_end = 0; + const uint8_t *payload = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &payload_end, der, der_end); + + if (NULL == payload) { + SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown data encoding, expected CCDER_CONSTRUCTED_SEQUENCE"), NULL, error); + return NULL; + } + + CFTypeRef keyObject = NULL; + CFTypeRef valueObject = NULL; + + + payload = der_decode_plist_with_repair(allocator, mutability, &keyObject, error, payload, payload_end, repairBlock); + payload = der_decode_plist_with_repair(allocator, mutability, &valueObject, error, payload, payload_end, repairBlock); + + if (payload != NULL) { + *key = keyObject; + *value = valueObject; + } else { + CFReleaseNull(keyObject); + CFReleaseNull(valueObject); + } + return payload; +} + +static const uint8_t* der_decode_array_with_repair(CFAllocatorRef allocator, CFOptionFlags mutability, + CFArrayRef* array, CFErrorRef *error, + const uint8_t* der, const uint8_t *der_end, + const uint8_t* (^repairBlock)(CFAllocatorRef, CFOptionFlags, CFPropertyListRef*, CFErrorRef*, + const uint8_t*, const uint8_t*)) +{ + if (NULL == der) { + SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Null DER"), NULL, error); + return NULL; + } + + CFMutableArrayRef result = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks); + + const uint8_t *elements_end; + const uint8_t *current_element = ccder_decode_sequence_tl(&elements_end, der, der_end); + + while (current_element != NULL && current_element < elements_end) { + CFPropertyListRef element = NULL; + current_element = der_decode_plist_with_repair(allocator, mutability, &element, error, current_element, elements_end, repairBlock); + if (current_element) { + CFArrayAppendValue(result, element); + CFReleaseNull(element); + } + } + + if (current_element) { + *array = result; + result = NULL; + } + + CFReleaseNull(result); + return current_element; +} + +static const uint8_t* der_decode_set_with_repair(CFAllocatorRef allocator, CFOptionFlags mutability, + CFSetRef* set, CFErrorRef *error, + const uint8_t* der, const uint8_t *der_end, + const uint8_t* (^repairBlock)(CFAllocatorRef, CFOptionFlags, CFPropertyListRef*, CFErrorRef*, + const uint8_t*, const uint8_t*)) +{ + if (NULL == der) { + SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Null DER"), NULL, error); + return NULL; + } + + const uint8_t *payload_end = 0; + const uint8_t *payload = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_CFSET, &payload_end, der, der_end); + + if (NULL == payload) { + SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown data encoding, expected CCDER_CONSTRUCTED_CFSET"), NULL, error); + return NULL; + } + + CFMutableSetRef theSet = (set && *set) ? CFSetCreateMutableCopy(allocator, 0, *set) + : CFSetCreateMutable(allocator, 0, &kCFTypeSetCallBacks); + + if (NULL == theSet) { + SecCFDERCreateError(kSecDERErrorAllocationFailure, CFSTR("Failed to create set"), NULL, error); + payload = NULL; + goto exit; + } + + while (payload != NULL && payload < payload_end) { + CFTypeRef value = NULL; + + payload = der_decode_plist_with_repair(allocator, mutability, &value, error, payload, payload_end, repairBlock); + + if (payload) { + CFSetAddValue(theSet, value); + } + CFReleaseNull(value); + } + + +exit: + if (set && payload == payload_end) { + CFTransferRetained(*set, theSet); + } + + CFReleaseNull(theSet); + + return payload; +} + +void SecDbResetMetadataKeys(void) { +#if !TARGET_OS_BRIDGE + [SecDbKeychainMetadataKeyStore resetSharedStore]; +#endif +} diff --git a/OSX/sec/securityd/SecDbKeychainItemV7.h b/OSX/sec/securityd/SecDbKeychainItemV7.h new file mode 100644 index 00000000..56af9f64 --- /dev/null +++ b/OSX/sec/securityd/SecDbKeychainItemV7.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import "SecKeybagSupport.h" +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SecDbKeychainItemV7 : NSObject + +@property (nonatomic, readonly) keyclass_t keyclass; + +- (nullable instancetype)initWithData:(NSData*)data decryptionKeybag:(keybag_handle_t)decryptionKeybag error:(NSError**)error; +- (instancetype)initWithSecretAttributes:(NSDictionary*)secretAttributes metadataAttributes:(NSDictionary*)metadataAttributes tamperCheck:(NSString*)tamperCheck keyclass:(keyclass_t)keyclass; + +- (nullable NSDictionary*)metadataAttributesWithError:(NSError**)error; +- (nullable NSDictionary*)secretAttributesWithAcmContext:(NSData*)acmContext accessControl:(SecAccessControlRef)accessControl callerAccessGroups:(NSArray*)callerAccessGroups error:(NSError**)error; +- (BOOL)deleteWithAcmContext:(NSData*)acmContext accessControl:(SecAccessControlRef)accessControl callerAccessGroups:(NSArray*)callerAccessGroups error:(NSError**)error; + +- (nullable NSData*)encryptedBlobWithKeybag:(keybag_handle_t)keybag accessControl:(SecAccessControlRef)accessControl acmContext:(nullable NSData*)acmContext error:(NSError**)error; + +@end + +extern NSString* const SecDbKeychainErrorDomain; +extern const NSInteger SecDbKeychainErrorDeserializationFailed; + + +@class SecDbKeychainSerializedMetadata; +@class SecDbKeychainSerializedSecretData; + +@interface SecDbKeychainItemV7 (UnitTesting) + ++ (bool)aksEncryptWithKeybag:(keybag_handle_t)keybag keyclass:(keyclass_t)keyclass keyData:(NSData*)keyData outKeyclass:(keyclass_t* _Nullable)outKeyclass wrappedKey:(NSMutableData*)wrappedKey error:(NSError**)error; ++ (bool)aksDecryptWithKeybag:(keybag_handle_t)keybag keyclass:(keyclass_t)keyclass wrappedKeyData:(NSData*)wrappedKeyData outKeyclass:(keyclass_t* _Nullable)outKeyclass unwrappedKey:(NSMutableData*)unwrappedKey error:(NSError**)error; + ++ (bool)isKeychainUnlocked; + +@property (readonly) NSData* encryptedMetadataBlob; +@property (readonly) NSData* encryptedSecretDataBlob; + +- (BOOL)encryptMetadataWithKeybag:(keybag_handle_t)keybag error:(NSError**)error; +- (BOOL)encryptSecretDataWithKeybag:(keybag_handle_t)keybag accessControl:(SecAccessControlRef)accessControl acmContext:(nullable NSData*)acmContext error:(NSError**)error; + +@end + +// For Db resets _only_ +@interface SecDbKeychainMetadataKeyStore : NSObject + ++ (bool)cachingEnabled; + ++ (void)resetSharedStore; ++ (instancetype)sharedStore; + +- (instancetype)init NS_UNAVAILABLE; + +- (void)dropClassAKeys; + +@end + +NS_ASSUME_NONNULL_END diff --git a/OSX/sec/securityd/SecDbKeychainItemV7.m b/OSX/sec/securityd/SecDbKeychainItemV7.m new file mode 100644 index 00000000..7f9e0591 --- /dev/null +++ b/OSX/sec/securityd/SecDbKeychainItemV7.m @@ -0,0 +1,1134 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import "SecDbKeychainItemV7.h" +#import "SecKeybagSupport.h" +#import "SecItemServer.h" +#import "SecAccessControl.h" +#import "SecDbKeychainSerializedItemV7.h" +#import "SecDbKeychainSerializedAKSWrappedKey.h" +#import "SecDbKeychainSerializedMetadata.h" +#import "SecDbKeychainSerializedSecretData.h" +#import +#import +#import +#import +#import "sec_action.h" +#if !TARGET_OS_BRIDGE +#import +#import +#import +#endif +#import + +#if USE_KEYSTORE +#import +#endif + +#define KEYCHAIN_ITEM_PADDING_MODULUS 20 + +NSString* const SecDbKeychainErrorDomain = @"SecDbKeychainErrorDomain"; +const NSInteger SecDbKeychainErrorDeserializationFailed = 1; + +static NSString* const SecDBTamperCheck = @"TamperCheck"; + +#define BridgeCFErrorToNSErrorOut(nsErrorOut, CFErr) \ +{ \ + if (nsErrorOut) { \ + *nsErrorOut = CFBridgingRelease(CFErr); \ + CFErr = NULL; \ + } \ + else { \ + CFReleaseNull(CFErr); \ + } \ +} + +#if TARGET_OS_BRIDGE + +@implementation SecDbKeychainItemV7 + +- (instancetype)initWithData:(NSData*)data decryptionKeybag:(keybag_handle_t)decryptionKeybag error:(NSError**)error +{ + return nil; +} + +- (instancetype)initWithSecretAttributes:(NSDictionary*)secretAttributes metadataAttributes:(NSDictionary*)metadataAttributes tamperCheck:(NSString*)tamperCheck keyclass:(keyclass_t)keyclass +{ + return nil; +} + +- (NSDictionary*)metadataAttributesWithError:(NSError**)error +{ + return nil; +} + +- (NSDictionary*)secretAttributesWithAcmContext:(NSData*)acmContext accessControl:(SecAccessControlRef)accessControl callerAccessGroups:(NSArray*)callerAccessGroups error:(NSError**)error +{ + return nil; +} + +- (BOOL)deleteWithAcmContext:(NSData*)acmContext accessControl:(SecAccessControlRef)accessControl callerAccessGroups:(NSArray*)callerAccessGroups error:(NSError**)error +{ + return NO; +} + +- (NSData*)encryptedBlobWithKeybag:(keybag_handle_t)keybag accessControl:(SecAccessControlRef)accessControl acmContext:(NSData*)acmContext error:(NSError**)error +{ + return nil; +} + +@end + +#else + +static NSDictionary* dictionaryFromDERData(NSData* data) +{ + NSDictionary* dict = (__bridge_transfer NSDictionary*)CFPropertyListCreateWithDERData(NULL, (__bridge CFDataRef)data, 0, NULL, NULL); + return [dict isKindOfClass:[NSDictionary class]] ? dict : nil; +} + +typedef NS_ENUM(uint32_t, SecDbKeychainAKSWrappedKeyType) { + SecDbKeychainAKSWrappedKeyTypeRegular, + SecDbKeychainAKSWrappedKeyTypeRefKey +}; + +@interface SecDbKeychainAKSWrappedKey : NSObject + +@property (readonly) NSData* wrappedKey; +@property (readonly) NSData* refKeyBlob; +@property (readonly) SecDbKeychainAKSWrappedKeyType type; + +@property (readonly) NSData* serializedRepresentation; + +- (instancetype)initWithData:(NSData*)data; +- (instancetype)initRegularWrappedKeyWithData:(NSData*)wrappedKey; +- (instancetype)initRefKeyWrappedKeyWithData:(NSData*)wrappedKey refKeyBlob:(NSData*)refKeyBlob; + +@end + +@interface SecDbKeychainMetadata : NSObject + +@property (readonly) SFAuthenticatedCiphertext* ciphertext; +@property (readonly) SFAuthenticatedCiphertext* wrappedKey; +@property (readonly) NSString* tamperCheck; + +@property (readonly) NSData* serializedRepresentation; + +- (instancetype)initWithData:(NSData*)data; +- (instancetype)initWithCiphertext:(SFAuthenticatedCiphertext*)ciphertext wrappedKey:(SFAuthenticatedCiphertext*)wrappedKey tamperCheck:(NSString*)tamperCheck error:(NSError**)error; + +@end + +@interface SecDbKeychainSecretData : NSObject + +@property (readonly) SFAuthenticatedCiphertext* ciphertext; +@property (readonly) SecDbKeychainAKSWrappedKey* wrappedKey; +@property (readonly) NSString* tamperCheck; + +@property (readonly) NSData* serializedRepresentation; + +- (instancetype)initWithData:(NSData*)data; +- (instancetype)initWithCiphertext:(SFAuthenticatedCiphertext*)ciphertext wrappedKey:(SecDbKeychainAKSWrappedKey*)wrappedKey tamperCheck:(NSString*)tamperCheck error:(NSError**)error; + +@end + +@implementation SecDbKeychainAKSWrappedKey { + SecDbKeychainSerializedAKSWrappedKey* _serializedHolder; +} + +- (instancetype)initRegularWrappedKeyWithData:(NSData*)wrappedKey +{ + if (self = [super init]) { + _serializedHolder = [[SecDbKeychainSerializedAKSWrappedKey alloc] init]; + _serializedHolder.wrappedKey = wrappedKey; + _serializedHolder.type = SecDbKeychainAKSWrappedKeyTypeRegular; + } + + return self; +} + +- (instancetype)initRefKeyWrappedKeyWithData:(NSData*)wrappedKey refKeyBlob:(NSData*)refKeyBlob +{ + if (self = [super init]) { + _serializedHolder = [[SecDbKeychainSerializedAKSWrappedKey alloc] init]; + _serializedHolder.wrappedKey = wrappedKey; + _serializedHolder.refKeyBlob = refKeyBlob; + _serializedHolder.type = SecDbKeychainAKSWrappedKeyTypeRefKey; + } + + return self; +} + +- (instancetype)initWithData:(NSData*)data +{ + if (self = [super init]) { + _serializedHolder = [[SecDbKeychainSerializedAKSWrappedKey alloc] initWithData:data]; + if (!_serializedHolder.wrappedKey || (_serializedHolder.type == SecDbKeychainAKSWrappedKeyTypeRefKey && !_serializedHolder.refKeyBlob)) { + self = nil; + } + } + + return self; +} + +- (NSData*)serializedRepresentation +{ + return _serializedHolder.data; +} + +- (NSData*)wrappedKey +{ + return _serializedHolder.wrappedKey; +} + +- (NSData*)refKeyBlob +{ + return _serializedHolder.refKeyBlob; +} + +- (SecDbKeychainAKSWrappedKeyType)type +{ + return _serializedHolder.type; +} + +@end + +@implementation SecDbKeychainMetadata { + SecDbKeychainSerializedMetadata* _serializedHolder; +} + +- (instancetype)initWithCiphertext:(SFAuthenticatedCiphertext*)ciphertext wrappedKey:(SFAuthenticatedCiphertext*)wrappedKey tamperCheck:(NSString*)tamperCheck error:(NSError**)error +{ + if (self = [super init]) { + _serializedHolder = [[SecDbKeychainSerializedMetadata alloc] init]; + _serializedHolder.ciphertext = [NSKeyedArchiver archivedDataWithRootObject:ciphertext requiringSecureCoding:YES error:error]; + _serializedHolder.wrappedKey = [NSKeyedArchiver archivedDataWithRootObject:wrappedKey requiringSecureCoding:YES error:error]; + _serializedHolder.tamperCheck = tamperCheck; + if (!_serializedHolder.ciphertext || !_serializedHolder.wrappedKey || !_serializedHolder.tamperCheck) { + self = nil; + } + } + + return self; +} + +- (instancetype)initWithData:(NSData*)data +{ + if (self = [super init]) { + _serializedHolder = [[SecDbKeychainSerializedMetadata alloc] initWithData:data]; + if (!_serializedHolder.ciphertext || !_serializedHolder.wrappedKey || !_serializedHolder.tamperCheck) { + self = nil; + } + } + + return self; +} + +- (NSData*)serializedRepresentation +{ + return _serializedHolder.data; +} + +- (SFAuthenticatedCiphertext*)ciphertext +{ + NSError* error = nil; + SFAuthenticatedCiphertext* ciphertext = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFAuthenticatedCiphertext class] fromData:_serializedHolder.ciphertext error:&error]; + if (!ciphertext) { + secerror("SecDbKeychainItemV7: error deserializing ciphertext from metadata: %@", error); + } + + return ciphertext; +} + +- (SFAuthenticatedCiphertext*)wrappedKey +{ + NSError* error = nil; + SFAuthenticatedCiphertext* wrappedKey = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFAuthenticatedCiphertext class] fromData:_serializedHolder.wrappedKey error:&error]; + if (!wrappedKey) { + secerror("SecDbKeychainItemV7: error deserializing wrappedKey from metadata: %@", error); + } + + return wrappedKey; +} + +- (NSString*)tamperCheck +{ + return _serializedHolder.tamperCheck; +} + +@end + +@implementation SecDbKeychainSecretData { + SecDbKeychainSerializedSecretData* _serializedHolder; +} + +- (instancetype)initWithCiphertext:(SFAuthenticatedCiphertext*)ciphertext wrappedKey:(SecDbKeychainAKSWrappedKey*)wrappedKey tamperCheck:(NSString*)tamperCheck error:(NSError**)error +{ + if (self = [super init]) { + _serializedHolder = [[SecDbKeychainSerializedSecretData alloc] init]; + _serializedHolder.ciphertext = [NSKeyedArchiver archivedDataWithRootObject:ciphertext requiringSecureCoding:YES error:error]; + _serializedHolder.wrappedKey = wrappedKey.serializedRepresentation; + _serializedHolder.tamperCheck = tamperCheck; + if (!_serializedHolder.ciphertext || !_serializedHolder.wrappedKey || !_serializedHolder.tamperCheck) { + self = nil; + } + } + + return self; +} + +- (instancetype)initWithData:(NSData*)data +{ + if (self = [super init]) { + _serializedHolder = [[SecDbKeychainSerializedSecretData alloc] initWithData:data]; + if (!_serializedHolder.ciphertext || !_serializedHolder.wrappedKey || !_serializedHolder.tamperCheck) { + self = nil; + } + } + + return self; +} + +- (NSData*)serializedRepresentation +{ + return _serializedHolder.data; +} + +- (SFAuthenticatedCiphertext*)ciphertext +{ + NSError* error = nil; + SFAuthenticatedCiphertext* ciphertext = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFAuthenticatedCiphertext class] fromData:_serializedHolder.ciphertext error:&error]; + if (!ciphertext) { + secerror("SecDbKeychainItemV7: error deserializing ciphertext from secret data: %@", error); + } + + return ciphertext; +} + +- (SecDbKeychainAKSWrappedKey*)wrappedKey +{ + return [[SecDbKeychainAKSWrappedKey alloc] initWithData:_serializedHolder.wrappedKey]; +} + +- (NSString*)tamperCheck +{ + return _serializedHolder.tamperCheck; +} + +@end + +////// SecDbKeychainMetadataKeyStore + +@interface SecDbKeychainMetadataKeyStore () +- (SFAESKey*)keyForKeyclass:(keyclass_t)keyClass + keybag:(keybag_handle_t)keybag + keySpecifier:(SFAESKeySpecifier*)keySpecifier + overwriteCorruptKey:(bool)overwriteCorruptKey + error:(NSError**)error; +@end + +static SecDbKeychainMetadataKeyStore* sharedStore = nil; +static dispatch_queue_t sharedMetadataStoreQueue; +static void initializeSharedMetadataStoreQueue(void) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedMetadataStoreQueue = dispatch_queue_create("metadata_store", DISPATCH_QUEUE_SERIAL); + }); +} + +@implementation SecDbKeychainMetadataKeyStore { + NSMutableDictionary* _keysDict; + dispatch_queue_t _queue; +} + ++ (void)resetSharedStore +{ + initializeSharedMetadataStoreQueue(); + dispatch_sync(sharedMetadataStoreQueue, ^{ + if(sharedStore) { + dispatch_sync(sharedStore->_queue, ^{ + [sharedStore _onQueueDropAllKeys]; + }); + } + sharedStore = nil; + }); +} + ++ (instancetype)sharedStore +{ + __block SecDbKeychainMetadataKeyStore* ret; + initializeSharedMetadataStoreQueue(); + dispatch_sync(sharedMetadataStoreQueue, ^{ + if(!sharedStore) { + sharedStore = [[self alloc] _init]; + } + + ret = sharedStore; + }); + + return ret; +} + ++ (bool)cachingEnabled +{ + return true; +} + +- (instancetype)_init +{ + if (self = [super init]) { + _keysDict = [[NSMutableDictionary alloc] init]; + _queue = dispatch_queue_create("SecDbKeychainMetadataKeyStore", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + int token = 0; + __weak __typeof(self) weakSelf = self; + notify_register_dispatch(kUserKeybagStateChangeNotification, &token, _queue, ^(int inToken) { + bool locked = true; + CFErrorRef error = NULL; + if (!SecAKSGetIsLocked(&locked, &error)) { + secerror("SecDbKeychainMetadataKeyStore: error getting lock state: %@", error); + CFReleaseNull(error); + } + + if (locked) { + [weakSelf _onQueueDropClassAKeys]; + } + }); + } + + return self; +} + +- (void)dropClassAKeys +{ + dispatch_sync(_queue, ^{ + [self _onQueueDropClassAKeys]; + }); +} + +- (void)_onQueueDropClassAKeys +{ + dispatch_assert_queue(_queue); + + secnotice("SecDbKeychainMetadataKeyStore", "dropping class A metadata keys"); + _keysDict[@(key_class_ak)] = nil; + _keysDict[@(key_class_aku)] = nil; + _keysDict[@(key_class_akpu)] = nil; +} + +- (void)_onQueueDropAllKeys +{ + dispatch_assert_queue(_queue); + + secnotice("SecDbKeychainMetadataKeyStore", "dropping all metadata keys"); + [_keysDict removeAllObjects]; +} + +- (SFAESKey*)keyForKeyclass:(keyclass_t)keyclass + keybag:(keybag_handle_t)keybag + keySpecifier:(SFAESKeySpecifier*)keySpecifier + overwriteCorruptKey:(bool)overwriteCorruptKey + error:(NSError**)error +{ + __block SFAESKey* key = nil; + __block NSError* nsErrorLocal = nil; + __block CFErrorRef cfError = NULL; + static __thread BOOL reentrant = NO; + + NSAssert(!reentrant, @"re-entering -[%@ %@] - that shouldn't happen!", NSStringFromClass(self.class), NSStringFromSelector(_cmd)); + reentrant = YES; + +#if USE_KEYSTORE + if (keyclass > key_class_last) { + // idea is that AKS may return a keyclass value with extra bits above key_class_last from aks_wrap_key, but we only keep metadata keys for the canonical key classes + // so just sanitize all our inputs to the canonical values + keyclass_t sanitizedKeyclass = keyclass & key_class_last; + secinfo("SecDbKeychainItemV7", "sanitizing request for metadata keyclass %d to keyclass %d", keyclass, sanitizedKeyclass); + keyclass = sanitizedKeyclass; + } +#endif + + dispatch_sync(_queue, ^{ + // if we think we're locked, it's possible AKS will still give us access to keys, such as during backup, + // but we should force AKS to be the truth and not used cached class A keys while locked + bool allowKeyCaching = [SecDbKeychainMetadataKeyStore cachingEnabled]; +#if 0 + // Fix keychain lock state check to be both secure and fast for EDU mode + if (![SecDbKeychainItemV7 isKeychainUnlocked]) { + [self _onQueueDropClassAKeys]; + allowKeyCaching = !(keyclass == key_class_ak || keyclass == key_class_aku || keyclass == key_class_akpu); + } +#endif + + key = allowKeyCaching ? self->_keysDict[@(keyclass)] : nil; + if (!key) { + __block bool ok = true; + __block bool metadataKeyDoesntAuthenticate = false; + ok &= kc_with_dbt_non_item_tables(true, &cfError, ^bool(SecDbConnectionRef dbt) { + __block NSString* sql = [NSString stringWithFormat:@"SELECT data, actualKeyclass FROM metadatakeys WHERE keyclass = %d", keyclass]; + ok &= SecDbPrepare(dbt, (__bridge CFStringRef)sql, &cfError, ^(sqlite3_stmt *stmt) { + ok &= SecDbStep(dbt, stmt, &cfError, ^(bool *stop) { + NSData* wrappedKeyData = [[NSData alloc] initWithBytes:sqlite3_column_blob(stmt, 0) length:sqlite3_column_bytes(stmt, 0)]; + NSMutableData* unwrappedKeyData = [NSMutableData dataWithLength:wrappedKeyData.length]; + + keyclass_t actualKeyclass = sqlite3_column_int(stmt, 1); + + keyclass_t actualKeyclassToWriteBackToDB = 0; + keyclass_t keyclassForUnwrapping = actualKeyclass == 0 ? keyclass : actualKeyclass; + ok &= [SecDbKeychainItemV7 aksDecryptWithKeybag:keybag keyclass:keyclassForUnwrapping wrappedKeyData:wrappedKeyData outKeyclass:NULL unwrappedKey:unwrappedKeyData error:&nsErrorLocal]; + if (ok) { + key = [[SFAESKey alloc] initWithData:unwrappedKeyData specifier:keySpecifier error:&nsErrorLocal]; + + if (actualKeyclass == 0) { + actualKeyclassToWriteBackToDB = keyclassForUnwrapping; + } + } +#if USE_KEYSTORE + else if (actualKeyclass == 0 && keyclass <= key_class_last) { + // in this case we might have luck decrypting with a key-rolled keyclass + keyclass_t keyrolledKeyclass = keyclass | (key_class_last + 1); + secerror("SecDbKeychainItemV7: failed to decrypt metadata key for class %d, but trying keyrolled keyclass (%d); error: %@", keyclass, keyrolledKeyclass, nsErrorLocal); + + // we don't want to pollute subsequent error-handling logic with what happens on our retry + // we'll give it a shot, and if it works, great - if it doesn't work, we'll just report that error in the log and move on + NSError* retryError = nil; + ok = [SecDbKeychainItemV7 aksDecryptWithKeybag:keybag keyclass:keyrolledKeyclass wrappedKeyData:wrappedKeyData outKeyclass:NULL unwrappedKey:unwrappedKeyData error:&retryError]; + + if (ok) { + secerror("SecDbKeychainItemV7: successfully decrypted metadata key using keyrolled keyclass %d", keyrolledKeyclass); + key = [[SFAESKey alloc] initWithData:unwrappedKeyData specifier:keySpecifier error:&retryError]; + } + else { + secerror("SecDbKeychainItemV7: failed to decrypt metadata key with keyrolled keyclass %d; error: %@", keyrolledKeyclass, retryError); + } + } +#endif + + if (ok) { + if (actualKeyclassToWriteBackToDB > 0) { + // we did not find an actualKeyclass entry in the db, so let's add one in now. + secinfo("SecDbKeychainItemV7", "saving actualKeyclass %d for metadata keyclass %d", actualKeyclassToWriteBackToDB, keyclass); + sql = @"UPDATE metadatakeys SET actualKeyclass = ? WHERE keyclass = ?"; + __block bool actualKeyWriteBackOk = true; + __block CFErrorRef actualKeyWriteBackError = NULL; + actualKeyWriteBackOk &= SecDbPrepare(dbt, (__bridge CFStringRef)sql, &actualKeyWriteBackError, ^(sqlite3_stmt* stmt) { + actualKeyWriteBackOk &= SecDbBindInt(stmt, 1, actualKeyclassToWriteBackToDB, &actualKeyWriteBackError); + actualKeyWriteBackOk &= SecDbBindInt(stmt, 2, keyclass, &actualKeyWriteBackError); + actualKeyWriteBackOk &= SecDbStep(dbt, stmt, &actualKeyWriteBackError, ^(bool* stop) { + // woohoo + }); + }); + + if (!actualKeyWriteBackOk) { + // we're not going to fail the whole metadata key fetch operation because this part failed. + // if we successfully fetched and unwrapped a key we'll go ahead and use it - we can always try this operation again in the future. + secerror("SecDbKeychainItemV7: failed to save actualKeyclass %d for metadata keyclass %d; error: %@", actualKeyclassToWriteBackToDB, keyclass, actualKeyWriteBackError); + } + } + } + else { + if (nsErrorLocal && [nsErrorLocal.domain isEqualToString:(__bridge NSString*)kSecErrorDomain] && nsErrorLocal.code == errSecInteractionNotAllowed) { + static dispatch_once_t kclockedtoken; + static sec_action_t kclockedaction; + dispatch_once(&kclockedtoken, ^{ + kclockedaction = sec_action_create("keychainlockedlogmessage", 1); + sec_action_set_handler(kclockedaction, ^{ + secerror("SecDbKeychainItemV7: failed to decrypt metadata key because the keychain is locked (%d)", (int)errSecInteractionNotAllowed); + }); + }); + sec_action_perform(kclockedaction); + } else { + secerror("SecDbKeychainItemV7: failed to decrypt metadata key for class %d; error: %@", keyclass, nsErrorLocal); + + // If this error is errSecDecode, then it's failed authentication and likely will forever. Other errors are scary. + metadataKeyDoesntAuthenticate = [nsErrorLocal.domain isEqualToString:NSOSStatusErrorDomain] && nsErrorLocal.code == errSecDecode; + } + } + }); + }); + + bool keyNotYetCreated = ok && !key; + bool forceOverwriteBadKey = !key && metadataKeyDoesntAuthenticate && overwriteCorruptKey; + + if (keyNotYetCreated || forceOverwriteBadKey) { + // we completed the database query, but no key exists or it's broken - we should create one + if(forceOverwriteBadKey) { + secerror("SecDbKeychainItemV7: metadata key is irreparably corrupt; throwing away forever"); + // TODO: track this in LocalKeychainAnalytics + } + + ok = true; // Reset 'ok': we have a second chance + + key = [[SFAESKey alloc] initRandomKeyWithSpecifier:keySpecifier error:&nsErrorLocal]; + if (key) { + NSMutableData* wrappedKey = [NSMutableData dataWithLength:key.keyData.length + 40]; + keyclass_t outKeyclass; + ok &= [SecDbKeychainItemV7 aksEncryptWithKeybag:keybag keyclass:keyclass keyData:key.keyData outKeyclass:&outKeyclass wrappedKey:wrappedKey error:&nsErrorLocal]; + if (ok) { + secinfo("SecDbKeychainItemV7", "attempting to save new metadata key for keyclass %d with actualKeyclass %d", keyclass, outKeyclass); + NSString* insertString = forceOverwriteBadKey ? @"INSERT OR REPLACE" : @"INSERT"; + sql = [NSString stringWithFormat:@"%@ into metadatakeys (keyclass, actualKeyclass, data) VALUES (?, ?, ?)", insertString]; + ok &= SecDbPrepare(dbt, (__bridge CFStringRef)sql, &cfError, ^(sqlite3_stmt* stmt) { + ok &= SecDbBindInt(stmt, 1, keyclass, &cfError); + ok &= SecDbBindInt(stmt, 2, outKeyclass, &cfError); + ok &= SecDbBindBlob(stmt, 3, wrappedKey.bytes, wrappedKey.length, SQLITE_TRANSIENT, NULL); + ok &= SecDbStep(dbt, stmt, &cfError, ^(bool *stop) { + // woohoo + }); + }); + + if (ok) { + secnotice("SecDbKeychainItemV7", "successfully saved new metadata key for keyclass %d", keyclass); + } + else { + secerror("SecDbKeychainItemV7: failed to save new metadata key for keyclass %d - probably there is already one in the database: %@", keyclass, cfError); + } + } else { + secerror("SecDbKeychainItemV7: unable to encrypt new metadata key(%d) with keybag(%d): %@", keyclass, keybag, nsErrorLocal); + } + } + else { + ok = false; + } + } + + return ok; + }); + + if (ok && key) { + if (allowKeyCaching) { + self->_keysDict[@(keyclass)] = key; + __weak __typeof(self) weakSelf = self; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(60 * 5 * NSEC_PER_SEC)), self->_queue, ^{ + [weakSelf _onQueueDropClassAKeys]; + }); + } + } + else { + key = nil; + } + } + }); + + reentrant = NO; + + if (error && nsErrorLocal) { + *error = nsErrorLocal; + CFReleaseNull(cfError); + } + else { + BridgeCFErrorToNSErrorOut(error, cfError); + } + + return key; +} + +@end + +@implementation SecDbKeychainItemV7 { + SecDbKeychainSecretData* _encryptedSecretData; + SecDbKeychainMetadata* _encryptedMetadata; + NSDictionary* _secretAttributes; + NSDictionary* _metadataAttributes; + NSString* _tamperCheck; + keyclass_t _keyclass; + keybag_handle_t _keybag; +} + +@synthesize keyclass = _keyclass; + ++ (bool)aksEncryptWithKeybag:(keybag_handle_t)keybag keyclass:(keyclass_t)keyclass keyData:(NSData*)keyData outKeyclass:(keyclass_t*)outKeyclass wrappedKey:(NSMutableData*)wrappedKey error:(NSError**)error +{ + CFErrorRef cfError = NULL; + bool result = ks_crypt(kAKSKeyOpEncrypt, keybag, keyclass, (uint32_t)keyData.length, keyData.bytes, outKeyclass, (__bridge CFMutableDataRef)wrappedKey, &cfError); + BridgeCFErrorToNSErrorOut(error, cfError); + return result; +} + ++ (bool)aksDecryptWithKeybag:(keybag_handle_t)keybag keyclass:(keyclass_t)keyclass wrappedKeyData:(NSData*)wrappedKeyData outKeyclass:(keyclass_t*)outKeyclass unwrappedKey:(NSMutableData*)unwrappedKey error:(NSError**)error +{ + CFErrorRef cfError = NULL; + bool result = ks_crypt(kAKSKeyOpDecrypt, keybag, keyclass, (uint32_t)wrappedKeyData.length, wrappedKeyData.bytes, outKeyclass, (__bridge CFMutableDataRef)unwrappedKey, &cfError); + BridgeCFErrorToNSErrorOut(error, cfError); + return result; +} + ++ (bool)isKeychainUnlocked +{ + return kc_is_unlocked(); +} + +- (instancetype)initWithData:(NSData*)data decryptionKeybag:(keybag_handle_t)decryptionKeybag error:(NSError**)error +{ + if (self = [super init]) { + SecDbKeychainSerializedItemV7* serializedItem = [[SecDbKeychainSerializedItemV7 alloc] initWithData:data]; + if (serializedItem) { + _keybag = decryptionKeybag; + _encryptedSecretData = [[SecDbKeychainSecretData alloc] initWithData:serializedItem.encryptedSecretData]; + _encryptedMetadata = [[SecDbKeychainMetadata alloc] initWithData:serializedItem.encryptedMetadata]; + _keyclass = serializedItem.keyclass; + if (![_encryptedSecretData.tamperCheck isEqualToString:_encryptedMetadata.tamperCheck]) { + self = nil; + } + } + else { + self = nil; + } + } + + if (!self && error) { + *error = [NSError errorWithDomain:(id)kCFErrorDomainOSStatus code:errSecItemNotFound userInfo:@{NSLocalizedDescriptionKey : @"failed to deserialize keychain item blob"}]; + } + + return self; +} + +- (instancetype)initWithSecretAttributes:(NSDictionary*)secretAttributes metadataAttributes:(NSDictionary*)metadataAttributes tamperCheck:(NSString*)tamperCheck keyclass:(keyclass_t)keyclass +{ + NSParameterAssert(tamperCheck); + + if (self = [super init]) { + _secretAttributes = secretAttributes ? secretAttributes.copy : [NSDictionary dictionary]; + _metadataAttributes = metadataAttributes ? metadataAttributes.copy : [NSDictionary dictionary]; + _tamperCheck = tamperCheck.copy; + _keyclass = keyclass; + } + + return self; +} + ++ (SFAESKeySpecifier*)keySpecifier +{ + static SFAESKeySpecifier* keySpecifier = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + keySpecifier = [[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256]; + }); + + return keySpecifier; +} + ++ (SFAuthenticatedEncryptionOperation*)encryptionOperation +{ + static SFAuthenticatedEncryptionOperation* encryptionOperation = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + encryptionOperation = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:[self keySpecifier]]; + }); + + return encryptionOperation; +} + ++ (SFAuthenticatedEncryptionOperation*)decryptionOperation +{ + static SFAuthenticatedEncryptionOperation* decryptionOperation = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + decryptionOperation = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:[self keySpecifier]]; + }); + + return decryptionOperation; +} + +- (NSDictionary*)metadataAttributesWithError:(NSError**)error +{ + if (!_metadataAttributes) { + SFAESKey* metadataClassKey = [self metadataClassKeyWithKeybag:_keybag + overwriteCorruptKey:false + error:error]; + if (metadataClassKey) { + NSError* localError = nil; + NSData* keyData = [[self.class decryptionOperation] decrypt:_encryptedMetadata.wrappedKey withKey:metadataClassKey error:&localError]; + if (!keyData) { + secerror("SecDbKeychainItemV7: error unwrapping item metadata key (class %d, bag %d): %@", (int)self.keyclass, _keybag, localError); + // TODO: track this in LocalKeychainAnalytics + if (error) { + CFErrorRef secError = (CFErrorRef)CFBridgingRetain(localError); // this makes localError become the underlying error + SecError(errSecDecode, &secError, CFSTR("failed to unwrap item metadata key")); + *error = CFBridgingRelease(secError); + } + return nil; + } + SFAESKey* key = [[SFAESKey alloc] initWithData:keyData specifier:[self.class keySpecifier] error:error]; + if (!key) { + return nil; + } + + NSData* metadata = [[self.class decryptionOperation] decrypt:_encryptedMetadata.ciphertext withKey:key error:&localError]; + if (!metadata) { + secerror("SecDbKeychainItemV7: error decrypting metadata content: %@", localError); + if (error) { + CFErrorRef secError = (CFErrorRef)CFBridgingRetain(localError); // this makes localError become the underlying error + SecError(errSecDecode, &secError, CFSTR("failed to decrypt item metadata contents")); + *error = CFBridgingRelease(secError); + } + return nil; + } + NSMutableDictionary* decryptedAttributes = dictionaryFromDERData(metadata).mutableCopy; + NSString* tamperCheck = decryptedAttributes[SecDBTamperCheck]; + if ([tamperCheck isEqualToString:_encryptedMetadata.tamperCheck]) { + [decryptedAttributes removeObjectForKey:SecDBTamperCheck]; + _metadataAttributes = decryptedAttributes; + } + else { + secerror("SecDbKeychainItemV7: tamper check failed for metadata decryption, expected %@ found %@", tamperCheck, _encryptedMetadata.tamperCheck); + if (error) { + CFErrorRef secError = NULL; + SecError(errSecDecode, &secError, CFSTR("tamper check failed for metadata decryption")); + *error = CFBridgingRelease(secError); + } + } + } + } + + return _metadataAttributes; +} + +- (NSDictionary*)secretAttributesWithAcmContext:(NSData*)acmContext accessControl:(SecAccessControlRef)accessControl callerAccessGroups:(NSArray*)callerAccessGroups error:(NSError**)error +{ + if (!_secretAttributes) { + SFAESKey* key = [self unwrapFromAKS:_encryptedSecretData.wrappedKey accessControl:accessControl acmContext:acmContext callerAccessGroups:callerAccessGroups delete:NO error:error]; + if (key) { + NSError* localError = nil; + NSData* secretDataWithPadding = [[self.class decryptionOperation] decrypt:_encryptedSecretData.ciphertext withKey:key error:&localError]; + if (!secretDataWithPadding) { + secerror("SecDbKeychainItemV7: error decrypting item secret data contents: %@", localError); + if (error) { + CFErrorRef secError = (CFErrorRef)CFBridgingRetain(localError); // this makes localError become the underlying error + SecError(errSecDecode, &secError, CFSTR("error decrypting item secret data contents")); + *error = CFBridgingRelease(secError); + } + return nil; + } + int8_t paddingLength = *((int8_t*)secretDataWithPadding.bytes + secretDataWithPadding.length - 1); + NSData* secretDataWithoutPadding = [secretDataWithPadding subdataWithRange:NSMakeRange(0, secretDataWithPadding.length - paddingLength)]; + + NSMutableDictionary* decryptedAttributes = dictionaryFromDERData(secretDataWithoutPadding).mutableCopy; + NSString* tamperCheck = decryptedAttributes[SecDBTamperCheck]; + if ([tamperCheck isEqualToString:_encryptedSecretData.tamperCheck]) { + [decryptedAttributes removeObjectForKey:SecDBTamperCheck]; + _secretAttributes = decryptedAttributes; + } + else { + secerror("SecDbKeychainItemV7: tamper check failed for secret data decryption, expected %@ found %@", tamperCheck, _encryptedMetadata.tamperCheck); + } + } + } + + return _secretAttributes; +} + +- (BOOL)deleteWithAcmContext:(NSData*)acmContext accessControl:(SecAccessControlRef)accessControl callerAccessGroups:(NSArray*)callerAccessGroups error:(NSError**)error +{ + NSError* localError = nil; + (void)[self unwrapFromAKS:_encryptedSecretData.wrappedKey accessControl:accessControl acmContext:acmContext callerAccessGroups:callerAccessGroups delete:YES error:&localError]; + if (localError) { + secerror("SecDbKeychainItemV7: failed to delete item secret key from aks"); + if (error) { + *error = localError; + } + + return NO; + } + + return YES; +} + +- (NSData*)encryptedBlobWithKeybag:(keybag_handle_t)keybag accessControl:(SecAccessControlRef)accessControl acmContext:(NSData*)acmContext error:(NSError**)error +{ + NSError* localError = nil; + BOOL success = [self encryptMetadataWithKeybag:keybag error:&localError]; + if (!success || !_encryptedMetadata || localError) { + if (error) { + *error = localError; + } + return nil; + } + + success = [self encryptSecretDataWithKeybag:keybag accessControl:accessControl acmContext:acmContext error:&localError]; + if (!success || !_encryptedSecretData || localError) { + if (error) { + *error = localError; + } + return nil; + } + + SecDbKeychainSerializedItemV7* serializedItem = [[SecDbKeychainSerializedItemV7 alloc] init]; + serializedItem.encryptedMetadata = self.encryptedMetadataBlob; + serializedItem.encryptedSecretData = self.encryptedSecretDataBlob; + serializedItem.keyclass = _keyclass; + return serializedItem.data; +} + +- (NSData*)encryptedMetadataBlob +{ + return _encryptedMetadata.serializedRepresentation; +} + +- (NSData*)encryptedSecretDataBlob +{ + return _encryptedSecretData.serializedRepresentation; +} + +- (BOOL)encryptMetadataWithKeybag:(keybag_handle_t)keybag error:(NSError**)error +{ + SFAESKey* key = [[SFAESKey alloc] initRandomKeyWithSpecifier:[self.class keySpecifier] error:error]; + if (!key) { + return NO; + } + SFAuthenticatedEncryptionOperation* encryptionOperation = [self.class encryptionOperation]; + + NSMutableDictionary* attributesToEncrypt = _metadataAttributes.mutableCopy; + attributesToEncrypt[SecDBTamperCheck] = _tamperCheck; + NSData* metadata = (__bridge_transfer NSData*)CFPropertyListCreateDERData(NULL, (__bridge CFDictionaryRef)attributesToEncrypt, NULL); + SFAuthenticatedCiphertext* ciphertext = [encryptionOperation encrypt:metadata withKey:key error:error]; + + SFAESKey* metadataClassKey = [self metadataClassKeyWithKeybag:keybag + overwriteCorruptKey:true + error:error]; + if (metadataClassKey) { + SFAuthenticatedCiphertext* wrappedKey = [encryptionOperation encrypt:key.keyData withKey:metadataClassKey error:error]; + _encryptedMetadata = [[SecDbKeychainMetadata alloc] initWithCiphertext:ciphertext wrappedKey:wrappedKey tamperCheck:_tamperCheck error:error]; + } + + return _encryptedMetadata != nil; +} + +- (BOOL)encryptSecretDataWithKeybag:(keybag_handle_t)keybag accessControl:(SecAccessControlRef)accessControl acmContext:(NSData*)acmContext error:(NSError**)error +{ + SFAESKey* key = [[SFAESKey alloc] initRandomKeyWithSpecifier:[self.class keySpecifier] error:error]; + if (!key) { + return NO; + } + SFAuthenticatedEncryptionOperation* encryptionOperation = [self.class encryptionOperation]; + + NSMutableDictionary* attributesToEncrypt = _secretAttributes.mutableCopy; + attributesToEncrypt[SecDBTamperCheck] = _tamperCheck; + NSMutableData* secretData = [(__bridge_transfer NSData*)CFPropertyListCreateDERData(NULL, (__bridge CFDictionaryRef)attributesToEncrypt, NULL) mutableCopy]; + + int8_t paddingLength = KEYCHAIN_ITEM_PADDING_MODULUS - (secretData.length % KEYCHAIN_ITEM_PADDING_MODULUS); + int8_t paddingBytes[KEYCHAIN_ITEM_PADDING_MODULUS]; + for (int i = 0; i < KEYCHAIN_ITEM_PADDING_MODULUS; i++) { + paddingBytes[i] = paddingLength; + } + [secretData appendBytes:paddingBytes length:paddingLength]; + + SFAuthenticatedCiphertext* ciphertext = [encryptionOperation encrypt:secretData withKey:key error:error]; + SecDbKeychainAKSWrappedKey* wrappedKey = [self wrapToAKS:key withKeybag:keybag accessControl:accessControl acmContext:acmContext error:error]; + + _encryptedSecretData = [[SecDbKeychainSecretData alloc] initWithCiphertext:ciphertext wrappedKey:wrappedKey tamperCheck:_tamperCheck error:error]; + return _encryptedSecretData != nil; +} + +- (SFAESKey*)metadataClassKeyWithKeybag:(keybag_handle_t)keybag + overwriteCorruptKey:(bool)force + error:(NSError**)error +{ + return [[SecDbKeychainMetadataKeyStore sharedStore] keyForKeyclass:_keyclass + keybag:keybag + keySpecifier:[self.class keySpecifier] + overwriteCorruptKey:force + error:error]; +} + +- (SecDbKeychainAKSWrappedKey*)wrapToAKS:(SFAESKey*)key withKeybag:(keybag_handle_t)keybag accessControl:(SecAccessControlRef)accessControl acmContext:(NSData*)acmContext error:(NSError**)error +{ + NSData* keyData = key.keyData; + +#if USE_KEYSTORE + NSDictionary* constraints = (__bridge NSDictionary*)SecAccessControlGetConstraints(accessControl); + if (constraints) { + aks_ref_key_t refKey = NULL; + CFErrorRef cfError = NULL; + NSData* authData = (__bridge_transfer NSData*)CFPropertyListCreateDERData(NULL, (__bridge CFDictionaryRef)@{(id)kAKSKeyAcl : constraints}, &cfError); + + if (!acmContext || !SecAccessControlIsBound(accessControl)) { + secerror("SecDbKeychainItemV7: access control error"); + if (error) { + CFDataRef accessControlData = SecAccessControlCopyData(accessControl); + ks_access_control_needed_error(&cfError, accessControlData, SecAccessControlIsBound(accessControl) ? kAKSKeyOpEncrypt : CFSTR("")); + CFReleaseNull(accessControlData); + } + + BridgeCFErrorToNSErrorOut(error, cfError); + return nil; + } + + void* aksParams = NULL; + size_t aksParamsLength = 0; + aks_operation_optional_params(0, 0, authData.bytes, authData.length, acmContext.bytes, (int)acmContext.length, &aksParams, &aksParamsLength); + + int aksResult = aks_ref_key_create(keybag, _keyclass, key_type_sym, aksParams, aksParamsLength, &refKey); + if (aksResult != 0) { + CFDataRef accessControlData = SecAccessControlCopyData(accessControl); + create_cferror_from_aks(aksResult, kAKSKeyOpEncrypt, keybag, _keyclass, accessControlData, (__bridge CFDataRef)acmContext, &cfError); + CFReleaseNull(accessControlData); + free(aksParams); + BridgeCFErrorToNSErrorOut(error, cfError); + return nil; + } + + size_t wrappedKeySize = 0; + void* wrappedKeyBytes = NULL; + aksResult = aks_ref_key_encrypt(refKey, aksParams, aksParamsLength, keyData.bytes, keyData.length, &wrappedKeyBytes, &wrappedKeySize); + if (aksResult != 0) { + CFDataRef accessControlData = SecAccessControlCopyData(accessControl); + create_cferror_from_aks(aksResult, kAKSKeyOpEncrypt, keybag, _keyclass, accessControlData, (__bridge CFDataRef)acmContext, &cfError); + CFReleaseNull(accessControlData); + free(aksParams); + aks_ref_key_free(&refKey); + BridgeCFErrorToNSErrorOut(error, cfError); + return nil; + } + free(aksParams); + + BridgeCFErrorToNSErrorOut(error, cfError); + + NSData* wrappedKey = [[NSData alloc] initWithBytesNoCopy:wrappedKeyBytes length:wrappedKeySize]; + + size_t refKeyBlobLength = 0; + const void* refKeyBlobBytes = aks_ref_key_get_blob(refKey, &refKeyBlobLength); + NSData* refKeyBlob = [[NSData alloc] initWithBytesNoCopy:(void*)refKeyBlobBytes length:refKeyBlobLength]; + aks_ref_key_free(&refKey); + return [[SecDbKeychainAKSWrappedKey alloc] initRefKeyWrappedKeyWithData:wrappedKey refKeyBlob:refKeyBlob]; + } + else { + NSMutableData* wrappedKey = [[NSMutableData alloc] initWithLength:(size_t)keyData.length + 40]; + bool success = [self.class aksEncryptWithKeybag:keybag keyclass:_keyclass keyData:keyData outKeyclass:&_keyclass wrappedKey:wrappedKey error:error]; + return success ? [[SecDbKeychainAKSWrappedKey alloc] initRegularWrappedKeyWithData:wrappedKey] : nil; + } +#else + NSMutableData* wrappedKey = [[NSMutableData alloc] initWithLength:(size_t)keyData.length + 40]; + bool success = [self.class aksEncryptWithKeybag:keybag keyclass:_keyclass keyData:keyData outKeyclass:&_keyclass wrappedKey:wrappedKey error:error]; + return success ? [[SecDbKeychainAKSWrappedKey alloc] initRegularWrappedKeyWithData:wrappedKey] : nil; +#endif +} + +- (SFAESKey*)unwrapFromAKS:(SecDbKeychainAKSWrappedKey*)wrappedKey accessControl:(SecAccessControlRef)accessControl acmContext:(NSData*)acmContext callerAccessGroups:(NSArray*)callerAccessGroups delete:(BOOL)delete error:(NSError**)error +{ + NSData* wrappedKeyData = wrappedKey.wrappedKey; + + if (wrappedKey.type == SecDbKeychainAKSWrappedKeyTypeRegular) { + NSMutableData* unwrappedKey = [NSMutableData dataWithCapacity:wrappedKeyData.length + 40]; + unwrappedKey.length = wrappedKeyData.length + 40; + bool result = [self.class aksDecryptWithKeybag:_keybag keyclass:_keyclass wrappedKeyData:wrappedKeyData outKeyclass:&_keyclass unwrappedKey:unwrappedKey error:error]; + if (result) { + return [[SFAESKey alloc] initWithData:unwrappedKey specifier:[self.class keySpecifier] error:error]; + } + else { + return nil; + } + } +#if USE_KEYSTORE + else if (wrappedKey.type == SecDbKeychainAKSWrappedKeyTypeRefKey) { + aks_ref_key_t refKey = NULL; + aks_ref_key_create_with_blob(_keybag, wrappedKey.refKeyBlob.bytes, wrappedKey.refKeyBlob.length, &refKey); + + CFErrorRef cfError = NULL; + size_t refKeyExternalDataLength = 0; + const uint8_t* refKeyExternalDataBytes = aks_ref_key_get_external_data(refKey, &refKeyExternalDataLength); + if (!refKeyExternalDataBytes) { + aks_ref_key_free(&refKey); + return nil; + } + NSDictionary* aclDict = nil; + der_decode_plist(NULL, kCFPropertyListImmutable, (CFPropertyListRef*)(void*)&aclDict, &cfError, refKeyExternalDataBytes, refKeyExternalDataBytes + refKeyExternalDataLength); + if (!aclDict) { + SecError(errSecDecode, &cfError, CFSTR("SecDbKeychainItemV7: failed to decode acl dict")); + } + SecAccessControlSetConstraints(accessControl, (__bridge CFDictionaryRef)aclDict); + if (!SecAccessControlGetConstraint(accessControl, kAKSKeyOpEncrypt)) { + SecAccessControlAddConstraintForOperation(accessControl, kAKSKeyOpEncrypt, kCFBooleanTrue, &cfError); + } + + size_t derPlistLength = der_sizeof_plist((__bridge CFPropertyListRef)callerAccessGroups, &cfError); + NSMutableData* accessGroupDERData = [[NSMutableData alloc] initWithLength:derPlistLength]; + der_encode_plist((__bridge CFPropertyListRef)callerAccessGroups, &cfError, accessGroupDERData.mutableBytes, accessGroupDERData.mutableBytes + derPlistLength); + void* aksParams = NULL; + size_t aksParamsLength = 0; + aks_operation_optional_params(accessGroupDERData.bytes, derPlistLength, NULL, 0, acmContext.bytes, (int)acmContext.length, &aksParams, &aksParamsLength); + + void* unwrappedKeyDERData = NULL; + size_t unwrappedKeyDERLength = 0; + int aksResult = aks_ref_key_decrypt(refKey, aksParams, aksParamsLength, wrappedKeyData.bytes, wrappedKeyData.length, &unwrappedKeyDERData, &unwrappedKeyDERLength); + if (aksResult != 0) { + CFDataRef accessControlData = SecAccessControlCopyData(accessControl); + create_cferror_from_aks(aksResult, kAKSKeyOpDecrypt, 0, 0, accessControlData, (__bridge CFDataRef)acmContext, &cfError); + CFReleaseNull(accessControlData); + aks_ref_key_free(&refKey); + free(aksParams); + BridgeCFErrorToNSErrorOut(error, cfError); + return nil; + } + if (!unwrappedKeyDERData) { + SecError(errSecDecode, &cfError, CFSTR("SecDbKeychainItemV7: failed to decrypt item, Item can't be decrypted due to failed decode der, so drop the item.")); + aks_ref_key_free(&refKey); + free(aksParams); + BridgeCFErrorToNSErrorOut(error, cfError); + return nil; + } + + CFPropertyListRef unwrappedKeyData = NULL; + der_decode_plist(NULL, kCFPropertyListImmutable, &unwrappedKeyData, &cfError, unwrappedKeyDERData, unwrappedKeyDERData + unwrappedKeyDERLength); + SFAESKey* result = nil; + if ([(__bridge NSData*)unwrappedKeyData isKindOfClass:[NSData class]]) { + result = [[SFAESKey alloc] initWithData:(__bridge NSData*)unwrappedKeyData specifier:[self.class keySpecifier] error:error]; + CFReleaseNull(unwrappedKeyDERData); + } + else { + SecError(errSecDecode, &cfError, CFSTR("SecDbKeychainItemV7: failed to decrypt item, Item can't be decrypted due to failed decode der, so drop the item.")); + aks_ref_key_free(&refKey); + free(aksParams); + free(unwrappedKeyDERData); + BridgeCFErrorToNSErrorOut(error, cfError); + return nil; + } + + if (delete) { + aksResult = aks_ref_key_delete(refKey, aksParams, aksParamsLength); + if (aksResult != 0) { + CFDataRef accessControlData = SecAccessControlCopyData(accessControl); + create_cferror_from_aks(aksResult, kAKSKeyOpDelete, 0, 0, accessControlData, (__bridge CFDataRef)acmContext, &cfError); + CFReleaseNull(accessControlData); + aks_ref_key_free(&refKey); + free(aksParams); + free(unwrappedKeyDERData); + BridgeCFErrorToNSErrorOut(error, cfError); + return nil; + } + } + + BridgeCFErrorToNSErrorOut(error, cfError); + aks_ref_key_free(&refKey); + free(aksParams); + free(unwrappedKeyDERData); + return result; + } +#endif + else { + return nil; + } +} + +@end + +#endif // TARGET_OS_BRIDGE diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainAKSSerializedWrappedKey.proto b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainAKSSerializedWrappedKey.proto new file mode 100644 index 00000000..4c6db5da --- /dev/null +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainAKSSerializedWrappedKey.proto @@ -0,0 +1,7 @@ +syntax = "proto2"; + +message SecDbKeychainSerializedAKSWrappedKey { + required bytes wrappedKey = 1; + optional bytes refKeyBlob = 2; + required uint32 type = 3; +} diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedAKSWrappedKey.h b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedAKSWrappedKey.h new file mode 100644 index 00000000..a0dbbbcd --- /dev/null +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedAKSWrappedKey.h @@ -0,0 +1,41 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from foo.proto + +#import +#import + +#ifdef __cplusplus +#define SECDBKEYCHAINSERIALIZEDAKSWRAPPEDKEY_FUNCTION extern "C" +#else +#define SECDBKEYCHAINSERIALIZEDAKSWRAPPEDKEY_FUNCTION extern +#endif + +@interface SecDbKeychainSerializedAKSWrappedKey : PBCodable +{ + NSData *_refKeyBlob; + uint32_t _type; + NSData *_wrappedKey; +} + + +@property (nonatomic, retain) NSData *wrappedKey; + +@property (nonatomic, readonly) BOOL hasRefKeyBlob; +@property (nonatomic, retain) NSData *refKeyBlob; + +@property (nonatomic) uint32_t type; + +// Performs a shallow copy into other +- (void)copyTo:(SecDbKeychainSerializedAKSWrappedKey *)other; + +// Performs a deep merge from other into self +// If set in other, singular values in self are replaced in self +// Singular composite values are recursively merged +// Repeated values from other are appended to repeated values in self +- (void)mergeFrom:(SecDbKeychainSerializedAKSWrappedKey *)other; + +SECDBKEYCHAINSERIALIZEDAKSWRAPPEDKEY_FUNCTION BOOL SecDbKeychainSerializedAKSWrappedKeyReadFrom(__unsafe_unretained SecDbKeychainSerializedAKSWrappedKey *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedAKSWrappedKey.m b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedAKSWrappedKey.m new file mode 100644 index 00000000..7df5d9ec --- /dev/null +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedAKSWrappedKey.m @@ -0,0 +1,168 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from foo.proto + +#import "SecDbKeychainSerializedAKSWrappedKey.h" +#import +#import +#import + +#if !__has_feature(objc_arc) +# error This generated file depends on ARC but it is not enabled; turn on ARC, or use 'objc_use_arc' option to generate non-ARC code. +#endif + +@implementation SecDbKeychainSerializedAKSWrappedKey + +@synthesize wrappedKey = _wrappedKey; +- (BOOL)hasRefKeyBlob +{ + return _refKeyBlob != nil; +} +@synthesize refKeyBlob = _refKeyBlob; +@synthesize type = _type; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_wrappedKey) + { + [dict setObject:self->_wrappedKey forKey:@"wrappedKey"]; + } + if (self->_refKeyBlob) + { + [dict setObject:self->_refKeyBlob forKey:@"refKeyBlob"]; + } + [dict setObject:[NSNumber numberWithUnsignedInt:self->_type] forKey:@"type"]; + return dict; +} + +BOOL SecDbKeychainSerializedAKSWrappedKeyReadFrom(__unsafe_unretained SecDbKeychainSerializedAKSWrappedKey *self, __unsafe_unretained PBDataReader *reader) { + while (PBReaderHasMoreData(reader)) { + uint32_t tag = 0; + uint8_t aType = 0; + + PBReaderReadTag32AndType(reader, &tag, &aType); + + if (PBReaderHasError(reader)) + break; + + if (aType == TYPE_END_GROUP) { + break; + } + + switch (tag) { + + case 1 /* wrappedKey */: + { + NSData *new_wrappedKey = PBReaderReadData(reader); + self->_wrappedKey = new_wrappedKey; + } + break; + case 2 /* refKeyBlob */: + { + NSData *new_refKeyBlob = PBReaderReadData(reader); + self->_refKeyBlob = new_refKeyBlob; + } + break; + case 3 /* type */: + { + self->_type = PBReaderReadUint32(reader); + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SecDbKeychainSerializedAKSWrappedKeyReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* wrappedKey */ + { + assert(nil != self->_wrappedKey); + PBDataWriterWriteDataField(writer, self->_wrappedKey, 1); + } + /* refKeyBlob */ + { + if (self->_refKeyBlob) + { + PBDataWriterWriteDataField(writer, self->_refKeyBlob, 2); + } + } + /* type */ + { + PBDataWriterWriteUint32Field(writer, self->_type, 3); + } +} + +- (void)copyTo:(SecDbKeychainSerializedAKSWrappedKey *)other +{ + other.wrappedKey = _wrappedKey; + if (_refKeyBlob) + { + other.refKeyBlob = _refKeyBlob; + } + other->_type = _type; +} + +- (id)copyWithZone:(NSZone *)zone +{ + SecDbKeychainSerializedAKSWrappedKey *copy = [[[self class] allocWithZone:zone] init]; + copy->_wrappedKey = [_wrappedKey copyWithZone:zone]; + copy->_refKeyBlob = [_refKeyBlob copyWithZone:zone]; + copy->_type = _type; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SecDbKeychainSerializedAKSWrappedKey *other = (SecDbKeychainSerializedAKSWrappedKey *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_wrappedKey && !other->_wrappedKey) || [self->_wrappedKey isEqual:other->_wrappedKey]) + && + ((!self->_refKeyBlob && !other->_refKeyBlob) || [self->_refKeyBlob isEqual:other->_refKeyBlob]) + && + self->_type == other->_type + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_wrappedKey hash] + ^ + [self->_refKeyBlob hash] + ^ + PBHashInt((NSUInteger)_type) + ; +} + +- (void)mergeFrom:(SecDbKeychainSerializedAKSWrappedKey *)other +{ + if (other->_wrappedKey) + { + [self setWrappedKey:other->_wrappedKey]; + } + if (other->_refKeyBlob) + { + [self setRefKeyBlob:other->_refKeyBlob]; + } + self->_type = other->_type; +} + +@end + diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedItemV7.h b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedItemV7.h new file mode 100644 index 00000000..4530a8a7 --- /dev/null +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedItemV7.h @@ -0,0 +1,81 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from foo.proto + +#import +#import + +typedef NS_ENUM(int32_t, SecDbKeychainSerializedItemV7_Keyclass) { + SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_AK = 6, + SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_CK = 7, + SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_DK = 8, + SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_AKU = 9, + SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_CKU = 10, + SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_DKU = 11, + SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_AKPU = 12, +}; +#ifdef __OBJC__ +NS_INLINE NSString *SecDbKeychainSerializedItemV7_KeyclassAsString(SecDbKeychainSerializedItemV7_Keyclass value) +{ + switch (value) + { + case SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_AK: return @"KEYCLASS_AK"; + case SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_CK: return @"KEYCLASS_CK"; + case SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_DK: return @"KEYCLASS_DK"; + case SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_AKU: return @"KEYCLASS_AKU"; + case SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_CKU: return @"KEYCLASS_CKU"; + case SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_DKU: return @"KEYCLASS_DKU"; + case SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_AKPU: return @"KEYCLASS_AKPU"; + default: return [NSString stringWithFormat:@"(unknown: %i)", value]; + } +} +#endif /* __OBJC__ */ +#ifdef __OBJC__ +NS_INLINE SecDbKeychainSerializedItemV7_Keyclass StringAsSecDbKeychainSerializedItemV7_Keyclass(NSString *value) +{ + if ([value isEqualToString:@"KEYCLASS_AK"]) return SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_AK; + if ([value isEqualToString:@"KEYCLASS_CK"]) return SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_CK; + if ([value isEqualToString:@"KEYCLASS_DK"]) return SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_DK; + if ([value isEqualToString:@"KEYCLASS_AKU"]) return SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_AKU; + if ([value isEqualToString:@"KEYCLASS_CKU"]) return SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_CKU; + if ([value isEqualToString:@"KEYCLASS_DKU"]) return SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_DKU; + if ([value isEqualToString:@"KEYCLASS_AKPU"]) return SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_AKPU; + return SecDbKeychainSerializedItemV7_Keyclass_KEYCLASS_AK; +} +#endif /* __OBJC__ */ + +#ifdef __cplusplus +#define SECDBKEYCHAINSERIALIZEDITEMV7_FUNCTION extern "C" +#else +#define SECDBKEYCHAINSERIALIZEDITEMV7_FUNCTION extern +#endif + +@interface SecDbKeychainSerializedItemV7 : PBCodable +{ + NSData *_encryptedMetadata; + NSData *_encryptedSecretData; + SecDbKeychainSerializedItemV7_Keyclass _keyclass; +} + + +@property (nonatomic, retain) NSData *encryptedSecretData; + +@property (nonatomic, retain) NSData *encryptedMetadata; + +@property (nonatomic) SecDbKeychainSerializedItemV7_Keyclass keyclass; +- (NSString *)keyclassAsString:(SecDbKeychainSerializedItemV7_Keyclass)value; +- (SecDbKeychainSerializedItemV7_Keyclass)StringAsKeyclass:(NSString *)str; + +// Performs a shallow copy into other +- (void)copyTo:(SecDbKeychainSerializedItemV7 *)other; + +// Performs a deep merge from other into self +// If set in other, singular values in self are replaced in self +// Singular composite values are recursively merged +// Repeated values from other are appended to repeated values in self +- (void)mergeFrom:(SecDbKeychainSerializedItemV7 *)other; + +SECDBKEYCHAINSERIALIZEDITEMV7_FUNCTION BOOL SecDbKeychainSerializedItemV7ReadFrom(__unsafe_unretained SecDbKeychainSerializedItemV7 *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedItemV7.m b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedItemV7.m new file mode 100644 index 00000000..8d7a75b7 --- /dev/null +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedItemV7.m @@ -0,0 +1,167 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from foo.proto + +#import "SecDbKeychainSerializedItemV7.h" +#import +#import +#import + +#if !__has_feature(objc_arc) +# error This generated file depends on ARC but it is not enabled; turn on ARC, or use 'objc_use_arc' option to generate non-ARC code. +#endif + +@implementation SecDbKeychainSerializedItemV7 + +@synthesize encryptedSecretData = _encryptedSecretData; +@synthesize encryptedMetadata = _encryptedMetadata; +@synthesize keyclass = _keyclass; +- (NSString *)keyclassAsString:(SecDbKeychainSerializedItemV7_Keyclass)value +{ + return SecDbKeychainSerializedItemV7_KeyclassAsString(value); +} +- (SecDbKeychainSerializedItemV7_Keyclass)StringAsKeyclass:(NSString *)str +{ + return StringAsSecDbKeychainSerializedItemV7_Keyclass(str); +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_encryptedSecretData) + { + [dict setObject:self->_encryptedSecretData forKey:@"encryptedSecretData"]; + } + if (self->_encryptedMetadata) + { + [dict setObject:self->_encryptedMetadata forKey:@"encryptedMetadata"]; + } + [dict setObject:SecDbKeychainSerializedItemV7_KeyclassAsString(self->_keyclass) forKey:@"keyclass"]; + return dict; +} + +BOOL SecDbKeychainSerializedItemV7ReadFrom(__unsafe_unretained SecDbKeychainSerializedItemV7 *self, __unsafe_unretained PBDataReader *reader) { + while (PBReaderHasMoreData(reader)) { + uint32_t tag = 0; + uint8_t aType = 0; + + PBReaderReadTag32AndType(reader, &tag, &aType); + + if (PBReaderHasError(reader)) + break; + + if (aType == TYPE_END_GROUP) { + break; + } + + switch (tag) { + + case 1 /* encryptedSecretData */: + { + NSData *new_encryptedSecretData = PBReaderReadData(reader); + self->_encryptedSecretData = new_encryptedSecretData; + } + break; + case 2 /* encryptedMetadata */: + { + NSData *new_encryptedMetadata = PBReaderReadData(reader); + self->_encryptedMetadata = new_encryptedMetadata; + } + break; + case 3 /* keyclass */: + { + self->_keyclass = PBReaderReadInt32(reader); + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SecDbKeychainSerializedItemV7ReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* encryptedSecretData */ + { + assert(nil != self->_encryptedSecretData); + PBDataWriterWriteDataField(writer, self->_encryptedSecretData, 1); + } + /* encryptedMetadata */ + { + assert(nil != self->_encryptedMetadata); + PBDataWriterWriteDataField(writer, self->_encryptedMetadata, 2); + } + /* keyclass */ + { + PBDataWriterWriteInt32Field(writer, self->_keyclass, 3); + } +} + +- (void)copyTo:(SecDbKeychainSerializedItemV7 *)other +{ + other.encryptedSecretData = _encryptedSecretData; + other.encryptedMetadata = _encryptedMetadata; + other->_keyclass = _keyclass; +} + +- (id)copyWithZone:(NSZone *)zone +{ + SecDbKeychainSerializedItemV7 *copy = [[[self class] allocWithZone:zone] init]; + copy->_encryptedSecretData = [_encryptedSecretData copyWithZone:zone]; + copy->_encryptedMetadata = [_encryptedMetadata copyWithZone:zone]; + copy->_keyclass = _keyclass; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SecDbKeychainSerializedItemV7 *other = (SecDbKeychainSerializedItemV7 *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_encryptedSecretData && !other->_encryptedSecretData) || [self->_encryptedSecretData isEqual:other->_encryptedSecretData]) + && + ((!self->_encryptedMetadata && !other->_encryptedMetadata) || [self->_encryptedMetadata isEqual:other->_encryptedMetadata]) + && + self->_keyclass == other->_keyclass + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_encryptedSecretData hash] + ^ + [self->_encryptedMetadata hash] + ^ + PBHashInt((NSUInteger)_keyclass) + ; +} + +- (void)mergeFrom:(SecDbKeychainSerializedItemV7 *)other +{ + if (other->_encryptedSecretData) + { + [self setEncryptedSecretData:other->_encryptedSecretData]; + } + if (other->_encryptedMetadata) + { + [self setEncryptedMetadata:other->_encryptedMetadata]; + } + self->_keyclass = other->_keyclass; +} + +@end + diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedItemV7.proto b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedItemV7.proto new file mode 100644 index 00000000..4138447d --- /dev/null +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedItemV7.proto @@ -0,0 +1,17 @@ +syntax = "proto2"; + +message SecDbKeychainSerializedItemV7 { + required bytes encryptedSecretData = 1; + required bytes encryptedMetadata = 2; + + enum Keyclass { + KEYCLASS_AK = 6; + KEYCLASS_CK = 7; + KEYCLASS_DK = 8; + KEYCLASS_AKU = 9; + KEYCLASS_CKU = 10; + KEYCLASS_DKU = 11; + KEYCLASS_AKPU = 12; + } + required Keyclass keyclass = 3 [default = KEYCLASS_AKPU]; +} diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedMetadata.h b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedMetadata.h new file mode 100644 index 00000000..0143c9b8 --- /dev/null +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedMetadata.h @@ -0,0 +1,40 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from foo.proto + +#import +#import + +#ifdef __cplusplus +#define SECDBKEYCHAINSERIALIZEDMETADATA_FUNCTION extern "C" +#else +#define SECDBKEYCHAINSERIALIZEDMETADATA_FUNCTION extern +#endif + +@interface SecDbKeychainSerializedMetadata : PBCodable +{ + NSData *_ciphertext; + NSString *_tamperCheck; + NSData *_wrappedKey; +} + + +@property (nonatomic, retain) NSData *ciphertext; + +@property (nonatomic, retain) NSData *wrappedKey; + +@property (nonatomic, retain) NSString *tamperCheck; + +// Performs a shallow copy into other +- (void)copyTo:(SecDbKeychainSerializedMetadata *)other; + +// Performs a deep merge from other into self +// If set in other, singular values in self are replaced in self +// Singular composite values are recursively merged +// Repeated values from other are appended to repeated values in self +- (void)mergeFrom:(SecDbKeychainSerializedMetadata *)other; + +SECDBKEYCHAINSERIALIZEDMETADATA_FUNCTION BOOL SecDbKeychainSerializedMetadataReadFrom(__unsafe_unretained SecDbKeychainSerializedMetadata *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedMetadata.m b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedMetadata.m new file mode 100644 index 00000000..e53c9f88 --- /dev/null +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedMetadata.m @@ -0,0 +1,167 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from foo.proto + +#import "SecDbKeychainSerializedMetadata.h" +#import +#import +#import + +#if !__has_feature(objc_arc) +# error This generated file depends on ARC but it is not enabled; turn on ARC, or use 'objc_use_arc' option to generate non-ARC code. +#endif + +@implementation SecDbKeychainSerializedMetadata + +@synthesize ciphertext = _ciphertext; +@synthesize wrappedKey = _wrappedKey; +@synthesize tamperCheck = _tamperCheck; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_ciphertext) + { + [dict setObject:self->_ciphertext forKey:@"ciphertext"]; + } + if (self->_wrappedKey) + { + [dict setObject:self->_wrappedKey forKey:@"wrappedKey"]; + } + if (self->_tamperCheck) + { + [dict setObject:self->_tamperCheck forKey:@"tamperCheck"]; + } + return dict; +} + +BOOL SecDbKeychainSerializedMetadataReadFrom(__unsafe_unretained SecDbKeychainSerializedMetadata *self, __unsafe_unretained PBDataReader *reader) { + while (PBReaderHasMoreData(reader)) { + uint32_t tag = 0; + uint8_t aType = 0; + + PBReaderReadTag32AndType(reader, &tag, &aType); + + if (PBReaderHasError(reader)) + break; + + if (aType == TYPE_END_GROUP) { + break; + } + + switch (tag) { + + case 1 /* ciphertext */: + { + NSData *new_ciphertext = PBReaderReadData(reader); + self->_ciphertext = new_ciphertext; + } + break; + case 2 /* wrappedKey */: + { + NSData *new_wrappedKey = PBReaderReadData(reader); + self->_wrappedKey = new_wrappedKey; + } + break; + case 3 /* tamperCheck */: + { + NSString *new_tamperCheck = PBReaderReadString(reader); + self->_tamperCheck = new_tamperCheck; + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SecDbKeychainSerializedMetadataReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* ciphertext */ + { + assert(nil != self->_ciphertext); + PBDataWriterWriteDataField(writer, self->_ciphertext, 1); + } + /* wrappedKey */ + { + assert(nil != self->_wrappedKey); + PBDataWriterWriteDataField(writer, self->_wrappedKey, 2); + } + /* tamperCheck */ + { + assert(nil != self->_tamperCheck); + PBDataWriterWriteStringField(writer, self->_tamperCheck, 3); + } +} + +- (void)copyTo:(SecDbKeychainSerializedMetadata *)other +{ + other.ciphertext = _ciphertext; + other.wrappedKey = _wrappedKey; + other.tamperCheck = _tamperCheck; +} + +- (id)copyWithZone:(NSZone *)zone +{ + SecDbKeychainSerializedMetadata *copy = [[[self class] allocWithZone:zone] init]; + copy->_ciphertext = [_ciphertext copyWithZone:zone]; + copy->_wrappedKey = [_wrappedKey copyWithZone:zone]; + copy->_tamperCheck = [_tamperCheck copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SecDbKeychainSerializedMetadata *other = (SecDbKeychainSerializedMetadata *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_ciphertext && !other->_ciphertext) || [self->_ciphertext isEqual:other->_ciphertext]) + && + ((!self->_wrappedKey && !other->_wrappedKey) || [self->_wrappedKey isEqual:other->_wrappedKey]) + && + ((!self->_tamperCheck && !other->_tamperCheck) || [self->_tamperCheck isEqual:other->_tamperCheck]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_ciphertext hash] + ^ + [self->_wrappedKey hash] + ^ + [self->_tamperCheck hash] + ; +} + +- (void)mergeFrom:(SecDbKeychainSerializedMetadata *)other +{ + if (other->_ciphertext) + { + [self setCiphertext:other->_ciphertext]; + } + if (other->_wrappedKey) + { + [self setWrappedKey:other->_wrappedKey]; + } + if (other->_tamperCheck) + { + [self setTamperCheck:other->_tamperCheck]; + } +} + +@end + diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedMetadata.proto b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedMetadata.proto new file mode 100644 index 00000000..f21796c2 --- /dev/null +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedMetadata.proto @@ -0,0 +1,7 @@ +syntax = "proto2"; + +message SecDbKeychainSerializedMetadata { + required bytes ciphertext = 1; + required bytes wrappedKey = 2; + required string tamperCheck = 3; +} diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.h b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.h new file mode 100644 index 00000000..43dfdf44 --- /dev/null +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.h @@ -0,0 +1,40 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from foo.proto + +#import +#import + +#ifdef __cplusplus +#define SECDBKEYCHAINSERIALIZEDSECRETDATA_FUNCTION extern "C" +#else +#define SECDBKEYCHAINSERIALIZEDSECRETDATA_FUNCTION extern +#endif + +@interface SecDbKeychainSerializedSecretData : PBCodable +{ + NSData *_ciphertext; + NSString *_tamperCheck; + NSData *_wrappedKey; +} + + +@property (nonatomic, retain) NSData *ciphertext; + +@property (nonatomic, retain) NSData *wrappedKey; + +@property (nonatomic, retain) NSString *tamperCheck; + +// Performs a shallow copy into other +- (void)copyTo:(SecDbKeychainSerializedSecretData *)other; + +// Performs a deep merge from other into self +// If set in other, singular values in self are replaced in self +// Singular composite values are recursively merged +// Repeated values from other are appended to repeated values in self +- (void)mergeFrom:(SecDbKeychainSerializedSecretData *)other; + +SECDBKEYCHAINSERIALIZEDSECRETDATA_FUNCTION BOOL SecDbKeychainSerializedSecretDataReadFrom(__unsafe_unretained SecDbKeychainSerializedSecretData *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.m b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.m new file mode 100644 index 00000000..864421a3 --- /dev/null +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.m @@ -0,0 +1,167 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from foo.proto + +#import "SecDbKeychainSerializedSecretData.h" +#import +#import +#import + +#if !__has_feature(objc_arc) +# error This generated file depends on ARC but it is not enabled; turn on ARC, or use 'objc_use_arc' option to generate non-ARC code. +#endif + +@implementation SecDbKeychainSerializedSecretData + +@synthesize ciphertext = _ciphertext; +@synthesize wrappedKey = _wrappedKey; +@synthesize tamperCheck = _tamperCheck; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_ciphertext) + { + [dict setObject:self->_ciphertext forKey:@"ciphertext"]; + } + if (self->_wrappedKey) + { + [dict setObject:self->_wrappedKey forKey:@"wrappedKey"]; + } + if (self->_tamperCheck) + { + [dict setObject:self->_tamperCheck forKey:@"tamperCheck"]; + } + return dict; +} + +BOOL SecDbKeychainSerializedSecretDataReadFrom(__unsafe_unretained SecDbKeychainSerializedSecretData *self, __unsafe_unretained PBDataReader *reader) { + while (PBReaderHasMoreData(reader)) { + uint32_t tag = 0; + uint8_t aType = 0; + + PBReaderReadTag32AndType(reader, &tag, &aType); + + if (PBReaderHasError(reader)) + break; + + if (aType == TYPE_END_GROUP) { + break; + } + + switch (tag) { + + case 1 /* ciphertext */: + { + NSData *new_ciphertext = PBReaderReadData(reader); + self->_ciphertext = new_ciphertext; + } + break; + case 2 /* wrappedKey */: + { + NSData *new_wrappedKey = PBReaderReadData(reader); + self->_wrappedKey = new_wrappedKey; + } + break; + case 3 /* tamperCheck */: + { + NSString *new_tamperCheck = PBReaderReadString(reader); + self->_tamperCheck = new_tamperCheck; + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SecDbKeychainSerializedSecretDataReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* ciphertext */ + { + assert(nil != self->_ciphertext); + PBDataWriterWriteDataField(writer, self->_ciphertext, 1); + } + /* wrappedKey */ + { + assert(nil != self->_wrappedKey); + PBDataWriterWriteDataField(writer, self->_wrappedKey, 2); + } + /* tamperCheck */ + { + assert(nil != self->_tamperCheck); + PBDataWriterWriteStringField(writer, self->_tamperCheck, 3); + } +} + +- (void)copyTo:(SecDbKeychainSerializedSecretData *)other +{ + other.ciphertext = _ciphertext; + other.wrappedKey = _wrappedKey; + other.tamperCheck = _tamperCheck; +} + +- (id)copyWithZone:(NSZone *)zone +{ + SecDbKeychainSerializedSecretData *copy = [[[self class] allocWithZone:zone] init]; + copy->_ciphertext = [_ciphertext copyWithZone:zone]; + copy->_wrappedKey = [_wrappedKey copyWithZone:zone]; + copy->_tamperCheck = [_tamperCheck copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SecDbKeychainSerializedSecretData *other = (SecDbKeychainSerializedSecretData *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_ciphertext && !other->_ciphertext) || [self->_ciphertext isEqual:other->_ciphertext]) + && + ((!self->_wrappedKey && !other->_wrappedKey) || [self->_wrappedKey isEqual:other->_wrappedKey]) + && + ((!self->_tamperCheck && !other->_tamperCheck) || [self->_tamperCheck isEqual:other->_tamperCheck]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_ciphertext hash] + ^ + [self->_wrappedKey hash] + ^ + [self->_tamperCheck hash] + ; +} + +- (void)mergeFrom:(SecDbKeychainSerializedSecretData *)other +{ + if (other->_ciphertext) + { + [self setCiphertext:other->_ciphertext]; + } + if (other->_wrappedKey) + { + [self setWrappedKey:other->_wrappedKey]; + } + if (other->_tamperCheck) + { + [self setTamperCheck:other->_tamperCheck]; + } +} + +@end + diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.proto b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.proto new file mode 100644 index 00000000..81b03aca --- /dev/null +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.proto @@ -0,0 +1,7 @@ +syntax = "proto2"; + +message SecDbKeychainSerializedSecretData { + required bytes ciphertext = 1; + required bytes wrappedKey = 2; + required string tamperCheck = 3; +} diff --git a/OSX/sec/securityd/SecDbQuery.c b/OSX/sec/securityd/SecDbQuery.c index 119f4f2e..81780ed1 100644 --- a/OSX/sec/securityd/SecDbQuery.c +++ b/OSX/sec/securityd/SecDbQuery.c @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/OSX/sec/securityd/SecItemBackupServer.c b/OSX/sec/securityd/SecItemBackupServer.c index 66d1b998..e7a8dd17 100644 --- a/OSX/sec/securityd/SecItemBackupServer.c +++ b/OSX/sec/securityd/SecItemBackupServer.c @@ -83,7 +83,7 @@ static bool SOSDataSourceWithBackup(SOSDataSourceRef ds, CFDataRef backup, keyba __block bool ok = true; CFPropertyListRef plist = CFPropertyListCreateWithDERData(kCFAllocatorDefault, backup, kCFPropertyListImmutable, NULL, error); CFDictionaryRef bdict = asDictionary(plist, error); - ok = bdict; + ok = (bdict != NULL); if (ok) CFDictionaryForEach(bdict, ^(const void *key, const void *value) { CFStringRef className = asString(key, error); if (className) { diff --git a/OSX/sec/securityd/SecItemDataSource.c b/OSX/sec/securityd/SecItemDataSource.c index ae2686d6..a19f39b6 100644 --- a/OSX/sec/securityd/SecItemDataSource.c +++ b/OSX/sec/securityd/SecItemDataSource.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -122,7 +123,7 @@ static bool SecDbItemSelectSHA1(SecDbQueryRef query, SecDbConnectionRef dbconn, static SOSManifestRef SecItemDataSourceCopyManifestWithQueries(SecItemDataSourceRef ds, CFArrayRef queries, CFErrorRef *error) { __block SOSManifestRef manifest = NULL; __block CFErrorRef localError = NULL; - if (!SecDbPerformRead(ds->db, error, ^(SecDbConnectionRef dbconn) { + if (!kc_with_custom_db(false, true, ds->db, error, ^bool(SecDbConnectionRef dbconn) { __block struct SOSDigestVector dv = SOSDigestVectorInit; Query *q; bool ok = true; @@ -148,6 +149,7 @@ static SOSManifestRef SecItemDataSourceCopyManifestWithQueries(SecItemDataSource manifest = SOSManifestCreateWithDigestVector(&dv, &localError); } SOSDigestVectorFree(&dv); + return ok; })) { CFReleaseSafe(manifest); } @@ -392,7 +394,7 @@ static bool dsForEachObject(SOSDataSourceRef data_source, SOSTransactionRef txn, __block CFStringRef *sqls = select_sql; __block sqlite3_stmt **stmts = select_stmts; - void (^readBlock)(SecDbConnectionRef dbconn) = ^(SecDbConnectionRef dbconn) + bool (^readBlock)(SecDbConnectionRef dbconn) = ^bool(SecDbConnectionRef dbconn) { // Setup for (size_t class_ix = 0; class_ix < dsSyncedClassesSize; ++class_ix) { @@ -426,12 +428,14 @@ static bool dsForEachObject(SOSDataSourceRef data_source, SOSTransactionRef txn, if (queries[class_ix]) result &= query_destroy(queries[class_ix], error); } + + return true; }; if (txn) { readBlock((SecDbConnectionRef)txn); } else { - result &= SecDbPerformRead(ds->db, error, readBlock); + result &= kc_with_custom_db(false, true, ds->db, error, readBlock); } return result; @@ -476,6 +480,7 @@ static CFDateRef copyObjectModDate(SOSObjectRef object, CFErrorRef *error) { static CFDictionaryRef objectCopyPropertyList(SOSObjectRef object, CFErrorRef *error) { SecDbItemRef item = (SecDbItemRef) object; + CFMutableDictionaryRef secretDataDict = SecDbItemCopyPListWithMask(item, kSecDbReturnDataFlag, error); CFMutableDictionaryRef cryptoDataDict = SecDbItemCopyPListWithMask(item, kSecDbInCryptoDataFlag, error); CFMutableDictionaryRef authDataDict = SecDbItemCopyPListWithMask(item, kSecDbInAuthenticatedDataFlag, error); @@ -485,18 +490,24 @@ static CFDictionaryRef objectCopyPropertyList(SOSObjectRef object, CFErrorRef *e CFDictionarySetValue(cryptoDataDict, key, value); }); } + if (secretDataDict) { + CFDictionaryForEach(secretDataDict, ^(const void* key, const void* value) { + CFDictionarySetValue(cryptoDataDict, key, value); + }); + } CFDictionaryAddValue(cryptoDataDict, kSecClass, SecDbItemGetClass(item)->name); } - - CFReleaseSafe(authDataDict); + + CFReleaseNull(secretDataDict); + CFReleaseNull(authDataDict); return cryptoDataDict; } static bool dsWith(SOSDataSourceRef data_source, CFErrorRef *error, SOSDataSourceTransactionSource source, bool onCommitQueue, void(^transaction)(SOSTransactionRef txn, bool *commit)) { SecItemDataSourceRef ds = (SecItemDataSourceRef)data_source; __block bool ok = true; - ok &= SecDbPerformWrite(ds->db, error, ^(SecDbConnectionRef dbconn) { - ok &= SecDbTransaction(dbconn, + ok &= kc_with_custom_db(true, true, ds->db, error, ^bool(SecDbConnectionRef dbconn) { + return SecDbTransaction(dbconn, source == kSOSDataSourceAPITransaction ? kSecDbExclusiveTransactionType : kSecDbExclusiveRemoteSOSTransactionType, error, ^(bool *commit) { if (onCommitQueue) { @@ -514,10 +525,11 @@ static bool dsWith(SOSDataSourceRef data_source, CFErrorRef *error, SOSDataSourc static bool dsReadWith(SOSDataSourceRef data_source, CFErrorRef *error, SOSDataSourceTransactionSource source, void(^perform)(SOSTransactionRef txn)) { SecItemDataSourceRef ds = (SecItemDataSourceRef)data_source; __block bool ok = true; - ok &= SecDbPerformRead(ds->db, error, ^(SecDbConnectionRef dbconn) { + ok &= kc_with_custom_db(false, true, ds->db, error, ^bool(SecDbConnectionRef dbconn) { SecDbPerformOnCommitQueue(dbconn, false, ^{ perform((SOSTransactionRef)dbconn); }); + return true; }); return ok; } @@ -657,8 +669,8 @@ static CFDataRef dsCopyStateWithKey(SOSDataSourceRef data_source, CFStringRef ke if (query) { if (query->q_item) CFReleaseSafe(query->q_item); query->q_item = dict; - void (^read_it)(SecDbConnectionRef dbconn) = ^(SecDbConnectionRef dbconn) { - SecDbItemSelect(query, dbconn, error, NULL, ^bool(const SecDbAttr *attr) { + bool (^read_it)(SecDbConnectionRef dbconn) = ^(SecDbConnectionRef dbconn) { + return SecDbItemSelect(query, dbconn, error, NULL, ^bool(const SecDbAttr *attr) { return CFDictionaryContainsKey(dict, attr->name); }, NULL, NULL, ^(SecDbItemRef item, bool *stop) { secnotice("ds", "found item for key %@@%@", key, pdmn); @@ -668,7 +680,7 @@ static CFDataRef dsCopyStateWithKey(SOSDataSourceRef data_source, CFStringRef ke if (txn) { read_it((SecDbConnectionRef) txn); } else { - SecDbPerformRead(ds->db, error, read_it); + kc_with_custom_db(false, true, ds->db, error, read_it); } query_destroy(query, error); } else { @@ -702,8 +714,8 @@ static CFDataRef dsCopyItemDataWithKeys(SOSDataSourceRef data_source, CFDictiona if (query) { if (query->q_item) CFReleaseSafe(query->q_item); query->q_item = dict; - SecDbPerformRead(ds->db, error, ^(SecDbConnectionRef dbconn) { - SecDbItemSelect(query, dbconn, error, NULL, ^bool(const SecDbAttr *attr) { + kc_with_custom_db(false, true, ds->db, error, ^bool(SecDbConnectionRef dbconn) { + return SecDbItemSelect(query, dbconn, error, NULL, ^bool(const SecDbAttr *attr) { return CFDictionaryContainsKey(dict, attr->name); }, NULL, NULL, ^(SecDbItemRef item, bool *stop) { secnotice("ds", "found item for keys %@", keys); diff --git a/OSX/sec/securityd/SecItemDb.c b/OSX/sec/securityd/SecItemDb.c index 5ebca2b1..c2d29f91 100644 --- a/OSX/sec/securityd/SecItemDb.c +++ b/OSX/sec/securityd/SecItemDb.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,7 @@ #include #include #include +#include "sec_action.h" #include "keychain/ckks/CKKS.h" @@ -390,11 +392,11 @@ s3dl_copy_data_from_col(sqlite3_stmt *stmt, int col, CFErrorRef *error) { static bool s3dl_item_from_col(sqlite3_stmt *stmt, Query *q, int col, CFArrayRef accessGroups, - CFMutableDictionaryRef *item, SecAccessControlRef *access_control, CFErrorRef *error) { + CFMutableDictionaryRef *item, SecAccessControlRef *access_control, keyclass_t* keyclass, CFErrorRef *error) { CFDataRef edata = NULL; bool ok = false; require(edata = s3dl_copy_data_from_col(stmt, col, error), out); - ok = s3dl_item_from_data(edata, q, accessGroups, item, access_control, error); + ok = s3dl_item_from_data(edata, q, accessGroups, item, access_control, keyclass, error); out: CFReleaseSafe(edata); @@ -453,11 +455,13 @@ handle_result(Query *q, itemRef = SecDbItemCreateWithAttributes(NULL, q->q_class, item, KEYBAG_DEVICE, &cferror); } if(!cferror && itemRef) { - CFTypeRef attrValue = attr->copyValue(itemRef, attr, &cferror); - if(!cferror && attrValue) { - CFDictionarySetValue(item, attr->name, attrValue); + if (attr->kind != kSecDbSHA1Attr || (q->q_return_type & kSecReturnDataMask)) { // we'll skip returning the sha1 attribute unless the client has also asked us to return data, because without data our sha1 could be invalid + CFTypeRef attrValue = attr->copyValue(itemRef, attr, &cferror); + if (!cferror && attrValue) { + CFDictionarySetValue(item, attr->name, attrValue); + } + CFReleaseNull(attrValue); } - CFReleaseNull(attrValue); } CFReleaseNull(cferror); } @@ -504,10 +508,14 @@ out: static void s3dl_query_row(sqlite3_stmt *stmt, void *context) { struct s3dl_query_ctx *c = context; Query *q = c->q; + ReturnTypeMask saved_mask = q->q_return_type; sqlite_int64 rowid = sqlite3_column_int64(stmt, 0); CFMutableDictionaryRef item = NULL; - bool ok = s3dl_item_from_col(stmt, q, 1, c->accessGroups, &item, NULL, &q->q_error); + bool ok; + +decode: + ok = s3dl_item_from_col(stmt, q, 1, c->accessGroups, &item, NULL, NULL, &q->q_error); if (!ok) { OSStatus status = SecErrorGetOSStatus(q->q_error); // errSecDecode means the item is corrupted, stash it for delete. @@ -526,6 +534,16 @@ static void s3dl_query_row(sqlite3_stmt *stmt, void *context) { CFReleaseNull(q->q_error); } else if (status == errSecAuthNeeded) { secwarning("Authentication is needed for %@,rowid=%" PRId64 " (%" PRIdOSStatus "): %@", q->q_class->name, rowid, status, q->q_error); + } else if (status == errSecInteractionNotAllowed) { + static dispatch_once_t kclockedtoken; + static sec_action_t kclockedaction; + dispatch_once(&kclockedtoken, ^{ + kclockedaction = sec_action_create("ratelimiterdisabledlogevent", 1); + sec_action_set_handler(kclockedaction, ^{ + secerror("decode item failed, keychain is locked (%d)", (int)errSecInteractionNotAllowed); + }); + }); + sec_action_perform(kclockedaction); } else { secerror("decode %@,rowid=%" PRId64 " failed (%" PRIdOSStatus "): %@", q->q_class->name, rowid, status, q->q_error); } @@ -536,6 +554,14 @@ static void s3dl_query_row(sqlite3_stmt *stmt, void *context) { if (!item) goto out; + if (CFDictionaryContainsKey(item, kSecAttrTokenID) && (q->q_return_type & kSecReturnDataMask) == 0) { + // For token-based items, to get really meaningful set of attributes we must provide also data field, so augment mask + // and restart item decoding cycle. + q->q_return_type |= kSecReturnDataMask; + CFReleaseNull(item); + goto decode; + } + if (q->q_token_object_id != NULL && !checkTokenObjectID(q->q_token_object_id, CFDictionaryGetValue(item, kSecValueData))) goto out; @@ -544,7 +570,7 @@ static void s3dl_query_row(sqlite3_stmt *stmt, void *context) { CFMutableDictionaryRef key; /* TODO : if there is a errSecDecode error here, we should cleanup */ - if (!s3dl_item_from_col(stmt, q, 3, c->accessGroups, &key, NULL, &q->q_error) || !key) + if (!s3dl_item_from_col(stmt, q, 3, c->accessGroups, &key, NULL, NULL, &q->q_error) || !key) goto out; CFDataRef certData = CFDictionaryGetValue(item, kSecValueData); @@ -582,6 +608,7 @@ static void s3dl_query_row(sqlite3_stmt *stmt, void *context) { } out: + q->q_return_type = saved_mask; CFReleaseSafe(item); } @@ -1110,6 +1137,7 @@ s3dl_query_update(SecDbConnectionRef dbt, Query *q, secerror("failed to delete corrupt %@,rowid=%" PRId64 " %@", q->q_class->name, SecDbItemGetRowId(item, NULL), localError); CFReleaseNull(localError); } + CFReleaseNull(new_item); return; } if (new_item != NULL && u->q_access_control != NULL) @@ -1140,7 +1168,7 @@ errOut: static bool SecDbItemNeedAuth(SecDbItemRef item, CFErrorRef *error) { CFErrorRef localError = NULL; - if (!SecDbItemEnsureDecrypted(item, &localError) && localError && CFErrorGetCode(localError) == errSecAuthNeeded) { + if (!SecDbItemEnsureDecrypted(item, true, &localError) && localError && CFErrorGetCode(localError) == errSecAuthNeeded) { if (error) *error = localError; return true; @@ -1292,6 +1320,7 @@ static bool SecItemIsSystemBound(CFDictionaryRef item, const SecDbClass *cls, bo if (multiUser && CFEqual(agrp, CFSTR("apple")) && cls == genp_class()) { static CFStringRef accountServices[] = { + /* accounts, remove with rdar://37595482 */ CFSTR("com.apple.account.AppleAccount.token"), CFSTR("com.apple.account.AppleAccount.password"), CFSTR("com.apple.account.AppleAccount.rpassword"), @@ -1302,6 +1331,7 @@ static bool SecItemIsSystemBound(CFDictionaryRef item, const SecDbClass *cls, bo CFSTR("com.apple.account.IdentityServices.password"), /* accountsd for ids */ CFSTR("com.apple.account.IdentityServices.rpassword"), CFSTR("com.apple.account.IdentityServices.token"), + /* IDS stuff */ CFSTR("BackupIDSAccountToken"), CFSTR("com.apple.ids"), CFSTR("ids"), @@ -1323,6 +1353,15 @@ static bool SecItemIsSystemBound(CFDictionaryRef item, const SecDbClass *cls, bo } } + /* accounts, remove with rdar://37595482 */ + if (multiUser && CFEqual(agrp, CFSTR("com.apple.ind")) && cls == genp_class()) { + CFStringRef service = CFDictionaryGetValue(item, kSecAttrService); + if (isString(service) && CFEqual(service, CFSTR("com.apple.ind.registration"))) { + secdebug("backup", "found exact sys_bound item: %@", item); + return true; + } + } + if (multiUser && CFEqual(agrp, CFSTR("ichat")) && cls == genp_class()) { static CFStringRef accountServices[] = { CFSTR("ids"), @@ -1446,55 +1485,68 @@ static void s3dl_export_row(sqlite3_stmt *stmt, void *context) { bool skip_akpu_or_token = c->filter == kSecBackupableItemFilter; sqlite_int64 rowid = sqlite3_column_int64(stmt, 0); - CFMutableDictionaryRef item = NULL; - bool ok = s3dl_item_from_col(stmt, q, 1, c->qc.accessGroups, &item, &access_control, &localError); + CFMutableDictionaryRef allAttributes = NULL; + CFMutableDictionaryRef metadataAttributes = NULL; + CFMutableDictionaryRef secretStuff = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + keyclass_t keyclass = 0; + bool ok = s3dl_item_from_col(stmt, q, 1, c->qc.accessGroups, &allAttributes, &access_control, &keyclass, &localError); + + if (ok) { + metadataAttributes = CFDictionaryCreateMutableCopy(NULL, 0, allAttributes); + SecDbForEachAttrWithMask(q->q_class, desc, kSecDbReturnDataFlag) { + CFTypeRef value = CFDictionaryGetValue(metadataAttributes, desc->name); + if (value) { + CFDictionarySetValue(secretStuff, desc->name, value); + CFDictionaryRemoveValue(metadataAttributes, desc->name); + } + } + } bool is_akpu = access_control ? CFEqualSafe(SecAccessControlGetProtection(access_control), - kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly) : false; - bool is_token = (ok && item != NULL) ? CFDictionaryContainsKey(item, kSecAttrTokenID) : false; + kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly) : keyclass == key_class_akpu; + bool is_token = (ok && allAttributes != NULL) ? CFDictionaryContainsKey(allAttributes, kSecAttrTokenID) : false; - if (ok && item && !(skip_akpu_or_token && (is_akpu || is_token))) { + if (ok && allAttributes && !(skip_akpu_or_token && (is_akpu || is_token))) { /* Only export sysbound items if do_sys_bound is true, only export non sysbound items otherwise. */ bool do_sys_bound = c->filter == kSecSysBoundItemFilter; if (c->filter == kSecNoItemFilter || - SecItemIsSystemBound(item, q->q_class, c->multiUser) == do_sys_bound) { + SecItemIsSystemBound(allAttributes, q->q_class, c->multiUser) == do_sys_bound) { /* Re-encode the item. */ - secdebug("item", "export rowid %llu item: %@", rowid, item); + secdebug("item", "export rowid %llu item: %@", rowid, allAttributes); /* The code below could be moved into handle_row. */ - CFDataRef pref = _SecItemCreatePersistentRef(q->q_class->name, rowid, item); + CFDataRef pref = _SecItemCreatePersistentRef(q->q_class->name, rowid, allAttributes); if (pref) { if (c->dest_keybag != KEYBAG_NONE) { CFMutableDictionaryRef auth_attribs = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); SecDbForEachAttrWithMask(q->q_class, desc, kSecDbInAuthenticatedDataFlag) { - CFTypeRef value = CFDictionaryGetValue(item, desc->name); + CFTypeRef value = CFDictionaryGetValue(metadataAttributes, desc->name); if(value) { CFDictionaryAddValue(auth_attribs, desc->name, value); - CFDictionaryRemoveValue(item, desc->name); + CFDictionaryRemoveValue(metadataAttributes, desc->name); } } /* Encode and encrypt the item to the specified keybag. */ CFDataRef edata = NULL; - bool encrypted = ks_encrypt_data(c->dest_keybag, access_control, q->q_use_cred_handle, item, auth_attribs, &edata, false, &q->q_error); - CFDictionaryRemoveAllValues(item); + bool encrypted = ks_encrypt_data(c->dest_keybag, access_control, q->q_use_cred_handle, secretStuff, metadataAttributes, auth_attribs, &edata, false, &q->q_error); + CFDictionaryRemoveAllValues(allAttributes); CFRelease(auth_attribs); if (encrypted) { - CFDictionarySetValue(item, kSecValueData, edata); + CFDictionarySetValue(allAttributes, kSecValueData, edata); CFReleaseSafe(edata); } else { seccritical("ks_encrypt_data %@,rowid=%" PRId64 ": failed: %@", q->q_class->name, rowid, q->q_error); CFReleaseNull(q->q_error); } } - if (CFDictionaryGetCount(item)) { - CFDictionarySetValue(item, kSecValuePersistentRef, pref); - CFArrayAppendValue((CFMutableArrayRef)c->qc.result, item); + if (CFDictionaryGetCount(allAttributes)) { + CFDictionarySetValue(allAttributes, kSecValuePersistentRef, pref); + CFArrayAppendValue((CFMutableArrayRef)c->qc.result, allAttributes); c->qc.found++; } CFReleaseSafe(pref); } } - CFRelease(item); } else { OSStatus status = SecErrorGetOSStatus(localError); @@ -1514,7 +1566,10 @@ static void s3dl_export_row(sqlite3_stmt *stmt, void *context) { } } } - CFReleaseSafe(access_control); + CFReleaseNull(access_control); + CFReleaseNull(allAttributes); + CFReleaseNull(metadataAttributes); + CFReleaseNull(secretStuff); } static CFStringRef @@ -1600,8 +1655,10 @@ SecServerCopyKeychainPlist(SecDbConnectionRef dbt, CFErrorRef localError = NULL; if (s3dl_query(s3dl_export_row, &ctx, &localError)) { - if (CFArrayGetCount(ctx.qc.result)) + if (CFArrayGetCount(ctx.qc.result)) { + SecSignpostBackupCount(SecSignpostImpulseBackupClassCount, q.q_class->name, CFArrayGetCount(ctx.qc.result), filter); CFDictionaryAddValue(keychain, q.q_class->name, ctx.qc.result); + } } else { OSStatus status = (OSStatus)CFErrorGetCode(localError); @@ -1819,11 +1876,13 @@ static void SecServerImportClass(const void *key, const void *value, if (isArray(value)) { CFArrayRef items = (CFArrayRef)value; secwarning("Import %ld items of class %@ (filter %d)", (long)CFArrayGetCount(items), key, state->filter); + SecSignpostBackupCount(SecSignpostImpulseRestoreClassCount, class->name, CFArrayGetCount(items), state->filter); CFArrayApplyFunction(items, CFRangeMake(0, CFArrayGetCount(items)), SecServerImportItem, &item_state); } else if (isDictionary(value)) { CFDictionaryRef item = (CFDictionaryRef)value; - secwarning("Import %ld items of class %@ (filter %d)", (long)CFDictionaryGetCount(item), key, state->filter); + secwarning("Import %ld items of class %@ (filter %d)", (long)1, key, state->filter); + SecSignpostBackupCount(SecSignpostImpulseRestoreClassCount, class->name, 1, state->filter); SecServerImportItem(item, &item_state); } else { secwarning("Unknown value type for class %@ (filter %d)", key, state->filter); @@ -1831,8 +1890,9 @@ static void SecServerImportClass(const void *key, const void *value, } bool SecServerImportKeychainInPlist(SecDbConnectionRef dbt, SecurityClient *client, - keybag_handle_t src_keybag, keybag_handle_t dest_keybag, - CFDictionaryRef keychain, enum SecItemFilter filter, CFErrorRef *error) { + keybag_handle_t src_keybag, keybag_handle_t dest_keybag, + CFDictionaryRef keychain, enum SecItemFilter filter, + bool removeKeychainContent, CFErrorRef *error) { CFStringRef keybaguuid = NULL; bool ok = true; @@ -1858,17 +1918,22 @@ bool SecServerImportKeychainInPlist(SecDbConnectionRef dbt, SecurityClient *clie } } - /* Delete everything in the keychain. */ + /* + Delete everything in the keychain. + We don't want this if we're restoring backups because we probably already synced stuff over + */ + if (removeKeychainContent) { #if TARGET_OS_IPHONE - if (client->inMultiUser) { - CFDataRef musrView = SecMUSRCreateActiveUserUUID(client->uid); - require_action(musrView, errOut, ok = false); - require_action(ok = SecServerDeleteAllForUser(dbt, musrView, true, error), errOut, CFReleaseNull(musrView)); - CFReleaseNull(musrView); - } else + if (client->inMultiUser) { + CFDataRef musrView = SecMUSRCreateActiveUserUUID(client->uid); + require_action(musrView, errOut, ok = false); + require_action(ok = SecServerDeleteAllForUser(dbt, musrView, true, error), errOut, CFReleaseNull(musrView)); + CFReleaseNull(musrView); + } else #endif - { - require(ok = SecServerDeleteAll(dbt, error), errOut); + { + require(ok = SecServerDeleteAll(dbt, error), errOut); + } } struct SecServerImportClassState state = { @@ -2020,8 +2085,9 @@ bool s3dl_dbt_update_keys(SecDbConnectionRef dbt, SecurityClient *client, CFErro secerror("Ignoring export error: %@ during roll export", localError); CFReleaseNull(localError); } + // 'true' argument: we're replacing everything with newly wrapped entries so remove the old stuff ok = SecServerImportKeychainInPlist(dbt, client, KEYBAG_NONE, - KEYBAG_DEVICE, backup, kSecNoItemFilter, &localError); + KEYBAG_DEVICE, backup, kSecNoItemFilter, true, &localError); if (localError) { secerror("Ignoring export error: %@ during roll export", localError); CFReleaseNull(localError); diff --git a/OSX/sec/securityd/SecItemDb.h b/OSX/sec/securityd/SecItemDb.h index 6d91d921..9cca3299 100644 --- a/OSX/sec/securityd/SecItemDb.h +++ b/OSX/sec/securityd/SecItemDb.h @@ -83,6 +83,7 @@ bool SecServerImportKeychainInPlist(SecDbConnectionRef dbt, keybag_handle_t dest_keybag, CFDictionaryRef keychain, enum SecItemFilter filter, + bool removeKeychainContent, CFErrorRef *error); CFStringRef @@ -93,8 +94,8 @@ SecServerBackupGetKeybagUUID(CFDictionaryRef keychain, CFErrorRef *error); bool SecServerDeleteAllForUser(SecDbConnectionRef dbt, CFDataRef musrView, bool keepU, CFErrorRef *error); #endif -bool kc_transaction(SecDbConnectionRef dbt, CFErrorRef *error, bool(^perform)()); -bool kc_transaction_type(SecDbConnectionRef dbt, SecDbTransactionType type, CFErrorRef *error, bool(^perform)()); +bool kc_transaction(SecDbConnectionRef dbt, CFErrorRef *error, bool(^perform)(void)); +bool kc_transaction_type(SecDbConnectionRef dbt, SecDbTransactionType type, CFErrorRef *error, bool(^perform)(void)); bool s3dl_copy_matching(SecDbConnectionRef dbt, Query *q, CFTypeRef *result, CFArrayRef accessGroups, CFErrorRef *error); bool s3dl_query_add(SecDbConnectionRef dbt, Query *q, CFTypeRef *result, CFErrorRef *error); diff --git a/OSX/sec/securityd/SecItemSchema.c b/OSX/sec/securityd/SecItemSchema.c index 069180a2..f3605330 100644 --- a/OSX/sec/securityd/SecItemSchema.c +++ b/OSX/sec/securityd/SecItemSchema.c @@ -234,6 +234,51 @@ SECDB_ATTR(v10_5epoch, "epoch", Number, SecDbFlags( ,L, , , , SECDB_ATTR(v10_5signature, "signature", Blob, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); SECDB_ATTR(v10_5version, "version", Number, SecDbFlags( ,L, , , , , , , , ,Z, ,N,U, , ), NULL, NULL); +SECDB_ATTR(v11_1osversion, "osversion", String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); +SECDB_ATTR(v11_1lastunlock, "lastunlock", String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); + +SECDB_ATTR(v11_2actualKeyclass, "actualKeyclass", String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); + +const SecDbClass v11_2_metadatakeys_class = { + .name = CFSTR("metadatakeys"), + .itemclass = false, + .attrs = { + &v10keyclass, + &v11_2actualKeyclass, + &v6data, + 0 + } +}; + +const SecDbClass v11_1_ckdevicestate_class = { + .name = CFSTR("ckdevicestate"), + .itemclass = false, + .attrs = { + &v10ckzone, + &v10_2device, + &v11_1osversion, + &v11_1lastunlock, + &v10_2peerid, + &v10_2circleStatus, + &v10_2keyState, + &v10_2currentTLK, + &v10_2currentClassA, + &v10_2currentClassC, + &v10_1encRecord, + 0 + } +}; + +const SecDbClass v11_metadatakeys_class = { + .name = CFSTR("metadatakeys"), + .itemclass = false, + .attrs = { + &v10keyclass, + &v6data, + 0 + } +}; + const SecDbClass v10_5_tlkshare_class = { .name = CFSTR("tlkshare"), .itemclass = false, @@ -894,6 +939,111 @@ const SecDbClass v_identity_class = { }, }; +/* + * Version 11.2 + */ +const SecDbSchema v11_2_schema = { + .majorVersion = 11, + .minorVersion = 2, + .classes = { + &v10_1_genp_class, + &v10_1_inet_class, + &v10_1_cert_class, + &v10_1_keys_class, + &v10_0_tversion_class, + &v10_2_outgoing_queue_class, + &v10_2_incoming_queue_class, + &v10_0_sync_key_class, + &v10_1_ckmirror_class, + &v10_0_current_key_class, + &v10_4_ckstate_class, + &v10_0_item_backup_class, + &v10_0_backup_keybag_class, + &v10_2_ckmanifest_class, + &v10_2_pending_manifest_class, + &v10_1_ckmanifest_leaf_class, + &v10_1_backup_keyarchive_class, + &v10_1_current_keyarchive_class, + &v10_1_current_archived_keys_class, + &v10_1_pending_manifest_leaf_class, + &v10_4_current_item_class, + &v11_1_ckdevicestate_class, + &v10_5_tlkshare_class, + &v11_2_metadatakeys_class, + 0 + } +}; + +/* + * Version 11.1 + */ +const SecDbSchema v11_1_schema = { + .majorVersion = 11, + .minorVersion = 1, + .classes = { + &v10_1_genp_class, + &v10_1_inet_class, + &v10_1_cert_class, + &v10_1_keys_class, + &v10_0_tversion_class, + &v10_2_outgoing_queue_class, + &v10_2_incoming_queue_class, + &v10_0_sync_key_class, + &v10_1_ckmirror_class, + &v10_0_current_key_class, + &v10_4_ckstate_class, + &v10_0_item_backup_class, + &v10_0_backup_keybag_class, + &v10_2_ckmanifest_class, + &v10_2_pending_manifest_class, + &v10_1_ckmanifest_leaf_class, + &v10_1_backup_keyarchive_class, + &v10_1_current_keyarchive_class, + &v10_1_current_archived_keys_class, + &v10_1_pending_manifest_leaf_class, + &v10_4_current_item_class, + &v11_1_ckdevicestate_class, + &v10_5_tlkshare_class, + &v11_metadatakeys_class, + 0 + } +}; + +/* + * Version 11 + */ +const SecDbSchema v11_schema = { + .majorVersion = 11, + .minorVersion = 0, + .classes = { + &v10_1_genp_class, + &v10_1_inet_class, + &v10_1_cert_class, + &v10_1_keys_class, + &v10_0_tversion_class, + &v10_2_outgoing_queue_class, + &v10_2_incoming_queue_class, + &v10_0_sync_key_class, + &v10_1_ckmirror_class, + &v10_0_current_key_class, + &v10_4_ckstate_class, + &v10_0_item_backup_class, + &v10_0_backup_keybag_class, + &v10_2_ckmanifest_class, + &v10_2_pending_manifest_class, + &v10_1_ckmanifest_leaf_class, + &v10_1_backup_keyarchive_class, + &v10_1_current_keyarchive_class, + &v10_1_current_archived_keys_class, + &v10_1_pending_manifest_leaf_class, + &v10_4_current_item_class, + &v10_3_ckdevicestate_class, + &v10_5_tlkshare_class, + &v11_metadatakeys_class, + 0 + } +}; + /* * Version 10.5 @@ -929,7 +1079,6 @@ const SecDbSchema v10_5_schema = { } }; - /* * Version 10.4 */ @@ -2299,6 +2448,9 @@ static const SecDbSchema v5_schema = { SecDbSchema const * const * kc_schemas = NULL; const SecDbSchema *v10_kc_schemas[] = { + &v11_2_schema, + &v11_1_schema, + &v11_schema, &v10_5_schema, &v10_4_schema, &v10_3_schema, diff --git a/OSX/sec/securityd/SecItemServer.c b/OSX/sec/securityd/SecItemServer.c index 6c7a3871..bb61f4d5 100644 --- a/OSX/sec/securityd/SecItemServer.c +++ b/OSX/sec/securityd/SecItemServer.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #include #include @@ -45,6 +47,7 @@ #include #include #include +#include #include @@ -107,7 +110,7 @@ void SecKeychainChanged() { } /* Return the current database version in *version. */ -static bool SecKeychainDbGetVersion(SecDbConnectionRef dbt, int *version, CFErrorRef *error) +bool SecKeychainDbGetVersion(SecDbConnectionRef dbt, int *version, CFErrorRef *error) { __block bool ok = true; __block CFErrorRef localError = NULL; @@ -354,7 +357,7 @@ static bool UpgradeSchemaPhase1(SecDbConnectionRef dbt, const SecDbSchema *oldSc if (isClassD(item)) { // Decrypt the item. - ok &= SecDbItemEnsureDecrypted(item, &localError); + ok &= SecDbItemEnsureDecrypted(item, true, &localError); require_quiet(ok, out); // Delete SHA1 field from the item, so that it is newly recalculated before storing @@ -469,8 +472,13 @@ out: return ok; } +__thread SecDbConnectionRef dbt = NULL; +__thread bool isUnlocked = false; + // Goes through all tables represented by old_schema and tries to migrate all items from them into new (current version) tables. -static bool UpgradeItemPhase2(SecDbConnectionRef dbt, bool *inProgress, CFErrorRef *error) { +static bool UpgradeItemPhase2(SecDbConnectionRef inDbt, bool *inProgress, CFErrorRef *error) { + SecDbConnectionRef oldDbt = dbt; + dbt = inDbt; __block bool ok = true; SecDbQueryRef query = NULL; #if TARGET_OS_EMBEDDED @@ -498,7 +506,7 @@ static bool UpgradeItemPhase2(SecDbConnectionRef dbt, bool *inProgress, CFErrorR query_destroy(query, NULL); } require_action_quiet(query = query_create(*class, SecMUSRGetAllViews(), NULL, error), out, ok = false); - ok = SecDbItemSelect(query, dbt, error, NULL, ^bool(const SecDbAttr *attr) { + ok &= SecDbItemSelect(query, dbt, error, NULL, ^bool(const SecDbAttr *attr) { // No simple per-attribute filtering. return false; }, ^bool(CFMutableStringRef sql, bool *needWhere) { @@ -517,7 +525,7 @@ static bool UpgradeItemPhase2(SecDbConnectionRef dbt, bool *inProgress, CFErrorR #endif // Decrypt the item. - if (SecDbItemEnsureDecrypted(item, &localError)) { + if (SecDbItemEnsureDecrypted(item, true, &localError)) { // Delete SHA1 field from the item, so that it is newly recalculated before storing // the item into the new table. @@ -541,11 +549,16 @@ static bool UpgradeItemPhase2(SecDbConnectionRef dbt, bool *inProgress, CFErrorR CFIndex status = CFErrorGetCode(localError); switch (status) { - case errSecDecode: + case errSecDecode: { // Items producing errSecDecode are silently dropped - they are not decodable and lost forever. - (void)SecDbItemDelete(item, dbt, false, error); + // make sure we use a local error so that this error is not proppaged upward and cause a + // migration failure. + CFErrorRef deleteError = NULL; + (void)SecDbItemDelete(item, dbt, false, &deleteError); + CFReleaseNull(deleteError); ok = true; break; + } case errSecInteractionNotAllowed: // If we are still not able to decrypt the item because the class key is not released yet, // remember that DB still needs phase2 migration to be run next time a connection is made. Also @@ -560,11 +573,24 @@ static bool UpgradeItemPhase2(SecDbConnectionRef dbt, bool *inProgress, CFErrorR // ACM context, which we do not have). ok = true; break; + case SQLITE_CONSTRAINT: // yeah... + if (!CFEqual(kSecDbErrorDomain, CFErrorGetDomain(localError))) { + secerror("Received SQLITE_CONSTRAINT with wrong error domain. Huh? Item: %@, error: %@", item, localError); + break; + } + case errSecDuplicateItem: + // continue to upgrade and don't propagate errors for insert failures + // that are typical of a single item failure + secnotice("upgr", "Ignoring duplicate item: %@", item); + secdebug("upgr", "Duplicate item error: %@", localError); + ok = true; + break; #if USE_KEYSTORE case kAKSReturnNotReady: case kAKSReturnTimeout: #endif case errSecNotAvailable: + *inProgress = true; // We're not done, call me again later! secnotice("upgr", "Bailing in phase 2 because AKS is unavailable: %@", localError); // FALLTHROUGH default: @@ -589,6 +615,8 @@ static bool UpgradeItemPhase2(SecDbConnectionRef dbt, bool *inProgress, CFErrorR out: if (query != NULL) query_destroy(query, NULL); + + dbt = oldDbt; return ok; } @@ -672,7 +700,10 @@ static bool SecKeychainDbUpgradeFromVersion(SecDbConnectionRef dbt, int version, secerror("no schema for version 0x%x", oldVersion)); secnotice("upgr", "Upgrading from version 0x%x to 0x%x", oldVersion, SCHEMA_VERSION(newSchema)); + SecSignpostStart(SecSignpostUpgradePhase1); + require_action(ok = UpgradeSchemaPhase1(dbt, oldSchema, &localError), out, secerror("upgrade: Upgrade phase1 failed: %@", localError)); + SecSignpostStop(SecSignpostUpgradePhase1); didPhase1 = true; } @@ -680,7 +711,9 @@ static bool SecKeychainDbUpgradeFromVersion(SecDbConnectionRef dbt, int version, { CFErrorRef phase2Error = NULL; - // Lests try to go through non-D-class items in new tables and apply decode/encode on them + SecSignpostStart(SecSignpostUpgradePhase2); + + // Lets try to go through non-D-class items in new tables and apply decode/encode on them // If this fails the error will be ignored after doing a phase1 since but not in the second // time when we are doing phase2. ok = UpgradeItemPhase2(dbt, inProgress, &phase2Error); @@ -688,11 +721,11 @@ static bool SecKeychainDbUpgradeFromVersion(SecDbConnectionRef dbt, int version, if (didPhase1) { *inProgress = true; ok = true; + CFReleaseNull(phase2Error); } else { SecErrorPropagate(phase2Error, &localError); } } - CFReleaseNull(phase2Error); require_action(ok, out, secerror("upgrade: Upgrade phase2 (%d) failed: %@", didPhase1, localError)); if (!*inProgress) { @@ -702,6 +735,7 @@ static bool SecKeychainDbUpgradeFromVersion(SecDbConnectionRef dbt, int version, oldVersion = 0; didPhase2 = true; + SecSignpostStop(SecSignpostUpgradePhase2); } } @@ -819,6 +853,9 @@ static CF_RETURNS_RETAINED CFDataRef SecServerExportBackupableKeychain(SecDbConn SecurityClient *client, keybag_handle_t src_keybag, keybag_handle_t dest_keybag, CFErrorRef *error) { CFDataRef data_out = NULL; + + SecSignpostStart(SecSignpostBackupKeychainBackupable); + /* Export everything except the items for which SecItemIsSystemBound() returns true. */ CFDictionaryRef keychain = SecServerCopyKeychainPlist(dbt, client, @@ -830,6 +867,7 @@ static CF_RETURNS_RETAINED CFDataRef SecServerExportBackupableKeychain(SecDbConn 0, error); CFRelease(keychain); } + SecSignpostStop(SecSignpostBackupKeychainBackupable); return data_out; } @@ -844,6 +882,9 @@ static bool SecServerImportBackupableKeychain(SecDbConnectionRef dbt, return kc_transaction(dbt, error, ^{ bool ok = false; CFDictionaryRef keychain; + + SecSignpostStart(SecSignpostRestoreKeychainBackupable); + keychain = CFPropertyListCreateWithData(kCFAllocatorDefault, data, kCFPropertyListImmutable, NULL, error); @@ -855,12 +896,16 @@ static bool SecServerImportBackupableKeychain(SecDbConnectionRef dbt, dest_keybag, keychain, kSecBackupableItemFilter, + false, // Restoring backup should not remove stuff that got into the keychain before us error); } else { ok = SecError(errSecParam, error, CFSTR("import: keychain is not a dictionary")); } CFRelease(keychain); } + + SecSignpostStop(SecSignpostRestoreKeychainBackupable); + return ok; }); } @@ -869,7 +914,7 @@ static bool SecServerImportBackupableKeychain(SecDbConnectionRef dbt, /* * Similar to ks_open_keybag, but goes through MKB interface */ -static bool mkb_open_keybag(CFDataRef keybag, CFDataRef password, MKBKeyBagHandleRef *handle, CFErrorRef *error) { +static bool mkb_open_keybag(CFDataRef keybag, CFDataRef password, MKBKeyBagHandleRef *handle, bool emcs, CFErrorRef *error) { kern_return_t rc; MKBKeyBagHandleRef mkbhandle = NULL; @@ -878,12 +923,14 @@ static bool mkb_open_keybag(CFDataRef keybag, CFDataRef password, MKBKeyBagHandl return SecKernError(rc, error, CFSTR("MKBKeyBagCreateWithData failed: %d"), rc); } - if (password) { + if (!emcs) { rc = MKBKeyBagUnlock(mkbhandle, password); if (rc != kMobileKeyBagSuccess) { CFRelease(mkbhandle); return SecKernError(rc, error, CFSTR("failed to unlock bag: %d"), rc); } + } else { + secnotice("keychainbackup", "skipping keybag unlock for EMCS"); } *handle = mkbhandle; @@ -894,23 +941,31 @@ static bool mkb_open_keybag(CFDataRef keybag, CFDataRef password, MKBKeyBagHandl static CFDataRef SecServerKeychainCreateBackup(SecDbConnectionRef dbt, SecurityClient *client, CFDataRef keybag, - CFDataRef password, CFErrorRef *error) { + CFDataRef password, bool emcs, CFErrorRef *error) { CFDataRef backup = NULL; keybag_handle_t backup_keybag; + + SecSignpostStart(SecSignpostBackupOpenKeybag); + #if USE_KEYSTORE MKBKeyBagHandleRef mkbhandle = NULL; - require(mkb_open_keybag(keybag, password, &mkbhandle, error), out); + require(mkb_open_keybag(keybag, password, &mkbhandle, emcs, error), out); require_noerr(MKBKeyBagGetAKSHandle(mkbhandle, &backup_keybag), out); #else backup_keybag = KEYBAG_NONE; #endif + SecSignpostStop(SecSignpostBackupOpenKeybag); + SecSignpostStart(SecSignpostBackupKeychain); + /* Export from system keybag to backup keybag. */ backup = SecServerExportBackupableKeychain(dbt, client, KEYBAG_DEVICE, backup_keybag, error); #if USE_KEYSTORE out: + SecSignpostStop(SecSignpostBackupOpenKeybag); + if (mkbhandle) CFRelease(mkbhandle); #endif @@ -926,19 +981,26 @@ static bool SecServerKeychainRestore(SecDbConnectionRef dbt, { bool ok = false; keybag_handle_t backup_keybag; + + + SecSignpostStart(SecSignpostRestoreOpenKeybag); #if USE_KEYSTORE MKBKeyBagHandleRef mkbhandle = NULL; - require(mkb_open_keybag(keybag, password, &mkbhandle, error), out); + require(mkb_open_keybag(keybag, password, &mkbhandle, false, error), out); require_noerr(MKBKeyBagGetAKSHandle(mkbhandle, &backup_keybag), out); #else backup_keybag = KEYBAG_NONE; #endif + SecSignpostStop(SecSignpostRestoreOpenKeybag); + SecSignpostStart(SecSignpostRestoreKeychain); + /* Import from backup keybag to system keybag. */ require(SecServerImportBackupableKeychain(dbt, client, backup_keybag, KEYBAG_DEVICE, backup, error), out); ok = true; out: + SecSignpostStop(SecSignpostRestoreKeychain); #if USE_KEYSTORE if (mkbhandle) CFRelease(mkbhandle); @@ -1003,6 +1065,12 @@ SecDbRef SecKeychainDbCreate(CFStringRef path, CFErrorRef* error) { return ok; }); + if (kc) { + SecDbSetCorruptionReset(kc, ^{ + SecDbResetMetadataKeys(); + }); + } + if(error) { *error = localerror; } @@ -1069,27 +1137,28 @@ static SecDbRef kc_dbhandle(CFErrorRef* error) void SecKeychainDbReset(dispatch_block_t inbetween) { dispatch_sync(get_kc_dbhandle_dispatch(), ^{ - CFStringRef dbPath = __SecKeychainCopyPath(); - if (dbPath == NULL) - abort(); - CFReleaseNull(_kc_dbhandle); + SecDbResetMetadataKeys(); if (inbetween) inbetween(); + }); +} - CFErrorRef error = NULL; - _kc_dbhandle = SecKeychainDbCreate(dbPath, &error); +static bool checkIsUnlocked() +{ + CFErrorRef aksError = NULL; + bool locked = true; - if(error) { - secerror("error resetting database: %@", error); - } + if(!SecAKSGetIsLocked(&locked, &aksError)) { + secerror("error querying lock state: %@", aksError); + CFReleaseNull(aksError); + } - CFRelease(dbPath); - }); + return !locked; } -static SecDbConnectionRef kc_acquire_dbt(bool writeAndRead, CFErrorRef *error) { +static bool kc_acquire_dbt(bool writeAndRead, SecDbConnectionRef* dbconn, CFErrorRef *error) { SecDbRef db = kc_dbhandle(error); if (db == NULL) { if(error && !(*error)) { @@ -1097,33 +1166,65 @@ static SecDbConnectionRef kc_acquire_dbt(bool writeAndRead, CFErrorRef *error) { } return NULL; } - return SecDbConnectionAcquire(db, !writeAndRead, error); + + return SecDbConnectionAcquireRefMigrationSafe(db, !writeAndRead, dbconn, error); } /* Return a per thread dbt handle for the keychain. If create is true create the database if it does not yet exist. If it is false, just return an error if it fails to auto-create. */ -__thread SecDbConnectionRef dbt = NULL; bool kc_with_dbt(bool writeAndRead, CFErrorRef *error, bool (^perform)(SecDbConnectionRef dbt)) { + return kc_with_custom_db(writeAndRead, true, NULL, error, perform); +} + +bool kc_with_dbt_non_item_tables(bool writeAndRead, CFErrorRef* error, bool (^perform)(SecDbConnectionRef dbt)) +{ + return kc_with_custom_db(writeAndRead, false, NULL, error, perform); +} + +bool kc_with_custom_db(bool writeAndRead, bool usesItemTables, SecDbRef db, CFErrorRef *error, bool (^perform)(SecDbConnectionRef dbt)) +{ + if (db && db != kc_dbhandle(error)) { + __block bool result = false; + if (writeAndRead) { + return SecDbPerformWrite(db, error, ^(SecDbConnectionRef dbconn) { + result = perform(dbconn); + }); + } + else { + return SecDbPerformRead(db, error, ^(SecDbConnectionRef dbconn) { + result = perform(dbconn); + }); + } + return result; + } + if(dbt) { // The kc_with_dbt upthread will clean this up when it's done. return perform(dbt); } - // Make sure we initialize our engines before writing to the keychain - if (writeAndRead) + + if (writeAndRead && usesItemTables) { SecItemDataSourceFactoryGetDefault(); + } bool ok = false; - dbt = kc_acquire_dbt(writeAndRead, error); - if (dbt) { + if (kc_acquire_dbt(writeAndRead, &dbt, error)) { + isUnlocked = checkIsUnlocked(); ok = perform(dbt); SecDbConnectionRelease(dbt); dbt = NULL; + isUnlocked = false; } return ok; } +bool kc_is_unlocked() +{ + return isUnlocked || checkIsUnlocked(); +} + static bool items_matching_issuer_parent(SecDbConnectionRef dbt, CFArrayRef accessGroups, CFDataRef musrView, CFDataRef issuer, CFArrayRef issuers, int recurse) @@ -1429,7 +1530,9 @@ SecItemServerCopyMatching(CFDictionaryRef query, CFTypeRef *result, SecTaskDiagnoseEntitlements(accessGroups); return SecEntitlementError(errSecMissingEntitlement, error); } - + + SecSignpostStart(SecSignpostSecItemCopyMatching); + if (client->canAccessNetworkExtensionAccessGroups) { CFDataRef persistentRef = CFDictionaryGetValue(query, kSecValuePersistentRef); CFStringRef itemClass = NULL; @@ -1508,6 +1611,8 @@ SecItemServerCopyMatching(CFDictionaryRef query, CFTypeRef *result, } CFReleaseNull(mutableAccessGroups); + SecSignpostStop(SecSignpostSecItemCopyMatching); + return ok; } @@ -1552,6 +1657,8 @@ _SecItemAdd(CFDictionaryRef attributes, SecurityClient *client, CFTypeRef *resul return SecEntitlementError(errSecMissingEntitlement, error); } + SecSignpostStart(SecSignpostSecItemAdd); + Query *q = query_create_with_limit(attributes, client->musr, 0, error); if (q) { /* Access group sanity checking. */ @@ -1631,6 +1738,9 @@ _SecItemAdd(CFDictionaryRef attributes, SecurityClient *client, CFTypeRef *resul } else { ok = false; } + + SecSignpostStop(SecSignpostSecItemAdd); + return ok; } @@ -1651,6 +1761,8 @@ _SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate, return SecEntitlementError(errSecMissingEntitlement, error); } + SecSignpostStart(SecSignpostSecItemUpdate); + if (SecPLShouldLogRegisteredEvent(CFSTR("SecItem"))) { CFTypeRef agrp = CFArrayGetValueAtIndex(accessGroups, 0); CFDictionaryRef dict = CFDictionaryCreateForCFTypes(NULL, CFSTR("operation"), CFSTR("update"), CFSTR("AccessGroup"), agrp, NULL); @@ -1727,6 +1839,9 @@ _SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate, if (q) { ok = query_notify_and_destroy(q, ok, error); } + + SecSignpostStop(SecSignpostSecItemUpdate); + return ok; } @@ -1746,6 +1861,8 @@ _SecItemDelete(CFDictionaryRef query, SecurityClient *client, CFErrorRef *error) return SecEntitlementError(errSecMissingEntitlement, error); } + SecSignpostStart(SecSignpostSecItemDelete); + if (SecPLShouldLogRegisteredEvent(CFSTR("SecItem"))) { CFTypeRef agrp = CFArrayGetValueAtIndex(accessGroups, 0); CFDictionaryRef dict = CFDictionaryCreateForCFTypes(NULL, CFSTR("operation"), CFSTR("delete"), CFSTR("AccessGroup"), agrp, NULL); @@ -1799,6 +1916,9 @@ _SecItemDelete(CFDictionaryRef query, SecurityClient *client, CFErrorRef *error) } else { ok = false; } + + SecSignpostStop(SecSignpostSecItemDelete); + return ok; } @@ -2713,7 +2833,7 @@ cleanup: // MARK: Keychain backup CF_RETURNS_RETAINED CFDataRef -_SecServerKeychainCreateBackup(SecurityClient *client, CFDataRef keybag, CFDataRef passcode, CFErrorRef *error) { +_SecServerKeychainCreateBackup(SecurityClient *client, CFDataRef keybag, CFDataRef passcode, bool emcs, CFErrorRef *error) { __block CFDataRef backup; kc_with_dbt(true, error, ^bool (SecDbConnectionRef dbt) { if (!dbt) @@ -2728,7 +2848,7 @@ _SecServerKeychainCreateBackup(SecurityClient *client, CFDataRef keybag, CFDataR backup = NULL; #endif /* USE_KEYSTORE */ } else { - backup = SecServerKeychainCreateBackup(dbt, client, keybag, passcode, error); + backup = SecServerKeychainCreateBackup(dbt, client, keybag, passcode, emcs, error); } return (backup != NULL); }); @@ -3559,7 +3679,6 @@ _SecServerTransmogrifyToSystemKeychain(SecurityClient *client, CFErrorRef *error out: SecErrorPropagate(localError, error); - CFReleaseSafe(localError); }); if (q) diff --git a/OSX/sec/securityd/SecItemServer.h b/OSX/sec/securityd/SecItemServer.h index a4196ce0..f3e147b6 100644 --- a/OSX/sec/securityd/SecItemServer.h +++ b/OSX/sec/securityd/SecItemServer.h @@ -49,7 +49,7 @@ bool _SecItemServerDeleteAllWithAccessGroups(CFArrayRef accessGroups, SecurityCl bool _SecServerRestoreKeychain(CFErrorRef *error); bool _SecServerMigrateKeychain(int32_t handle_in, CFDataRef data_in, int32_t *handle_out, CFDataRef *data_out, CFErrorRef *error); -CFDataRef _SecServerKeychainCreateBackup(SecurityClient *client, CFDataRef keybag, CFDataRef passcode, CFErrorRef *error); +CFDataRef _SecServerKeychainCreateBackup(SecurityClient *client, CFDataRef keybag, CFDataRef passcode, bool emcs, CFErrorRef *error); bool _SecServerKeychainRestore(CFDataRef backup, SecurityClient *client, CFDataRef keybag, CFDataRef passcode, CFErrorRef *error); CFStringRef _SecServerBackupCopyUUID(CFDataRef backup, CFErrorRef *error); @@ -84,6 +84,9 @@ SecDbRef SecKeychainDbCreate(CFStringRef path, CFErrorRef* error); SecDbRef SecKeychainDbInitialize(SecDbRef db); bool kc_with_dbt(bool writeAndRead, CFErrorRef *error, bool (^perform)(SecDbConnectionRef dbt)); +bool kc_with_dbt_non_item_tables(bool writeAndRead, CFErrorRef* error, bool (^perform)(SecDbConnectionRef dbt)); // can be used when only tables which don't store 'items' are accessed - avoids invoking SecItemDataSourceFactoryGetDefault() +bool kc_with_custom_db(bool writeAndRead, bool usesItemTables, SecDbRef db, CFErrorRef *error, bool (^perform)(SecDbConnectionRef dbt)); +bool kc_is_unlocked(void); /* For whitebox testing only */ @@ -125,6 +128,8 @@ bool _SecServerGetKeyStats(const SecDbClass *qclass, struct _SecServerKeyStats * CF_RETURNS_RETAINED CFArrayRef _SecItemCopyParentCertificates(CFDataRef normalizedIssuer, CFArrayRef accessGroups, CFErrorRef *error); bool _SecItemCertificateExists(CFDataRef normalizedIssuer, CFDataRef serialNumber, CFArrayRef accessGroups, CFErrorRef *error); +bool SecKeychainDbGetVersion(SecDbConnectionRef dbt, int *version, CFErrorRef *error); + // Should all be blocks called from SecItemDb bool match_item(SecDbConnectionRef dbt, Query *q, CFArrayRef accessGroups, CFDictionaryRef item); diff --git a/OSX/sec/securityd/SecKeybagSupport.c b/OSX/sec/securityd/SecKeybagSupport.c index d20ea19f..ed026e45 100644 --- a/OSX/sec/securityd/SecKeybagSupport.c +++ b/OSX/sec/securityd/SecKeybagSupport.c @@ -181,7 +181,7 @@ bool ks_crypt(CFTypeRef operation, keybag_handle_t keybag, } #if USE_KEYSTORE -static bool ks_access_control_needed_error(CFErrorRef *error, CFDataRef access_control_data, CFTypeRef operation) { +bool ks_access_control_needed_error(CFErrorRef *error, CFDataRef access_control_data, CFTypeRef operation) { if (error == NULL) return false; @@ -268,7 +268,7 @@ bool ks_separate_data_and_key(CFDictionaryRef blob_dict, CFDataRef *ed_data, CFD return ok; } -static bool create_cferror_from_aks(int aks_return, CFTypeRef operation, keybag_handle_t keybag, keyclass_t keyclass, CFDataRef access_control_data, CFDataRef acm_context_data, CFErrorRef *error) +bool create_cferror_from_aks(int aks_return, CFTypeRef operation, keybag_handle_t keybag, keyclass_t keyclass, CFDataRef access_control_data, CFDataRef acm_context_data, CFErrorRef *error) { const char *operation_string = ""; if (CFEqual(operation, kAKSKeyOpDecrypt)) { diff --git a/OSX/sec/securityd/SecKeybagSupport.h b/OSX/sec/securityd/SecKeybagSupport.h index 565952c0..6f48990d 100644 --- a/OSX/sec/securityd/SecKeybagSupport.h +++ b/OSX/sec/securityd/SecKeybagSupport.h @@ -83,6 +83,9 @@ bool ks_delete_acl(aks_ref_key_t ref_key, CFDataRef encrypted_data, const void* ks_ref_key_get_external_data(keybag_handle_t keybag, CFDataRef key_data, aks_ref_key_t *ref_key, size_t *external_data_len, CFErrorRef *error); bool ks_separate_data_and_key(CFDictionaryRef blob_dict, CFDataRef *ed_data, CFDataRef *key_data); + +bool ks_access_control_needed_error(CFErrorRef *error, CFDataRef access_control_data, CFTypeRef operation); +bool create_cferror_from_aks(int aks_return, CFTypeRef operation, keybag_handle_t keybag, keyclass_t keyclass, CFDataRef access_control_data, CFDataRef acm_context_data, CFErrorRef *error); #endif bool ks_open_keybag(CFDataRef keybag, CFDataRef password, keybag_handle_t *handle, CFErrorRef *error); bool ks_close_keybag(keybag_handle_t keybag, CFErrorRef *error); diff --git a/OSX/sec/securityd/SecOCSPCache.c b/OSX/sec/securityd/SecOCSPCache.c index 7e109eaf..1aaf7abf 100644 --- a/OSX/sec/securityd/SecOCSPCache.c +++ b/OSX/sec/securityd/SecOCSPCache.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010,2012-2015 Apple Inc. All Rights Reserved. + * Copyright (c) 2009-2010,2012-2017 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,7 @@ #include #include #include +#include "utilities/SecCFWrappers.h" #include "utilities/SecDb.h" #include "utilities/SecFileLocations.h" #include "utilities/iOSforOSX.h" @@ -44,6 +46,7 @@ /* Note that lastUsed is actually time of insert because we don't refresh lastUsed on each SELECT. */ +#define flushSQL CFSTR("DELETE FROM responses") #define expireSQL CFSTR("DELETE FROM responses WHERE expires= 0) { - ok = SecDbWithSQL(dbconn, deleteResponseSQL, &localError, ^bool(sqlite3_stmt *deleteResponse) { - ok = SecDbBindInt64(deleteResponse, 1, responseId, &localError); + ok &= SecDbWithSQL(dbconn, deleteResponseSQL, &localError, ^bool(sqlite3_stmt *deleteResponse) { + ok &= SecDbBindInt64(deleteResponse, 1, responseId, &localError); /* Execute the delete statement. */ - if (ok) - ok = SecDbStep(dbconn, deleteResponse, &localError, NULL); + ok &= SecDbStep(dbconn, deleteResponse, &localError, NULL); return ok; }); } - if (ok) ok = SecDbWithSQL(dbconn, insertResponseSQL, &localError, ^bool(sqlite3_stmt *insertResponse) { - if (ok) - ok = SecDbBindBlob(insertResponse, 1, - CFDataGetBytePtr(responseData), - CFDataGetLength(responseData), - SQLITE_TRANSIENT, &localError); + ok &= SecDbWithSQL(dbconn, insertResponseSQL, &localError, ^bool(sqlite3_stmt *insertResponse) { + ok &= SecDbBindBlob(insertResponse, 1, + CFDataGetBytePtr(responseData), + CFDataGetLength(responseData), + SQLITE_TRANSIENT, &localError); /* responses.responderURI */ if (ok) { @@ -231,72 +240,73 @@ static void _SecOCSPCacheReplaceResponse(SecOCSPCacheRef this, } } /* responses.expires */ - if (ok) - ok = SecDbBindDouble(insertResponse, 3, - SecOCSPResponseGetExpirationTime(ocspResponse), - &localError); + ok &= SecDbBindDouble(insertResponse, 3, + SecOCSPResponseGetExpirationTime(ocspResponse), + &localError); /* responses.lastUsed */ - if (ok) - ok = SecDbBindDouble(insertResponse, 4, - verifyTime, - &localError); + ok &= SecDbBindDouble(insertResponse, 4, + verifyTime, + &localError); /* Execute the insert statement. */ - if (ok) - ok = SecDbStep(dbconn, insertResponse, &localError, NULL); + ok &= SecDbStep(dbconn, insertResponse, &localError, NULL); responseId = sqlite3_last_insert_rowid(SecDbHandle(dbconn)); return ok; }); /* Now add a link record for every singleResponse in the ocspResponse. */ - if (ok) ok = SecDbWithSQL(dbconn, insertLinkSQL, &localError, ^bool(sqlite3_stmt *insertLink) { + ok &= SecDbWithSQL(dbconn, insertLinkSQL, &localError, ^bool(sqlite3_stmt *insertLink) { SecAsn1OCSPSingleResponse **responses; for (responses = ocspResponse->responseData.responses; *responses; ++responses) { SecAsn1OCSPSingleResponse *resp = *responses; SecAsn1OCSPCertID *certId = &resp->certID; - if (ok) ok = SecDbBindBlob(insertLink, 1, - certId->algId.algorithm.Data, - certId->algId.algorithm.Length, - SQLITE_TRANSIENT, &localError); - if (ok) ok = SecDbBindBlob(insertLink, 2, - certId->issuerNameHash.Data, - certId->issuerNameHash.Length, - SQLITE_TRANSIENT, &localError); - if (ok) ok = SecDbBindBlob(insertLink, 3, - certId->issuerPubKeyHash.Data, - certId->issuerPubKeyHash.Length, - SQLITE_TRANSIENT, &localError); - if (ok) ok = SecDbBindBlob(insertLink, 4, - certId->serialNumber.Data, - certId->serialNumber.Length, - SQLITE_TRANSIENT, &localError); - if (ok) ok = SecDbBindInt64(insertLink, 5, responseId, &localError); + ok &= SecDbBindBlob(insertLink, 1, + certId->algId.algorithm.Data, + certId->algId.algorithm.Length, + SQLITE_TRANSIENT, &localError); + ok &= SecDbBindBlob(insertLink, 2, + certId->issuerNameHash.Data, + certId->issuerNameHash.Length, + SQLITE_TRANSIENT, &localError); + ok &= SecDbBindBlob(insertLink, 3, + certId->issuerPubKeyHash.Data, + certId->issuerPubKeyHash.Length, + SQLITE_TRANSIENT, &localError); + ok &= SecDbBindBlob(insertLink, 4, + certId->serialNumber.Data, + certId->serialNumber.Length, + SQLITE_TRANSIENT, &localError); + ok &= SecDbBindInt64(insertLink, 5, responseId, &localError); /* Execute the insert statement. */ - if (ok) ok = SecDbStep(dbconn, insertLink, &localError, NULL); - if (ok) ok = SecDbReset(insertLink, &localError); + ok &= SecDbStep(dbconn, insertLink, &localError, NULL); + ok &= SecDbReset(insertLink, &localError); } return ok; }); // Remove expired entries here. // TODO: Consider only doing this once per 24 hours or something. - if (ok) ok = _SecOCSPCacheExpireWithTransaction(dbconn, verifyTime, &localError); + ok &= _SecOCSPCacheExpireWithTransaction(dbconn, verifyTime, &localError); if (!ok) *commit = false; }); }); if (!ok) { secerror("_SecOCSPCacheAddResponse failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TAOCSPCache, TAOperationWrite, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); CFReleaseNull(localError); } else { // force a vacuum when we modify the database ok &= SecDbPerformWrite(this->db, &localError, ^(SecDbConnectionRef dbconn) { - ok = SecDbExec(dbconn, CFSTR("VACUUM"), &localError); + ok &= SecDbExec(dbconn, CFSTR("VACUUM"), &localError); if (!ok) { secerror("_SecOCSPCacheAddResponse VACUUM failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TAOCSPCache, TAOperationWrite, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); } }); } @@ -338,16 +348,16 @@ static SecOCSPResponseRef _SecOCSPCacheCopyMatching(SecOCSPCacheRef this, if (issuerNameHash && issuerPubKeyHash && ok) ok &= SecDbWithSQL(dbconn, selectResponseSQL, &localError, ^bool(sqlite3_stmt *selectResponse) { /* Now we have the serial, algorithm, issuerNameHash and issuerPubKeyHash so let's lookup the db entry. */ - if (ok) ok = SecDbBindDouble(selectResponse, 1, minInsertTime, &localError); - if (ok) ok = SecDbBindBlob(selectResponse, 2, CFDataGetBytePtr(issuerNameHash), - CFDataGetLength(issuerNameHash), SQLITE_TRANSIENT, &localError); - if (ok) ok = SecDbBindBlob(selectResponse, 3, CFDataGetBytePtr(issuerPubKeyHash), - CFDataGetLength(issuerPubKeyHash), SQLITE_TRANSIENT, &localError); - if (ok) ok = SecDbBindBlob(selectResponse, 4, CFDataGetBytePtr(serial), - CFDataGetLength(serial), SQLITE_TRANSIENT, &localError); - if (ok) ok = SecDbBindBlob(selectResponse, 5, algorithm.Data, - algorithm.Length, SQLITE_TRANSIENT, &localError); - if (ok) ok &= SecDbStep(dbconn, selectResponse, &localError, ^(bool *stopResponse) { + ok &= SecDbBindDouble(selectResponse, 1, minInsertTime, &localError); + ok &= SecDbBindBlob(selectResponse, 2, CFDataGetBytePtr(issuerNameHash), + CFDataGetLength(issuerNameHash), SQLITE_TRANSIENT, &localError); + ok &= SecDbBindBlob(selectResponse, 3, CFDataGetBytePtr(issuerPubKeyHash), + CFDataGetLength(issuerPubKeyHash), SQLITE_TRANSIENT, &localError); + ok &= SecDbBindBlob(selectResponse, 4, CFDataGetBytePtr(serial), + CFDataGetLength(serial), SQLITE_TRANSIENT, &localError); + ok &= SecDbBindBlob(selectResponse, 5, algorithm.Data, + algorithm.Length, SQLITE_TRANSIENT, &localError); + ok &= SecDbStep(dbconn, selectResponse, &localError, ^(bool *stopResponse) { /* Found an entry! */ secdebug("ocspcache", "found cached response"); CFDataRef resp = CFDataCreate(kCFAllocatorDefault, @@ -383,12 +393,14 @@ errOut: CFReleaseSafe(serial); CFReleaseSafe(issuer); - if (!ok) { + if (!ok || localError) { secerror("ocsp cache lookup failed: %@", localError); if (response) { SecOCSPResponseFinalize(response); response = NULL; } + TrustdHealthAnalyticsLogErrorCodeForDatabase(TAOCSPCache, TAOperationRead, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); } CFReleaseSafe(localError); @@ -397,6 +409,22 @@ errOut: return response; } +static bool _SecOCSPCacheFlush(SecOCSPCacheRef cache, CFErrorRef *error) { + __block CFErrorRef localError = NULL; + __block bool ok = true; + + ok &= SecDbPerformWrite(cache->db, &localError, ^(SecDbConnectionRef dbconn) { + ok &= SecDbExec(dbconn, flushSQL, &localError); + }); + if (!ok || localError) { + TrustdHealthAnalyticsLogErrorCodeForDatabase(TAOCSPCache, TAOperationWrite, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); + } + (void) CFErrorPropagate(localError, error); + + return ok; +} + /* Public API */ @@ -424,3 +452,11 @@ SecOCSPResponseRef SecOCSPCacheCopyMatchingWithMinInsertTime(SecOCSPRequestRef r }); return response; } + +bool SecOCSPCacheFlush(CFErrorRef *error) { + __block bool result = false; + SecOCSPCacheWith(^(SecOCSPCacheRef cache) { + result = _SecOCSPCacheFlush(cache, error); + }); + return result; +} diff --git a/OSX/sec/securityd/SecOCSPCache.h b/OSX/sec/securityd/SecOCSPCache.h index f0011134..0069a502 100644 --- a/OSX/sec/securityd/SecOCSPCache.h +++ b/OSX/sec/securityd/SecOCSPCache.h @@ -1,15 +1,15 @@ /* - * Copyright (c) 2009-2010,2012-2014 Apple Inc. All Rights Reserved. + * Copyright (c) 2009-2010,2012-2017 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -17,7 +17,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_LICENSE_HEADER_END@ * */ @@ -47,6 +47,8 @@ SecOCSPResponseRef SecOCSPCacheCopyMatching(SecOCSPRequestRef request, SecOCSPResponseRef SecOCSPCacheCopyMatchingWithMinInsertTime(SecOCSPRequestRef request, CFURLRef localResponderURI, CFAbsoluteTime minInsertTime); +bool SecOCSPCacheFlush(CFErrorRef *error); + __END_DECLS #endif /* _SECURITY_SECOCSPCACHE_H_ */ diff --git a/OSX/sec/securityd/SecOCSPResponse.c b/OSX/sec/securityd/SecOCSPResponse.c index 784c65df..ba5634d9 100644 --- a/OSX/sec/securityd/SecOCSPResponse.c +++ b/OSX/sec/securityd/SecOCSPResponse.c @@ -217,7 +217,6 @@ bool SecOCSPResponseCalculateValidity(SecOCSPResponseRef this, { bool ok = false; this->latestNextUpdate = NULL_TIME; - CFStringRef hexResp = CFDataCopyHexString(this->data); if (this->producedAt > verifyTime + LEEWAY) { secnotice("ocsp", "OCSPResponse: producedAt more than 1:15 from now"); @@ -310,8 +309,12 @@ bool SecOCSPResponseCalculateValidity(SecOCSPResponseRef this, } else { /* maxAge http header attempting to make us cache the response longer than it's valid for, bad http header! Ignoring you. */ +#ifdef DEBUG + CFStringRef hexResp = CFDataCopyHexString(this->data); ocspdDebug("OCSPResponse: now + maxAge > latestNextUpdate," " using latestNextUpdate %@", hexResp); + CFReleaseSafe(hexResp); +#endif this->expireTime = this->latestNextUpdate; } } else { @@ -321,12 +324,10 @@ bool SecOCSPResponseCalculateValidity(SecOCSPResponseRef this, ok = true; exit: - CFReleaseSafe(hexResp); return ok; } SecOCSPResponseRef SecOCSPResponseCreateWithID(CFDataRef ocspResponse, int64_t responseID) { - CFStringRef hexResp = CFDataCopyHexString(ocspResponse); SecAsn1OCSPResponse topResp = {}; SecOCSPResponseRef this; @@ -353,8 +354,12 @@ SecOCSPResponseRef SecOCSPResponseCreateWithID(CFDataRef ocspResponse, int64_t r } this->responseStatus = topResp.responseStatus.Data[0]; if (this->responseStatus != kSecOCSPSuccess) { - secdebug("ocsp", "OCSPResponse: status: %d %@", this->responseStatus, hexResp); - /* not a failure of our constructor; this object is now useful, but +#ifdef DEBUG + CFStringRef hexResp = CFDataCopyHexString(this->data); + secdebug("ocsp", "OCSPResponse: status: %d %@", this->responseStatus, hexResp); + CFReleaseNull(hexResp); +#endif + /* not a failure of our constructor; this object is now useful, but * only for this one byte of status info */ goto fini; } @@ -420,11 +425,15 @@ SecOCSPResponseRef SecOCSPResponseCreateWithID(CFDataRef ocspResponse, int64_t r } fini: - CFReleaseSafe(hexResp); return this; errOut: - secdebug("ocsp", "bad ocsp response: %@", hexResp); - CFReleaseSafe(hexResp); +#ifdef DEBUG + { + CFStringRef hexResp = CFDataCopyHexString(this->data); + secdebug("ocsp", "bad ocsp response: %@", hexResp); + CFReleaseSafe(hexResp); + } +#endif if (this) { SecOCSPResponseFinalize(this); } diff --git a/OSX/sec/securityd/SecOCSPResponse.h b/OSX/sec/securityd/SecOCSPResponse.h index ae19dc71..63585a6a 100644 --- a/OSX/sec/securityd/SecOCSPResponse.h +++ b/OSX/sec/securityd/SecOCSPResponse.h @@ -36,7 +36,6 @@ #include #include #include -#include __BEGIN_DECLS @@ -154,7 +153,7 @@ CFArrayRef SecOCSPSingleResponseCopySCTs(SecOCSPSingleResponseRef this); void SecOCSPSingleResponseDestroy(SecOCSPSingleResponseRef this); -/* Returns the SecCertificatePathRef who's leaf signed this ocspResponse if +/* Returns the SecCertificateRef whose leaf signed this ocspResponse if we can find one and NULL if we can't find a valid signer. The issuerPath contains the cert chain from the anchor to the certificate that issued the leaf certificate for which this ocspResponse is supposed to be valid. */ diff --git a/OSX/sec/securityd/SecOTRRemote.m b/OSX/sec/securityd/SecOTRRemote.m index 683ec8a6..c41d1d8c 100644 --- a/OSX/sec/securityd/SecOTRRemote.m +++ b/OSX/sec/securityd/SecOTRRemote.m @@ -147,6 +147,7 @@ bool _SecOTRSessionProcessPacketRemote(CFDataRef sessionData, CFDataRef inputPac *outputPacket = negotiationResponse; *readyForMessages = SecOTRSGetIsReadyForMessages(session); + CFReleaseNull(session); return true; } diff --git a/OSX/sec/securityd/SecPinningDb.h b/OSX/sec/securityd/SecPinningDb.h index 42b1ddcd..e8e198fc 100644 --- a/OSX/sec/securityd/SecPinningDb.h +++ b/OSX/sec/securityd/SecPinningDb.h @@ -45,6 +45,13 @@ extern const CFStringRef kSecPinningDbKeyRules; CFDictionaryRef _Nullable SecPinningDbCopyMatching(CFDictionaryRef _Nonnull query); void SecPinningDbInitialize(void); +#if !TARGET_OS_BRIDGE +/* Updating the pinning DB isn't supported on BridgeOS because we treat the disk as read-only. */ +bool SecPinningDbUpdateFromURL(CFURLRef url); +#endif + +CFNumberRef SecPinningDbCopyContentVersion(void); + CF_IMPLICIT_BRIDGING_DISABLED CF_ASSUME_NONNULL_END diff --git a/OSX/sec/securityd/SecPinningDb.m b/OSX/sec/securityd/SecPinningDb.m index 0a498a7a..425adcdc 100644 --- a/OSX/sec/securityd/SecPinningDb.m +++ b/OSX/sec/securityd/SecPinningDb.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Apple Inc. All Rights Reserved. + * Copyright (c) 2016-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -38,12 +38,14 @@ #if TARGET_OS_OSX #import +#include #endif #import #import #import +#import #include "utilities/debugging.h" #include "utilities/sqlutils.h" @@ -69,15 +71,6 @@ const CFStringRef kSecPinningDbKeyHostname = CFSTR("PinningHostname"); const CFStringRef kSecPinningDbKeyPolicyName = CFSTR("PinningPolicyName"); const CFStringRef kSecPinningDbKeyRules = CFSTR("PinningRules"); -#if !TARGET_OS_BRIDGE -const NSString *PinningDbMobileAssetType = @"com.apple.MobileAsset.CertificatePinning"; -#define kSecPinningDbMobileAssetNotification "com.apple.MobileAsset.CertificatePinning.cached-metadata-updated" -#endif - -#if TARGET_OS_OSX -const NSUInteger PinningDbMobileAssetCompatibilityVersion = 1; -#endif - @interface SecPinningDb : NSObject @property (assign) SecDbRef db; @property dispatch_queue_t queue; @@ -87,20 +80,6 @@ const NSUInteger PinningDbMobileAssetCompatibilityVersion = 1; - ( NSDictionary * _Nullable ) queryForPolicyName:(NSString *)policyName; @end -static bool isDbOwner() { -#ifdef NO_SERVER - // Test app running as securityd -#elif TARGET_OS_IPHONE - if (getuid() == 64) // _securityd -#else - if (getuid() == 0) -#endif - { - return true; - } - return false; -} - static inline bool isNSNumber(id nsType) { return nsType && [nsType isKindOfClass:[NSNumber class]]; } @@ -326,16 +305,8 @@ static inline bool isNSDictionary(id nsType) { secerror("SecPinningDb: missing url for downloaded asset"); return NO; } - NSURL* basePath = nil, *fileLoc = nil; - if (![localURL scheme]) { - /* MobileAsset provides the URL without the scheme. Fix it up. */ - NSString *pathWithScheme = [[NSString alloc] initWithFormat:@"%@",localURL]; - basePath = [NSURL fileURLWithPath:pathWithScheme isDirectory:YES]; - } else { - basePath = localURL; - } - fileLoc = [NSURL URLWithString:@"CertificatePinning.plist" - relativeToURL:basePath]; + NSURL *fileLoc = [NSURL URLWithString:@"CertificatePinning.plist" + relativeToURL:localURL]; __block NSArray *pinningList = [NSArray arrayWithContentsOfURL:fileLoc]; if (!pinningList) { secerror("SecPinningDb: unable to create pinning list from asset file: %@", fileLoc); @@ -351,271 +322,50 @@ static inline bool isNSDictionary(id nsType) { /* Update Content */ __block CFErrorRef error = NULL; __block BOOL ok = YES; - ok &= SecDbPerformWrite(_db, &error, ^(SecDbConnectionRef dbconn) { - ok &= [self updateDb:dbconn error:&error pinningList:pinningList updateSchema:NO updateContent:YES]; + dispatch_sync(self->_queue, ^{ + ok &= SecDbPerformWrite(self->_db, &error, ^(SecDbConnectionRef dbconn) { + ok &= [self updateDb:dbconn error:&error pinningList:pinningList updateSchema:NO updateContent:YES]; + }); }); - if (error) { + if (!ok || error) { secerror("SecPinningDb: error installing updated pinning list version %@: %@", [pinningList objectAtIndex:0], error); + [[TrustdHealthAnalytics logger] logHardError:(__bridge NSError *)error + withEventName:TrustdHealthAnalyticsEventDatabaseEvent + withAttributes:@{TrustdHealthAnalyticsAttributeAffectedDatabase : @(TAPinningDb), + TrustdHealthAnalyticsAttributeDatabaseOperation : @(TAOperationWrite) }]; CFReleaseNull(error); } return ok; } - -#if TARGET_OS_OSX -const CFStringRef kSecSUPrefDomain = CFSTR("com.apple.SoftwareUpdate"); -const CFStringRef kSecSUScanPrefConfigDataInstallKey = CFSTR("ConfigDataInstall"); -#endif - -static BOOL PinningDbCanCheckMobileAsset(void) { - BOOL result = YES; -#if TARGET_OS_OSX - /* Check the user's SU preferences to determine if "Install system data files" is off */ - if (!CFPreferencesSynchronize(kSecSUPrefDomain, kCFPreferencesAnyUser, kCFPreferencesCurrentHost)) { - secerror("SecPinningDb: unable to synchronize SoftwareUpdate prefs"); - return NO; - } - - id value = nil; - if (CFPreferencesAppValueIsForced(kSecSUScanPrefConfigDataInstallKey, kSecSUPrefDomain)) { - value = CFBridgingRelease(CFPreferencesCopyAppValue(kSecSUScanPrefConfigDataInstallKey, kSecSUPrefDomain)); - } else { - value = CFBridgingRelease(CFPreferencesCopyValue(kSecSUScanPrefConfigDataInstallKey, kSecSUPrefDomain, - kCFPreferencesAnyUser, kCFPreferencesCurrentHost)); - } - if (isNSNumber(value)) { - result = [value boolValue]; - } - - if (!result) { secnotice("pinningDb", "User has disabled system data installation."); } - - /* MobileAsset.framework isn't mastered into the BaseSystem. Check that the MA classes are linked. */ - if (![ASAssetQuery class] || ![ASAsset class] || ![MAAssetQuery class] || ![MAAsset class]) { - secnotice("PinningDb", "Weak linked MobileAsset framework missing."); - result = NO; - } -#endif - return result; -} - -#if TARGET_OS_IPHONE -- (void) downloadPinningAsset:(BOOL __unused)isLocalOnly { - if (!PinningDbCanCheckMobileAsset()) { - secnotice("pinningDb", "MobileAsset disabled, skipping check."); - return; - } - - secnotice("pinningDb", "begin MobileAsset query for catalog"); - [MAAsset startCatalogDownload:(NSString *)PinningDbMobileAssetType then:^(MADownLoadResult result) { - if (result != MADownloadSucceesful) { - secerror("SecPinningDb: failed to download catalog: %ld", (long)result); - return; - } - MAAssetQuery *query = [[MAAssetQuery alloc] initWithType:(NSString *)PinningDbMobileAssetType]; - [query augmentResultsWithState:true]; - - secnotice("pinningDb", "begin MobileAsset metadata sync request"); - MAQueryResult queryResult = [query queryMetaDataSync]; - if (queryResult != MAQuerySucceesful) { - secerror("SecPinningDb: failed to query MobileAsset metadata: %ld", (long)queryResult); - return; - } - - if (!query.results) { - secerror("SecPinningDb: no results in MobileAsset query"); - return; - } - - for (MAAsset *asset in query.results) { - NSNumber *asset_version = [asset assetProperty:@"_ContentVersion"]; - if (![self shouldUpdateContent:asset_version]) { - secdebug("pinningDb", "skipping asset because we already have _ContentVersion %@", asset_version); - continue; - } - switch(asset.state) { - default: - secerror("SecPinningDb: unknown asset state %ld", (long)asset.state); - continue; - case MAInstalled: - /* The asset is already in the cache, get it from disk. */ - secdebug("pinningDb", "CertificatePinning asset already installed"); - if([self installDbFromURL:[asset getLocalUrl]]) { - secnotice("pinningDb", "finished db update from installed asset. purging asset."); - [asset purge:^(MAPurgeResult purge_result) { - if (purge_result != MAPurgeSucceeded) { - secerror("SecPinningDb: purge failed: %ld", (long)purge_result); - } - }]; - } - break; - case MAUnknown: - secerror("SecPinningDb: pinning asset is unknown"); - continue; - case MADownloading: - secnotice("pinningDb", "pinning asset is downloading"); - /* fall through */ - case MANotPresent: - secnotice("pinningDb", "begin download of CertificatePinning asset"); - [asset startDownload:^(MADownLoadResult downloadResult) { - if (downloadResult != MADownloadSucceesful) { - secerror("SecPinningDb: failed to download pinning asset: %ld", (long)downloadResult); - return; - } - if([self installDbFromURL:[asset getLocalUrl]]) { - secnotice("pinningDb", "finished db update from installed asset. purging asset."); - [asset purge:^(MAPurgeResult purge_result) { - if (purge_result != MAPurgeSucceeded) { - secerror("SecPinningDb: purge failed: %ld", (long)purge_result); - } - }]; - } - }]; - break; - } - } - }]; -} -#else /* !TARGET_OS_IPHONE */ -/* MobileAssetV2 fails on macOS, so use V1 */ -- (void) downloadPinningAsset:(BOOL)isLocalOnly { - if (!PinningDbCanCheckMobileAsset()) { - secnotice("pinningDb", "MobileAsset disabled, skipping check."); - return; - } - - ASAssetQuery *query = [[ASAssetQuery alloc] initWithAssetType:(NSString *)PinningDbMobileAssetType]; - [query setQueriesLocalAssetInformationOnly:isLocalOnly]; // Omitting this leads to a notifcation loop. - NSError *error = nil; - NSArray*query_results = [query runQueryAndReturnError:&error]; - if (!query_results) { - secerror("SecPinningDb: asset query failed: %@", error); - return; - } - - for (ASAsset *asset in query_results) { - NSDictionary *attributes = [asset attributes]; - - NSNumber *compatibilityVersion = [attributes objectForKey:ASAttributeCompatibilityVersion]; - if (!isNSNumber(compatibilityVersion) || - [compatibilityVersion unsignedIntegerValue] != PinningDbMobileAssetCompatibilityVersion) { - secnotice("pinningDb", "Skipping asset with compatibility version %@", compatibilityVersion); - continue; - } - - NSNumber *contentVersion = [attributes objectForKey:ASAttributeContentVersion]; - if (!isNSNumber(contentVersion) || ![self shouldUpdateContent:contentVersion]) { - secnotice("pinningDb", "Skipping asset with content version %@", contentVersion); - continue; - } - - ASProgressHandler pinningHandler = ^(NSDictionary *state, NSError *progressError){ - if (progressError) { - secerror("SecPinningDb: asset download error: %@", progressError); - return; - } - - if (!state) { - secerror("SecPinningDb: no asset state in progress handler"); - return; - } - - NSString *operationState = [state objectForKey:ASStateOperation]; - secdebug("pinningDb", "Asset state is %@", operationState); - - if (operationState && [operationState isEqualToString:ASOperationCompleted]) { - if ([self installDbFromURL:[asset localURL]]) { - secnotice("pinningDb", "finished db update from installed asset. purging asset."); - [asset purge:^(NSError *error) { - if (error) { - secerror("SecPinningDb: purge failed %@", error); - } - }]; - } - } - }; - - switch ([asset state]) { - case ASAssetStateNotPresent: - secdebug("pinningDb", "CertificatePinning asset needs to be downloaded"); - asset.progressHandler= pinningHandler; - asset.userInitiatedDownload = YES; - [asset beginDownloadWithOptions:@{ASDownloadOptionPriority : ASDownloadPriorityNormal}]; - break; - case ASAssetStateInstalled: - /* The asset is already in the cache, get it from disk. */ - secdebug("pinningDb", "CertificatePinning asset already installed"); - if([self installDbFromURL:[asset localURL]]) { - secnotice("pinningDb", "finished db update from installed asset. purging asset."); - [asset purge:^(NSError *error) { - if (error) { - secerror("SecPinningDb: purge failed %@", error); - } - }]; - } - break; - case ASAssetStatePaused: - secdebug("pinningDb", "CertificatePinning asset download paused"); - asset.progressHandler = pinningHandler; - asset.userInitiatedDownload = YES; - if (![asset resumeDownloadAndReturnError:&error]) { - secerror("SecPinningDb: failed to resume download of asset: %@", error); - } - break; - case ASAssetStateDownloading: - secdebug("pinningDb", "CertificatePinning asset downloading"); - asset.progressHandler = pinningHandler; - asset.userInitiatedDownload = YES; - break; - default: - secerror("SecPinningDb: unhandled asset state %ld", (long)asset.state); - continue; - } - } -} -#endif /* !TARGET_OS_IPHONE */ - -- (void) downloadPinningAsset { - [self downloadPinningAsset:NO]; -} #endif /* !TARGET_OS_BRIDGE */ -- (NSArray *) copyCurrentPinningList { +- (NSArray *) copySystemPinningList { NSArray *pinningList = nil; + NSURL *pinningListURL = nil; /* Get the pinning list shipped with the OS */ SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef(); if (otapkiref) { - pinningList = CFBridgingRelease(SecOTAPKICopyPinningList(otapkiref)); + pinningListURL = CFBridgingRelease(SecOTAPKICopyPinningList(otapkiref)); CFReleaseNull(otapkiref); + if (!pinningListURL) { + secerror("SecPinningDb: failed to get pinning plist URL"); + } + NSError *error = nil; + pinningList = [NSArray arrayWithContentsOfURL:pinningListURL error:&error]; if (!pinningList) { - secerror("SecPinningDb: failed to read pinning plist from bundle"); + secerror("SecPinningDb: failed to read pinning plist from bundle: %@", error); } } -#if !TARGET_OS_BRIDGE - /* Asynchronously ask MobileAsset for most recent pinning list. */ - dispatch_async(_queue, ^{ - secnotice("pinningDb", "Initial check with MobileAsset for newer pinning asset"); - [self downloadPinningAsset]; - }); - - /* Register for changes in our asset */ - if (PinningDbCanCheckMobileAsset()) { - int out_token = 0; - notify_register_dispatch(kSecPinningDbMobileAssetNotification, &out_token, self->_queue, ^(int __unused token) { - secnotice("pinningDb", "Got a notification about a new pinning asset."); - [self downloadPinningAsset:YES]; - }); - } -#endif - return pinningList; } - (BOOL) updateDb:(SecDbConnectionRef)dbconn error:(CFErrorRef *)error pinningList:(NSArray *)pinningList updateSchema:(BOOL)updateSchema updateContent:(BOOL)updateContent { - if (!isDbOwner()) { return false; } + if (!SecOTAPKIIsSystemTrustd()) { return false; } secdebug("pinningDb", "updating or creating database"); __block bool ok = true; @@ -648,13 +398,17 @@ static BOOL PinningDbCanCheckMobileAsset(void) { } - (SecDbRef) createAtPath { - bool readWrite = isDbOwner(); - mode_t mode = 0644; + bool readWrite = SecOTAPKIIsSystemTrustd(); +#if TARGET_OS_OSX + mode_t mode = 0644; // Root trustd can rw. All other trustds need to read. +#else + mode_t mode = 0600; // Only one trustd. +#endif CFStringRef path = CFStringCreateWithCString(NULL, [_dbPath fileSystemRepresentation], kCFStringEncodingUTF8); SecDbRef result = SecDbCreateWithOptions(path, mode, readWrite, readWrite, false, ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error) { - if (!isDbOwner()) { + if (!SecOTAPKIIsSystemTrustd()) { /* Non-owner process can't update the db, but it should get a db connection. * @@@ Revisit if new schema version is needed by reader processes. */ return true; @@ -666,7 +420,7 @@ static BOOL PinningDbCanCheckMobileAsset(void) { bool updateContent = false; /* Get the pinning plist */ - NSArray *pinningList = [self copyCurrentPinningList]; + NSArray *pinningList = [self copySystemPinningList]; if (!pinningList) { secerror("SecPinningDb: failed to find pinning plist in bundle"); ok = false; @@ -680,6 +434,7 @@ static BOOL PinningDbCanCheckMobileAsset(void) { } NSNumber *plist_version = [pinningList objectAtIndex:0]; NSNumber *db_version = [self getContentVersion:dbconn error:error]; + secnotice("pinningDb", "Opening db with version %@", db_version); if (!db_version || [plist_version compare:db_version] == NSOrderedDescending) { secnotice("pinningDb", "Updating pinning database content from version %@ to version %@", db_version ? db_version : 0, plist_version); @@ -695,9 +450,16 @@ static BOOL PinningDbCanCheckMobileAsset(void) { if (updateContent || updateSchema) { ok &= [self updateDb:dbconn error:error pinningList:pinningList updateSchema:updateSchema updateContent:updateContent]; + /* Since we updated the DB to match the list that shipped with the system, + * reset the OTAPKI Asset version to the system asset version */ + (void)SecOTAPKIResetCurrentAssetVersion(NULL); } if (!ok) { secerror("SecPinningDb: %s failed: %@", didCreate ? "Create" : "Open", error ? *error : NULL); + [[TrustdHealthAnalytics logger] logHardError:(error ? (__bridge NSError *)*error : nil) + withEventName:TrustdHealthAnalyticsEventDatabaseEvent + withAttributes:@{TrustdHealthAnalyticsAttributeAffectedDatabase : @(TAPinningDb), + TrustdHealthAnalyticsAttributeDatabaseOperation : didCreate ? @(TAOperationCreate) : @(TAOperationOpen)}]; } }); return ok; @@ -765,9 +527,10 @@ static void verify_create_path(const char *path) } } + dispatch_once(&once, ^{ - /* Only log system-wide pinning status once a minute */ - action = sec_action_create("pinning logging charles", 60.0); + /* Only log system-wide pinning status once every five minutes */ + action = sec_action_create("pinning logging charles", 5*60.0); sec_action_set_handler(action, ^{ if (!SecIsInternalRelease()) { secnotice("pinningQA", "could not disable pinning: not an internal release"); @@ -845,8 +608,12 @@ static void verify_create_path(const char *path) }); }); - if (error) { + if (!ok || error) { secerror("SecPinningDb: error querying DB for hostname: %@", error); + [[TrustdHealthAnalytics logger] logHardError:(__bridge NSError *)error + withEventName:TrustdHealthAnalyticsEventDatabaseEvent + withAttributes:@{TrustdHealthAnalyticsAttributeAffectedDatabase : @(TAPinningDb), + TrustdHealthAnalyticsAttributeDatabaseOperation : @(TAOperationRead)}]; CFReleaseNull(error); } @@ -872,6 +639,8 @@ static void verify_create_path(const char *path) return nil; } + secinfo("SecPinningDb", "Fetching rules for policy named %@", policyName); + /* Perform SELECT */ __block bool ok = true; __block CFErrorRef error = NULL; @@ -895,8 +664,12 @@ static void verify_create_path(const char *path) }); }); - if (error) { + if (!ok || error) { secerror("SecPinningDb: error querying DB for policyName: %@", error); + [[TrustdHealthAnalytics logger] logHardError:(__bridge NSError *)error + withEventName:TrustdHealthAnalyticsEventDatabaseEvent + withAttributes:@{TrustdHealthAnalyticsAttributeAffectedDatabase : @(TAPinningDb), + TrustdHealthAnalyticsAttributeDatabaseOperation : @(TAOperationRead)}]; CFReleaseNull(error); } @@ -910,34 +683,70 @@ static void verify_create_path(const char *path) @end +/* C interfaces */ static SecPinningDb *pinningDb = nil; void SecPinningDbInitialize(void) { + /* Create the pinning object once per launch */ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - pinningDb = [[SecPinningDb alloc] init]; - __block CFErrorRef error = NULL; - BOOL ok = SecDbPerformRead([pinningDb db], &error, ^(SecDbConnectionRef dbconn) { - NSNumber *contentVersion = [pinningDb getContentVersion:dbconn error:&error]; - NSNumber *schemaVersion = [pinningDb getSchemaVersion:dbconn error:&error]; - secinfo("pinningDb", "Database Schema: %@ Content: %@", schemaVersion, contentVersion); - }); - if (!ok || error) { - secerror("SecPinningDb: unable to initialize db: %@", error); + @autoreleasepool { + pinningDb = [[SecPinningDb alloc] init]; + __block CFErrorRef error = NULL; + BOOL ok = SecDbPerformRead([pinningDb db], &error, ^(SecDbConnectionRef dbconn) { + NSNumber *contentVersion = [pinningDb getContentVersion:dbconn error:&error]; + NSNumber *schemaVersion = [pinningDb getSchemaVersion:dbconn error:&error]; + secinfo("pinningDb", "Database Schema: %@ Content: %@", schemaVersion, contentVersion); + }); + if (!ok || error) { + secerror("SecPinningDb: unable to initialize db: %@", error); + [[TrustdHealthAnalytics logger] logHardError:(__bridge NSError *)error + withEventName:TrustdHealthAnalyticsEventDatabaseEvent + withAttributes:@{TrustdHealthAnalyticsAttributeAffectedDatabase : @(TAPinningDb), + TrustdHealthAnalyticsAttributeDatabaseOperation : @(TAOperationRead)}]; + } + CFReleaseNull(error); } - CFReleaseNull(error); }); } CFDictionaryRef _Nullable SecPinningDbCopyMatching(CFDictionaryRef query) { + @autoreleasepool { + SecPinningDbInitialize(); + + NSDictionary *nsQuery = (__bridge NSDictionary*)query; + NSString *hostname = [nsQuery objectForKey:(__bridge NSString*)kSecPinningDbKeyHostname]; + + NSDictionary *results = [pinningDb queryForDomain:hostname]; + if (results) { return CFBridgingRetain(results); } + NSString *policyName = [nsQuery objectForKey:(__bridge NSString*)kSecPinningDbKeyPolicyName]; + results = [pinningDb queryForPolicyName:policyName]; + if (!results) { return nil; } + return CFBridgingRetain(results); + } +} + +#if !TARGET_OS_BRIDGE +bool SecPinningDbUpdateFromURL(CFURLRef url) { SecPinningDbInitialize(); - NSDictionary *nsQuery = (__bridge NSDictionary*)query; - NSString *hostname = [nsQuery objectForKey:(__bridge NSString*)kSecPinningDbKeyHostname]; + return [pinningDb installDbFromURL:(__bridge NSURL*)url]; +} +#endif - NSDictionary *results = [pinningDb queryForDomain:hostname]; - if (results) { return CFBridgingRetain(results); } - NSString *policyName = [nsQuery objectForKey:(__bridge NSString*)kSecPinningDbKeyPolicyName]; - results = [pinningDb queryForPolicyName:policyName]; - if (!results) { return nil; } - return CFBridgingRetain(results); +CFNumberRef SecPinningDbCopyContentVersion(void) { + @autoreleasepool { + __block CFErrorRef error = NULL; + __block NSNumber *contentVersion = nil; + BOOL ok = SecDbPerformRead([pinningDb db], &error, ^(SecDbConnectionRef dbconn) { + contentVersion = [pinningDb getContentVersion:dbconn error:&error]; + }); + if (!ok || error) { + secerror("SecPinningDb: unable to get content version: %@", error); + } + CFReleaseNull(error); + if (!contentVersion) { + contentVersion = [NSNumber numberWithInteger:0]; + } + return CFBridgingRetain(contentVersion); + } } diff --git a/OSX/sec/securityd/SecPolicyServer.c b/OSX/sec/securityd/SecPolicyServer.c index 56d212ce..77bf37cc 100644 --- a/OSX/sec/securityd/SecPolicyServer.c +++ b/OSX/sec/securityd/SecPolicyServer.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include @@ -314,69 +314,6 @@ static void SecPolicyCheckExtendedKeyUsage(SecPVCRef pvc, CFStringRef key) { } } -#if 0 -static void SecPolicyCheckBasicContraintsCommon(SecPVCRef pvc, - CFStringRef key, bool strict) { - CFIndex ix, count = SecPVCGetCertificateCount(pvc); - for (ix = 0; ix < count; ++ix) { - SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, ix); - const SecCEBasicConstraints *bc = - SecCertificateGetBasicConstraints(cert); - if (bc) { - if (strict) { - if (ix == 0) { - /* Leaf certificate has basic constraints extension. */ - if (!SecPVCSetResult(pvc, key, ix, kCFBooleanFalse)) - return; - } else if (!bc->critical) { - /* Basic constraints extension is not marked critical. */ - if (!SecPVCSetResult(pvc, key, ix, kCFBooleanFalse)) - return; - } - } - - if (ix > 0 || count == 1) { - if (!bc->isCA) { - /* Non leaf certificate marked as isCA false. */ - if (!SecPVCSetResult(pvc, key, ix, kCFBooleanFalse)) - return; - } - - if (bc->pathLenConstraintPresent) { - if (bc->pathLenConstraint < (uint32_t)(ix - 1)) { -#if 0 - /* @@@ If a self signed certificate is issued by - another cert that is trusted, then we are supposed - to treat the self signed cert itself as the anchor - for path length purposes. */ - CFIndex ssix = SecCertificatePathSelfSignedIndex(path); - if (ssix >= 0 && ix >= ssix) { - /* It's ok if the pathLenConstraint isn't met for - certificates signing a self signed cert in the - chain. */ - } else -#endif - { - /* Path Length Constraint Exceeded. */ - if (!SecPVCSetResult(pvc, key, ix, - kCFBooleanFalse)) - return; - } - } - } - } - } else if (strict && ix > 0) { - /* In strict mode all CA certificates *MUST* have a critical - basic constraints extension and the leaf certificate - *MUST NOT* have a basic constraints extension. */ - /* CA certificate is missing basicConstraints extension. */ - if (!SecPVCSetResult(pvc, key, ix, kCFBooleanFalse)) - return; - } - } -} -#endif - static void SecPolicyCheckBasicConstraints(SecPVCRef pvc, CFStringRef key) { //SecPolicyCheckBasicContraintsCommon(pvc, key, false); @@ -396,10 +333,6 @@ static void SecPolicyCheckNonEmptySubject(SecPVCRef pvc, } } -static void SecPolicyCheckQualifiedCertStatements(SecPVCRef pvc, - CFStringRef key) { -} - /* AUDIT[securityd](done): policy->_options is a caller provided dictionary, only its cf type has been checked. @@ -448,11 +381,11 @@ static void SecPolicyCheckEmail(SecPVCRef pvc, CFStringRef key) { } } -static void SecPolicyCheckValidIntermediates(SecPVCRef pvc, +static void SecPolicyCheckTemporalValidity(SecPVCRef pvc, CFStringRef key) { CFIndex ix, count = SecPVCGetCertificateCount(pvc); CFAbsoluteTime verifyTime = SecPVCGetVerifyTime(pvc); - for (ix = 1; ix < count - 1; ++ix) { + for (ix = 0; ix < count; ++ix) { SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, ix); if (!SecCertificateIsValid(cert, verifyTime)) { /* Intermediate certificate has expired. */ @@ -462,30 +395,6 @@ static void SecPolicyCheckValidIntermediates(SecPVCRef pvc, } } -static void SecPolicyCheckValidLeaf(SecPVCRef pvc, - CFStringRef key) { - CFAbsoluteTime verifyTime = SecPVCGetVerifyTime(pvc); - SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, 0); - if (!SecCertificateIsValid(cert, verifyTime)) { - /* Leaf certificate has expired. */ - if (!SecPVCSetResult(pvc, key, 0, kCFBooleanFalse)) - return; - } -} - -static void SecPolicyCheckValidRoot(SecPVCRef pvc, - CFStringRef key) { - CFIndex ix, count = SecPVCGetCertificateCount(pvc); - CFAbsoluteTime verifyTime = SecPVCGetVerifyTime(pvc); - ix = count - 1; - SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, ix); - if (!SecCertificateIsValid(cert, verifyTime)) { - /* Root certificate has expired. */ - if (!SecPVCSetResult(pvc, key, ix, kCFBooleanFalse)) - return; - } -} - /* AUDIT[securityd](done): policy->_options is a caller provided dictionary, only its cf type has been checked. @@ -836,7 +745,6 @@ static void SecPolicyCheckBlackListedLeaf(SecPVCRef pvc, serial_ptr, sizeof(*UTN_USERFirst_Hardware_Serial))) { SecPVCSetResult(pvc, key, 0, kCFBooleanFalse); - pvc->result = kSecTrustResultFatalTrustFailure; CFReleaseSafe(serial); return; } @@ -861,7 +769,6 @@ static void SecPolicyCheckBlackListedLeaf(SecPVCRef pvc, if (CFSetContainsValue(blackListedKeys, dgst)) { SecPVCSetResult(pvc, key, 0, kCFBooleanFalse); - pvc->result = kSecTrustResultFatalTrustFailure; } CFRelease(dgst); } @@ -918,6 +825,7 @@ static void SecPolicyCheckLeafMarkerOidWithoutValueCheck(SecPVCRef pvc, CFString } } + /* * The value is a dictionary. The dictionary contains keys indicating * whether the value is for Prod or QA. The values are the same as @@ -1038,10 +946,20 @@ static void SecPolicyCheckBasicCertificateProcessing(SecPVCRef pvc, /* trust may be restored for a path with an untrusted root that matches the allow list. (isAllowlisted is set by revocation check, which is performed prior to path checks) */ if (!SecCertificatePathVCIsAllowlisted(path)) { - /* Add a detail for the root not being trusted. */ - if (!SecPVCSetResultForced(pvc, kSecPolicyCheckAnchorTrusted, - n - 1, kCFBooleanFalse, true)) { - return; + Boolean isSelfSigned = false; + (void) SecCertificateIsSelfSigned(SecCertificatePathVCGetCertificateAtIndex(path, n - 1), &isSelfSigned); + if (isSelfSigned) { + /* Add a detail for the root not being trusted. */ + if (!SecPVCSetResultForced(pvc, kSecPolicyCheckAnchorTrusted, + n - 1, kCFBooleanFalse, true)) { + return; + } + } else { + /* Add a detail for the missing intermediate. */ + if (!SecPVCSetResultForced(pvc, kSecPolicyCheckMissingIntermediate, + n - 1, kCFBooleanFalse, true)) { + return; + } } } } @@ -1057,13 +975,13 @@ static void SecPolicyCheckBasicCertificateProcessing(SecPVCRef pvc, permitted_subtrees = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); excluded_subtrees = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); require_action_quiet(permitted_subtrees != NULL, errOut, - SecPVCSetResultForced(pvc, key, 0, kCFBooleanFalse, true)); + SecPVCSetResultForced(pvc, kSecPolicyCheckNameConstraints, 0, kCFBooleanFalse, true)); require_action_quiet(excluded_subtrees != NULL, errOut, - SecPVCSetResultForced(pvc, key, 0, kCFBooleanFalse, true)); + SecPVCSetResultForced(pvc, kSecPolicyCheckNameConstraints, 0, kCFBooleanFalse, true)); #endif if (!SecCertificatePathVCVerifyPolicyTree(path, is_anchor_trusted)) { - if (!SecPVCSetResultForced(pvc, key, 0, kCFBooleanFalse, true)) { + if (!SecPVCSetResultForced(pvc, kSecPolicyCheckPolicyConstraints, 0, kCFBooleanFalse, true)) { goto errOut; } } @@ -1085,22 +1003,24 @@ static void SecPolicyCheckBasicCertificateProcessing(SecPVCRef pvc, /* (a) Verify the basic certificate information. */ /* @@@ Ensure that cert was signed with working_public_key_algorithm using the working_public_key and the working_public_key_parameters. */ -#if 1 + /* Already done by chain builder. */ if (!SecCertificateIsValid(cert, verify_time)) { - CFStringRef fail_key = i == n ? kSecPolicyCheckValidLeaf : kSecPolicyCheckValidIntermediates; - if (!SecPVCSetResult(pvc, fail_key, n - i, kCFBooleanFalse)) { + if (!SecPVCSetResult(pvc, kSecPolicyCheckTemporalValidity, n - i, kCFBooleanFalse)) { goto errOut; } } if (SecCertificateIsWeakKey(cert)) { - CFStringRef fail_key = i == n ? kSecPolicyCheckWeakLeaf : kSecPolicyCheckWeakIntermediates; - if (!SecPVCSetResult(pvc, fail_key, n - i, kCFBooleanFalse)) { + if (!SecPVCSetResult(pvc, kSecPolicyCheckWeakKeySize, n - i, kCFBooleanFalse)) { goto errOut; } - pvc->result = kSecTrustResultFatalTrustFailure; } -#endif + if (!SecPolicyCheckCertWeakSignature(cert, NULL)) { + if (!SecPVCSetResult(pvc, kSecPolicyCheckWeakSignature, n - i, kCFBooleanFalse)) { + goto errOut; + } + } + /* @@@ cert.issuer == working_issuer_name. */ #if POLICY_SUBTREES @@ -1111,14 +1031,14 @@ static void SecPolicyCheckBasicCertificateProcessing(SecPVCRef pvc, if(excluded_subtrees && CFArrayGetCount(excluded_subtrees)) { if ((errSecSuccess != SecNameContraintsMatchSubtrees(cert, excluded_subtrees, &found, false)) || found) { secnotice("policy", "name in excluded subtrees"); - if(!SecPVCSetResultForced(pvc, key, n - i, kCFBooleanFalse, true)) { goto errOut; } + if(!SecPVCSetResultForced(pvc, kSecPolicyCheckNameConstraints, n - i, kCFBooleanFalse, true)) { goto errOut; } } } /* Verify certificate Subject Name and SubjectAltNames are within the permitted_subtrees */ if(permitted_subtrees && CFArrayGetCount(permitted_subtrees)) { if ((errSecSuccess != SecNameContraintsMatchSubtrees(cert, permitted_subtrees, &found, true)) || !found) { secnotice("policy", "name not in permitted subtrees"); - if(!SecPVCSetResultForced(pvc, key, n - i, kCFBooleanFalse, true)) { goto errOut; } + if(!SecPVCSetResultForced(pvc, kSecPolicyCheckNameConstraints, n - i, kCFBooleanFalse, true)) { goto errOut; } } } } @@ -1154,31 +1074,22 @@ static void SecPolicyCheckBasicCertificateProcessing(SecPVCRef pvc, #endif /* (h), (i), (j) done by SecCertificatePathVCVerifyPolicyTree */ - /* (k) */ - const SecCEBasicConstraints *bc = - SecCertificateGetBasicConstraints(cert); -#if 0 /* Checked in chain builder pre signature verify already. SecPVCParentCertificateChecks */ - if (!bc || !bc->isCA) { - /* Basic constraints not present or not marked as isCA, illegal. */ - if (!SecPVCSetResult(pvc, kSecPolicyCheckBasicConstraints, - n - i, kCFBooleanFalse)) { - goto errOut; - } - } -#endif + /* (k) Checked in chain builder pre signature verify already. SecPVCParentCertificateChecks */ + /* (l) */ if (!is_self_issued) { if (max_path_length > 0) { max_path_length--; } else { /* max_path_len exceeded, illegal. */ - if (!SecPVCSetResult(pvc, kSecPolicyCheckBasicConstraints, - n - i, kCFBooleanFalse)) { + if (!SecPVCSetResultForced(pvc, kSecPolicyCheckBasicConstraintsPathLen, + n - i, kCFBooleanFalse, true)) { goto errOut; } } } /* (m) */ + const SecCEBasicConstraints *bc = SecCertificateGetBasicConstraints(cert); if (bc && bc->pathLenConstraintPresent && bc->pathLenConstraint < max_path_length) { max_path_length = bc->pathLenConstraint; @@ -1686,7 +1597,7 @@ out: return SCTs; } -static void SecPolicyCheckCT(SecPVCRef pvc, CFStringRef key) +static void SecPolicyCheckCT(SecPVCRef pvc) { SecCertificateRef leafCert = SecPVCGetCertificateAtIndex(pvc, 0); CFArrayRef embeddedScts = SecCertificateCopySignedCertificateTimestamps(leafCert); @@ -1695,6 +1606,8 @@ static void SecPolicyCheckCT(SecPVCRef pvc, CFStringRef key) CFArrayRef ocspScts = copy_ocsp_scts(pvc); CFDataRef precertEntry = copy_precert_entry_from_chain(pvc); CFDataRef x509Entry = copy_x509_entry_from_chain(pvc); + __block uint32_t trustedSCTCount = 0; + __block CFIndex totalSCTSize = 0; // This eventually contain list of logs who validated the SCT. CFMutableDictionaryRef currentLogsValidatingScts = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); @@ -1718,8 +1631,10 @@ static void SecPolicyCheckCT(SecPVCRef pvc, CFStringRef key) if(!CFDictionaryContainsKey(log, CFSTR("expiry"))) { addValidatingLog(currentLogsValidatingScts, log, sct_at); at_least_one_currently_valid_embedded = true; + trustedSCTCount++; } } + totalSCTSize += CFDataGetLength(value); }); } @@ -1730,7 +1645,9 @@ static void SecPolicyCheckCT(SecPVCRef pvc, CFStringRef key) if(log) { addValidatingLog(currentLogsValidatingScts, log, sct_at); at_least_one_currently_valid_external = true; + trustedSCTCount++; } + totalSCTSize += CFDataGetLength(value); }); } @@ -1741,7 +1658,9 @@ static void SecPolicyCheckCT(SecPVCRef pvc, CFStringRef key) if(log) { addValidatingLog(currentLogsValidatingScts, log, sct_at); at_least_one_currently_valid_external = true; + trustedSCTCount++; } + totalSCTSize += CFDataGetLength(value); }); } } @@ -1769,7 +1688,7 @@ static void SecPolicyCheckCT(SecPVCRef pvc, CFStringRef key) __block int lifetime; // in Months __block unsigned once_or_current_qualified_embedded = 0; - /* Calculate issuance time base on timestamp of SCTs from current logs */ + /* Calculate issuance time based on timestamp of SCTs from current logs */ CFDictionaryForEach(currentLogsValidatingScts, ^(const void *key, const void *value) { CFDictionaryRef log = key; if(!CFDictionaryContainsKey(log, CFSTR("expiry"))) { @@ -1787,8 +1706,12 @@ static void SecPolicyCheckCT(SecPVCRef pvc, CFStringRef key) CFDictionaryRef log = key; CFDateRef ts = value; CFDateRef expiry = CFDictionaryGetValue(log, CFSTR("expiry")); - if(expiry == NULL || CFDateCompare(ts, expiry, NULL) == kCFCompareLessThan) { + if (expiry == NULL) { // Currently qualified OR once_or_current_qualified_embedded++; + } else if (CFDateCompare(ts, expiry, NULL) == kCFCompareLessThan && // Once qualified. That is, qualified at the time of SCT AND + issuanceTime < CFDateGetAbsoluteTime(expiry)) { // at the time of issuance.) + once_or_current_qualified_embedded++; + trustedSCTCount++; } }); @@ -1818,6 +1741,30 @@ static void SecPolicyCheckCT(SecPVCRef pvc, CFStringRef key) } } + /* Record analytics data for CT */ + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(pvc->builder); + require_quiet(analytics, out); + uint32_t sctCount = 0; + /* Count the total number of SCTs we found and report where we got them */ + if (embeddedScts && CFArrayGetCount(embeddedScts) > 0) { + analytics->sct_sources |= TA_SCTEmbedded; + sctCount += CFArrayGetCount(embeddedScts); + } + if (builderScts && CFArrayGetCount(builderScts) > 0) { + analytics->sct_sources |= TA_SCT_TLS; + sctCount += CFArrayGetCount(builderScts); + } + if (ocspScts && CFArrayGetCount(ocspScts) > 0) { + analytics->sct_sources |= TA_SCT_OCSP; + sctCount += CFArrayGetCount(ocspScts); + } + /* Report how many of those SCTs were once or currently qualified */ + analytics->number_trusted_scts = trustedSCTCount; + /* Report the total number of bytes in the SCTs */ + analytics->total_sct_size = totalSCTSize; + /* Report how many SCTs we got */ + analytics->number_scts = sctCount; + out: CFReleaseSafe(logsValidatingEmbeddedScts); CFReleaseSafe(currentLogsValidatingScts); @@ -1848,7 +1795,7 @@ static bool checkPolicyOidData(SecPVCRef pvc, CFDataRef oid) { return false; } -static void SecPolicyCheckCertificatePolicyOid(SecPVCRef pvc, CFStringRef key) +static void SecPolicyCheckCertificatePolicy(SecPVCRef pvc, CFStringRef key) { SecPolicyRef policy = SecPVCGetPolicy(pvc); CFTypeRef value = CFDictionaryGetValue(policy->_options, key); @@ -1900,51 +1847,39 @@ static void SecPolicyCheckNoNetworkAccess(SecPVCRef pvc, } } -static void SecPolicyCheckWeakIntermediates(SecPVCRef pvc, +static void SecPolicyCheckWeakKeySize(SecPVCRef pvc, CFStringRef key) { CFIndex ix, count = SecPVCGetCertificateCount(pvc); - for (ix = 1; ix < count - 1; ++ix) { + for (ix = 0; ix < count; ++ix) { SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, ix); if (cert && SecCertificateIsWeakKey(cert)) { /* Intermediate certificate has a weak key. */ if (!SecPVCSetResult(pvc, key, ix, kCFBooleanFalse)) return; - pvc->result = kSecTrustResultFatalTrustFailure; } } } -static void SecPolicyCheckWeakLeaf(SecPVCRef pvc, - CFStringRef key) { - SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, 0); - if (cert && SecCertificateIsWeakKey(cert)) { - /* Leaf certificate has a weak key. */ - if (!SecPVCSetResult(pvc, key, 0, kCFBooleanFalse)) - return; - pvc->result = kSecTrustResultFatalTrustFailure; - } -} - -static void SecPolicyCheckWeakRoot(SecPVCRef pvc, - CFStringRef key) { +static void SecPolicyCheckKeySize(SecPVCRef pvc, CFStringRef key) { CFIndex ix, count = SecPVCGetCertificateCount(pvc); - ix = count - 1; - SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, ix); - if (cert && SecCertificateIsWeakKey(cert)) { - /* Root certificate has a weak key. */ - if (!SecPVCSetResult(pvc, key, ix, kCFBooleanFalse)) - return; - pvc->result = kSecTrustResultFatalTrustFailure; + SecPolicyRef policy = SecPVCGetPolicy(pvc); + CFDictionaryRef keySizes = CFDictionaryGetValue(policy->_options, key); + for (ix = 0; ix < count; ++ix) { + SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, ix); + if (!SecCertificateIsAtLeastMinKeySize(cert, keySizes)) { + if (!SecPVCSetResult(pvc, key, ix, kCFBooleanFalse)) + return; + } } } -static void SecPolicyCheckKeySize(SecPVCRef pvc, CFStringRef key) { +static void SecPolicyCheckWeakSignature(SecPVCRef pvc, CFStringRef key) { CFIndex ix, count = SecPVCGetCertificateCount(pvc); SecPolicyRef policy = SecPVCGetPolicy(pvc); - CFDictionaryRef keySizes = CFDictionaryGetValue(policy->_options, key); + CFTypeRef pvcValue = CFDictionaryGetValue(policy->_options, key); for (ix = 0; ix < count; ++ix) { SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, ix); - if (!SecCertificateIsAtLeastMinKeySize(cert, keySizes)) { + if (!SecPolicyCheckCertWeakSignature(cert, pvcValue)) { if (!SecPVCSetResult(pvc, key, ix, kCFBooleanFalse)) return; } @@ -1979,19 +1914,11 @@ static bool leaf_is_on_weak_hash_whitelist(SecPVCRef pvc) { 0x7b, 0x3b, 0xad, 0x43, 0x88, 0xa9, 0x66, 0x59, 0xa8, 0x18 }; - /* subject:/C=US/ST=Kansas/L=Overland Park/O=Sprint/CN=oma.ssprov.sprint.com */ - /* issuer :/C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C */ - /* Not After : Aug 16 05:04:29 2017 GMT */ - static const uint8_t sprint[] = { - 0xa3, 0x18, 0x70, 0x4f, 0xf7, 0xbf, 0xfb, 0x2b, 0xe2, 0x64, - 0x3a, 0x2d, 0x2b, 0xb8, 0x10, 0x5f, 0x77, 0xd5, 0x01, 0xab - }; - CFDataRef leafFingerprint = SecCertificateGetSHA1Digest(leaf); require_quiet(leafFingerprint, out); const unsigned int len = 20; const uint8_t *dp = CFDataGetBytePtr(leafFingerprint); - if (dp && (!memcmp(vodafone, dp, len) || !memcmp(sprint,dp,len))) { + if (dp && (!memcmp(vodafone, dp, len))) { return true; } @@ -2107,150 +2034,23 @@ void SecPolicyServerInitialize(void) { gSecPolicyPathCallbacks = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, NULL); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckBasicCertificateProcessing, - SecPolicyCheckBasicCertificateProcessing); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckCriticalExtensions, - SecPolicyCheckCriticalExtensions); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckIdLinkage, - SecPolicyCheckIdLinkage); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckKeyUsage, - SecPolicyCheckKeyUsage); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckExtendedKeyUsage, - SecPolicyCheckExtendedKeyUsage); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckBasicConstraints, - SecPolicyCheckBasicConstraints); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckNonEmptySubject, - SecPolicyCheckNonEmptySubject); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckQualifiedCertStatements, - SecPolicyCheckQualifiedCertStatements); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckSSLHostname, - SecPolicyCheckSSLHostname); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckEmail, - SecPolicyCheckEmail); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckValidIntermediates, - SecPolicyCheckValidIntermediates); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckValidLeaf, - SecPolicyCheckValidLeaf); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckValidRoot, - SecPolicyCheckValidRoot); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckIssuerCommonName, - SecPolicyCheckIssuerCommonName); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckSubjectCommonNamePrefix, - SecPolicyCheckSubjectCommonNamePrefix); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckSubjectCommonName, - SecPolicyCheckSubjectCommonName); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckNotValidBefore, - SecPolicyCheckNotValidBefore); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckChainLength, - SecPolicyCheckChainLength); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckAnchorSHA1, - SecPolicyCheckAnchorSHA1); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckAnchorSHA256, - SecPolicyCheckAnchorSHA256); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckAnchorApple, - SecPolicyCheckAnchorApple); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckSubjectOrganization, - SecPolicyCheckSubjectOrganization); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckSubjectOrganizationalUnit, - SecPolicyCheckSubjectOrganizationalUnit); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckEAPTrustedServerNames, - SecPolicyCheckEAPTrustedServerNames); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckSubjectCommonNameTEST, - SecPolicyCheckSubjectCommonNameTEST); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckRevocation, - SecPolicyCheckRevocation); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckRevocationResponseRequired, - SecPolicyCheckRevocationResponseRequired); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckRevocationOnline, - SecPolicyCheckRevocationOnline); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckNoNetworkAccess, - SecPolicyCheckNoNetworkAccess); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckBlackListedLeaf, - SecPolicyCheckBlackListedLeaf); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckGrayListedLeaf, - SecPolicyCheckGrayListedLeaf); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckLeafMarkerOid, - SecPolicyCheckLeafMarkerOid); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckLeafMarkerOidWithoutValueCheck, - SecPolicyCheckLeafMarkerOidWithoutValueCheck); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckLeafMarkersProdAndQA, - SecPolicyCheckLeafMarkersProdAndQA); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckIntermediateSPKISHA256, - SecPolicyCheckIntermediateSPKISHA256); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckIntermediateEKU, - SecPolicyCheckIntermediateEKU); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckIntermediateMarkerOid, - SecPolicyCheckIntermediateMarkerOid); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckCertificatePolicy, - SecPolicyCheckCertificatePolicyOid); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckWeakIntermediates, - SecPolicyCheckWeakIntermediates); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckWeakLeaf, - SecPolicyCheckWeakLeaf); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckWeakRoot, - SecPolicyCheckWeakRoot); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckKeySize, - SecPolicyCheckKeySize); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckSignatureHashAlgorithms, - SecPolicyCheckSignatureHashAlgorithms); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckSystemTrustedWeakHash, - SecPolicyCheckSystemTrustedWeakHash); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckSystemTrustedWeakKey, - SecPolicyCheckSystemTrustedWeakKey); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckIntermediateOrganization, - SecPolicyCheckIntermediateOrganization); - CFDictionaryAddValue(gSecPolicyPathCallbacks, - kSecPolicyCheckIntermediateCountry, - SecPolicyCheckIntermediateCountry); - CFDictionaryAddValue(gSecPolicyLeafCallbacks, - kSecPolicyCheckPinningRequired, - SecPolicyCheckPinningRequired); +#undef POLICYCHECKMACRO +#define __PC_ADD_CHECK_(NAME) +#define __PC_ADD_CHECK_L(NAME) CFDictionaryAddValue(gSecPolicyLeafCallbacks, kSecPolicyCheck##NAME, SecPolicyCheck##NAME); +#define __PC_ADD_CHECK_A(NAME) CFDictionaryAddValue(gSecPolicyPathCallbacks, kSecPolicyCheck##NAME, SecPolicyCheck##NAME); + +#define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) \ +__PC_ADD_CHECK_##LEAFCHECK(NAME) \ +__PC_ADD_CHECK_##PATHCHECK(NAME) +#include "../Security/SecPolicyChecks.list" + + /* Some of these don't follow the naming conventions but are in the Pinning DB. + * fix policy check constant values */ + CFDictionaryAddValue(gSecPolicyLeafCallbacks, CFSTR("CheckLeafMarkerOid"), SecPolicyCheckLeafMarkerOid); + CFDictionaryAddValue(gSecPolicyLeafCallbacks, CFSTR("CheckLeafMarkersProdAndQA"), SecPolicyCheckLeafMarkersProdAndQA); + CFDictionaryAddValue(gSecPolicyPathCallbacks, CFSTR("CheckIntermediateMarkerOid"), SecPolicyCheckIntermediateMarkerOid); + CFDictionaryAddValue(gSecPolicyPathCallbacks, CFSTR("CheckIntermediateCountry"), SecPolicyCheckIntermediateCountry); + CFDictionaryAddValue(gSecPolicyPathCallbacks, CFSTR("CheckIntermediateOrganization"), SecPolicyCheckIntermediateOrganization); } // MARK: - @@ -2357,6 +2157,14 @@ static bool SecPVCIsExceptedError(SecPVCRef pvc, CFIndex ix, CFStringRef key, CF } } return true; + } else if (CFEqual(key, kSecPolicyCheckTemporalValidity) && CFDictionaryContainsKey(options, kSecPolicyCheckValidRoot)) { + /* Another special case - ValidRoot excepts Valid only for self-signed certs */ + Boolean isSelfSigned = false; + SecCertificateRef cert = SecPathBuilderGetCertificateAtIndex(pvc->builder, ix); + if (!cert || (errSecSuccess != SecCertificateIsSelfSigned(cert, &isSelfSigned)) || !isSelfSigned) { + return false; + } + return true; } } #endif @@ -2395,9 +2203,7 @@ static int32_t detailKeyToCssmErr(CFStringRef key) { else if (CFEqual(key, kSecPolicyCheckEmail)) { result = -2147408872; // CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND } - else if (CFEqual(key, kSecPolicyCheckValidLeaf) || - CFEqual(key, kSecPolicyCheckValidIntermediates) || - CFEqual(key, kSecPolicyCheckValidRoot)) { + else if (CFEqual(key, kSecPolicyCheckTemporalValidity)) { result = -2147409654; // CSSMERR_TP_CERT_EXPIRED } @@ -2458,6 +2264,28 @@ static bool SecPVCKeyIsConstraintPolicyOption(SecPVCRef pvc, CFStringRef key) { return false; } +static SecTrustResultType trust_result_for_key(CFStringRef key) { + SecTrustResultType result = kSecTrustResultRecoverableTrustFailure; +#undef POLICYCHECKMACRO +#define __PC_TYPE_MEMBER_ false +#define __PC_TYPE_MEMBER_R false +#define __PC_TYPE_MEMBER_F true +#define __PC_TYPE_MEMBER_D true + +#define __TRUSTRESULT_ kSecTrustResultRecoverableTrustFailure +#define __TRUSTRESULT_F kSecTrustResultFatalTrustFailure +#define __TRUSTRESULT_D kSecTrustResultDeny +#define __TRUSTRESULT_R kSecTrustResultRecoverableTrustFailure + +#define POLICYCHECKMACRO(NAME, TRUSTRESULT, SUBTYPE, LEAFCHECK, PATHCHECK, LEAFONLY, CSSMERR, OSSTATUS) \ +if (__PC_TYPE_MEMBER_##TRUSTRESULT && CFEqual(key,CFSTR(#NAME))) { \ + result = __TRUSTRESULT_##TRUSTRESULT; \ +} +#include "../Security/SecPolicyChecks.list" + return result; +} + + /* AUDIT[securityd](done): policy->_options is a caller provided dictionary, only its cf type has been checked. @@ -2495,10 +2323,15 @@ bool SecPVCSetResultForced(SecPVCRef pvc, return true; } - /* Check SecPVCIsOkResult to avoid resetting deny or fatal to recoverable */ - if (SecPVCIsOkResult(pvc)) { - pvc->result = kSecTrustResultRecoverableTrustFailure; - } + /* Avoid resetting deny or fatal to recoverable */ + SecTrustResultType trustResult = trust_result_for_key(key); + if (SecPVCIsOkResult(pvc) || trustResult == kSecTrustResultFatalTrustFailure) { + pvc->result = trustResult; + } else if (trustResult == kSecTrustResultDeny && + pvc->result == kSecTrustResultRecoverableTrustFailure) { + pvc->result = trustResult; + } + if (!pvc->details) return false; @@ -2534,19 +2367,27 @@ static void SecPVCValidateKey(const void *key, const void *value, CFDictionaryGetValue(pvc->callbacks, key); if (!fcn) { + /* "Optional" policy checks. This may be a new key from the + * pinning DB which is not implemented in this OS version. Log a + * warning, and on debug builds fail evaluation, to encourage us + * to ensure that checks are synchronized across the same build. */ if (pvc->callbacks == gSecPolicyLeafCallbacks) { if (!CFDictionaryContainsKey(gSecPolicyPathCallbacks, key)) { + secwarning("policy: unknown policy key %@, skipping", key); +#if DEBUG pvc->result = kSecTrustResultOtherError; +#endif } } else if (pvc->callbacks == gSecPolicyPathCallbacks) { if (!CFDictionaryContainsKey(gSecPolicyLeafCallbacks, key)) { + secwarning("policy: unknown policy key %@, skipping", key); +#if DEBUG pvc->result = kSecTrustResultOtherError; +#endif } } else { - /* Non standard validation phase. This may be a new key from the - * pinning DB which is not implemented in this OS version. Log - * a warning. */ - secwarning("policy: unknown policy key %@, skipping", key); + /* Non standard validation phase, nothing is optional. */ + pvc->result = kSecTrustResultOtherError; } return; } @@ -2597,16 +2438,21 @@ bool SecPVCParentCertificateChecks(SecPVCRef pvc, CFIndex ix) { if (!SecCertificateIsValid(cert, verifyTime)) { /* Certificate has expired. */ - if (!SecPVCSetResult(pvc, is_anchor ? kSecPolicyCheckValidRoot - : kSecPolicyCheckValidIntermediates, ix, kCFBooleanFalse)) { + if (!SecPVCSetResult(pvc, kSecPolicyCheckTemporalValidity, ix, kCFBooleanFalse)) { goto errOut; } } if (SecCertificateIsWeakKey(cert)) { /* Certificate uses weak key. */ - if (!SecPVCSetResult(pvc, is_anchor ? kSecPolicyCheckWeakRoot - : kSecPolicyCheckWeakIntermediates, ix, kCFBooleanFalse)) { + if (!SecPVCSetResult(pvc, kSecPolicyCheckWeakKeySize, ix, kCFBooleanFalse)) { + goto errOut; + } + } + + if (!SecPolicyCheckCertWeakSignature(cert, NULL)) { + /* Certificate uses weak hash. */ + if (!SecPVCSetResult(pvc, kSecPolicyCheckWeakSignature, ix, kCFBooleanFalse)) { goto errOut; } } @@ -2621,12 +2467,18 @@ bool SecPVCParentCertificateChecks(SecPVCRef pvc, CFIndex ix) { if (SecCertificateVersion(cert) >= 3) { const SecCEBasicConstraints *bc = SecCertificateGetBasicConstraints(cert); - if (!bc || !bc->isCA) { - /* Basic constraints not present or not marked as isCA, illegal. */ + if (!bc) { + /* Basic constraints not present, illegal. */ if (!SecPVCSetResultForced(pvc, kSecPolicyCheckBasicConstraints, ix, kCFBooleanFalse, true)) { goto errOut; } + } else if (!bc->isCA) { + /* Basic constraints not marked as isCA, illegal. */ + if (!SecPVCSetResultForced(pvc, kSecPolicyCheckBasicConstraintsCA, + ix, kCFBooleanFalse, true)) { + goto errOut; + } } } /* For a v1 or v2 certificate in an intermediate slot (not a leaf and @@ -2685,7 +2537,6 @@ static bool SecPVCBlackListedKeyChecks(SecPVCRef pvc, CFIndex ix) { if (!allowed) { SecPVCSetResultForced(pvc, kSecPolicyCheckBlackListedKey, ix, kCFBooleanFalse, true); - pvc->result = kSecTrustResultFatalTrustFailure; } } CFRelease(dgst); @@ -3065,7 +2916,6 @@ static void SecPVCCheckUsageConstraints(SecPVCRef pvc) { /* Set the pvc trust result based on the usage constraints and anchor source. */ if (result == kSecTrustSettingsResultDeny) { SecPVCSetResultForced(pvc, kSecPolicyCheckUsageConstraints, certIX, kCFBooleanFalse, true); - pvc->result = kSecTrustResultDeny; } else if ((result == kSecTrustSettingsResultTrustRoot || result == kSecTrustSettingsResultTrustAsRoot || result == kSecTrustSettingsResultInvalid) && SecPVCIsOkResult(pvc)) { /* If we already think the PVC is ok and this cert is from one of the user/ @@ -3084,7 +2934,6 @@ static void SecPVCCheckUsageConstraints(SecPVCRef pvc) { } } -#define kSecPolicySHA256Size 32 static const UInt8 kTestDateConstraintsRoot[kSecPolicySHA256Size] = { 0x51,0xA0,0xF3,0x1F,0xC0,0x1D,0xEC,0x87,0x32,0xB6,0xFD,0x13,0x6A,0x43,0x4D,0x6C, 0x87,0xCD,0x62,0xE0,0x38,0xB4,0xFB,0xD6,0x40,0xB0,0xFD,0x62,0x4D,0x1F,0xCF,0x6D @@ -3152,7 +3001,6 @@ static void SecPVCCheckIssuerDateConstraints(SecPVCRef pvc) { /* 1 Dec 2016 00:00:00 GMT */ if (child && (CFAbsoluteTime)502243200.0 <= SecCertificateNotValidBefore(child)) { SecPVCSetResultForced(pvc, kSecPolicyCheckBlackListedKey, certIX, kCFBooleanFalse, true); - pvc->result = kSecTrustResultFatalTrustFailure; shouldDeny = true; break; } @@ -3174,8 +3022,6 @@ void SecPVCPathChecks(SecPVCRef pvc) { pvc->policyIX = 0; SecPolicyCheckIdLinkage(pvc, kSecPolicyCheckIdLinkage); if (SecPVCIsOkResult(pvc) || pvc->details) { - /* @@@ This theoretically only needs to be done once per path, but since - this function affects the pvc result, we'll run it every time. */ SecPolicyCheckBasicCertificateProcessing(pvc, kSecPolicyCheckBasicCertificateProcessing); } @@ -3220,7 +3066,7 @@ void SecPVCPathChecks(SecPVCRef pvc) { /* Check for CT */ /* This call will set the value of pvc->is_ct, but won't change the result (pvc->result) */ - SecPolicyCheckCT(pvc, kSecPolicyCheckCertificateTransparency); + SecPolicyCheckCT(pvc); /* Certs are only EV if they are also CT verified */ if (ev_check_ok && SecCertificatePathVCIsCT(path)) { @@ -3228,7 +3074,21 @@ void SecPVCPathChecks(SecPVCRef pvc) { } } -//errOut: + /* Check that this path meets CT constraints. */ + if (!SecCertificatePathVCIsCT(path)) { + SecPathCTPolicy ctp = SecCertificatePathVCRequiresCT(path); + if (ctp > kSecPathCTNotRequired) { + /* CT was required. Error is always set on leaf certificate. */ + SecPVCSetResultForced(pvc, kSecPolicyCheckCTRequired, + 0, kCFBooleanFalse, true); + if (ctp != kSecPathCTRequiredOverridable) { + /* Normally kSecPolicyCheckCTRequired is recoverable, + so need to manually change trust result here. */ + pvc->result = kSecTrustResultFatalTrustFailure; + } + } + } + secdebug("policy", "end %strusted path: %@", (SecPVCIsOkResult(pvc) ? "" : "not "), SecPathBuilderGetPath(pvc->builder)); @@ -3236,20 +3096,32 @@ void SecPVCPathChecks(SecPVCRef pvc) { return; } -void SecPVCPathCheckRevocationRequired(SecPVCRef pvc) { +void SecPVCPathCheckRevocationResponsesReceived(SecPVCRef pvc) { +#if TARGET_OS_WATCH + /* Since we don't currently allow networking on watchOS, + * don't enforce the revocation-required check here. (32728029) */ + bool required = false; +#else + bool required = true; +#endif SecCertificatePathVCRef path = SecPathBuilderGetPath(pvc->builder); CFIndex ix, certCount = SecCertificatePathVCGetCount(path); for (ix = 0; ix < certCount; ix++) { - /* If we require revocation (for that cert per the SecCertificateVCRef or - * per the pvc) */ - if (SecCertificatePathVCIsRevocationRequiredForCertificateAtIndex(path, ix) || - ((ix == 0) && pvc->require_revocation_response)) { - /* Do we have a valid revocation response? */ - SecRVCRef rvc = SecCertificatePathVCGetRVCAtIndex(path, ix); - if (SecRVCGetEarliestNextUpdate(rvc) == NULL_TIME) { + SecRVCRef rvc = SecCertificatePathVCGetRVCAtIndex(path, ix); + /* Do we have a valid revocation response? */ + if (SecRVCGetEarliestNextUpdate(rvc) == NULL_TIME) { + /* No valid revocation response. + * Do we require revocation (for that cert per the + * SecCertificateVCRef, or per the pvc)? */ + if (required && (SecCertificatePathVCIsRevocationRequiredForCertificateAtIndex(path, ix) || + ((ix == 0) && pvc->require_revocation_response))) { SecPVCSetResultForced(pvc, kSecPolicyCheckRevocationResponseRequired, ix, kCFBooleanFalse, true); } + /* Do we have a definitive Valid revocation result for this cert? */ + if (SecRVCHasDefinitiveValidInfo(rvc) && SecRVCHasRevokedValidInfo(rvc)) { + SecRVCSetRevokedResult(rvc); + } } } } diff --git a/OSX/sec/securityd/SecPolicyServer.h b/OSX/sec/securityd/SecPolicyServer.h index 18840997..90f428ab 100644 --- a/OSX/sec/securityd/SecPolicyServer.h +++ b/OSX/sec/securityd/SecPolicyServer.h @@ -39,6 +39,8 @@ __BEGIN_DECLS +#define kSecPolicySHA256Size 32 + void SecPVCInit(SecPVCRef pvc, SecPathBuilderRef builder, CFArrayRef policies); void SecPVCDelete(SecPVCRef pvc); void SecPVCSetPath(SecPVCRef pvc, SecCertificatePathVCRef path); @@ -71,15 +73,17 @@ bool SecPVCParentCertificateChecks(SecPVCRef pvc, CFIndex ix); SecPathBuilderStep() should be called. */ void SecPVCPathChecks(SecPVCRef pvc); -/* Check whether revocation was required for any cert but revocation - * check failed. */ -void SecPVCPathCheckRevocationRequired(SecPVCRef pvc); +/* Check whether revocation responses were received for certificates + * in the path in pvc. If a valid response was not obtained for a + * certificate, this sets the appropriate error result if revocation + * was required, and/or definitive revocation info is present. */ +void SecPVCPathCheckRevocationResponsesReceived(SecPVCRef pvc); typedef void (*SecPolicyCheckFunction)(SecPVCRef pv, CFStringRef key); /* - Used by SecTrust to verify if a particular certificate chain matches - this policy. Returns true if the policy accepts the certificate chain. + * Used by SecTrust to verify if a particular certificate chain matches + * this policy. Returns true if the policy accepts the certificate chain. */ bool SecPolicyValidate(SecPolicyRef policy, SecPVCRef pvc, CFStringRef key); diff --git a/OSX/sec/securityd/SecRevocationDb.c b/OSX/sec/securityd/SecRevocationDb.c index f102eb64..2b9e6dcc 100644 --- a/OSX/sec/securityd/SecRevocationDb.c +++ b/OSX/sec/securityd/SecRevocationDb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2016-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,11 @@ static CFStringRef kSecPrefsDomain = CFSTR("com.apple.security"); static CFStringRef kUpdateServerKey = CFSTR("ValidUpdateServer"); static CFStringRef kUpdateEnabledKey = CFSTR("ValidUpdateEnabled"); static CFStringRef kUpdateIntervalKey = CFSTR("ValidUpdateInterval"); +static CFStringRef kBoolTrueKey = CFSTR("1"); +static CFStringRef kBoolFalseKey = CFSTR("0"); + +/* constant length of boolean string keys */ +#define BOOL_STRING_KEY_LENGTH 1 typedef CF_OPTIONS(CFOptionFlags, SecValidInfoFlags) { kSecValidInfoComplete = 1u << 0, @@ -80,7 +86,11 @@ typedef CF_OPTIONS(CFOptionFlags, SecValidInfoFlags) { kSecValidInfoKnownOnly = 1u << 2, kSecValidInfoRequireCT = 1u << 3, kSecValidInfoAllowlist = 1u << 4, - kSecValidInfoNoCACheck = 1u << 5 + kSecValidInfoNoCACheck = 1u << 5, + kSecValidInfoOverridable = 1u << 6, + kSecValidInfoDateConstraints = 1u << 7, + kSecValidInfoNameConstraints = 1u << 8, + kSecValidInfoPolicyConstraints = 1u << 9, }; /* minimum update interval */ @@ -97,26 +107,29 @@ typedef CF_OPTIONS(CFOptionFlags, SecValidInfoFlags) { #define kSecRevocationDbFileName "valid.sqlite3" #define kSecRevocationDbReplaceFile ".valid_replace" +#define isDbOwner SecOTAPKIIsSystemTrustd + /* database schema version v1 = initial version v2 = fix for group entry transitions v3 = handle optional entries in update dictionaries v4 = add db_format and db_source entries + v5 = add date constraints table, with updated group flags Note: kSecRevocationDbMinSchemaVersion is the lowest version whose results can be used. This allows revocation results to be obtained from an existing db before the next update interval occurs, at which time we'll update to the current version (kSecRevocationDbSchemaVersion). */ -#define kSecRevocationDbSchemaVersion 4 /* current version we support */ -#define kSecRevocationDbMinSchemaVersion 3 /* minimum version we can use */ +#define kSecRevocationDbSchemaVersion 5 /* current version we support */ +#define kSecRevocationDbMinSchemaVersion 5 /* minimum version we can use */ /* update file format */ CF_ENUM(CFIndex) { - kSecValidUpdateFormatG1 = 1, /* initial version */ - kSecValidUpdateFormatG2 = 2, /* signed content, single plist */ - kSecValidUpdateFormatG3 = 3 /* signed content, multiple plists */ + kSecValidUpdateFormatG1 = 1, /* initial version */ + kSecValidUpdateFormatG2 = 2, /* signed content, single plist */ + kSecValidUpdateFormatG3 = 3 /* signed content, multiple plists */ }; #define kSecRevocationDbUpdateFormat 3 /* current version we support */ @@ -126,7 +139,9 @@ bool SecRevocationDbVerifyUpdate(void *update, CFIndex length); CFIndex SecRevocationDbIngestUpdate(CFDictionaryRef update, CFIndex chunkVersion); void SecRevocationDbApplyUpdate(CFDictionaryRef update, CFIndex version); CFAbsoluteTime SecRevocationDbComputeNextUpdateTime(CFIndex updateInterval); -void SecRevocationDbSetSchemaVersion(CFIndex dbversion); +bool SecRevocationDbSetVersion(CFIndex version); +bool SecRevocationDbSetSchemaVersion(CFIndex dbversion); +bool SecRevocationDbUpdateSchema(void); CFIndex SecRevocationDbGetUpdateFormat(void); void SecRevocationDbSetUpdateFormat(CFIndex dbformat); void SecRevocationDbSetUpdateSource(CFStringRef source); @@ -362,19 +377,6 @@ static bool removeFileWithSuffix(const char *basepath, const char *suffix) { return result; } -static bool isDbOwner() { -#if TARGET_OS_EMBEDDED - if (getuid() == 64) // _securityd -#else - if (getuid() == 0) -#endif - { - return true; - } - return false; -} - - // MARK: - // MARK: SecValidUpdate @@ -489,7 +491,7 @@ static bool SecValidUpdateProcessData(CFIndex format, CFDataRef updateData) { } if (version > 0) { - secdebug("validupdate", "Update received: v%lu", (unsigned long)version); + secdebug("validupdate", "Update received: v%ld", (long)version); gLastVersion = version; gNextUpdate = SecRevocationDbComputeNextUpdateTime(interval); secdebug("validupdate", "Next update time: %f", gNextUpdate); @@ -516,41 +518,16 @@ void SecValidUpdateVerifyAndIngest(CFDataRef updateData) { } if (!result) { secerror("failed to process valid update"); + TrustdHealthAnalyticsLogErrorCode(TAEventValidUpdate, TAFatalError, errSecDecode); + } else { + TrustdHealthAnalyticsLogSuccess(TAEventValidUpdate); } } else { secerror("failed to verify valid update"); + TrustdHealthAnalyticsLogErrorCode(TAEventValidUpdate, TAFatalError, errSecVerifyFailed); } } -static bool SecValidUpdateFromCompressed(CFDataRef CF_CONSUMED data) { - if (!data) { return false; } - - /* We're about to use a lot of memory for the uncompressed update -- go active */ - os_transaction_t transaction; - transaction = os_transaction_create("com.apple.trustd.valid"); - - /* Expand the update */ - __block CFDataRef inflatedData = NULL; - WithPathInRevocationInfoDirectory(CFSTR(kSecRevocationCurUpdateFile), ^(const char *curUpdatePath) { - inflatedData = copyInflatedDataToFile(data, (char *)curUpdatePath); - secdebug("validupdate", "data expanded: %ld bytes", (long)CFDataGetLength(inflatedData)); - }); - unmapData(data); - os_release(transaction); - - if (inflatedData) { - SecValidUpdateVerifyAndIngest(inflatedData); - unmapData(inflatedData); - } - - /* All done with the temporary file */ - WithPathInRevocationInfoDirectory(CFSTR(kSecRevocationCurUpdateFile), ^(const char *curUpdatePath) { - (void)removeFileWithSuffix(curUpdatePath, ""); - }); - - return true; -} - static bool SecValidDatabaseFromCompressed(CFDataRef CF_CONSUMED data) { if (!data) { return false; } @@ -670,28 +647,14 @@ static bool SecValidUpdateSatisfiedLocally(CFStringRef server, CFIndex version, } } result = SecValidDatabaseFromCompressed(data); - if (result) { - goto updateExit; - } - - // unable to use database asset; try update asset - const char *validUpdatePathBuf = SecOTAPKIGetValidUpdateSnapshot(otapkiRef); - if (validUpdatePathBuf) { - secdebug("validupdate", "will read data from \"%s\"", validUpdatePathBuf); - if ((rtn = readValidFile(validUpdatePathBuf, &data)) != 0) { - unmapData(data); - data = NULL; - secnotice("validupdate", "readValidFile error %d", rtn); - } - } - result = SecValidUpdateFromCompressed(data); updateExit: CFReleaseNull(otapkiRef); if (result) { sNumLocalUpdates++; - SecRevocationDbSetUpdateSource(server); gLastVersion = SecRevocationDbGetVersion(); + SecRevocationDbSetUpdateSource(server); + SecRevocationDbUpdateSchema(); gUpdateStarted = 0; secdebug("validupdate", "local update to g%ld/v%ld complete at %f", (long)SecRevocationDbGetUpdateFormat(), (long)gLastVersion, @@ -715,6 +678,7 @@ static bool SecValidUpdateSchedule(bool updateEnabled, CFStringRef server, CFInd #if !TARGET_OS_BRIDGE /* Schedule as a maintenance task */ + secdebug("validupdate", "will fetch v%lu from \"%@\"", (unsigned long)version, server); return SecValidUpdateRequest(SecRevocationDbGetUpdateQueue(), server, version); #else return false; @@ -789,13 +753,23 @@ static SecValidInfoRef SecValidInfoCreate(SecValidInfoFormat format, bool isOnList, CFDataRef certHash, CFDataRef issuerHash, - CFDataRef anchorHash) { + CFDataRef anchorHash, + CFDateRef notBeforeDate, + CFDateRef notAfterDate, + CFDataRef nameConstraints, + CFDataRef policyConstraints) { SecValidInfoRef validInfo; validInfo = (SecValidInfoRef)calloc(1, sizeof(struct __SecValidInfo)); if (!validInfo) { return NULL; } CFRetainSafe(certHash); CFRetainSafe(issuerHash); + CFRetainSafe(anchorHash); + CFRetainSafe(notBeforeDate); + CFRetainSafe(notAfterDate); + CFRetainSafe(nameConstraints); + CFRetainSafe(policyConstraints); + validInfo->format = format; validInfo->certHash = certHash; validInfo->issuerHash = issuerHash; @@ -807,15 +781,27 @@ static SecValidInfoRef SecValidInfoCreate(SecValidInfoFormat format, validInfo->knownOnly = (flags & kSecValidInfoKnownOnly); validInfo->requireCT = (flags & kSecValidInfoRequireCT); validInfo->noCACheck = (flags & kSecValidInfoNoCACheck); + validInfo->overridable = (flags & kSecValidInfoOverridable); + validInfo->hasDateConstraints = (flags & kSecValidInfoDateConstraints); + validInfo->hasNameConstraints = (flags & kSecValidInfoNameConstraints); + validInfo->hasPolicyConstraints = (flags & kSecValidInfoPolicyConstraints); + validInfo->notBeforeDate = notBeforeDate; + validInfo->notAfterDate = notAfterDate; + validInfo->nameConstraints = nameConstraints; + validInfo->policyConstraints = policyConstraints; return validInfo; } void SecValidInfoRelease(SecValidInfoRef validInfo) { if (validInfo) { - CFReleaseSafe(validInfo->certHash); - CFReleaseSafe(validInfo->issuerHash); - CFReleaseSafe(validInfo->anchorHash); + CFReleaseNull(validInfo->certHash); + CFReleaseNull(validInfo->issuerHash); + CFReleaseNull(validInfo->anchorHash); + CFReleaseNull(validInfo->notBeforeDate); + CFReleaseNull(validInfo->notAfterDate); + CFReleaseNull(validInfo->nameConstraints); + CFReleaseNull(validInfo->policyConstraints); free(validInfo); } } @@ -934,8 +920,7 @@ static bool _SecRevocationDbCheckNextUpdate(void) { if (db_version < kSecRevocationDbSchemaVersion || db_format < kSecRevocationDbUpdateFormat || kCFCompareEqualTo != CFStringCompare(server, db_source, kCFCompareCaseInsensitive)) { - /* we need to fully rebuild the db contents. */ - SecRevocationDbRemoveAllEntries(); + // we need to fully rebuild the db contents, so we set our version to 0. version = gLastVersion = 0; } @@ -1130,7 +1115,7 @@ CFIndex SecRevocationDbIngestUpdate(CFDictionaryRef update, CFIndex chunkVersion /* admin table holds these key-value (or key-ival) pairs: 'version' (integer) // version of database content - 'check_again' (double) // CFAbsoluteTime of next check (optional; this value is currently stored in prefs) + 'check_again' (double) // CFAbsoluteTime of next check (optional) 'db_version' (integer) // version of database schema 'db_hash' (blob) // SHA-256 database hash --> entries in admin table are unique by text key @@ -1144,12 +1129,16 @@ CFIndex SecRevocationDbIngestUpdate(CFDictionaryRef update, CFIndex chunkVersion groups table holds records with these attributes: groupid (integer) // ordinal ID associated with this group entry flags (integer) // a bitmask of the following values: - kSecValidInfoComplete (0x00000001) set if we have all revocation info for this issuer group - kSecValidInfoCheckOCSP (0x00000002) set if must check ocsp for certs from this issuer group - kSecValidInfoKnownOnly (0x00000004) set if any CA from this issuer group must be in database - kSecValidInfoRequireCT (0x00000008) set if all certs from this issuer group must have SCTs - kSecValidInfoAllowlist (0x00000010) set if this entry describes valid certs (i.e. is allowed) - kSecValidInfoNoCACheck (0x00000020) set if this entry does not require an OCSP check to accept + kSecValidInfoComplete (0x00000001) set if we have all revocation info for this issuer group + kSecValidInfoCheckOCSP (0x00000002) set if must check ocsp for certs from this issuer group + kSecValidInfoKnownOnly (0x00000004) set if any CA from this issuer group must be in database + kSecValidInfoRequireCT (0x00000008) set if all certs from this issuer group must have SCTs + kSecValidInfoAllowlist (0x00000010) set if this entry describes valid certs (i.e. is allowed) + kSecValidInfoNoCACheck (0x00000020) set if this entry does not require an OCSP check to accept + kSecValidInfoOverridable (0x00000040) set if the trust status is recoverable and can be overridden + kSecValidInfoDateConstraints (0x00000080) set if this group has not-before or not-after constraints + kSecValidInfoNameConstraints (0x00000100) [RESERVED] set if this group has name constraints in database + kSecValidInfoPolicyConstraints (0x00000200) [RESERVED] set if this group has policy constraints in database format (integer) // an integer describing format of entries: kSecValidInfoFormatUnknown (0) unknown format kSecValidInfoFormatSerial (1) serial number, not greater than 20 bytes in length @@ -1159,90 +1148,118 @@ CFIndex SecRevocationDbIngestUpdate(CFDictionaryRef update, CFIndex chunkVersion --> entries in groups table are unique by groupid serials table holds serial number blobs with these attributes: - rowid (integer) // ordinal ID associated with this serial number entry groupid (integer) // identifier for issuer group in the groups table serial (blob) // serial number --> entries in serials table are unique by serial and groupid hashes table holds SHA-256 hashes of certificates with these attributes: - rowid (integer) // ordinal ID associated with this sha256 hash entry groupid (integer) // identifier for issuer group in the groups table sha256 (blob) // SHA-256 hash of subject certificate --> entries in hashes table are unique by sha256 and groupid + + dates table holds notBefore and notAfter dates (as CFAbsoluteTime) with these attributes: + groupid (integer) // identifier for issuer group in the groups table (primary key) + notbefore (real) // issued certs are invalid if their notBefore is prior to this date + notafter (real) // issued certs are invalid after this date (or their notAfter, if earlier) + --> entries in dates table are unique by groupid, and only exist if kSecValidInfoDateConstraints is true + */ #define createTablesSQL CFSTR("CREATE TABLE admin(" \ - "key TEXT PRIMARY KEY NOT NULL," \ - "ival INTEGER NOT NULL," \ - "value BLOB" \ + "key TEXT PRIMARY KEY NOT NULL," \ + "ival INTEGER NOT NULL," \ + "value BLOB" \ ");" \ "CREATE TABLE issuers(" \ - "groupid INTEGER NOT NULL," \ - "issuer_hash BLOB PRIMARY KEY NOT NULL" \ + "groupid INTEGER NOT NULL," \ + "issuer_hash BLOB PRIMARY KEY NOT NULL" \ ");" \ "CREATE INDEX issuer_idx ON issuers(issuer_hash);" \ "CREATE TABLE groups(" \ - "groupid INTEGER PRIMARY KEY AUTOINCREMENT," \ - "flags INTEGER," \ - "format INTEGER," \ - "data BLOB" \ + "groupid INTEGER PRIMARY KEY AUTOINCREMENT," \ + "flags INTEGER," \ + "format INTEGER," \ + "data BLOB" \ ");" \ "CREATE TABLE serials(" \ - "rowid INTEGER PRIMARY KEY AUTOINCREMENT," \ - "groupid INTEGER NOT NULL," \ - "serial BLOB NOT NULL," \ - "UNIQUE(groupid,serial)" \ + "groupid INTEGER NOT NULL," \ + "serial BLOB NOT NULL," \ + "UNIQUE(groupid,serial)" \ ");" \ "CREATE TABLE hashes(" \ - "rowid INTEGER PRIMARY KEY AUTOINCREMENT," \ - "groupid INTEGER NOT NULL," \ - "sha256 BLOB NOT NULL," \ - "UNIQUE(groupid,sha256)" \ + "groupid INTEGER NOT NULL," \ + "sha256 BLOB NOT NULL," \ + "UNIQUE(groupid,sha256)" \ + ");" \ + "CREATE TABLE dates(" \ + "groupid INTEGER PRIMARY KEY NOT NULL," \ + "notbefore REAL," \ + "notafter REAL," \ ");" \ "CREATE TRIGGER group_del BEFORE DELETE ON groups FOR EACH ROW " \ "BEGIN " \ - "DELETE FROM serials WHERE groupid=OLD.groupid; " \ - "DELETE FROM hashes WHERE groupid=OLD.groupid; " \ - "DELETE FROM issuers WHERE groupid=OLD.groupid; " \ + "DELETE FROM serials WHERE groupid=OLD.groupid; " \ + "DELETE FROM hashes WHERE groupid=OLD.groupid; " \ + "DELETE FROM issuers WHERE groupid=OLD.groupid; " \ + "DELETE FROM dates WHERE groupid=OLD.groupid; " \ "END;") #define selectGroupIdSQL CFSTR("SELECT DISTINCT groupid " \ -"FROM issuers WHERE issuer_hash=?") + "FROM issuers WHERE issuer_hash=?") #define selectVersionSQL CFSTR("SELECT ival FROM admin " \ -"WHERE key='version'") + "WHERE key='version'") #define selectDbVersionSQL CFSTR("SELECT ival FROM admin " \ -"WHERE key='db_version'") + "WHERE key='db_version'") #define selectDbFormatSQL CFSTR("SELECT ival FROM admin " \ -"WHERE key='db_format'") + "WHERE key='db_format'") #define selectDbHashSQL CFSTR("SELECT value FROM admin " \ -"WHERE key='db_hash'") + "WHERE key='db_hash'") #define selectDbSourceSQL CFSTR("SELECT value FROM admin " \ -"WHERE key='db_source'") + "WHERE key='db_source'") #define selectNextUpdateSQL CFSTR("SELECT value FROM admin " \ -"WHERE key='check_again'") + "WHERE key='check_again'") #define selectGroupRecordSQL CFSTR("SELECT flags,format,data FROM " \ -"groups WHERE groupid=?") + "groups WHERE groupid=?") #define selectSerialRecordSQL CFSTR("SELECT rowid FROM serials " \ -"WHERE groupid=? AND serial=?") + "WHERE groupid=? AND serial=?") +#define selectDateRecordSQL CFSTR("SELECT notbefore,notafter FROM " \ + "dates WHERE groupid=?") #define selectHashRecordSQL CFSTR("SELECT rowid FROM hashes " \ -"WHERE groupid=? AND sha256=?") + "WHERE groupid=? AND sha256=?") #define insertAdminRecordSQL CFSTR("INSERT OR REPLACE INTO admin " \ -"(key,ival,value) VALUES (?,?,?)") + "(key,ival,value) VALUES (?,?,?)") #define insertIssuerRecordSQL CFSTR("INSERT OR REPLACE INTO issuers " \ -"(groupid,issuer_hash) VALUES (?,?)") + "(groupid,issuer_hash) VALUES (?,?)") #define insertGroupRecordSQL CFSTR("INSERT OR REPLACE INTO groups " \ -"(groupid,flags,format,data) VALUES (?,?,?,?)") + "(groupid,flags,format,data) VALUES (?,?,?,?)") #define insertSerialRecordSQL CFSTR("INSERT OR REPLACE INTO serials " \ -"(groupid,serial) VALUES (?,?)") + "(groupid,serial) VALUES (?,?)") +#define insertDateRecordSQL CFSTR("INSERT OR REPLACE INTO dates " \ + "(groupid,notbefore,notafter) VALUES (?,?,?)") #define insertSha256RecordSQL CFSTR("INSERT OR REPLACE INTO hashes " \ -"(groupid,sha256) VALUES (?,?)") + "(groupid,sha256) VALUES (?,?)") #define deleteGroupRecordSQL CFSTR("DELETE FROM groups WHERE groupid=?") -#define deleteAllEntriesSQL CFSTR("DELETE from hashes; " \ -"DELETE from serials; DELETE from issuers; DELETE from groups; " \ -"DELETE from admin; DELETE from sqlite_sequence") +#define updateConstraintsTablesSQL CFSTR("" \ +"CREATE TABLE if not exists dates(" \ + "groupid INTEGER PRIMARY KEY NOT NULL," \ + "notbefore REAL," \ + "notafter REAL," \ +");") + +#define updateGroupDeleteTriggerSQL CFSTR("" \ + "DROP TRIGGER if exists group_del;" \ + "CREATE TRIGGER group_del BEFORE DELETE ON groups FOR EACH ROW " \ + "BEGIN " \ + "DELETE FROM serials WHERE groupid=OLD.groupid; " \ + "DELETE FROM hashes WHERE groupid=OLD.groupid; " \ + "DELETE FROM issuers WHERE groupid=OLD.groupid; " \ + "DELETE FROM dates WHERE groupid=OLD.groupid; " \ + "END;") + #define deleteTablesSQL CFSTR("DROP TABLE hashes; " \ -"DROP TABLE serials; DROP TABLE issuers; DROP TABLE groups; " \ -"DROP TABLE admin; DELETE from sqlite_sequence") + "DROP TABLE serials; DROP TABLE issuers; " \ + "DROP TABLE dates; DROP TABLE groups; " \ + "DROP TABLE admin; DELETE from sqlite_sequence") /* Database management */ @@ -1263,9 +1280,15 @@ static SecDbRef SecRevocationDbCreate(CFStringRef path) { *commit = ok; }); } - CFReleaseSafe(localError); - if (!ok) + if (!ok || localError) { + CFIndex errCode = errSecInternalComponent; + if (error && *error) { + errCode = CFErrorGetCode(*error); + } secerror("%s failed: %@", didCreate ? "Create" : "Open", error ? *error : NULL); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationCreate, TAFatalError, errCode); + } + CFReleaseSafe(localError); return ok; }); @@ -1295,6 +1318,7 @@ static SecRevocationDbRef SecRevocationDbInit(CFStringRef db_name) { require(rdb->db = SecRevocationDbCreate(db_name), errOut); attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_BACKGROUND, 0); + attr = dispatch_queue_attr_make_with_autorelease_frequency(attr, DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM); require(rdb->update_queue = dispatch_queue_create(NULL, attr), errOut); return rdb; @@ -1350,42 +1374,45 @@ static int64_t _SecRevocationDbGetVersion(SecRevocationDbRef rdb, CFErrorRef *er __block CFErrorRef localError = NULL; ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - if (ok) ok &= SecDbWithSQL(dbconn, selectVersionSQL, &localError, ^bool(sqlite3_stmt *selectVersion) { - ok = SecDbStep(dbconn, selectVersion, &localError, NULL); - version = sqlite3_column_int64(selectVersion, 0); + ok &= SecDbWithSQL(dbconn, selectVersionSQL, &localError, ^bool(sqlite3_stmt *selectVersion) { + ok &= SecDbStep(dbconn, selectVersion, &localError, ^void(bool *stop) { + version = sqlite3_column_int64(selectVersion, 0); + *stop = true; + }); return ok; }); }); + if (!ok || localError) { + secerror("_SecRevocationDbGetVersion failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationRead, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); + } (void) CFErrorPropagate(localError, error); return version; } -static void _SecRevocationDbSetVersion(SecRevocationDbRef rdb, CFIndex version){ +static void _SecRevocationDbSetVersion(SecRevocationDbRef rdb, CFIndex version) { secdebug("validupdate", "setting version to %ld", (long)version); __block CFErrorRef localError = NULL; __block bool ok = true; ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - if (ok) ok = SecDbWithSQL(dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertVersion) { - if (ok) { - const char *versionKey = "version"; - ok = SecDbBindText(insertVersion, 1, versionKey, strlen(versionKey), - SQLITE_TRANSIENT, &localError); - } - if (ok) { - ok = SecDbBindInt64(insertVersion, 2, - (sqlite3_int64)version, &localError); - } - if (ok) { - ok = SecDbStep(dbconn, insertVersion, &localError, NULL); - } + ok &= SecDbWithSQL(dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertVersion) { + const char *versionKey = "version"; + ok = ok && SecDbBindText(insertVersion, 1, versionKey, strlen(versionKey), + SQLITE_TRANSIENT, &localError); + ok = ok && SecDbBindInt64(insertVersion, 2, + (sqlite3_int64)version, &localError); + ok = ok && SecDbStep(dbconn, insertVersion, &localError, NULL); return ok; }); }); }); - if (!ok) { + if (!ok || localError) { secerror("_SecRevocationDbSetVersion failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); } CFReleaseSafe(localError); } @@ -1397,46 +1424,83 @@ static int64_t _SecRevocationDbGetSchemaVersion(SecRevocationDbRef rdb, CFErrorR __block CFErrorRef localError = NULL; ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - if (ok) ok &= SecDbWithSQL(dbconn, selectDbVersionSQL, &localError, ^bool(sqlite3_stmt *selectDbVersion) { - ok = SecDbStep(dbconn, selectDbVersion, &localError, NULL); - db_version = sqlite3_column_int64(selectDbVersion, 0); + ok &= SecDbWithSQL(dbconn, selectDbVersionSQL, &localError, ^bool(sqlite3_stmt *selectDbVersion) { + ok &= SecDbStep(dbconn, selectDbVersion, &localError, ^void(bool *stop) { + db_version = sqlite3_column_int64(selectDbVersion, 0); + *stop = true; + }); return ok; }); }); + if (!ok || localError) { + secerror("_SecRevocationDbGetSchemaVersion failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationRead, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); + } (void) CFErrorPropagate(localError, error); return db_version; } -static void _SecRevocationDbSetSchemaVersion(SecRevocationDbRef rdb, CFIndex dbversion) { +static bool _SecRevocationDbSetSchemaVersion(SecRevocationDbRef rdb, CFIndex dbversion) { + if (dbversion > 0) { + int64_t db_version = _SecRevocationDbGetSchemaVersion(rdb, NULL); + if (db_version >= dbversion) { + return true; /* requested schema is earlier than current schema */ + } + } secdebug("validupdate", "setting db_version to %ld", (long)dbversion); __block CFErrorRef localError = NULL; __block bool ok = true; ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - if (ok) ok = SecDbWithSQL(dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertDbVersion) { - if (ok) { - const char *dbVersionKey = "db_version"; - ok = SecDbBindText(insertDbVersion, 1, dbVersionKey, strlen(dbVersionKey), - SQLITE_TRANSIENT, &localError); - } - if (ok) { - ok = SecDbBindInt64(insertDbVersion, 2, - (sqlite3_int64)dbversion, &localError); - } - if (ok) { - ok = SecDbStep(dbconn, insertDbVersion, &localError, NULL); - } + ok &= SecDbWithSQL(dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertDbVersion) { + const char *dbVersionKey = "db_version"; + ok = ok && SecDbBindText(insertDbVersion, 1, dbVersionKey, strlen(dbVersionKey), + SQLITE_TRANSIENT, &localError); + ok = ok && SecDbBindInt64(insertDbVersion, 2, + (sqlite3_int64)dbversion, &localError); + ok = ok && SecDbStep(dbconn, insertDbVersion, &localError, NULL); return ok; }); }); }); - if (!ok) { + if (!ok || localError) { secerror("_SecRevocationDbSetSchemaVersion failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); } else { rdb->unsupportedVersion = false; } CFReleaseSafe(localError); + return ok; +} + +static bool _SecRevocationDbUpdateSchema(SecRevocationDbRef rdb) { + secdebug("validupdate", "updating db schema to v%ld", (long)kSecRevocationDbSchemaVersion); + + __block CFErrorRef localError = NULL; + __block bool ok = true; + ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { + ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { + ok &= SecDbWithSQL(dbconn, updateConstraintsTablesSQL, &localError, ^bool(sqlite3_stmt *updateTables) { + ok = SecDbStep(dbconn, updateTables, &localError, NULL); + return ok; + }); + + ok &= SecDbWithSQL(dbconn, updateGroupDeleteTriggerSQL, &localError, ^bool(sqlite3_stmt *updateTrigger) { + ok = SecDbStep(dbconn, updateTrigger, &localError, NULL); + return ok; + }); + }); + }); + if (!ok) { + secerror("_SecRevocationDbUpdateSchema failed: %@", localError); + } else { + ok &= _SecRevocationDbSetSchemaVersion(rdb, kSecRevocationDbSchemaVersion); + } + CFReleaseSafe(localError); + return ok; } static int64_t _SecRevocationDbGetUpdateFormat(SecRevocationDbRef rdb, CFErrorRef *error) { @@ -1446,12 +1510,19 @@ static int64_t _SecRevocationDbGetUpdateFormat(SecRevocationDbRef rdb, CFErrorRe __block CFErrorRef localError = NULL; ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - if (ok) ok &= SecDbWithSQL(dbconn, selectDbFormatSQL, &localError, ^bool(sqlite3_stmt *selectDbFormat) { - ok = SecDbStep(dbconn, selectDbFormat, &localError, NULL); - db_format = sqlite3_column_int64(selectDbFormat, 0); + ok &= SecDbWithSQL(dbconn, selectDbFormatSQL, &localError, ^bool(sqlite3_stmt *selectDbFormat) { + ok &= SecDbStep(dbconn, selectDbFormat, &localError, ^void(bool *stop) { + db_format = sqlite3_column_int64(selectDbFormat, 0); + *stop = true; + }); return ok; }); }); + if (!ok || localError) { + secerror("_SecRevocationDbGetUpdateFormat failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationRead, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); + } (void) CFErrorPropagate(localError, error); return db_format; } @@ -1463,25 +1534,21 @@ static void _SecRevocationDbSetUpdateFormat(SecRevocationDbRef rdb, CFIndex dbfo __block bool ok = true; ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - if (ok) ok = SecDbWithSQL(dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertDbFormat) { - if (ok) { - const char *dbFormatKey = "db_format"; - ok = SecDbBindText(insertDbFormat, 1, dbFormatKey, strlen(dbFormatKey), - SQLITE_TRANSIENT, &localError); - } - if (ok) { - ok = SecDbBindInt64(insertDbFormat, 2, - (sqlite3_int64)dbformat, &localError); - } - if (ok) { - ok = SecDbStep(dbconn, insertDbFormat, &localError, NULL); - } + ok &= SecDbWithSQL(dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertDbFormat) { + const char *dbFormatKey = "db_format"; + ok = ok && SecDbBindText(insertDbFormat, 1, dbFormatKey, strlen(dbFormatKey), + SQLITE_TRANSIENT, &localError); + ok = ok && SecDbBindInt64(insertDbFormat, 2, + (sqlite3_int64)dbformat, &localError); + ok = ok && SecDbStep(dbconn, insertDbFormat, &localError, NULL); return ok; }); }); }); - if (!ok) { + if (!ok || localError) { secerror("_SecRevocationDbSetUpdateFormat failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); } else { rdb->unsupportedVersion = false; } @@ -1495,19 +1562,25 @@ static CFStringRef _SecRevocationDbCopyUpdateSource(SecRevocationDbRef rdb, CFEr __block CFErrorRef localError = NULL; ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - if (ok) ok &= SecDbWithSQL(dbconn, selectDbSourceSQL, &localError, ^bool(sqlite3_stmt *selectDbSource) { - ok = SecDbStep(dbconn, selectDbSource, &localError, NULL); - const UInt8 *p = (const UInt8 *)sqlite3_column_blob(selectDbSource, 0); - if (p != NULL) { - CFIndex length = (CFIndex)sqlite3_column_bytes(selectDbSource, 0); - if (length > 0) { - updateSource = CFStringCreateWithBytes(kCFAllocatorDefault, p, length, kCFStringEncodingUTF8, false); + ok &= SecDbWithSQL(dbconn, selectDbSourceSQL, &localError, ^bool(sqlite3_stmt *selectDbSource) { + ok &= SecDbStep(dbconn, selectDbSource, &localError, ^void(bool *stop) { + const UInt8 *p = (const UInt8 *)sqlite3_column_blob(selectDbSource, 0); + if (p != NULL) { + CFIndex length = (CFIndex)sqlite3_column_bytes(selectDbSource, 0); + if (length > 0) { + updateSource = CFStringCreateWithBytes(kCFAllocatorDefault, p, length, kCFStringEncodingUTF8, false); + } } - } + *stop = true; + }); return ok; }); }); - + if (!ok || localError) { + secerror("_SecRevocationDbCopyUpdateSource failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationRead, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); + } (void) CFErrorPropagate(localError, error); return updateSource; } @@ -1534,30 +1607,24 @@ static void _SecRevocationDbSetUpdateSource(SecRevocationDbRef rdb, CFStringRef __block bool ok = true; ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - if (ok) ok = SecDbWithSQL(dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertRecord) { - if (ok) { - const char *dbSourceKey = "db_source"; - ok = SecDbBindText(insertRecord, 1, dbSourceKey, strlen(dbSourceKey), - SQLITE_TRANSIENT, &localError); - } - if (ok) { - ok = SecDbBindInt64(insertRecord, 2, - (sqlite3_int64)0, &localError); - } - if (ok) { - ok = SecDbBindBlob(insertRecord, 3, - updateSourceCStr, strlen(updateSourceCStr), - SQLITE_TRANSIENT, &localError); - } - if (ok) { - ok = SecDbStep(dbconn, insertRecord, &localError, NULL); - } + ok &= SecDbWithSQL(dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertRecord) { + const char *dbSourceKey = "db_source"; + ok = ok && SecDbBindText(insertRecord, 1, dbSourceKey, strlen(dbSourceKey), + SQLITE_TRANSIENT, &localError); + ok = ok && SecDbBindInt64(insertRecord, 2, + (sqlite3_int64)0, &localError); + ok = ok && SecDbBindBlob(insertRecord, 3, + updateSourceCStr, strlen(updateSourceCStr), + SQLITE_TRANSIENT, &localError); + ok = ok && SecDbStep(dbconn, insertRecord, &localError, NULL); return ok; }); }); }); - if (!ok) { + if (!ok || localError) { secerror("_SecRevocationDbSetUpdateSource failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); } CFReleaseSafe(localError); } @@ -1569,18 +1636,24 @@ static CFAbsoluteTime _SecRevocationDbGetNextUpdateTime(SecRevocationDbRef rdb, __block CFErrorRef localError = NULL; ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { - if (ok) ok &= SecDbWithSQL(dbconn, selectNextUpdateSQL, &localError, ^bool(sqlite3_stmt *selectNextUpdate) { - ok = SecDbStep(dbconn, selectNextUpdate, &localError, NULL); - CFAbsoluteTime *p = (CFAbsoluteTime *)sqlite3_column_blob(selectNextUpdate, 0); - if (p != NULL) { - if (sizeof(CFAbsoluteTime) == sqlite3_column_bytes(selectNextUpdate, 0)) { - nextUpdate = *p; + ok &= SecDbWithSQL(dbconn, selectNextUpdateSQL, &localError, ^bool(sqlite3_stmt *selectNextUpdate) { + ok &= SecDbStep(dbconn, selectNextUpdate, &localError, ^void(bool *stop) { + CFAbsoluteTime *p = (CFAbsoluteTime *)sqlite3_column_blob(selectNextUpdate, 0); + if (p != NULL) { + if (sizeof(CFAbsoluteTime) == sqlite3_column_bytes(selectNextUpdate, 0)) { + nextUpdate = *p; + } } - } + *stop = true; + }); return ok; }); }); - + if (!ok || localError) { + secerror("_SecRevocationDbGetNextUpdateTime failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationRead, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); + } (void) CFErrorPropagate(localError, error); return nextUpdate; } @@ -1592,30 +1665,24 @@ static void _SecRevocationDbSetNextUpdateTime(SecRevocationDbRef rdb, CFAbsolute __block bool ok = true; ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - if (ok) ok = SecDbWithSQL(dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertRecord) { - if (ok) { - const char *nextUpdateKey = "check_again"; - ok = SecDbBindText(insertRecord, 1, nextUpdateKey, strlen(nextUpdateKey), - SQLITE_TRANSIENT, &localError); - } - if (ok) { - ok = SecDbBindInt64(insertRecord, 2, - (sqlite3_int64)0, &localError); - } - if (ok) { - ok = SecDbBindBlob(insertRecord, 3, - &nextUpdate, sizeof(CFAbsoluteTime), - SQLITE_TRANSIENT, &localError); - } - if (ok) { - ok = SecDbStep(dbconn, insertRecord, &localError, NULL); - } + ok &= SecDbWithSQL(dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertRecord) { + const char *nextUpdateKey = "check_again"; + ok = ok && SecDbBindText(insertRecord, 1, nextUpdateKey, strlen(nextUpdateKey), + SQLITE_TRANSIENT, &localError); + ok = ok && SecDbBindInt64(insertRecord, 2, + (sqlite3_int64)0, &localError); + ok = ok && SecDbBindBlob(insertRecord, 3, + &nextUpdate, sizeof(CFAbsoluteTime), + SQLITE_TRANSIENT, &localError); + ok = ok && SecDbStep(dbconn, insertRecord, &localError, NULL); return ok; }); }); }); - if (!ok) { + if (!ok || localError) { secerror("_SecRevocationDbSetNextUpdate failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); } CFReleaseSafe(localError); } @@ -1625,12 +1692,11 @@ static bool _SecRevocationDbRemoveAllEntries(SecRevocationDbRef rdb) { __block bool ok = true; __block CFErrorRef localError = NULL; + /* update schema first */ + _SecRevocationDbUpdateSchema(rdb); + ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - //ok &= SecDbWithSQL(dbconn, deleteAllEntriesSQL, &localError, ^bool(sqlite3_stmt *deleteAll) { - // ok = SecDbStep(dbconn, deleteAll, &localError, NULL); - // return ok; - //}); /* drop all tables and recreate them, in case of schema changes */ ok &= SecDbExec(dbconn, deleteTablesSQL, &localError); ok &= SecDbExec(dbconn, createTablesSQL, &localError); @@ -1638,12 +1704,17 @@ static bool _SecRevocationDbRemoveAllEntries(SecRevocationDbRef rdb) { *commit = ok; }); /* compact the db (must be done outside transaction scope) */ - SecDbExec(dbconn, CFSTR("VACUUM"), &localError); + ok &= SecDbExec(dbconn, CFSTR("VACUUM"), &localError); }); /* one more thing: update the schema version and format to current */ _SecRevocationDbSetSchemaVersion(rdb, kSecRevocationDbSchemaVersion); _SecRevocationDbSetUpdateFormat(rdb, kSecRevocationDbUpdateFormat); + if (!ok || localError) { + secerror("_SecRevocationDbRemoveAllEntries failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); + } CFReleaseSafe(localError); return ok; } @@ -1663,33 +1734,31 @@ static bool _SecRevocationDbUpdateIssuers(SecRevocationDbRef rdb, int64_t groupI for (issuerIX=0; issuerIXdb, &localError, ^(SecDbConnectionRef dbconn) { + ok &= SecDbWithSQL(dbconn, selectDateRecordSQL, &localError, ^bool(sqlite3_stmt *selectDates) { + /* (groupid,notbefore,notafter) */ + ok &= SecDbBindInt64(selectDates, 1, groupId, &localError); + ok = ok && SecDbStep(dbconn, selectDates, &localError, ^(bool *stop) { + /* if column has no value, its type will be SQLITE_NULL */ + if (SQLITE_NULL != sqlite3_column_type(selectDates, 0)) { + CFAbsoluteTime nb = (CFAbsoluteTime)sqlite3_column_double(selectDates, 0); + localNotBefore = CFDateCreate(NULL, nb); + } + if (SQLITE_NULL != sqlite3_column_type(selectDates, 1)) { + CFAbsoluteTime na = (CFAbsoluteTime)sqlite3_column_double(selectDates, 1); + localNotAfter = CFDateCreate(NULL, na); + } + }); + return ok; + }); + }); + /* must have at least one date constraint */ + ok = ok && (localNotBefore != NULL || localNotAfter != NULL); + if (!ok || localError) { + secerror("_SecRevocationDbCopyDateConstraints failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationRead, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); + CFReleaseNull(localNotBefore); + CFReleaseNull(localNotAfter); + } + if (notBeforeDate) { + *notBeforeDate = localNotBefore; + } else { + CFReleaseSafe(localNotBefore); + } + if (notAfterDate) { + *notAfterDate = localNotAfter; + } else { + CFReleaseSafe(localNotAfter); + } + + (void) CFErrorPropagate(localError, error); + return ok; +} + +static bool _SecRevocationDbUpdateIssuerConstraints(SecRevocationDbRef rdb, int64_t groupId, CFDictionaryRef dict, CFErrorRef *error) { + /* update optional records in dates, names, or policies tables. */ + if (!dict || groupId < 0) { + return false; /* must have something to insert, and a group to associate with it */ + } + __block bool ok = true; + __block CFErrorRef localError = NULL; + __block CFAbsoluteTime notBefore = -3155760000.0; /* default: 1901-01-01 00:00:00-0000 */ + __block CFAbsoluteTime notAfter = 31556908800.0; /* default: 3001-01-01 00:00:00-0000 */ + + CFDateRef notBeforeDate = (CFDateRef)CFDictionaryGetValue(dict, CFSTR("not-before")); + CFDateRef notAfterDate = (CFDateRef)CFDictionaryGetValue(dict, CFSTR("not-after")); + if (isDate(notBeforeDate)) { + notBefore = CFDateGetAbsoluteTime(notBeforeDate); + } else { + notBeforeDate = NULL; + } + if (isDate(notAfterDate)) { + notAfter = CFDateGetAbsoluteTime(notAfterDate); + } else { + notAfterDate = NULL; + } + if (!(notBeforeDate || notAfterDate)) { + return false; /* no dates supplied, so we have nothing to update for this issuer */ + } + + if (!(notBeforeDate && notAfterDate)) { + /* only one date was supplied, so check for existing date constraints */ + CFDateRef curNotBeforeDate = NULL; + CFDateRef curNotAfterDate = NULL; + if (_SecRevocationDbCopyDateConstraints(rdb, groupId, &curNotBeforeDate, + &curNotAfterDate, &localError)) { + if (!notBeforeDate) { + notBeforeDate = curNotBeforeDate; + notBefore = CFDateGetAbsoluteTime(notBeforeDate); + } else { + CFReleaseSafe(curNotBeforeDate); + } + if (!notAfterDate) { + notAfterDate = curNotAfterDate; + notAfter = CFDateGetAbsoluteTime(notAfterDate); + } else { + CFReleaseSafe(curNotAfterDate); + } + } + } + + ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { + ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { + ok &= SecDbWithSQL(dbconn, insertDateRecordSQL, &localError, ^bool(sqlite3_stmt *insertDate) { + /* (groupid,notbefore,notafter) */ + ok = ok && SecDbBindInt64(insertDate, 1, groupId, &localError); + ok = ok && SecDbBindDouble(insertDate, 2, notBefore, &localError); + ok = ok && SecDbBindDouble(insertDate, 3, notAfter, &localError); + ok = ok && SecDbStep(dbconn, insertDate, &localError, NULL); + return ok; + }); + + /* %%% (TBI:9254570,21234699) update name and policy constraint entries here */ + }); + }); + + if (!ok || localError) { + secinfo("validupdate", "_SecRevocationDbUpdateIssuerConstraints failed (ok=%s, localError=%@)", + (ok) ? "1" : "0", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); + } (void) CFErrorPropagate(localError, error); return ok; @@ -1763,14 +1956,14 @@ static SecValidInfoFormat _SecRevocationDbGetGroupFormat(SecRevocationDbRef rdb, /* Select the group record to determine flags and format. */ ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { ok &= SecDbWithSQL(dbconn, selectGroupRecordSQL, &localError, ^bool(sqlite3_stmt *selectGroup) { - ok = SecDbBindInt64(selectGroup, 1, groupId, &localError); - ok &= SecDbStep(dbconn, selectGroup, &localError, ^(bool *stop) { + ok = ok && SecDbBindInt64(selectGroup, 1, groupId, &localError); + ok = ok && SecDbStep(dbconn, selectGroup, &localError, ^(bool *stop) { if (flags) { *flags = (SecValidInfoFlags)sqlite3_column_int(selectGroup, 0); } format = (SecValidInfoFormat)sqlite3_column_int(selectGroup, 1); if (data) { - //TODO: stream this from sqlite through the inflation so we return an inflated copy, then remove inflate from others + //%%% stream the data from the db into a streamed decompression uint8_t *p = (uint8_t *)sqlite3_column_blob(selectGroup, 2); if (p != NULL && format == kSecValidInfoFormatNto1) { CFIndex length = (CFIndex)sqlite3_column_bytes(selectGroup, 2); @@ -1781,8 +1974,10 @@ static SecValidInfoFormat _SecRevocationDbGetGroupFormat(SecRevocationDbRef rdb, return ok; }); }); - if (!ok) { + if (!ok || localError) { secdebug("validupdate", "GetGroupFormat for groupId %lu failed", (unsigned long)groupId); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationRead, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); format = kSecValidInfoFormatUnknown; } (void) CFErrorPropagate(localError, error); @@ -1794,14 +1989,28 @@ static SecValidInfoFormat _SecRevocationDbGetGroupFormat(SecRevocationDbRef rdb, static bool _SecRevocationDbUpdateFlags(CFDictionaryRef dict, CFStringRef key, SecValidInfoFlags mask, SecValidInfoFlags *flags) { /* If a boolean value exists in the given dictionary for the given key, + or an explicit "1" or "0" is specified as the key string, set or clear the corresponding bit(s) defined by the mask argument. Function returns true if the flags value was changed, false otherwise. */ - bool result = false; + if (!isDictionary(dict) || !isString(key) || !flags) { + return false; + } + bool hasValue = false, newValue = false, result = false; CFTypeRef value = (CFBooleanRef)CFDictionaryGetValue(dict, key); - if (isBoolean(value) && flags) { + if (isBoolean(value)) { + newValue = CFBooleanGetValue((CFBooleanRef)value); + hasValue = true; + } else if (BOOL_STRING_KEY_LENGTH == CFStringGetLength(key)) { + if (CFStringCompare(key, kBoolTrueKey, 0) == kCFCompareEqualTo) { + hasValue = newValue = true; + } else if (CFStringCompare(key, kBoolFalseKey, 0) == kCFCompareEqualTo) { + hasValue = true; + } + } + if (hasValue) { SecValidInfoFlags oldFlags = *flags; - if (CFBooleanGetValue((CFBooleanRef)value)) { + if (newValue) { *flags |= mask; } else { *flags &= ~(mask); @@ -1961,7 +2170,7 @@ static int64_t _SecRevocationDbUpdateGroup(SecRevocationDbRef rdb, int64_t group /* fetch the flags and data for an existing group record, in case some are being changed. */ format = _SecRevocationDbGetGroupFormat(rdb, groupId, &flags, &data, NULL); if (format == kSecValidInfoFormatUnknown) { - secdebug("validupdate", "existing group %lld has unknown format %d, flags=%lu", + secdebug("validupdate", "existing group %lld has unknown format %d, flags=0x%lx", (long long)groupId, format, flags); //%%% clean up by deleting all issuers with this groupId, then the group record, // or just force a full update? note: we can get here if we fail to bind the @@ -1995,9 +2204,7 @@ static int64_t _SecRevocationDbUpdateGroup(SecRevocationDbRef rdb, int64_t group ok &= SecDbWithSQL(dbconn, deleteGroupRecordSQL, &localError, ^bool(sqlite3_stmt *deleteResponse) { ok = SecDbBindInt64(deleteResponse, 1, groupId, &localError); /* Execute the delete statement. */ - if (ok) { - ok = SecDbStep(dbconn, deleteResponse, &localError, NULL); - } + ok = ok && SecDbStep(dbconn, deleteResponse, &localError, NULL); return ok; }); } @@ -2019,6 +2226,22 @@ static int64_t _SecRevocationDbUpdateGroup(SecRevocationDbRef rdb, int64_t group (void)_SecRevocationDbUpdateFlags(dict, CFSTR("require-ct"), kSecValidInfoRequireCT, &flags); (void)_SecRevocationDbUpdateFlags(dict, CFSTR("valid"), kSecValidInfoAllowlist, &flags); (void)_SecRevocationDbUpdateFlags(dict, CFSTR("no-ca"), kSecValidInfoNoCACheck, &flags); + (void)_SecRevocationDbUpdateFlags(dict, CFSTR("overridable"), kSecValidInfoOverridable, &flags); + + /* date constraints exist if either "not-before" or "not-after" keys are found */ + CFTypeRef notBeforeValue = (CFDateRef)CFDictionaryGetValue(dict, CFSTR("not-before")); + CFTypeRef notAfterValue = (CFDateRef)CFDictionaryGetValue(dict, CFSTR("not-after")); + if (isDate(notBeforeValue) || isDate(notAfterValue)) { + (void)_SecRevocationDbUpdateFlags(dict, kBoolTrueKey, kSecValidInfoDateConstraints, &flags); + /* Note that the spec defines not-before and not-after dates as optional, such that + not providing one does not change the database contents. Therefore, we can never clear + this flag; either a new date entry will be supplied, or a format change will cause + the entire group entry to be deleted. */ + } + + /* %%% (TBI:9254570,21234699) name and policy constraints don't exist yet */ + (void)_SecRevocationDbUpdateFlags(dict, kBoolFalseKey, kSecValidInfoNameConstraints, &flags); + (void)_SecRevocationDbUpdateFlags(dict, kBoolFalseKey, kSecValidInfoPolicyConstraints, &flags); ok = SecDbBindInt(insertGroup, 2, (int)flags, &localError); if (!ok) { @@ -2080,7 +2303,11 @@ static int64_t _SecRevocationDbUpdateGroup(SecRevocationDbRef rdb, int64_t group }); }); }); - + if (!ok || localError) { + secerror("_SecRevocationDbUpdateGroup failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); + } (void) CFErrorPropagate(localError, error); return result; } @@ -2116,7 +2343,7 @@ static int64_t _SecRevocationDbGroupIdForIssuerHash(SecRevocationDbRef rdb, CFDa */ ok &= SecDbPerformRead(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { ok &= SecDbWithSQL(dbconn, selectGroupIdSQL, &localError, ^bool(sqlite3_stmt *selectGroupId) { - ok = SecDbBindBlob(selectGroupId, 1, CFDataGetBytePtr(hash), CFDataGetLength(hash), SQLITE_TRANSIENT, &localError); + ok &= SecDbBindBlob(selectGroupId, 1, CFDataGetBytePtr(hash), CFDataGetLength(hash), SQLITE_TRANSIENT, &localError); ok &= SecDbStep(dbconn, selectGroupId, &localError, ^(bool *stopGroupId) { groupId = sqlite3_column_int64(selectGroupId, 0); }); @@ -2125,6 +2352,11 @@ static int64_t _SecRevocationDbGroupIdForIssuerHash(SecRevocationDbRef rdb, CFDa }); errOut: + if (!ok || localError) { + secerror("_SecRevocationDbGroupIdForIssuerHash failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationRead, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); + } (void) CFErrorPropagate(localError, error); return groupId; } @@ -2141,18 +2373,21 @@ static bool _SecRevocationDbApplyGroupDelete(SecRevocationDbRef rdb, CFDataRef i ok &= SecDbPerformWrite(rdb->db, &localError, ^(SecDbConnectionRef dbconn) { ok &= SecDbTransaction(dbconn, kSecDbExclusiveTransactionType, &localError, ^(bool *commit) { - ok = SecDbWithSQL(dbconn, deleteGroupRecordSQL, &localError, ^bool(sqlite3_stmt *deleteResponse) { - ok = SecDbBindInt64(deleteResponse, 1, groupId, &localError); + ok &= SecDbWithSQL(dbconn, deleteGroupRecordSQL, &localError, ^bool(sqlite3_stmt *deleteResponse) { + ok &= SecDbBindInt64(deleteResponse, 1, groupId, &localError); /* Execute the delete statement. */ - if (ok) { - ok = SecDbStep(dbconn, deleteResponse, &localError, NULL); - } + ok = ok && SecDbStep(dbconn, deleteResponse, &localError, NULL); return ok; }); }); }); errOut: + if (!ok || localError) { + secerror("_SecRevocationDbApplyGroupDelete failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); + } (void) CFErrorPropagate(localError, error); return (groupId < 0) ? false : true; } @@ -2180,7 +2415,9 @@ static bool _SecRevocationDbApplyGroupUpdate(SecRevocationDbRef rdb, CFDictionar /* create or update issuer entries, now that we know the group id */ _SecRevocationDbUpdateIssuers(rdb, groupId, issuers, &localError); /* create or update entries in serials or hashes tables */ - _SecRevocationDbUpdatePerIssuerData(rdb, groupId, dict, &localError); + _SecRevocationDbUpdateIssuerData(rdb, groupId, dict, &localError); + /* create or update entries in dates/names/policies tables */ + _SecRevocationDbUpdateIssuerConstraints(rdb, groupId, dict, &localError); } (void) CFErrorPropagate(localError, error); @@ -2220,6 +2457,8 @@ static void _SecRevocationDbApplyUpdate(SecRevocationDbRef rdb, CFDictionaryRef if (isData(issuerHash)) { (void)_SecRevocationDbApplyGroupDelete(rdb, issuerHash, &localError); CFReleaseNull(localError); + } else { + secdebug("validupdate", "skipping delete %ld (hash is not a data value)", (long)deleteIX); } } } @@ -2234,6 +2473,8 @@ static void _SecRevocationDbApplyUpdate(SecRevocationDbRef rdb, CFDictionaryRef if (isDictionary(dict)) { (void)_SecRevocationDbApplyGroupUpdate(rdb, dict, &localError); CFReleaseNull(localError); + } else { + secdebug("validupdate", "skipping update %ld (not a dictionary)", (long)updateIX); } } } @@ -2285,6 +2526,11 @@ static bool _SecRevocationDbSerialInGroup(SecRevocationDbRef rdb, }); errOut: + if (!ok || localError) { + secerror("_SecRevocationDbSerialInGroup failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationRead, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); + } (void) CFErrorPropagate(localError, error); return result; } @@ -2311,6 +2557,11 @@ static bool _SecRevocationDbCertHashInGroup(SecRevocationDbRef rdb, }); errOut: + if (!ok || localError) { + secerror("_SecRevocationDbCertHashInGroup failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationRead, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); + } (void) CFErrorPropagate(localError, error); return result; } @@ -2395,6 +2646,10 @@ static SecValidInfoRef _SecRevocationDbValidInfoForCertificate(SecRevocationDbRe int64_t groupId = 0; CFDataRef serial = NULL; CFDataRef certHash = NULL; + CFDateRef notBeforeDate = NULL; + CFDateRef notAfterDate = NULL; + CFDataRef nameConstraints = NULL; + CFDataRef policyConstraints = NULL; SecValidInfoRef result = NULL; require((serial = SecCertificateCopySerialNumberData(certificate, NULL)) != NULL, errOut); @@ -2405,7 +2660,8 @@ static SecValidInfoRef _SecRevocationDbValidInfoForCertificate(SecRevocationDbRe format = _SecRevocationDbGetGroupFormat(rdb, groupId, &flags, &data, &localError); if (format == kSecValidInfoFormatUnknown) { - /* No group record found for this issuer. */ + /* No group record found for this issuer. Don't return a SecValidInfoRef */ + goto errOut; } else if (format == kSecValidInfoFormatSerial) { /* Look up certificate's serial number in the serials table. */ @@ -2424,31 +2680,28 @@ static SecValidInfoRef _SecRevocationDbValidInfoForCertificate(SecRevocationDbRe if (matched) { /* Found a specific match for this certificate. */ - secdebug("validupdate", "Valid db matched certificate: %@, format=%d, flags=%lu", + secdebug("validupdate", "Valid db matched certificate: %@, format=%d, flags=0x%lx", certHash, format, flags); isOnList = true; } - else if ((flags & kSecValidInfoComplete) && (flags & kSecValidInfoAllowlist)) { - /* Not matching against a complete allowlist is equivalent to revocation. */ - secdebug("validupdate", "Valid db did NOT match certificate on allowlist: %@, format=%d, flags=%lu", - certHash, format, flags); - matched = true; - } - else if ((!(flags & kSecValidInfoComplete)) && (format > kSecValidInfoFormatUnknown)) { - /* Not matching against an incomplete list implies we need to check OCSP. */ - secdebug("validupdate", "Valid db did not find certificate on incomplete list: %@, format=%d, flags=%lu", - certHash, format, flags); - matched = true; - } - if (matched) { - /* Return SecValidInfo for a matched certificate. */ - result = SecValidInfoCreate(format, flags, isOnList, certHash, issuerHash, NULL); + /* If supplemental constraints are present for this issuer, then we always match. */ + if ((flags & kSecValidInfoDateConstraints) && + (_SecRevocationDbCopyDateConstraints(rdb, groupId, ¬BeforeDate, ¬AfterDate, &localError))) { + secdebug("validupdate", "Valid db matched supplemental date constraints for groupId %lld: nb=%@, na=%@", + (long long)groupId, notBeforeDate, notAfterDate); } + + /* Return SecValidInfo for certificates for which an issuer entry is found. */ + result = SecValidInfoCreate(format, flags, isOnList, + certHash, issuerHash, /*anchorHash*/ NULL, + notBeforeDate, notAfterDate, + nameConstraints, policyConstraints); + if (result && SecIsAppleTrustAnchor(certificate, 0)) { /* Prevent a catch-22. */ - secdebug("validupdate", "Valid db match for Apple trust anchor: %@, format=%d, flags=%lu", + secdebug("validupdate", "Valid db match for Apple trust anchor: %@, format=%d, flags=0x%lx", certHash, format, flags); SecValidInfoRelease(result); result = NULL; @@ -2459,6 +2712,10 @@ errOut: CFReleaseSafe(data); CFReleaseSafe(certHash); CFReleaseSafe(serial); + CFReleaseSafe(notBeforeDate); + CFReleaseSafe(notAfterDate); + CFReleaseSafe(nameConstraints); + CFReleaseSafe(policyConstraints); return result; } @@ -2495,14 +2752,40 @@ void SecRevocationDbApplyUpdate(CFDictionaryRef update, CFIndex version) { }); } +/* Update the database schema, insert missing tables and replace triggers. + (This function is expected to be called only by the database maintainer, + normally the system instance of trustd.) +*/ +bool SecRevocationDbUpdateSchema(void) { + __block bool result = false; + SecRevocationDbWith(^(SecRevocationDbRef db) { + result = _SecRevocationDbUpdateSchema(db); + }); + return result; +} + /* Set the schema version for the revocation database. (This function is expected to be called only by the database maintainer, normally the system instance of trustd.) */ -void SecRevocationDbSetSchemaVersion(CFIndex db_version) { +bool SecRevocationDbSetSchemaVersion(CFIndex db_version) { + __block bool result = false; SecRevocationDbWith(^(SecRevocationDbRef db) { - _SecRevocationDbSetSchemaVersion(db, db_version); + result = _SecRevocationDbSetSchemaVersion(db, db_version); }); + return result; +} + +/* Set the current version for the revocation database. + (This function is expected to be called only by the database maintainer, + normally the system instance of trustd.) +*/ +bool SecRevocationDbSetVersion(CFIndex version) { + __block bool result = false; + SecRevocationDbWith(^(SecRevocationDbRef db) { + _SecRevocationDbSetVersion(db, version); + }); + return result; } /* Set the update format for the revocation database. diff --git a/OSX/sec/securityd/SecRevocationDb.h b/OSX/sec/securityd/SecRevocationDb.h index 6c7c8c90..29a715fe 100644 --- a/OSX/sec/securityd/SecRevocationDb.h +++ b/OSX/sec/securityd/SecRevocationDb.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Apple Inc. All Rights Reserved. + * Copyright (c) 2016-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -55,17 +55,25 @@ typedef CF_ENUM(uint32_t, SecValidInfoFormat) { typedef struct __SecValidInfo *SecValidInfoRef; struct __SecValidInfo { - SecValidInfoFormat format; // format of per-issuer validity data - CFDataRef certHash; // SHA-256 hash of cert to which the following info applies - CFDataRef issuerHash; // SHA-256 hash of issuing CA certificate - CFDataRef anchorHash; // SHA-256 hash of anchor certificate (optional) - bool isOnList; // true if this cert was found on allow list or block list - bool valid; // true if this is an allow list, false if a block list - bool complete; // true if list is complete (i.e. status is definitive) - bool checkOCSP; // true if complete is false and OCSP check is required - bool knownOnly; // true if all intermediates under issuer must be found in database - bool requireCT; // true if this cert must have CT proof - bool noCACheck; // true if an entry does not require an OCSP check to accept + SecValidInfoFormat format; // format of per-issuer validity data + CFDataRef certHash; // SHA-256 hash of cert to which the following info applies + CFDataRef issuerHash; // SHA-256 hash of issuing CA certificate + CFDataRef anchorHash; // SHA-256 hash of anchor certificate (optional) + bool isOnList; // true if this cert was found on allow list or block list + bool valid; // true if this is an allow list, false if a block list + bool complete; // true if list is complete (i.e. status is definitive) + bool checkOCSP; // true if complete is false and OCSP check is required + bool knownOnly; // true if all intermediates under issuer must be found in database + bool requireCT; // true if this cert must have CT proof + bool noCACheck; // true if an entry does not require an OCSP check to accept + bool overridable; // true if the trust status is recoverable and can be overridden + bool hasDateConstraints; // true if this issuer has supplemental date constraints + bool hasNameConstraints; // true if this issuer has supplemental name constraints + bool hasPolicyConstraints; // true if this issuer has policy constraints + CFDateRef notBeforeDate; // minimum notBefore for this certificate (if hasDateConstraints is true) + CFDateRef notAfterDate; // maximum notAfter for this certificate (if hasDateConstraints is true) + CFDataRef nameConstraints; // name constraints blob (if hasNameConstraints is true) + CFDataRef policyConstraints; // policy constraints blob (if policyConstraints is true) }; /*! diff --git a/OSX/sec/securityd/SecRevocationNetworking.m b/OSX/sec/securityd/SecRevocationNetworking.m index 21a0742a..a91c5851 100644 --- a/OSX/sec/securityd/SecRevocationNetworking.m +++ b/OSX/sec/securityd/SecRevocationNetworking.m @@ -35,6 +35,7 @@ #include "utilities/SecFileLocations.h" #include "SecRevocationDb.h" +#import "SecTrustLoggingServer.h" #import "SecRevocationNetworking.h" @@ -119,6 +120,7 @@ typedef void (^CompletionHandler)(void); int rtn; if ((rtn = readValidFile(updateFilePath, &updateData)) != 0) { secerror("failed to read %@ with error %d", updateFileURL, rtn); + TrustdHealthAnalyticsLogErrorCode(TAEventValidUpdate, TAFatalError, rtn); [self reschedule]; return; } @@ -198,6 +200,9 @@ didReceiveResponse:(NSURLResponse *)response self->_currentUpdateFile = [NSFileHandle fileHandleForWritingToURL:self->_currentUpdateFileURL error:&error]; if (!self->_currentUpdateFile) { secnotice("validupdate", "failed to open %@: %@. canceling task %@", self->_currentUpdateFileURL, error, dataTask); +#if ENABLE_TRUSTD_ANALYTICS + [[TrustdHealthAnalytics logger] logResultForEvent:TrustdHealthAnalyticsEventValidUpdate hardFailure:NO result:error]; +#endif // ENABLE_TRUSTD_ANALYTICS completionHandler(NSURLSessionResponseCancel); [self reschedule]; return; @@ -227,6 +232,7 @@ didReceiveResponse:(NSURLResponse *)response } @catch(NSException *exception) { secnotice("validupdate", "%s", exception.description.UTF8String); + TrustdHealthAnalyticsLogErrorCode(TAEventValidUpdate, TARecoverableError, errSecDiskFull); [dataTask cancel]; [self reschedule]; } @@ -242,6 +248,9 @@ didCompleteWithError:(NSError *)error { } if (error) { secnotice("validupdate", "Session %@ task %@ failed with error %@", session, task, error); +#if ENABLE_TRUSTD_ANALYTICS + [[TrustdHealthAnalytics logger] logResultForEvent:TrustdHealthAnalyticsEventValidUpdate hardFailure:NO result:error]; +#endif // ENABLE_TRUSTD_ANALYTICS [self reschedule]; /* close file before we leave */ [self->_currentUpdateFile closeFile]; @@ -343,8 +352,7 @@ static ValidUpdateRequest *request = nil; /* nsurlsessiond waits for unlock to finish launching, so we can't block trust evaluations * on scheduling this background task. Also, we want to wait a sufficient amount of time * after system boot before trying to initiate network activity, to avoid the possibility - * of a performance regression in the boot path. - */ + * of a performance regression in the boot path. */ dispatch_async(updateQueue, ^{ CFAbsoluteTime now = CFAbsoluteTimeGetCurrent(); if (self.updateScheduled != 0.0) { diff --git a/OSX/sec/securityd/SecRevocationServer.c b/OSX/sec/securityd/SecRevocationServer.c index a0400b49..78823096 100644 --- a/OSX/sec/securityd/SecRevocationServer.c +++ b/OSX/sec/securityd/SecRevocationServer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2008-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -27,6 +27,8 @@ #include +#include + #include #include #include @@ -182,7 +184,7 @@ static bool SecOCSPSingleResponseProcess(SecOCSPSingleResponseRef this, SInt32 reason = this->crlReason; CFNumberRef cfreason = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &reason); SecPathBuilderSetResultInPVCs(rvc->builder, kSecPolicyCheckRevocation, rvc->certIX, - cfreason, true, kSecTrustResultFatalTrustFailure); + cfreason, true); if (rvc->builder) { CFMutableDictionaryRef info = SecPathBuilderGetInfo(rvc->builder); if (info) { @@ -221,7 +223,7 @@ typedef void (^SecOCSPEvaluationCompleted)(SecTrustResultType tr); static void SecOCSPEvaluateCompleted(const void *userData, - SecCertificatePathRef chain, CFArrayRef details, CFDictionaryRef info, + CFArrayRef chain, CFArrayRef details, CFDictionaryRef info, SecTrustResultType result) { SecOCSPEvaluationCompleted evaluated = (SecOCSPEvaluationCompleted)userData; evaluated(result); @@ -359,9 +361,6 @@ static void SecORVCConsumeOCSPResponse(SecORVCRef rvc, SecOCSPResponseRef ocspRe require_quiet(!rvc->ocspSingleResponse || rvc->ocspSingleResponse->thisUpdate < sr->thisUpdate, errOut); CFAbsoluteTime verifyTime = CFAbsoluteTimeGetCurrent(); - /* TODO: If the responder doesn't have the ocsp-nocheck extension we should - check whether the leaf was revoked (we are already checking the rest of - the chain). */ /* Check the OCSP response signature and verify the response. */ require_quiet(SecOCSPResponseVerify(ocspResponse, rvc, sr->certStatus == CS_Revoked ? SecOCSPResponseProducedAt(ocspResponse) : verifyTime), errOut); @@ -401,6 +400,11 @@ errOut: static void SecOCSPFetchCompleted(asynchttp_t *http, CFTimeInterval maxAge) { SecORVCRef rvc = (SecORVCRef)http->info; SecPathBuilderRef builder = rvc->builder; + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder); + if (analytics) { + /* Add the time this fetch took to complete to the total time */ + analytics->ocsp_fetch_time += (mach_absolute_time() - http->start_time); + } SecOCSPResponseRef ocspResponse = NULL; if (http->response) { CFDataRef data = CFHTTPMessageCopyBody(http->response); @@ -411,10 +415,19 @@ static void SecOCSPFetchCompleted(asynchttp_t *http, CFTimeInterval maxAge) { } } + if ((!http->response || !ocspResponse) && analytics) { + /* We didn't get any data back, so the fetch failed */ + analytics->ocsp_fetch_failed++; + } + SecORVCConsumeOCSPResponse(rvc, ocspResponse, maxAge, true); // TODO: maybe we should set the cache-control: false in the http header and try again if the response is stale if (!rvc->done) { + if (analytics && ocspResponse) { + /* We got an OCSP response that didn't pass validation */ + analytics-> ocsp_validation_failed = true; + } /* Clear the data for the next response. */ asynchttp_free(http); SecORVCFetchNext(rvc); @@ -548,9 +561,7 @@ static CFURLRef SecCRVCGetNextDistributionPoint(SecCRVCRef rvc) { static void SecCRVCGetCRLStatus(SecCRVCRef rvc) { SecCertificateRef cert = SecPathBuilderGetCertificateAtIndex(rvc->builder, rvc->certIX); SecCertificatePathVCRef path = SecPathBuilderGetPath(rvc->builder); - SecCertificatePathRef nonVCpath = SecCertificatePathVCCopyCertificatePath(path); - CFArrayRef serializedCertPath = SecCertificatePathCreateSerialized(nonVCpath, NULL); - CFReleaseNull(nonVCpath); + CFArrayRef serializedCertPath = SecCertificatePathVCCreateSerialized(path); secdebug("rvc", "searching CRL cache for cert: %ld", rvc->certIX); rvc->status = SecTrustLegacyCRLStatus(cert, serializedCertPath, rvc->distributionPoint); CFReleaseNull(serializedCertPath); @@ -577,9 +588,7 @@ static bool SecCRVCFetchNext(SecCRVCRef rvc) { while ((rvc->distributionPoint = SecCRVCGetNextDistributionPoint(rvc))) { SecCertificateRef cert = SecPathBuilderGetCertificateAtIndex(rvc->builder, rvc->certIX); SecCertificatePathVCRef path = SecPathBuilderGetPath(rvc->builder); - SecCertificatePathRef nonVCpath = SecCertificatePathVCCopyCertificatePath(path); - CFArrayRef serializedCertPath = SecCertificatePathCreateSerialized(nonVCpath, NULL); - CFReleaseNull(nonVCpath); + CFArrayRef serializedCertPath = SecCertificatePathVCCreateSerialized(path); secinfo("rvc", "fetching CRL for cert: %ld", rvc->certIX); if (!SecTrustLegacyCRLFetch(&rvc->async_ocspd, rvc->distributionPoint, CFAbsoluteTimeGetCurrent(), cert, serializedCertPath)) { @@ -611,7 +620,7 @@ static void SecCRVCUpdatePVC(SecCRVCRef rvc) { SInt32 reason = 0; // unspecified, since ocspd didn't tell us CFNumberRef cfreason = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &reason); SecPathBuilderSetResultInPVCs(rvc->builder, kSecPolicyCheckRevocation, rvc->certIX, - cfreason, true, kSecTrustResultFatalTrustFailure); + cfreason, true); if (rvc->builder) { CFMutableDictionaryRef info = SecPathBuilderGetInfo(rvc->builder); if (info) { @@ -626,6 +635,11 @@ static void SecCRVCUpdatePVC(SecCRVCRef rvc) { static void SecCRVCFetchCompleted(async_ocspd_t *ocspd) { SecCRVCRef rvc = ocspd->info; SecPathBuilderRef builder = rvc->builder; + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder); + if (analytics) { + /* Add the time this fetch took to complete to the total time */ + analytics->crl_fetch_time += (mach_absolute_time() - ocspd->start_time); + } /* we got a response indicating that the CRL was checked */ if (ocspd->response == errSecSuccess || ocspd->response == errSecCertificateRevoked) { rvc->status = ocspd->response; @@ -639,6 +653,10 @@ static void SecCRVCFetchCompleted(async_ocspd_t *ocspd) { SecPathBuilderStep(builder); } } else { + if (analytics) { + /* We didn't get any data back, so the fetch failed */ + analytics->crl_fetch_failed++; + } if(SecCRVCFetchNext(rvc)) { if (!SecPathBuilderDecrementAsyncJobCount(builder)) { secdebug("rvc", "done with all async jobs"); @@ -671,10 +689,14 @@ static SecCRVCRef SecCRVCCreate(SecRVCRef rvc, SecPathBuilderRef builder, CFInde static bool SecRVCShouldCheckCRL(SecRVCRef rvc) { CFStringRef revocation_method = SecPathBuilderGetRevocationMethod(rvc->builder); + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(rvc->builder); if (revocation_method && CFEqual(kSecPolicyCheckRevocationCRL, revocation_method)) { /* Our client insists on CRLs */ secinfo("rvc", "client told us to check CRL"); + if (analytics) { + analytics->crl_client = true; + } return true; } SecCertificateRef cert = SecPathBuilderGetCertificateAtIndex(rvc->builder, rvc->certIX); @@ -684,6 +706,9 @@ static bool SecRVCShouldCheckCRL(SecRVCRef rvc) { /* The cert doesn't have OCSP responders and the client didn't specifically ask for OCSP. * This logic will skip the CRL cache check if the client didn't ask for revocation checking */ secinfo("rvc", "client told us to check revocation and CRL is only option for cert: %ld", rvc->certIX); + if (analytics) { + analytics->crl_cert = true; + } return true; } return false; @@ -744,65 +769,182 @@ static bool SecRVCShouldCheckOCSP(SecRVCRef rvc) { } #endif -static void SecRVCProcessValidInfoResults(SecRVCRef rvc) { +static void SecRVCProcessValidDateConstraints(SecRVCRef rvc) { if (!rvc || !rvc->valid_info || !rvc->builder) { return; } - SecValidInfoFormat format = rvc->valid_info->format; - bool valid = rvc->valid_info->valid; - bool noCACheck = rvc->valid_info->noCACheck; - bool checkOCSP = rvc->valid_info->checkOCSP; - bool complete = rvc->valid_info->complete; - bool isOnList = rvc->valid_info->isOnList; - bool definitive = false; - - if (format == kSecValidInfoFormatSerial || format == kSecValidInfoFormatSHA256) { - /* serial or hash list: could be blocked or allowed; could be incomplete */ - if (((!valid && complete && isOnList) || (valid && complete && !isOnList)) && noCACheck) { - /* definitely revoked */ - SInt32 reason = 0; /* unspecified, since the Valid db doesn't tell us */ + if (!rvc->valid_info->hasDateConstraints) { + return; + } + SecCertificateRef certificate = SecPathBuilderGetCertificateAtIndex(rvc->builder, rvc->certIX); + if (!certificate) { + return; + } + CFAbsoluteTime certIssued = SecCertificateNotValidBefore(certificate); + CFAbsoluteTime caNotBefore = -3155760000.0; /* default: 1901-01-01 00:00:00-0000 */ + CFAbsoluteTime caNotAfter = 31556908800.0; /* default: 3001-01-01 00:00:00-0000 */ + if (rvc->valid_info->notBeforeDate) { + caNotBefore = CFDateGetAbsoluteTime(rvc->valid_info->notBeforeDate); + } + if (rvc->valid_info->notAfterDate) { + caNotAfter = CFDateGetAbsoluteTime(rvc->valid_info->notAfterDate); + /* per the Valid specification, if this date is in the past, we need to check CT. */ + CFAbsoluteTime now = CFAbsoluteTimeGetCurrent(); + if (caNotAfter < now) { + rvc->valid_info->requireCT = true; + } + } + if ((certIssued < caNotBefore) && (rvc->certIX > 0)) { + /* not-before constraint is only applied to leaf certificate, for now. */ + return; + } + + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(rvc->builder); + if ((certIssued < caNotBefore) || (certIssued > caNotAfter)) { + /* We are outside the constrained validity period. */ + secnotice("rvc", "certificate issuance date not within the allowed range for this CA%s", + (rvc->valid_info->overridable) ? "" : " (non-recoverable error)"); + if (analytics) { + analytics->valid_status |= TAValidDateContrainedRevoked; + } + if (rvc->valid_info->overridable) { + /* error is recoverable, treat certificate as untrusted + (note this date check is different from kSecPolicyCheckTemporalValidity) */ + SecPathBuilderSetResultInPVCs(rvc->builder, kSecPolicyCheckGrayListedKey, rvc->certIX, + kCFBooleanFalse, true); + } else { + /* error is non-overridable, treat certificate as revoked */ + SInt32 reason = 0; /* unspecified reason code */ CFNumberRef cfreason = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &reason); SecPathBuilderSetResultInPVCs(rvc->builder, kSecPolicyCheckRevocation, rvc->certIX, - cfreason, true, kSecTrustResultFatalTrustFailure); + cfreason, true); CFMutableDictionaryRef info = SecPathBuilderGetInfo(rvc->builder); if (info) { /* make the revocation reason available in the trust result */ CFDictionarySetValue(info, kSecTrustRevocationReason, cfreason); } CFReleaseNull(cfreason); - definitive = true; } - else if (valid && complete && isOnList && noCACheck) { + } else if (analytics) { + analytics->valid_status |= TAValidDateConstrainedOK; + } +} + +bool SecRVCHasDefinitiveValidInfo(SecRVCRef rvc) { + if (!rvc || !rvc->valid_info) { + return false; + } + SecValidInfoRef info = rvc->valid_info; + /* outcomes as defined in Valid server specification */ + if (info->format == kSecValidInfoFormatSerial || + info->format == kSecValidInfoFormatSHA256) { + if (info->noCACheck || info->complete || info->isOnList) { + return true; + } + } else { /* info->format == kSecValidInfoFormatNto1 */ + if (info->noCACheck || (info->complete && !info->isOnList)) { + return true; + } + } + return false; +} + +bool SecRVCHasRevokedValidInfo(SecRVCRef rvc) { + if (!rvc || !rvc->valid_info) { + return false; + } + SecValidInfoRef info = rvc->valid_info; + /* either not present on an allowlist, or present on a blocklist */ + return (!info->isOnList && info->valid) || (info->isOnList && !info->valid); +} + +void SecRVCSetRevokedResult(SecRVCRef rvc) { + if (!rvc || !rvc->valid_info || !rvc->builder) { + return; + } + if (rvc->valid_info->overridable) { + /* error is recoverable, treat certificate as untrusted */ + SecPathBuilderSetResultInPVCs(rvc->builder, kSecPolicyCheckGrayListedKey, rvc->certIX, + kCFBooleanFalse, true); + return; + } + /* error is fatal, treat certificate as revoked */ + SInt32 reason = 0; /* unspecified, since the Valid db doesn't tell us */ + CFNumberRef cfreason = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &reason); + SecPathBuilderSetResultInPVCs(rvc->builder, kSecPolicyCheckRevocation, rvc->certIX, + cfreason, true); + CFMutableDictionaryRef info = SecPathBuilderGetInfo(rvc->builder); + if (info) { + /* make the revocation reason available in the trust result */ + CFDictionarySetValue(info, kSecTrustRevocationReason, cfreason); + } + CFReleaseNull(cfreason); +} + +static void SecRVCProcessValidInfoResults(SecRVCRef rvc) { + if (!rvc || !rvc->valid_info || !rvc->builder) { + return; + } + SecCertificatePathVCRef path = SecPathBuilderGetPath(rvc->builder); + SecValidInfoRef info = rvc->valid_info; + + bool definitive = SecRVCHasDefinitiveValidInfo(rvc); + bool revoked = SecRVCHasRevokedValidInfo(rvc); + + /* set analytics */ + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(rvc->builder); + if (analytics) { + if (revoked) { + analytics->valid_status |= definitive ? TAValidDefinitelyRevoked : TAValidProbablyRevoked; + } else { + analytics->valid_status |= definitive ? TAValidDefinitelyOK : TAValidProbablyOK; + } + } + + /* Handle no-ca cases */ + if (info->noCACheck) { + bool allowed = (info->valid && info->complete && info->isOnList); + if (revoked) { + /* definitely revoked */ + SecRVCSetRevokedResult(rvc); + } else if (allowed) { /* definitely not revoked (allowlisted) */ - SecCertificatePathVCRef path = SecPathBuilderGetPath(rvc->builder); - if (path) { - SecCertificatePathVCSetIsAllowlisted(path, true); - } else { - secdebug("validupdate", "rvc: no certificate path for builder"); - } - definitive = true; + SecCertificatePathVCSetIsAllowlisted(path, true); } - if (definitive) { - /* either definitely revoked or allowed; no need to check further. */ - secdebug("validupdate", "rvc: definitely %s cert %" PRIdCFIndex, - (valid && complete && isOnList) ? "allowed" : "revoked", rvc->certIX); - rvc->done = true; - return; + /* no-ca is definitive; no need to check further. */ + secdebug("validupdate", "rvc: definitely %s cert %" PRIdCFIndex, + (allowed) ? "allowed" : "revoked", rvc->certIX); + rvc->done = true; + return; + } + + /* Handle date constraints, if present. + * Note: a not-after date may set the CT requirement, + * so check requireCT after this function is called. */ + SecRVCProcessValidDateConstraints(rvc); + + /* Set CT requirement on path, if present. */ + if (info->requireCT) { + if (analytics) { + analytics->valid_require_ct |= info->requireCT; } - /* verify our info with the OCSP server */ - checkOCSP = true; + SecPathCTPolicy ctp = kSecPathCTRequired; + if (info->overridable) { + ctp = kSecPathCTRequiredOverridable; + } + SecCertificatePathVCSetRequiresCT(path, ctp); } - /* Handle non-definitive information. - We set rvc->done = true above ONLY if the result was definitive; - otherwise we require a revocation check for SSL usage. - */ - if (format == kSecValidInfoFormatNto1) { - /* matched the filter */ - checkOCSP = true; + /* Trigger OCSP for any non-definitive or revoked cases */ + if (!definitive || revoked) { + info->checkOCSP = true; } - if (checkOCSP) { + if (info->checkOCSP) { + if (analytics) { + /* Valid DB results caused us to do OCSP */ + analytics->valid_trigger_ocsp = true; + } CFIndex count = SecPathBuilderGetCertificateCount(rvc->builder); CFIndex issuerIX = rvc->certIX + 1; if (issuerIX >= count) { @@ -831,7 +973,7 @@ static void SecRVCProcessValidInfoResults(SecRVCRef rvc) { } } secdebug("validupdate", "rvc: %s%s cert %" PRIdCFIndex " (will check OCSP)", - (complete) ? "" : "possibly ", (valid) ? "allowed" : "revoked", + (info->complete) ? "" : "possibly ", (info->valid) ? "allowed" : "revoked", rvc->certIX); SecPathBuilderSetRevocationMethod(rvc->builder, kSecPolicyCheckRevocationAny); } @@ -906,6 +1048,11 @@ static void SecRVCCheckRevocationCaches(SecRVCRef rvc) { SecORVCConsumeOCSPResponse(rvc->orvc, response, NULL_TIME, false); + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(rvc->builder); + if (rvc->orvc->done && analytics) { + /* We found a valid OCSP response in the cache */ + analytics->ocsp_cache_hit = true; + } } #if ENABLE_CRLS /* Don't check CRL cache if policy requested OCSP only */ @@ -925,6 +1072,7 @@ static void SecRVCUpdatePVC(SecRVCRef rvc) { static bool SecRVCFetchNext(SecRVCRef rvc) { bool OCSP_fetch_finished = true; + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(rvc->builder); /* Don't send OCSP request only if CRLs enabled and policy requested CRL only */ if (SecRVCShouldCheckOCSP(rvc)) { OCSP_fetch_finished &= SecORVCFetchNext(rvc->orvc); @@ -932,6 +1080,10 @@ static bool SecRVCFetchNext(SecRVCRef rvc) { if (OCSP_fetch_finished) { /* we didn't start an OCSP background job for this cert */ (void)SecPathBuilderDecrementAsyncJobCount(rvc->builder); + } else if (analytics) { + /* We did a network OCSP fetch, set report appropriately */ + analytics->ocsp_network = true; + analytics->ocsp_fetches++; } #if ENABLE_CRLS @@ -946,6 +1098,9 @@ static bool SecRVCFetchNext(SecRVCRef rvc) { if (CRL_fetch_finished) { /* we didn't start a CRL background job for this cert */ (void)SecPathBuilderDecrementAsyncJobCount(rvc->builder); + } else if (analytics) { + /* We did a CRL fetch */ + analytics->crl_fetches++; } OCSP_fetch_finished &= CRL_fetch_finished; #endif @@ -1010,7 +1165,21 @@ bool SecPathBuilderCheckRevocation(SecPathBuilderRef builder) { } SecRVCInit(rvc, builder, certIX); - if (rvc->done){ + + /* RFC 6960: OCSP No-Check extension says that we shouldn't check revocation. */ + if (SecCertificateHasMarkerExtension(SecCertificatePathVCGetCertificateAtIndex(path, certIX), + CFSTR("1.3.6.1.5.5.7.48.1.5"))) // id-pkix-ocsp-nocheck + { + secdebug("rvc", "skipping revocation checks for no-check cert: %ld", certIX); + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder); + if (analytics) { + /* This certificate has OCSP No-Check, so add to reporting analytics */ + analytics->ocsp_no_check = true; + } + rvc->done = true; + } + + if (rvc->done) { continue; } diff --git a/OSX/sec/securityd/SecRevocationServer.h b/OSX/sec/securityd/SecRevocationServer.h index aa73ab88..255f1f78 100644 --- a/OSX/sec/securityd/SecRevocationServer.h +++ b/OSX/sec/securityd/SecRevocationServer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2017-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -30,11 +30,9 @@ #ifndef _SECURITY_SECREVOCATIONSERVER_H_ #define _SECURITY_SECREVOCATIONSERVER_H_ -#include +#include #include -#define ENABLE_CRLS (TARGET_OS_MAC && !TARGET_OS_IPHONE) - typedef struct OpaqueSecORVC *SecORVCRef; #if ENABLE_CRLS typedef struct OpaqueSecCRVC *SecCRVCRef; @@ -43,28 +41,31 @@ typedef struct OpaqueSecCRVC *SecCRVCRef; /* Revocation verification context. */ struct OpaqueSecRVC { /* Pointer to the builder for this revocation check */ - SecPathBuilderRef builder; + SecPathBuilderRef builder; /* Index of cert in pvc that this RVC is for 0 = leaf, etc. */ - CFIndex certIX; + CFIndex certIX; /* The OCSP Revocation verification context */ - SecORVCRef orvc; + SecORVCRef orvc; #if ENABLE_CRLS - SecCRVCRef crvc; + SecCRVCRef crvc; #endif /* Valid database info for this revocation check */ - SecValidInfoRef valid_info; + SecValidInfoRef valid_info; - bool done; + bool done; }; typedef struct OpaqueSecRVC *SecRVCRef; bool SecPathBuilderCheckRevocation(SecPathBuilderRef builder); CFAbsoluteTime SecRVCGetEarliestNextUpdate(SecRVCRef rvc); void SecRVCDelete(SecRVCRef rvc); +bool SecRVCHasDefinitiveValidInfo(SecRVCRef rvc); +bool SecRVCHasRevokedValidInfo(SecRVCRef rvc); +void SecRVCSetRevokedResult(SecRVCRef rvc); #endif /* _SECURITY_SECREVOCATIONSERVER_H_ */ diff --git a/OSX/sec/securityd/SecTrustLoggingServer.c b/OSX/sec/securityd/SecTrustLoggingServer.c deleted file mode 100644 index 16c771eb..00000000 --- a/OSX/sec/securityd/SecTrustLoggingServer.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - * - * SecTrustLoggingServer.c - logging for certificate trust evaluation engine - * - */ - -#include "SecTrustLoggingServer.h" - diff --git a/OSX/sec/securityd/SecTrustLoggingServer.m b/OSX/sec/securityd/SecTrustLoggingServer.m new file mode 100644 index 00000000..8e456720 --- /dev/null +++ b/OSX/sec/securityd/SecTrustLoggingServer.m @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2016 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + * + * SecTrustLoggingServer.c - logging for certificate trust evaluation engine + * + */ + +#include +#include "SecTrustLoggingServer.h" + diff --git a/OSX/sec/securityd/SecTrustServer.c b/OSX/sec/securityd/SecTrustServer.c index 7667fb98..481a1246 100644 --- a/OSX/sec/securityd/SecTrustServer.c +++ b/OSX/sec/securityd/SecTrustServer.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -69,6 +68,7 @@ #include "OTATrustUtilities.h" #include "personalization.h" #include +#include #if TARGET_OS_OSX #include @@ -88,6 +88,7 @@ static void SecPathBuilderExtendPaths(void *context, CFArrayRef parents); ********************************************************/ struct SecPathBuilder { dispatch_queue_t queue; + uint64_t startTime; CFDataRef clientAuditToken; SecCertificateSourceRef certificateSource; SecCertificateSourceRef itemCertificateSource; @@ -107,7 +108,7 @@ struct SecPathBuilder { Note that this is the only container in which certificatePath objects are retained. Every certificatePath being considered is always in allPaths and in at - most one of partialPaths, rejectedPaths, candidatePath or extendedPaths + least one of partialPaths, rejectedPaths, or candidatePath, all of which don't retain their values. */ CFMutableSetRef allPaths; @@ -141,6 +142,7 @@ struct SecPathBuilder { bool (*state)(SecPathBuilderRef); SecPathBuilderCompleted completed; const void *context; + TrustAnalyticsBuilder * analyticsData; }; /* State functions. Return false if a async job was scheduled, return @@ -167,23 +169,26 @@ static void SecPathBuilderInit(SecPathBuilderRef builder, secdebug("alloc", "%p", builder); CFAllocatorRef allocator = kCFAllocatorDefault; + builder->analyticsData = calloc(1, sizeof(TrustAnalyticsBuilder)); + builder->analyticsData->start_time = mach_absolute_time(); + builder->clientAuditToken = (CFDataRef) ((clientAuditToken) ? CFRetain(clientAuditToken) : NULL); builder->queue = dispatch_queue_create("builder", DISPATCH_QUEUE_SERIAL); builder->nextParentSource = 1; #if !TARGET_OS_WATCH + /* */ builder->canAccessNetwork = true; #endif builder->anchorSources = CFArrayCreateMutable(allocator, 0, NULL); builder->parentSources = CFArrayCreateMutable(allocator, 0, NULL); - builder->allPaths = CFSetCreateMutable(allocator, 0, - &kCFTypeSetCallBacks); - builder->partialPaths = CFArrayCreateMutable(allocator, 0, NULL); - builder->rejectedPaths = CFArrayCreateMutable(allocator, 0, NULL); - builder->candidatePaths = CFArrayCreateMutable(allocator, 0, NULL); + builder->allPaths = CFSetCreateMutable(allocator, 0, &kCFTypeSetCallBacks); + builder->partialPaths = CFArrayCreateMutable(allocator, 0, NULL); // Does not retain, allPaths retains members. See declaration. + builder->rejectedPaths = CFArrayCreateMutable(allocator, 0, NULL); // Does not retain, allPaths retains members. See declaration. + builder->candidatePaths = CFArrayCreateMutable(allocator, 0, NULL); // Does not retain, allPaths retains members. See declaration. /* Init the policy verification context. */ builder->pvcs = malloc(sizeof(SecPVCRef)); @@ -296,8 +301,6 @@ static void SecPathBuilderInit(SecPathBuilderRef builder, SecPathBuilderSetPath(builder, path); CFRelease(path); - /* Set the revocation context */ - /* Next step is to process the leaf. We do that work on the builder queue * to avoid blocking the main thread with database lookups. */ builder->state = SecPathBuilderProcessLeaf; @@ -366,6 +369,9 @@ static void SecPathBuilderDestroy(SecPathBuilderRef builder) { CFReleaseNull(builder->info); CFReleaseNull(builder->exceptions); + free(builder->analyticsData); + builder->analyticsData = NULL; + if (builder->pvcs) { CFIndex ix; for (ix = 0; ix < builder->pvcCount; ix++) { @@ -406,6 +412,7 @@ void SecPathBuilderSetCanAccessNetwork(SecPathBuilderRef builder, bool allow) { a parent source. */ CFArrayAppendValue(builder->parentSources, kSecCAIssuerSource); #else + /* */ secnotice("http", "network access not allowed on WatchOS"); builder->canAccessNetwork = false; #endif @@ -437,6 +444,21 @@ CFArrayRef SecPathBuilderCopyTrustedLogs(SecPathBuilderRef builder) return CFRetainSafe(builder->trustedLogs); } +SecCertificateSourceRef SecPathBuilderGetAppAnchorSource(SecPathBuilderRef builder) +{ + return builder->anchorSource; +} + +CFSetRef SecPathBuilderGetAllPaths(SecPathBuilderRef builder) +{ + return builder->allPaths; +} + +TrustAnalyticsBuilder *SecPathBuilderGetAnalyticsData(SecPathBuilderRef builder) +{ + return builder->analyticsData; +} + SecCertificatePathVCRef SecPathBuilderGetBestPath(SecPathBuilderRef builder) { return builder->bestPath; @@ -455,7 +477,7 @@ bool SecPathBuilderHasTemporalParentChecks(SecPathBuilderRef builder) { SecPathBuilderForEachPVC(builder, ^(SecPVCRef pvc, bool *stop) { CFArrayForEach(pvc->policies, ^(const void *value) { SecPolicyRef policy = (SecPolicyRef)value; - if (CFDictionaryContainsKey(policy->_options, kSecPolicyCheckValidIntermediates)) { + if (CFDictionaryContainsKey(policy->_options, kSecPolicyCheckTemporalValidity)) { validIntermediates = true; *stop = true; } @@ -523,11 +545,9 @@ SecPVCRef SecPathBuilderGetPVCAtIndex(SecPathBuilderRef builder, CFIndex ix) { } void SecPathBuilderSetResultInPVCs(SecPathBuilderRef builder, CFStringRef key, - CFIndex ix, CFTypeRef result, bool force, - SecTrustResultType resultType) { + CFIndex ix, CFTypeRef result, bool force) { SecPathBuilderForEachPVC(builder, ^(SecPVCRef pvc, bool * __unused stop) { SecPVCSetResultForced(pvc, key, ix, result, force); - pvc->result = resultType; }); } @@ -540,7 +560,7 @@ static bool SecPathBuilderIsOkResult(SecPathBuilderRef builder) { return acceptPath; } -static SecPVCRef SecPathBuilderGetResultPVC(SecPathBuilderRef builder) { +SecPVCRef SecPathBuilderGetResultPVC(SecPathBuilderRef builder) { /* Return the first PVC that passed */ __block SecPVCRef resultPVC = NULL; SecPathBuilderForEachPVC(builder, ^(SecPVCRef pvc, bool *stop) { @@ -725,7 +745,7 @@ static void SecPathBuilderAddPinningPolicies(SecPathBuilderRef builder) { /* Found pinning policies. Apply them to the path builder. */ CFArrayRef newRules = CFDictionaryGetValue(results, kSecPinningDbKeyRules); CFStringRef dbPolicyName = CFDictionaryGetValue(results, kSecPinningDbKeyPolicyName); - secinfo("trust", "found pinning %lu %@ policies for hostname %@, policyName %@", + secinfo("SecPinningDb", "found pinning %lu %@ policies for hostname %@, policyName %@", (unsigned long)CFArrayGetCount(newRules), dbPolicyName, hostname, policyName); CFIndex newRulesIX; for (newRulesIX = 0; newRulesIX < CFArrayGetCount(newRules); newRulesIX++) { @@ -1079,7 +1099,8 @@ static bool SecPathBuilderValidatePath(SecPathBuilderRef builder) { builder->state = SecPathBuilderDidValidatePath; /* Revocation checking is now done before path checks, to ensure that - isAllowlisted will be set correctly for the subsequent path checks. */ + we have OCSP responses for CT checking and that isAllowlisted is + appropriately set for other checks. */ bool completed = SecPathBuilderCheckRevocation(builder); SecPathBuilderForEachPVC(builder, ^(SecPVCRef pvc, bool * __unused stop) { @@ -1094,7 +1115,7 @@ static bool SecPathBuilderDidValidatePath(SecPathBuilderRef builder) { * this is the state we call back into once all the asynchronous * revocation check calls are done. */ SecPathBuilderForEachPVC(builder, ^(SecPVCRef pvc, bool * __unused stop) { - SecPVCPathCheckRevocationRequired(pvc); + SecPVCPathCheckRevocationResponsesReceived(pvc); }); if (SecPathBuilderIsOkResult(builder)) { @@ -1113,7 +1134,6 @@ static bool SecPathBuilderComputeDetails(SecPathBuilderRef builder) { __block CFIndex ix, pathLength = SecCertificatePathVCGetCount(builder->bestPath); __block bool completed = true; - SecPathBuilderForEachPVC(builder, ^(SecPVCRef pvc, bool * __unused stop) { SecPVCComputeDetails(pvc, builder->bestPath); completed &= SecPathBuilderCheckRevocation(builder); @@ -1125,8 +1145,9 @@ static bool SecPathBuilderComputeDetails(SecPathBuilderRef builder) { builder->state = SecPathBuilderReportResult; + /* Check revocation responses. */ SecPathBuilderForEachPVC(builder, ^(SecPVCRef pvc, bool * __unused stop) { - SecPVCPathCheckRevocationRequired(pvc); + SecPVCPathCheckRevocationResponsesReceived(pvc); }); /* Reject the certificate if it was accepted before but we failed it now. (Should not happen anymore.) */ @@ -1152,7 +1173,7 @@ static bool SecPathBuilderReportResult(SecPathBuilderRef builder) { CFAbsoluteTime nextUpdate = SecCertificatePathVCGetEarliestNextUpdate(builder->bestPath); if (nextUpdate != 0) { #else - /* We don't do networking on watchOS, so we can't require OCSP for EV */ + /* We don't do networking on watchOS, so we can't require OCSP for EV */ { { #endif @@ -1261,7 +1282,7 @@ bool SecPathBuilderStep(SecPathBuilderRef builder) { builder->bestPath, pvc->details, result); if (builder->completed) { - SecCertificatePathRef resultPath = SecCertificatePathVCCopyCertificatePath(builder->bestPath); + CFArrayRef resultPath = SecCertificatePathVCCopyCertificates(builder->bestPath); builder->completed(builder->context, resultPath, pvc->details, builder->info, result); CFReleaseNull(resultPath); @@ -1288,19 +1309,20 @@ CFDataRef SecPathBuilderCopyClientAuditToken(SecPathBuilderRef builder) { ****************** SecTrustServer ********************** ********************************************************/ -typedef void (^SecTrustServerEvaluationCompleted)(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, SecCertificatePathRef chain, CFErrorRef error); +typedef void (^SecTrustServerEvaluationCompleted)(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, CFArrayRef chain, CFErrorRef error); static void SecTrustServerEvaluateCompleted(const void *userData, - SecCertificatePathRef chain, CFArrayRef details, CFDictionaryRef info, + CFArrayRef chain, CFArrayRef details, CFDictionaryRef info, SecTrustResultType result) { SecTrustServerEvaluationCompleted evaluated = (SecTrustServerEvaluationCompleted)userData; + TrustdHealthAnalyticsLogSuccess(TAEventEvaluationCompleted); evaluated(result, details, info, chain, NULL); Block_release(evaluated); } void -SecTrustServerEvaluateBlock(CFDataRef clientAuditToken, CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, bool keychainsAllowed, CFArrayRef policies, CFArrayRef responses, CFArrayRef SCTs, CFArrayRef trustedLogs, CFAbsoluteTime verifyTime, CFArrayRef accessGroups, CFArrayRef exceptions, void (^evaluated)(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, SecCertificatePathRef chain, CFErrorRef error)) { +SecTrustServerEvaluateBlock(CFDataRef clientAuditToken, CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, bool keychainsAllowed, CFArrayRef policies, CFArrayRef responses, CFArrayRef SCTs, CFArrayRef trustedLogs, CFAbsoluteTime verifyTime, CFArrayRef accessGroups, CFArrayRef exceptions, void (^evaluated)(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, CFArrayRef chain, CFErrorRef error)) { /* We need an array containing at least one certificate to proceed. */ if (!isArray(certificates) || !(CFArrayGetCount(certificates) > 0)) { CFErrorRef certError = CFErrorCreate(NULL, kCFErrorDomainOSStatus, errSecInvalidCertificate, NULL); @@ -1321,10 +1343,10 @@ SecTrustServerEvaluateBlock(CFDataRef clientAuditToken, CFArrayRef certificates, // NO_SERVER Shim code only, xpc interface should call SecTrustServerEvaluateBlock() directly -SecTrustResultType SecTrustServerEvaluate(CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, bool keychainsAllowed, CFArrayRef policies, CFArrayRef responses, CFArrayRef SCTs, CFArrayRef trustedLogs, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, CFArrayRef exceptions, CFArrayRef *pdetails, CFDictionaryRef *pinfo, SecCertificatePathRef *pchain, CFErrorRef *perror) { +SecTrustResultType SecTrustServerEvaluate(CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, bool keychainsAllowed, CFArrayRef policies, CFArrayRef responses, CFArrayRef SCTs, CFArrayRef trustedLogs, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, CFArrayRef exceptions, CFArrayRef *pdetails, CFDictionaryRef *pinfo, CFArrayRef *pchain, CFErrorRef *perror) { dispatch_semaphore_t done = dispatch_semaphore_create(0); __block SecTrustResultType result = kSecTrustResultInvalid; - SecTrustServerEvaluateBlock(NULL, certificates, anchors, anchorsOnly, keychainsAllowed, policies, responses, SCTs, trustedLogs, verifyTime, accessGroups, exceptions, ^(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, SecCertificatePathRef chain, CFErrorRef error) { + SecTrustServerEvaluateBlock(NULL, certificates, anchors, anchorsOnly, keychainsAllowed, policies, responses, SCTs, trustedLogs, verifyTime, accessGroups, exceptions, ^(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, CFArrayRef chain, CFErrorRef error) { result = tr; if (tr == kSecTrustResultInvalid) { if (perror) { diff --git a/OSX/sec/securityd/SecTrustServer.h b/OSX/sec/securityd/SecTrustServer.h index 1f068a66..0495c410 100644 --- a/OSX/sec/securityd/SecTrustServer.h +++ b/OSX/sec/securityd/SecTrustServer.h @@ -32,14 +32,16 @@ #include #include /* For errSecWaitForCallback. */ -#include #include #include #include - __BEGIN_DECLS +/* CRLs only implemented for macOS for legacy compatibility purposes using + * ocspd's (legacy) interfaces */ +#define ENABLE_CRLS TARGET_OS_OSX + typedef struct SecPathBuilder *SecPathBuilderRef; typedef struct OpaqueSecPVC *SecPVCRef; @@ -60,7 +62,7 @@ struct OpaqueSecPVC { /* Completion callback. */ typedef void(*SecPathBuilderCompleted)(const void *userData, - SecCertificatePathRef chain, CFArrayRef details, CFDictionaryRef info, + CFArrayRef chain, CFArrayRef details, CFDictionaryRef info, SecTrustResultType result); /* Returns a new trust path builder and policy evaluation engine instance. */ @@ -83,6 +85,7 @@ CFArrayRef SecPathBuilderCopySignedCertificateTimestamps(SecPathBuilderRef build CFArrayRef SecPathBuilderCopyOCSPResponses(SecPathBuilderRef builder); CFArrayRef SecPathBuilderCopyTrustedLogs(SecPathBuilderRef builder); +CFSetRef SecPathBuilderGetAllPaths(SecPathBuilderRef builder); SecCertificatePathVCRef SecPathBuilderGetPath(SecPathBuilderRef builder); SecCertificatePathVCRef SecPathBuilderGetBestPath(SecPathBuilderRef builder); CFAbsoluteTime SecPathBuilderGetVerifyTime(SecPathBuilderRef builder); @@ -97,14 +100,16 @@ bool SecPathBuilderHasTemporalParentChecks(SecPathBuilderRef builder); * as trust in an anchor is contextual to the policy being validated. */ bool SecPathBuilderIsAnchored(SecPathBuilderRef builder); bool SecPathBuilderIsAnchorSource(SecPathBuilderRef builder, SecCertificateSourceRef source); - +SecCertificateSourceRef SecPathBuilderGetAppAnchorSource(SecPathBuilderRef builder); CFIndex SecPathBuilderGetPVCCount(SecPathBuilderRef builder); SecPVCRef SecPathBuilderGetPVCAtIndex(SecPathBuilderRef builder, CFIndex ix); +/* Returns the first PVC that passed */ +SecPVCRef SecPathBuilderGetResultPVC(SecPathBuilderRef builder); + void SecPathBuilderSetResultInPVCs(SecPathBuilderRef builder, CFStringRef key, - CFIndex ix, CFTypeRef result, bool force, - SecTrustResultType resultType); + CFIndex ix, CFTypeRef result, bool force); /* This is a pre-decrement operation */ unsigned int SecPathBuilderDecrementAsyncJobCount(SecPathBuilderRef builder); @@ -134,12 +139,65 @@ dispatch_queue_t SecPathBuilderGetQueue(SecPathBuilderRef builder); CFDataRef SecPathBuilderCopyClientAuditToken(SecPathBuilderRef builder); /* Evaluate trust and call evaluated when done. */ -void SecTrustServerEvaluateBlock(CFDataRef clientAuditToken, CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, bool keychainsAllowed, CFArrayRef policies, CFArrayRef responses, CFArrayRef SCTs, CFArrayRef trustedLogs, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, CFArrayRef exceptions, void (^evaluated)(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, SecCertificatePathRef chain, CFErrorRef error)); +void SecTrustServerEvaluateBlock(CFDataRef clientAuditToken, CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, bool keychainsAllowed, CFArrayRef policies, CFArrayRef responses, CFArrayRef SCTs, CFArrayRef trustedLogs, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, CFArrayRef exceptions, void (^evaluated)(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, CFArrayRef chain, CFErrorRef error)); /* Synchronously invoke SecTrustServerEvaluateBlock. */ -SecTrustResultType SecTrustServerEvaluate(CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, bool keychainsAllowed, CFArrayRef policies, CFArrayRef responses, CFArrayRef SCTs, CFArrayRef trustedLogs, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, CFArrayRef exceptions, CFArrayRef *details, CFDictionaryRef *info, SecCertificatePathRef *chain, CFErrorRef *error); +SecTrustResultType SecTrustServerEvaluate(CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, bool keychainsAllowed, CFArrayRef policies, CFArrayRef responses, CFArrayRef SCTs, CFArrayRef trustedLogs, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, CFArrayRef exceptions, CFArrayRef *details, CFDictionaryRef *info, CFArrayRef *chain, CFErrorRef *error); + +/* TrustAnalytics builder types */ +typedef CF_OPTIONS(uint8_t, TA_SCTSource) { + TA_SCTEmbedded = 1 << 0, + TA_SCT_OCSP = 1 << 1, + TA_SCT_TLS = 1 << 2, +}; + +typedef CF_OPTIONS(uint8_t, TAValidStatus) { + TAValidDefinitelyOK = 1 << 0, + TAValidProbablyOK = 1 << 1, + TAValidProbablyRevoked = 1 << 2, + TAValidDefinitelyRevoked = 1 << 3, + TAValidDateConstrainedOK = 1 << 4, + TAValidDateContrainedRevoked = 1 << 5, +}; -void InitializeAnchorTable(void); +typedef struct { + uint64_t start_time; + // Certificate Transparency + TA_SCTSource sct_sources; + uint32_t number_scts; + uint32_t number_trusted_scts; + size_t total_sct_size; + // CAIssuer + bool ca_issuer_cache_hit; + bool ca_issuer_network; + uint32_t ca_issuer_fetches; + uint64_t ca_issuer_fetch_time; + uint32_t ca_issuer_fetch_failed; + bool ca_issuer_unsupported_data; + bool ca_issuer_multiple_certs; + // OCSP + bool ocsp_no_check; + bool ocsp_cache_hit; + bool ocsp_network; + uint32_t ocsp_fetches; + uint64_t ocsp_fetch_time; + uint32_t ocsp_fetch_failed; + bool ocsp_validation_failed; +#if ENABLE_CRLS + // CRLs + bool crl_client; + bool crl_cert; + uint32_t crl_fetches; + uint64_t crl_fetch_time; + uint32_t crl_fetch_failed; +#endif + // Valid + TAValidStatus valid_status; + bool valid_trigger_ocsp; + bool valid_require_ct; +} TrustAnalyticsBuilder; + +TrustAnalyticsBuilder *SecPathBuilderGetAnalyticsData(SecPathBuilderRef builder); __END_DECLS diff --git a/OSX/sec/securityd/SecTrustStoreServer.c b/OSX/sec/securityd/SecTrustStoreServer.c index 28fd42c9..c7f0a5ba 100644 --- a/OSX/sec/securityd/SecTrustStoreServer.c +++ b/OSX/sec/securityd/SecTrustStoreServer.c @@ -52,6 +52,7 @@ #include #include "utilities/SecFileLocations.h" #include +#include /* uid of the _securityd user. */ #define SECURTYD_UID 64 @@ -165,7 +166,7 @@ errOutNotLocked: static SecTrustStoreRef SecTrustStoreCreate(const char *db_name, bool create) { SecTrustStoreRef ts; - int s3e; + int s3e = SQLITE_OK; require(ts = (SecTrustStoreRef)malloc(sizeof(struct __SecTrustStore)), errOut); ts->queue = dispatch_queue_create("truststore", DISPATCH_QUEUE_SERIAL); @@ -216,6 +217,8 @@ errOut: dispatch_release_safe(ts->queue); free(ts); } + secerror("Failed to create trust store database: %d", s3e); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TATrustStore, TAOperationCreate, TAFatalError, s3e); return NULL; } @@ -303,18 +306,18 @@ bool _SecTrustStoreSetTrustSettings(SecTrustStoreRef ts, require_action_quiet(s3e == SQLITE_OK, errOut, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e)); /* Parameter order is sha1,subj,tset,data. */ - require_noerr_action_quiet(sqlite3_prepare(ts->s3h, insertSQL, sizeof(insertSQL), + require_noerr_action_quiet(s3e = sqlite3_prepare(ts->s3h, insertSQL, sizeof(insertSQL), &insert, NULL), errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e)); - require_noerr_action_quiet(sqlite3_bind_blob_wrapper(insert, 1, + require_noerr_action_quiet(s3e = sqlite3_bind_blob_wrapper(insert, 1, CFDataGetBytePtr(digest), CFDataGetLength(digest), SQLITE_STATIC), errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e)); - require_noerr_action_quiet(sqlite3_bind_blob_wrapper(insert, 2, + require_noerr_action_quiet(s3e = sqlite3_bind_blob_wrapper(insert, 2, CFDataGetBytePtr(subject), CFDataGetLength(subject), SQLITE_STATIC), errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e)); - require_noerr_action_quiet(sqlite3_bind_blob_wrapper(insert, 3, + require_noerr_action_quiet(s3e = sqlite3_bind_blob_wrapper(insert, 3, CFDataGetBytePtr(xmlData), CFDataGetLength(xmlData), SQLITE_STATIC), errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e)); - require_noerr_action_quiet(sqlite3_bind_blob_wrapper(insert, 4, + require_noerr_action_quiet(s3e = sqlite3_bind_blob_wrapper(insert, 4, SecCertificateGetBytePtr(certificate), SecCertificateGetLength(certificate), SQLITE_STATIC), errOutSql, ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e)); s3e = sqlite3_step(insert); @@ -342,15 +345,20 @@ bool _SecTrustStoreSetTrustSettings(SecTrustStoreRef ts, } errOutSql: - if (insert) + if (insert) { s3e = sqlite3_finalize(insert); - if (update) + } + if (update) { s3e = sqlite3_finalize(update); + } - if (ok && s3e == SQLITE_OK) + if (ok && s3e == SQLITE_OK) { s3e = sqlite3_exec(ts->s3h, "COMMIT TRANSACTION", NULL, NULL, NULL); + } if (!ok || s3e != SQLITE_OK) { + secerror("Failed to update trust store: (%d) %@", s3e, error ? *error : NULL); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TATrustStore, TAOperationWrite, TAFatalError, s3e); sqlite3_exec(ts->s3h, "ROLLBACK TRANSACTION", NULL, NULL, NULL); if (ok) { ok = SecError(errSecInternal, error, CFSTR("sqlite3 error: %d"), s3e); @@ -374,18 +382,24 @@ bool SecTrustStoreRemoveCertificateWithDigest(SecTrustStoreRef ts, require_quiet(ts, errOutNotLocked); require(!ts->readOnly, errOutNotLocked); dispatch_sync(ts->queue, ^{ + int s3e = SQLITE_OK; sqlite3_stmt *deleteStmt = NULL; - require_noerr(sqlite3_prepare(ts->s3h, deleteSQL, sizeof(deleteSQL), + + require_noerr(s3e = sqlite3_prepare(ts->s3h, deleteSQL, sizeof(deleteSQL), &deleteStmt, NULL), errOut); - require_noerr(sqlite3_bind_blob_wrapper(deleteStmt, 1, + require_noerr(s3e = sqlite3_bind_blob_wrapper(deleteStmt, 1, CFDataGetBytePtr(digest), CFDataGetLength(digest), SQLITE_STATIC), errOut); - sqlite3_step(deleteStmt); + s3e = sqlite3_step(deleteStmt); errOut: if (deleteStmt) { verify_noerr(sqlite3_finalize(deleteStmt)); } + if (s3e != SQLITE_OK && s3e != SQLITE_DONE) { + secerror("Removal of certificate from trust store failed: %d", s3e); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TATrustStore, TAOperationWrite, TAFatalError, s3e); + } }); errOutNotLocked: return true; @@ -397,9 +411,13 @@ bool _SecTrustStoreRemoveAll(SecTrustStoreRef ts, CFErrorRef *error) require(ts, errOutNotLocked); require(!ts->readOnly, errOutNotLocked); dispatch_sync(ts->queue, ^{ - if (SQLITE_OK == sqlite3_exec(ts->s3h, deleteAllSQL, NULL, NULL, NULL)) { + int s3e =sqlite3_exec(ts->s3h, deleteAllSQL, NULL, NULL, NULL); + if (s3e == SQLITE_OK) { removed_all = true; ts->containsSettings = false; + } else { + secerror("Clearing of trust store failed: %d", s3e); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TATrustStore, TAOperationWrite, TAFatalError, s3e); } /* prepared statements become unusable after deleteAllSQL, reset them */ @@ -421,19 +439,20 @@ CFArrayRef SecTrustStoreCopyParents(SecTrustStoreRef ts, __block CFMutableArrayRef parents = NULL; require(ts, errOutNotLocked); dispatch_sync(ts->queue, ^{ - require_quiet(ts->containsSettings, errOut); + int s3e = SQLITE_OK; + require_quiet(ts->containsSettings, ok); CFDataRef issuer; require(issuer = SecCertificateGetNormalizedIssuerContent(certificate), errOut); /* @@@ Might have to use SQLITE_TRANSIENT */ - require_noerr(sqlite3_bind_blob_wrapper(ts->copyParents, 1, + require_noerr(s3e = sqlite3_bind_blob_wrapper(ts->copyParents, 1, CFDataGetBytePtr(issuer), CFDataGetLength(issuer), SQLITE_STATIC), errOut); require(parents = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), errOut); for (;;) { - int s3e = sqlite3_step(ts->copyParents); + s3e = sqlite3_step(ts->copyParents); if (s3e == SQLITE_ROW) { SecCertificateRef cert; require(cert = SecCertificateCreateWithBytes(kCFAllocatorDefault, @@ -442,13 +461,15 @@ CFArrayRef SecTrustStoreCopyParents(SecTrustStoreRef ts, CFArrayAppendValue(parents, cert); CFRelease(cert); } else { - require(s3e == SQLITE_DONE, errOut); + require(s3e == SQLITE_DONE || s3e == SQLITE_OK, errOut); break; } } goto ok; errOut: + secerror("Failed to read parents from trust store: %d", s3e); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TATrustStore, TAOperationRead, TAFatalError, s3e); if (parents) { CFRelease(parents); parents = NULL; @@ -470,8 +491,8 @@ static bool SecTrustStoreQueryCertificateWithDigest(SecTrustStoreRef ts, dispatch_sync(ts->queue, ^{ CFDataRef xmlData = NULL; CFPropertyListRef trustSettings = NULL; + int s3e = SQLITE_OK; require_action_quiet(ts->containsSettings, errOut, ok = true); - int s3e; require_noerr_action(s3e = sqlite3_bind_blob_wrapper(ts->contains, 1, CFDataGetBytePtr(digest), CFDataGetLength(digest), SQLITE_STATIC), errOut, ok = SecDbErrorWithStmt(s3e, ts->contains, error, CFSTR("sqlite3_bind_blob failed"))); @@ -491,10 +512,15 @@ static bool SecTrustStoreQueryCertificateWithDigest(SecTrustStoreRef ts, *usageConstraints = CFRetain(trustSettings); } } else { - require_action(s3e == SQLITE_DONE, errOut, ok = SecDbErrorWithStmt(s3e, ts->contains, error, CFSTR("sqlite3_step failed"))); + require_action(s3e == SQLITE_DONE || s3e == SQLITE_OK, errOut, + ok = SecDbErrorWithStmt(s3e, ts->contains, error, CFSTR("sqlite3_step failed"))); } errOut: + if (!ok) { + secerror("Failed to query for cert in trust store: %d", s3e); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TATrustStore, TAOperationRead, TAFatalError, s3e); + } verify_noerr(sqlite3_reset(ts->contains)); verify_noerr(sqlite3_clear_bindings(ts->contains)); CFReleaseNull(xmlData); @@ -525,12 +551,12 @@ bool _SecTrustStoreCopyAll(SecTrustStoreRef ts, CFArrayRef *trustStoreContents, CFDataRef xmlData = NULL; CFPropertyListRef trustSettings = NULL; CFArrayRef certSettingsPair = NULL; - require_noerr(sqlite3_prepare(ts->s3h, copyAllSQL, sizeof(copyAllSQL), - ©AllStmt, NULL), errOut); + int s3e = SQLITE_OK; + require_noerr(s3e = sqlite3_prepare(ts->s3h, copyAllSQL, sizeof(copyAllSQL), + ©AllStmt, NULL), errOut); require(CertsAndSettings = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks), errOut); - for(;;) { - int s3e = sqlite3_step(copyAllStmt); + s3e = sqlite3_step(copyAllStmt); if (s3e == SQLITE_ROW) { require(cert = CFDataCreate(kCFAllocatorDefault, sqlite3_column_blob(copyAllStmt, 0), @@ -551,13 +577,15 @@ bool _SecTrustStoreCopyAll(SecTrustStoreRef ts, CFArrayRef *trustStoreContents, CFReleaseNull(trustSettings); CFReleaseNull(certSettingsPair); } else { - require_action(s3e == SQLITE_DONE, errOut, ok = SecDbErrorWithStmt(s3e, copyAllStmt, error, CFSTR("sqlite3_step failed"))); + require_action(s3e == SQLITE_DONE || s3e == SQLITE_OK, errOut, ok = SecDbErrorWithStmt(s3e, copyAllStmt, error, CFSTR("sqlite3_step failed"))); break; } } goto ok; errOut: + secerror("Failed to query for all certs in trust store: %d", s3e); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TATrustStore, TAOperationRead, TAFatalError, s3e); CFReleaseNull(cert); CFReleaseNull(xmlData); CFReleaseNull(trustSettings); diff --git a/OSX/sec/securityd/asynchttp.c b/OSX/sec/securityd/asynchttp.c index 0a29fc43..d13e023a 100644 --- a/OSX/sec/securityd/asynchttp.c +++ b/OSX/sec/securityd/asynchttp.c @@ -38,6 +38,7 @@ #include #include #include +#include #include @@ -455,6 +456,8 @@ bool asynchttp_request(CFHTTPMessageRef request, uint64_t timeout, asynchttp_t * | kCFStreamEventEndEncountered), handle_server_response, &stream_context); CFReadStreamSetDispatchQueue(http->stream, http->queue); + + http->start_time = mach_absolute_time(); CFReadStreamOpen(http->stream); return false; /* false -> something was scheduled. */ diff --git a/OSX/sec/securityd/asynchttp.h b/OSX/sec/securityd/asynchttp.h index ea9c42fd..5a417954 100644 --- a/OSX/sec/securityd/asynchttp.h +++ b/OSX/sec/securityd/asynchttp.h @@ -46,6 +46,7 @@ typedef struct asynchttp_s { CFHTTPMessageRef request; CFHTTPMessageRef response; dispatch_queue_t queue; + uint64_t start_time; /* The fields below should be considered private. */ CFMutableDataRef data; CFReadStreamRef stream; diff --git a/OSX/sec/securityd/com.apple.secd.sb b/OSX/sec/securityd/com.apple.secd.sb index f73a83d3..15990dd1 100644 --- a/OSX/sec/securityd/com.apple.secd.sb +++ b/OSX/sec/securityd/com.apple.secd.sb @@ -31,10 +31,15 @@ (global-name "com.apple.SystemConfiguration.configd") (global-name "com.apple.security.cloudkeychainproxy3") (global-name "com.apple.security.keychainsyncingoveridsproxy") + (global-name "com.apple.cdp.daemon") (global-name "com.apple.cloudd") (global-name "com.apple.apsd") (global-name "com.apple.windowserver.active")) +;; Used to send logs for MoiC. +(allow mach-lookup + (global-name "com.apple.imagent.desktop.auth")) + (allow iokit-open (iokit-user-client-class "AppleKeyStoreUserClient")) diff --git a/OSX/sec/securityd/entitlements.plist b/OSX/sec/securityd/entitlements.plist index 68535bba..fe8c7f7e 100644 --- a/OSX/sec/securityd/entitlements.plist +++ b/OSX/sec/securityd/entitlements.plist @@ -2,6 +2,8 @@ + com.apple.private.accounts.allaccounts + com.apple.private.aps-connection-initiate aps-connection-initiate @@ -50,6 +52,8 @@ com.apple.private.applecredentialmanager.allow + com.apple.private.imcore.imagent + com.apple.private.MobileGestalt.AllowedProtectedKeys SerialNumber diff --git a/OSX/sec/securityd/policytree.c b/OSX/sec/securityd/policytree.c index b85f4fd4..15efe996 100644 --- a/OSX/sec/securityd/policytree.c +++ b/OSX/sec/securityd/policytree.c @@ -26,7 +26,7 @@ */ #include "policytree.h" -#include +#include #include diff --git a/OSX/sec/securityd/spi.c b/OSX/sec/securityd/spi.c index c845fa5e..9fb3b586 100644 --- a/OSX/sec/securityd/spi.c +++ b/OSX/sec/securityd/spi.c @@ -34,9 +34,11 @@ #include #include #include +#include #include #include #include +#include #include #include "utilities/iOSforOSX.h" @@ -153,11 +155,13 @@ static struct trustd trustd_spi = { .sec_trust_store_remove_certificate = SecTrustStoreRemoveCertificateWithDigest, .sec_truststore_remove_all = _SecTrustStoreRemoveAll, .sec_trust_evaluate = SecTrustServerEvaluate, - .sec_ota_pki_asset_version = SecOTAPKIGetCurrentAssetVersion, + .sec_ota_pki_trust_store_version = SecOTAPKIGetCurrentTrustStoreVersion, .ota_CopyEscrowCertificates = SecOTAPKICopyCurrentEscrowCertificates, .sec_ota_pki_get_new_asset = SecOTAPKISignalNewAsset, .sec_trust_store_copy_all = _SecTrustStoreCopyAll, .sec_trust_store_copy_usage_constraints = _SecTrustStoreCopyUsageConstraints, + .sec_ocsp_cache_flush = SecOCSPCacheFlush, + .sec_tls_analytics_report = SecTLSAnalyticsReport, }; #endif diff --git a/OSX/sectests/SecurityTests-Entitlements.plist b/OSX/sectests/SecurityTests-Entitlements.plist index f1509978..bcd392ae 100644 --- a/OSX/sectests/SecurityTests-Entitlements.plist +++ b/OSX/sectests/SecurityTests-Entitlements.plist @@ -31,17 +31,5 @@ 123456.test.group 123456.test.group2 - com.apple.private.ubiquity-kvstore-access - - com.apple.securityd - - com.apple.developer.ubiquity-kvstore-identifier - com.apple.security.cloudkeychainproxy3 - com.apple.developer.ubiquity-container-identifiers - - com.apple.security.cloudkeychainproxy3 - com.apple.security.cloudkeychain - CloudKeychainProxy.xpc - diff --git a/OSX/shared_regressions/shared_regressions.h b/OSX/shared_regressions/shared_regressions.h index 534d53f6..9a5f7497 100644 --- a/OSX/shared_regressions/shared_regressions.h +++ b/OSX/shared_regressions/shared_regressions.h @@ -61,6 +61,7 @@ ONE_TEST(si_82_sectrust_ct) ONE_TEST(si_83_seccertificate_sighashalg) ONE_TEST(si_85_sectrust_ssl_policy) ONE_TEST(si_87_sectrust_name_constraints) +ONE_TEST(si_88_sectrust_valid) ONE_TEST(si_97_sectrust_path_scoring) ONE_TEST(rk_01_recoverykey) diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/PinningPolicyTrustTest.plist b/OSX/shared_regressions/si-20-sectrust-policies-data/PinningPolicyTrustTest.plist index 7ab213a3..d33efc70 100644 --- a/OSX/shared_regressions/si-20-sectrust-policies-data/PinningPolicyTrustTest.plist +++ b/OSX/shared_regressions/si-20-sectrust-policies-data/PinningPolicyTrustTest.plist @@ -2366,7 +2366,7 @@ Anchors AppleRootCA ExpectedResult - 4 + 6 ChainLength 3 VerifyDate @@ -2422,7 +2422,7 @@ Anchors AppleRootCA ExpectedResult - 4 + 6 ChainLength 3 VerifyDate @@ -2478,7 +2478,7 @@ Anchors AppleRootCA ExpectedResult - 4 + 6 ChainLength 3 VerifyDate @@ -2536,7 +2536,7 @@ Anchors AppleRootCA ExpectedResult - 4 + 6 ChainLength 3 VerifyDate diff --git a/OSX/shared_regressions/si-20-sectrust-policies.m b/OSX/shared_regressions/si-20-sectrust-policies.m index bffb97fd..992cbc5e 100644 --- a/OSX/shared_regressions/si-20-sectrust-policies.m +++ b/OSX/shared_regressions/si-20-sectrust-policies.m @@ -325,7 +325,7 @@ errOut: @end -void (^runTestForObject)(id, NSUInteger, BOOL *) = +void (^runPolicyTestForObject)(id, NSUInteger, BOOL *) = ^(NSDictionary *testDict, NSUInteger idx, BOOL *stop) { NSString *majorTestName = nil, *minorTestName = nil; TestObject *test = nil; @@ -384,7 +384,7 @@ void (^runTestForObject)(id, NSUInteger, BOOL *) = require_action_quiet(expectedResult = [testDict objectForKey:kSecTrustTestExpectedResult], testOut, fail("%@: failed to get expected result for test", test.fullTestName)); - /* If we enabled test certificates on a non-internal device, expect a failure instead of succees. */ + /* If we enabled test certificates on a non-internal device, expect a failure instead of success. */ if (enableTestCertificates && !SecIsInternalRelease() && ([expectedResult unsignedIntValue] == 4)) { ok(trustResult == 5, "%@: actual trust result %u did not match expected trust result %u", @@ -425,7 +425,7 @@ static void tests(void) plan_tests((int)[testsArray count]); - [testsArray enumerateObjectsUsingBlock:runTestForObject]; + [testsArray enumerateObjectsUsingBlock:runPolicyTestForObject]; exit: return; diff --git a/OSX/shared_regressions/si-88-sectrust-valid.m b/OSX/shared_regressions/si-88-sectrust-valid.m new file mode 100644 index 00000000..6d4aa4c2 --- /dev/null +++ b/OSX/shared_regressions/si-88-sectrust-valid.m @@ -0,0 +1,149 @@ +/* + * si-88-sectrust-valid.m + * Security + * + * Copyright (c) 2017-2018 Apple Inc. All Rights Reserved. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "shared_regressions.h" + +static void test_valid_trust(SecCertificateRef leaf, SecCertificateRef ca, CFArrayRef anchors, + CFDateRef date, SecTrustResultType expected, const char *test_name) +{ + CFArrayRef policies=NULL; + SecPolicyRef policy=NULL; + SecTrustRef trust=NULL; + SecTrustResultType trustResult; + CFMutableArrayRef certs=NULL; + + printf("Starting %s\n", test_name); + isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array"); + if (certs) { + if (leaf) { + CFArrayAppendValue(certs, leaf); + } + if (ca) { + CFArrayAppendValue(certs, ca); + } + } + + isnt(policy = SecPolicyCreateBasicX509(), NULL, "create policy"); + isnt(policies = CFArrayCreate(kCFAllocatorDefault, (const void **)&policy, 1, &kCFTypeArrayCallBacks), NULL, "create policies"); + ok_status(SecTrustCreateWithCertificates(certs, policies, &trust), "create trust"); + + assert(trust); // silence analyzer + ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors"); + ok_status(SecTrustSetVerifyDate(trust, date), "set date"); + ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); + ok(trustResult == expected, "trustResult %d expected (got %d)", + (int)expected, (int)trustResult); + + CFReleaseSafe(certs); + CFReleaseSafe(policy); + CFReleaseSafe(policies); + CFReleaseSafe(trust); +} + +#import +SecCertificateRef SecCertificateCreateWithPEM(CFAllocatorRef allocator, CFDataRef pem_certificate); + +static SecCertificateRef SecCertificateCreateFromResource(NSString *name) +{ + NSString *resources = @"si-88-sectrust-valid-data"; + NSString *extension = @"pem"; + + NSURL *url = [[NSBundle mainBundle] URLForResource:name withExtension:extension subdirectory:resources]; + if (!url) { + printf("No URL for resource \"%s.pem\"\n", [name UTF8String]); + return NULL; + } + + NSData *certData = [NSData dataWithContentsOfURL:url]; + if (!certData) { + printf("No cert data for resource \"%s.pem\"\n", [name UTF8String]); + return NULL; + } + + return SecCertificateCreateWithPEM(kCFAllocatorDefault, (__bridge CFDataRef)certData); +} + +static void tests() +{ + SecCertificateRef ca_na=NULL, ca_nb=NULL, root=NULL; + SecCertificateRef leaf_na_ok1=NULL, leaf_na_ok2=NULL; + SecCertificateRef leaf_nb_ok1=NULL, leaf_nb_ok2=NULL, leaf_nb_revoked1=NULL; + + isnt(ca_na = SecCertificateCreateFromResource(@"ca-na"), NULL, "create ca-na cert"); + isnt(ca_nb = SecCertificateCreateFromResource(@"ca-nb"), NULL, "create ca-nb cert"); + isnt(root = SecCertificateCreateFromResource(@"root"), NULL, "create root cert"); + isnt(leaf_na_ok1 = SecCertificateCreateFromResource(@"leaf-na-ok1"), NULL, "create leaf-na-ok1 cert"); + isnt(leaf_na_ok2 = SecCertificateCreateFromResource(@"leaf-na-ok2"), NULL, "create leaf-na-ok2 cert"); + isnt(leaf_nb_ok1 = SecCertificateCreateFromResource(@"leaf-nb-ok1"), NULL, "create leaf-nb-ok1 cert"); + isnt(leaf_nb_ok2 = SecCertificateCreateFromResource(@"leaf-nb-ok2"), NULL, "create leaf-nb-ok2 cert"); + isnt(leaf_nb_revoked1 = SecCertificateCreateFromResource(@"leaf-nb-revoked1"), NULL, "create leaf-nb-revoked1 cert"); + + CFMutableArrayRef anchors=NULL; + isnt(anchors = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create anchors array"); + if (anchors && root) { + CFArrayAppendValue(anchors, root); + } + CFCalendarRef cal = NULL; + CFAbsoluteTime at; + CFDateRef date_20180102 = NULL; // a date when our test certs would all be valid, in the absence of Valid db info + + isnt(cal = CFCalendarCreateWithIdentifier(kCFAllocatorDefault, kCFGregorianCalendar), NULL, "create calendar"); + ok(CFCalendarComposeAbsoluteTime(cal, &at, "yMd", 2018, 1, 2), "create verify absolute time 20180102"); + isnt(date_20180102 = CFDateCreate(kCFAllocatorDefault, at), NULL, "create verify date 20180102"); + + /* Case 1: leaf_na_ok1 (not revoked) */ + /* -- was OK: cert issued 2017-10-20, before the CA not-after date of 2017-10-21 */ + /* -- now BAD: since a not-after date now requires CT and the test cert has no SCT, this is fatal. */ + test_valid_trust(leaf_na_ok1, ca_na, anchors, date_20180102, kSecTrustResultFatalTrustFailure, "leaf_na_ok1 test"); + + /* Case 2: leaf_na_ok2 (revoked) */ + /* -- BAD: cert issued 2017-10-26, after the CA not-after date of 2017-10-21 */ + test_valid_trust(leaf_na_ok2, ca_na, anchors, date_20180102, kSecTrustResultFatalTrustFailure, "leaf_na_ok2 test"); + + /* Case 3: leaf_nb_ok1 (revoked) */ + /* -- BAD: cert issued 2017-10-20, before the CA not-before date of 2017-10-22 */ + test_valid_trust(leaf_nb_ok1, ca_nb, anchors, date_20180102, kSecTrustResultFatalTrustFailure, "leaf_nb_ok1 test"); + + /* Case 4: leaf_nb_ok2 (not revoked) */ + /* -- OK: cert issued 2017-10-26, after the CA not-before date of 2017-10-22 */ + test_valid_trust(leaf_nb_ok2, ca_nb, anchors, date_20180102, kSecTrustResultUnspecified, "leaf_nb_ok2 test"); + + /* Case 5: leaf_nb_revoked1 (revoked) */ + /* -- BAD: cert issued 2017-10-20, before the CA not-before date of 2017-10-22 */ + test_valid_trust(leaf_nb_revoked1, ca_nb, anchors, date_20180102, kSecTrustResultFatalTrustFailure, "leaf_nb_revoked1 test"); + + CFReleaseSafe(ca_na); + CFReleaseSafe(ca_nb); + CFReleaseSafe(root); + CFReleaseSafe(leaf_na_ok1); + CFReleaseSafe(leaf_na_ok2); + CFReleaseSafe(leaf_nb_ok1); + CFReleaseSafe(leaf_nb_ok2); + CFReleaseSafe(leaf_nb_revoked1); + CFReleaseSafe(anchors); + CFReleaseSafe(cal); + CFReleaseSafe(date_20180102); +} + + +int si_88_sectrust_valid(int argc, char *const *argv) +{ + plan_tests(52); + + tests(); + + return 0; +} diff --git a/OSX/trustd/iOS/entitlements.plist b/OSX/trustd/iOS/entitlements.plist index 8513f430..dd43167f 100644 --- a/OSX/trustd/iOS/entitlements.plist +++ b/OSX/trustd/iOS/entitlements.plist @@ -19,6 +19,7 @@ com.apple.private.assets.accessible-asset-types com.apple.MobileAsset.CertificatePinning + com.apple.MobileAsset.PKITrustSupplementals seatbelt-profiles diff --git a/OSX/trustd/macOS/SecTrustOSXEntryPoints.h b/OSX/trustd/macOS/SecTrustOSXEntryPoints.h index 3f44a3a4..6dd6529b 100644 --- a/OSX/trustd/macOS/SecTrustOSXEntryPoints.h +++ b/OSX/trustd/macOS/SecTrustOSXEntryPoints.h @@ -39,6 +39,7 @@ void SecTrustLegacySourcesListenForKeychainEvents(void); OSStatus SecTrustLegacyCRLStatus(SecCertificateRef cert, CFArrayRef chain, CFURLRef currCRLDP); typedef struct async_ocspd_s { + uint64_t start_time; void (*completed)(struct async_ocspd_s *ocspd); void *info; OSStatus response; diff --git a/OSX/trustd/macOS/entitlements.plist b/OSX/trustd/macOS/entitlements.plist index d8fc3a06..3dbd2c88 100644 --- a/OSX/trustd/macOS/entitlements.plist +++ b/OSX/trustd/macOS/entitlements.plist @@ -15,6 +15,7 @@ com.apple.private.assets.accessible-asset-types com.apple.MobileAsset.CertificatePinning + com.apple.MobileAsset.PKITrustSupplementals diff --git a/OSX/trustd/trustd.c b/OSX/trustd/trustd.c index 6975da25..2fd55127 100644 --- a/OSX/trustd/trustd.c +++ b/OSX/trustd/trustd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2017-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -31,12 +31,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -47,12 +49,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #if TARGET_OS_OSX #include @@ -69,17 +73,29 @@ static struct trustd trustd_spi = { .sec_trust_store_remove_certificate = SecTrustStoreRemoveCertificateWithDigest, .sec_truststore_remove_all = _SecTrustStoreRemoveAll, .sec_trust_evaluate = SecTrustServerEvaluate, - .sec_ota_pki_asset_version = SecOTAPKIGetCurrentAssetVersion, + .sec_ota_pki_trust_store_version = SecOTAPKIGetCurrentTrustStoreVersion, .ota_CopyEscrowCertificates = SecOTAPKICopyCurrentEscrowCertificates, .sec_ota_pki_get_new_asset = SecOTAPKISignalNewAsset, .sec_trust_store_copy_all = _SecTrustStoreCopyAll, .sec_trust_store_copy_usage_constraints = _SecTrustStoreCopyUsageConstraints, + .sec_ocsp_cache_flush = SecOCSPCacheFlush, + .sec_tls_analytics_report = SecTLSAnalyticsReport, }; -static bool SecXPCDictionarySetChainOptional(xpc_object_t message, const char *key, SecCertificatePathRef path, CFErrorRef *error) { +static bool SecXPCDictionarySetChainOptional(xpc_object_t message, const char *key, CFArrayRef path, CFErrorRef *error) { if (!path) return true; - xpc_object_t xpc_chain = SecCertificatePathCopyXPCArray(path, error); + __block xpc_object_t xpc_chain = NULL; + require_action_quiet(xpc_chain = xpc_array_create(NULL, 0), exit, SecError(errSecParam, error, CFSTR("xpc_array_create failed"))); + CFArrayForEach(path, ^(const void *value) { + SecCertificateRef cert = (SecCertificateRef)value; + if (xpc_chain && !SecCertificateAppendToXPCArray(cert, xpc_chain, error)) { + xpc_release(xpc_chain); + xpc_chain = NULL; + } + }); + +exit: if (!xpc_chain) return false; @@ -189,32 +205,30 @@ static bool SecXPCTrustStoreSetTrustSettings(xpc_object_t event, xpc_object_t re } static bool SecXPCTrustStoreRemoveCertificate(xpc_object_t event, xpc_object_t reply, CFErrorRef *error) { - bool noError = false; SecTrustStoreRef ts = SecXPCDictionaryGetTrustStore(event, kSecXPCKeyDomain, error); if (ts) { CFDataRef digest = SecXPCDictionaryCopyData(event, kSecXPCKeyDigest, error); if (digest) { bool result = SecTrustStoreRemoveCertificateWithDigest(ts, digest, error); xpc_dictionary_set_bool(reply, kSecXPCKeyResult, result); - noError = true; CFReleaseNull(digest); + return true; } } - return noError; + return false; } static bool SecXPCTrustStoreCopyAll(xpc_object_t event, xpc_object_t reply, CFErrorRef *error) { - bool result = false; SecTrustStoreRef ts = SecXPCDictionaryGetTrustStore(event, kSecXPCKeyDomain, error); if (ts) { CFArrayRef trustStoreContents = NULL; if(_SecTrustStoreCopyAll(ts, &trustStoreContents, error) && trustStoreContents) { SecXPCDictionarySetPList(reply, kSecXPCKeyResult, trustStoreContents, error); CFReleaseNull(trustStoreContents); - result = true; + return true; } } - return result; + return false; } static bool SecXPCTrustStoreCopyUsageConstraints(xpc_object_t event, xpc_object_t reply, CFErrorRef *error) { @@ -235,8 +249,15 @@ static bool SecXPCTrustStoreCopyUsageConstraints(xpc_object_t event, xpc_object_ return result; } +static bool SecXPC_OCSPCacheFlush(xpc_object_t __unused event, xpc_object_t __unused reply, CFErrorRef *error) { + if(SecOCSPCacheFlush(error)) { + return true; + } + return false; +} + static bool SecXPC_OTAPKI_GetAssetVersion(xpc_object_t __unused event, xpc_object_t reply, CFErrorRef *error) { - xpc_dictionary_set_int64(reply, kSecXPCKeyResult, SecOTAPKIGetCurrentAssetVersion(error)); + xpc_dictionary_set_uint64(reply, kSecXPCKeyResult, SecOTAPKIGetCurrentTrustStoreVersion(error)); return true; } @@ -255,10 +276,22 @@ static bool SecXPC_OTAPKI_GetEscrowCertificates(xpc_object_t event, xpc_object_t } static bool SecXPC_OTAPKI_GetNewAsset(xpc_object_t __unused event, xpc_object_t reply, CFErrorRef *error) { - xpc_dictionary_set_int64(reply, kSecXPCKeyResult, SecOTAPKISignalNewAsset(error)); + xpc_dictionary_set_uint64(reply, kSecXPCKeyResult, SecOTAPKISignalNewAsset(error)); return true; } +static bool SecXPC_TLS_AnalyticsReport(xpc_object_t event, xpc_object_t reply, CFErrorRef *error) { + xpc_object_t attributes = xpc_dictionary_get_dictionary(event, kSecTrustEventAttributesKey); + CFStringRef eventName = SecXPCDictionaryCopyString(event, kSecTrustEventNameKey, error); + bool result = false; + if (attributes && eventName) { + result = SecTLSAnalyticsReport(eventName, attributes, error); + } + xpc_dictionary_set_bool(reply, kSecXPCKeyResult, result); + CFReleaseNull(eventName); + return result; +} + typedef bool(*SecXPCOperationHandler)(xpc_object_t event, xpc_object_t reply, CFErrorRef *error); typedef struct { @@ -272,9 +305,11 @@ struct trustd_operations { SecXPCServerOperation trust_store_remove_certificate; SecXPCServerOperation trust_store_copy_all; SecXPCServerOperation trust_store_copy_usage_constraints; - SecXPCServerOperation ota_pki_asset_version; + SecXPCServerOperation ocsp_cache_flush; + SecXPCServerOperation ota_pki_trust_store_version; SecXPCServerOperation ota_pki_get_escrow_certs; SecXPCServerOperation ota_pki_get_new_asset; + SecXPCServerOperation tls_analytics_report; }; static struct trustd_operations trustd_ops = { @@ -283,9 +318,11 @@ static struct trustd_operations trustd_ops = { .trust_store_remove_certificate = { kSecEntitlementModifyAnchorCertificates, SecXPCTrustStoreRemoveCertificate }, .trust_store_copy_all = { kSecEntitlementModifyAnchorCertificates, SecXPCTrustStoreCopyAll }, .trust_store_copy_usage_constraints = { kSecEntitlementModifyAnchorCertificates, SecXPCTrustStoreCopyUsageConstraints }, - .ota_pki_asset_version = { NULL, SecXPC_OTAPKI_GetAssetVersion }, + .ocsp_cache_flush = { NULL, SecXPC_OCSPCacheFlush }, + .ota_pki_trust_store_version = { NULL, SecXPC_OTAPKI_GetAssetVersion }, .ota_pki_get_escrow_certs = { NULL, SecXPC_OTAPKI_GetEscrowCertificates }, .ota_pki_get_new_asset = { NULL, SecXPC_OTAPKI_GetNewAsset }, + .tls_analytics_report = { NULL, SecXPC_TLS_AnalyticsReport }, }; static void trustd_xpc_dictionary_handler(const xpc_connection_t connection, xpc_object_t event) { @@ -350,7 +387,7 @@ static void trustd_xpc_dictionary_handler(const xpc_connection_t connection, xpc SecTrustServerEvaluateBlock(clientAuditToken, certificates, anchors, anchorsOnly, keychainsAllowed, policies, responses, scts, trustedLogs, verifyTime, client.accessGroups, exceptions, - ^(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, SecCertificatePathRef chain, + ^(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, CFArrayRef chain, CFErrorRef replyError) { // Send back reply now if (replyError) { @@ -372,7 +409,39 @@ static void trustd_xpc_dictionary_handler(const xpc_connection_t connection, xpc } else { secdebug("ipc", "%@ %@ responding %@", client.task, SOSCCGetOperationDescription((enum SecXPCOperation)operation), asyncReply); } +#if TARGET_OS_IPHONE + // Ensure that we remain dirty for two seconds after ending the client's transaction to avoid jetsam loops. + // Refer to rdar://problem/38044831 for more details. + static dispatch_queue_t dirty_timer_queue = NULL; + static dispatch_source_t dirty_timer = NULL; + static bool has_transcation = false; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + dirty_timer_queue = dispatch_queue_create("dirty timer queue", DISPATCH_QUEUE_SERIAL); + dirty_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dirty_timer_queue); + dispatch_source_set_event_handler(dirty_timer, ^{ + /* timer fired, end the transaction */ + os_assumes(has_transcation); + xpc_transaction_end(); + has_transcation = false; + }); + }); + dispatch_sync(dirty_timer_queue, ^{ + /* reset the timer for 2 seconds from now */ + dispatch_source_set_timer(dirty_timer, dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), + DISPATCH_TIME_FOREVER, 100 * NSEC_PER_MSEC); + if (!has_transcation) { + /* timer is not running/not holding a transaction, start transaction */ + xpc_transaction_begin(); + has_transcation = true; + } + static dispatch_once_t onceToken2; + dispatch_once(&onceToken2, ^{ + dispatch_resume(dirty_timer); + }); + }); +#endif xpc_connection_send_message(connection, asyncReply); xpc_release(asyncReply); xpc_release(connection); @@ -405,8 +474,11 @@ static void trustd_xpc_dictionary_handler(const xpc_connection_t connection, xpc case sec_trust_store_copy_usage_constraints_id: server_op = &trustd_ops.trust_store_copy_usage_constraints; break; - case sec_ota_pki_asset_version_id: - server_op = &trustd_ops.ota_pki_asset_version; + case sec_ocsp_cache_flush_id: + server_op = &trustd_ops.ocsp_cache_flush; + break; + case sec_ota_pki_trust_store_version_id: + server_op = &trustd_ops.ota_pki_trust_store_version; break; case kSecXPCOpOTAGetEscrowCertificates: server_op = &trustd_ops.ota_pki_get_escrow_certs; @@ -414,6 +486,8 @@ static void trustd_xpc_dictionary_handler(const xpc_connection_t connection, xpc case kSecXPCOpOTAPKIGetNewAsset: server_op = &trustd_ops.ota_pki_get_new_asset; break; + case kSecXPCOpTLSAnaltyicsReport: + server_op = &trustd_ops.tls_analytics_report; default: break; } @@ -493,56 +567,77 @@ static void trustd_xpc_init(const char *service_name) xpc_connection_resume(listener); } -static void trustd_delete_old_files(void) { - -#if TARGET_OS_EMBEDDED - if (getuid() != 64) // _securityd -#else - if (getuid() != 0) -#endif - { return; } - /* If we get past this line, then we can attempt to delete old revocation files; - otherwise we won't have sufficient privilege. */ - - /* We try to clean up after ourselves, but don't care if we succeed. */ - WithPathInRevocationInfoDirectory(CFSTR("update-current"), ^(const char *utf8String) { +static void trustd_delete_old_sqlite_keychain_files(CFStringRef baseFilename) { + WithPathInKeychainDirectory(baseFilename, ^(const char *utf8String) { (void)remove(utf8String); }); - WithPathInRevocationInfoDirectory(CFSTR("update-full"), ^(const char *utf8String) { + CFStringRef shmFile = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@-shm"), baseFilename); + WithPathInKeychainDirectory(shmFile, ^(const char *utf8String) { (void)remove(utf8String); }); - WithPathInRevocationInfoDirectory(CFSTR("update-full.gz"), ^(const char *utf8String) { + CFReleaseNull(shmFile); + CFStringRef walFile = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@-wal"), baseFilename); + WithPathInKeychainDirectory(walFile, ^(const char *utf8String) { (void)remove(utf8String); }); + CFReleaseNull(walFile); + CFStringRef journalFile = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@-journal"), baseFilename); + WithPathInKeychainDirectory(journalFile, ^(const char *utf8String) { + (void)remove(utf8String); + }); + CFReleaseNull(journalFile); } #if TARGET_OS_OSX -static void trustd_delete_old_caches(void) { - /* We try to clean up after ourselves, but don't care if we succeed. */ - WithPathInKeychainDirectory(CFSTR("ocspcache.sqlite3"), ^(const char *utf8String) { +static void trustd_delete_old_sqlite_user_cache_files(CFStringRef baseFilename) { + WithPathInUserCacheDirectory(baseFilename, ^(const char *utf8String) { (void)remove(utf8String); }); - WithPathInKeychainDirectory(CFSTR("ocspcache.sqlite3-wal"), ^(const char *utf8String) { + CFStringRef shmFile = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@-shm"), baseFilename); + WithPathInUserCacheDirectory(shmFile, ^(const char *utf8String) { (void)remove(utf8String); }); - WithPathInKeychainDirectory(CFSTR("ocspcache.sqlite3-shm"), ^(const char *utf8String) { + CFReleaseNull(shmFile); + CFStringRef walFile = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@-wal"), baseFilename); + WithPathInUserCacheDirectory(walFile, ^(const char *utf8String) { (void)remove(utf8String); }); - WithPathInKeychainDirectory(CFSTR("ocspcache.sqlite3-journal"), ^(const char *utf8String) { + CFReleaseNull(walFile); + CFStringRef journalFile = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@-journal"), baseFilename); + WithPathInUserCacheDirectory(journalFile, ^(const char *utf8String) { (void)remove(utf8String); }); - WithPathInKeychainDirectory(CFSTR("caissuercache.sqlite3"), ^(const char *utf8String) { - (void)remove(utf8String); - }); - WithPathInKeychainDirectory(CFSTR("caissuercache.sqlite3-wal"), ^(const char *utf8String) { + CFReleaseNull(journalFile); +} +#endif // TARGET_OS_OSX + +static void trustd_delete_old_files(void) { + /* We try to clean up after ourselves, but don't care if we succeed. */ + WithPathInRevocationInfoDirectory(CFSTR("update-current"), ^(const char *utf8String) { (void)remove(utf8String); }); - WithPathInKeychainDirectory(CFSTR("caissuercache.sqlite3-shm"), ^(const char *utf8String) { + WithPathInRevocationInfoDirectory(CFSTR("update-full"), ^(const char *utf8String) { (void)remove(utf8String); }); - WithPathInKeychainDirectory(CFSTR("caissuercache.sqlite3-journal"), ^(const char *utf8String) { + WithPathInRevocationInfoDirectory(CFSTR("update-full.gz"), ^(const char *utf8String) { (void)remove(utf8String); }); +#if TARGET_OS_IPHONE + trustd_delete_old_sqlite_keychain_files(CFSTR("trustd_health_analytics.db")); + trustd_delete_old_sqlite_keychain_files(CFSTR("trust_analytics.db")); + trustd_delete_old_sqlite_keychain_files(CFSTR("TLS_analytics.db")); +#else + trustd_delete_old_sqlite_user_cache_files(CFSTR("trustd_health_analytics.db")); + trustd_delete_old_sqlite_user_cache_files(CFSTR("trust_analytics.db")); + trustd_delete_old_sqlite_user_cache_files(CFSTR("TLS_analytics.db")); +#endif //TARGET_OS_IPHONE +} + +#if TARGET_OS_OSX +static void trustd_delete_old_caches(void) { + /* We try to clean up after ourselves, but don't care if we succeed. */ + trustd_delete_old_sqlite_keychain_files(CFSTR("ocspcache.sqlite3")); + trustd_delete_old_sqlite_keychain_files(CFSTR("caissuercache.sqlite3")); } static void trustd_sandbox(void) { @@ -597,7 +692,6 @@ static void trustd_sandbox(void) { #endif static void trustd_cfstream_init() { - /* Force legacy CFStream run loop initialization before any NSURLSession usage */ CFReadStreamRef rs = CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8*) "", 0, kCFAllocatorNull); CFReadStreamSetDispatchQueue(rs, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); CFReadStreamSetDispatchQueue(rs, NULL); @@ -636,11 +730,12 @@ int main(int argc, char *argv[]) * After we enter the sandbox, we won't be able to access them. */ trustd_delete_old_caches(); #endif - /* Also clean up old files in /Library/Keychains/crls */ - trustd_delete_old_files(); trustd_sandbox(); + /* Also clean up old files in our sandbox. After sandboxing, so that user dir suffix is set. */ + trustd_delete_old_files(); + const char *serviceName = kTrustdXPCServiceName; if (argc > 1 && (!strcmp(argv[1], "--agent"))) { serviceName = kTrustdAgentXPCServiceName; @@ -649,17 +744,20 @@ int main(int argc, char *argv[]) /* set up SQLite before some other component has a chance to create a database connection */ _SecDbServerSetup(); - /* set up revocation database if it doesn't already exist, or needs to be replaced */ - SecRevocationDbInitialize(); + /* Force legacy CFStream run loop initialization before any NSURLSession usage */ + trustd_cfstream_init(); gTrustd = &trustd_spi; - SecPolicyServerInitialize(); - SecPinningDbInitialize(); + + /* Initialize static content */ + SecPolicyServerInitialize(); // set up callbacks for policy checks + SecRevocationDbInitialize(); // set up revocation database if it doesn't already exist, or needs to be replaced + SecPinningDbInitialize(); // set up the pinning database #if TARGET_OS_OSX - SecTrustLegacySourcesListenForKeychainEvents(); + SecTrustLegacySourcesListenForKeychainEvents(); // set up the legacy keychain event listeners (for cache invalidation) #endif - trustd_cfstream_init(); - trustd_xpc_init(serviceName); + /* We're ready now. Go. */ + trustd_xpc_init(serviceName); dispatch_main(); } diff --git a/OSX/utilities/SecurityTool/security_tool_commands.h b/OSX/utilities/SecurityTool/security_tool_commands.h index 78ad8e3a..b6d601c9 100644 --- a/OSX/utilities/SecurityTool/security_tool_commands.h +++ b/OSX/utilities/SecurityTool/security_tool_commands.h @@ -21,6 +21,7 @@ * @APPLE_LICENSE_HEADER_END@ */ +#define SHOW_USAGE_MESSAGE 2 // This is included to make SECURITY_COMMAND macros result in declarations of // commands for use in SecurityTool @@ -40,5 +41,4 @@ #define SECURITY_COMMAND_MAC(name, function, parameters, description) extern int command_not_on_this_platform(int argc, char * const *argv); #endif - #endif diff --git a/OSX/utilities/src/SecCFError.c b/OSX/utilities/src/SecCFError.c index 0aebede6..39caa712 100644 --- a/OSX/utilities/src/SecCFError.c +++ b/OSX/utilities/src/SecCFError.c @@ -175,6 +175,7 @@ bool SecCFCreateErrorWithFormat(CFIndex errorCode, CFStringRef domain, CFErrorRe return result; } +// Also consumes whatever newError points to bool SecCFCreateErrorWithFormatAndArguments(CFIndex errorCode, CFStringRef domain, CF_CONSUMED CFErrorRef previousError, CFErrorRef *newError, CFDictionaryRef formatoptions, CFStringRef format, va_list args) @@ -186,12 +187,19 @@ bool SecCFCreateErrorWithFormatAndArguments(CFIndex errorCode, CFStringRef domai const void* values[2] = { formattedString, previousError }; const CFIndex numEntriesToUse = (previousError != NULL) ? 2 : 1; + // Prepare to release whatever we replaced, as long as they didn't tell us to do so via previousError + // In a sane world, this function wouldn't have a previousError argument, since it should always release what it's replacing, + // but changing all callsites is a huge change + CFErrorRef replacing = ((*newError) == previousError) ? NULL : *newError; + *newError = CFErrorCreateWithUserInfoKeysAndValues(kCFAllocatorDefault, domain, errorCode, keys, values, numEntriesToUse); CFReleaseNull(formattedString); if (previousError) secdebug("error_thee_well", "encapsulated %@ with new error: %@", previousError, *newError); + + CFReleaseNull(replacing); CFReleaseNull(previousError); } else { if (previousError && newError && (previousError != *newError)) { diff --git a/OSX/utilities/src/SecCFWrappers.h b/OSX/utilities/src/SecCFWrappers.h index 9598944e..b54b4c24 100644 --- a/OSX/utilities/src/SecCFWrappers.h +++ b/OSX/utilities/src/SecCFWrappers.h @@ -424,7 +424,7 @@ static inline char *CFStringToCString(CFStringRef inStr) // need to extract into buffer CFIndex length = CFStringGetLength(inStr); // in 16-bit character units - size_t len = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8); + size_t len = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1; char *buffer = (char *)malloc(len); // pessimistic if (!CFStringGetCString(inStr, buffer, len, kCFStringEncodingUTF8)) buffer[0] = 0; diff --git a/OSX/utilities/src/SecDb.c b/OSX/utilities/src/SecDb.c index f9e75861..814cb4f1 100644 --- a/OSX/utilities/src/SecDb.c +++ b/OSX/utilities/src/SecDb.c @@ -95,6 +95,7 @@ struct __OpaqueSecDb { bool readWrite; /* open database read-write, default true */ bool allowRepair; /* allow database repair, default true */ bool useWAL; /* use WAL mode, default true */ + void (^corruptionReset)(void); }; // MARK: Error domains and error helper functions @@ -262,6 +263,7 @@ SecDbCreateWithOptions(CFStringRef dbName, mode_t mode, bool readWrite, bool all db->readWrite = readWrite; db->allowRepair = allowRepair; db->useWAL = useWAL; + db->corruptionReset = NULL; done: return db; @@ -406,17 +408,7 @@ static bool SecDbDidCreateFirstConnection(SecDbConnectionRef dbconn, bool didCre void SecDbCorrupt(SecDbConnectionRef dbconn, CFErrorRef error) { - CFStringRef str = CFStringCreateWithFormat(NULL, NULL, CFSTR("SecDBCorrupt: %@"), error); - if (str) { - char buffer[1000] = "?"; - uint32_t errorCode = 0; - CFStringGetCString(str, buffer, sizeof(buffer), kCFStringEncodingUTF8); - os_log_fault(secLogObjForScope("SecEmergency"), "%s", buffer); - if (error) - errorCode = (uint32_t)CFErrorGetCode(error); - __security_simulatecrash(str, __sec_exception_code_CorruptDb(errorCode)); - CFRelease(str); - } + os_log_fault(secLogObjForScope("SecEmergency"), "SecDBCorrupt: %@", error); dbconn->isCorrupted = true; CFRetainAssign(dbconn->corruptionError, error); } @@ -873,9 +865,25 @@ static bool SecDbHandleCorrupt(SecDbConnectionRef dbconn, int rc, CFErrorRef *er ok = dbconn->db->opened(dbconn->db, dbconn, true, &dbconn->db->callOpenedHandlerForNextConnection, error); } + if (dbconn->db->corruptionReset) { + dbconn->db->corruptionReset(); + } + return ok; } +void +SecDbSetCorruptionReset(SecDbRef db, void (^corruptionReset)(void)) +{ + if (db->corruptionReset) { + Block_release(db->corruptionReset); + db->corruptionReset = NULL; + } + if (corruptionReset) { + db->corruptionReset = Block_copy(corruptionReset); + } +} + static bool SecDbLoggingEnabled(CFStringRef type) { CFTypeRef profile = NULL; @@ -1027,16 +1035,33 @@ static void SecDbConectionSetReadOnly(SecDbConnectionRef dbconn, bool readOnly) /* Read only connections go to the end of the queue, writeable connections go to the start of the queue. */ SecDbConnectionRef SecDbConnectionAcquire(SecDbRef db, bool readOnly, CFErrorRef *error) { + SecDbConnectionRef dbconn = NULL; + SecDbConnectionAcquireRefMigrationSafe(db, readOnly, &dbconn, error); + return dbconn; +} + +bool SecDbConnectionAcquireRefMigrationSafe(SecDbRef db, bool readOnly, SecDbConnectionRef* dbconnRef, CFErrorRef *error) +{ CFRetain(db); secinfo("dbconn", "acquire %s connection", readOnly ? "ro" : "rw"); dispatch_semaphore_wait(readOnly ? db->read_semaphore : db->write_semaphore, DISPATCH_TIME_FOREVER); __block SecDbConnectionRef dbconn = NULL; __block bool ok = true; __block bool ranOpenedHandler = false; + + bool (^assignDbConn)(SecDbConnectionRef) = ^bool(SecDbConnectionRef connection) { + dbconn = connection; + if (dbconnRef) { + *dbconnRef = connection; + } + + return dbconn != NULL; + }; + dispatch_sync(db->queue, ^{ if (!db->didFirstOpen) { bool didCreate = false; - ok = dbconn = SecDbConnectionCreate(db, false, error); + ok = assignDbConn(SecDbConnectionCreate(db, false, error)); CFErrorRef localError = NULL; if (ok && !SecDbOpenHandle(dbconn, &didCreate, &localError)) { secerror("Unable to create database: %@", localError); @@ -1064,9 +1089,8 @@ SecDbConnectionRef SecDbConnectionAcquire(SecDbRef db, bool readOnly, CFErrorRef CFIndex count = CFArrayGetCount(db->connections); while (count && !dbconn) { CFIndex ix = readOnly ? count - 1 : 0; - dbconn = (SecDbConnectionRef)CFArrayGetValueAtIndex(db->connections, ix); - if (dbconn) - CFRetain(dbconn); + if (assignDbConn((SecDbConnectionRef)CFArrayGetValueAtIndex(db->connections, ix))) + CFRetainSafe(dbconn); else secerror("got NULL dbconn at index: %" PRIdCFIndex " skipping", ix); CFArrayRemoveValueAtIndex(db->connections, ix); @@ -1082,12 +1106,12 @@ SecDbConnectionRef SecDbConnectionAcquire(SecDbRef db, bool readOnly, CFErrorRef } else if (ok) { /* Nothing found in cache, create a new connection */ bool created = false; - dbconn = SecDbConnectionCreate(db, readOnly, error); - if (dbconn && !SecDbOpenHandle(dbconn, &created, error)) { + if (assignDbConn(SecDbConnectionCreate(db, readOnly, error)) && !SecDbOpenHandle(dbconn, &created, error)) { CFReleaseNull(dbconn); } } + if (dbconn && !ranOpenedHandler && dbconn->db->opened) { dispatch_sync(db->queue, ^{ if (dbconn->db->callOpenedHandlerForNextConnection) { @@ -1101,13 +1125,17 @@ SecDbConnectionRef SecDbConnectionAcquire(SecDbRef db, bool readOnly, CFErrorRef }); } + if (dbconnRef) { + *dbconnRef = dbconn; + } + if (!dbconn) { // If acquire fails we need to signal the semaphore again. dispatch_semaphore_signal(readOnly ? db->read_semaphore : db->write_semaphore); CFRelease(db); } - return dbconn; + return dbconn ? true : false; } void SecDbConnectionRelease(SecDbConnectionRef dbconn) { diff --git a/OSX/utilities/src/SecDb.h b/OSX/utilities/src/SecDb.h index d00276cf..1e86e10d 100644 --- a/OSX/utilities/src/SecDb.h +++ b/OSX/utilities/src/SecDb.h @@ -107,11 +107,13 @@ SecDbRef SecDbCreateWithOptions(CFStringRef dbName, mode_t mode, bool readWrite, SecDbRef SecDbCreate(CFStringRef dbName, bool (^opened)(SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error)); void SecDbAddNotifyPhaseBlock(SecDbRef db, SecDBNotifyBlock notifyPhase); +void SecDbSetCorruptionReset(SecDbRef db, void (^corruptionReset)(void)); // Read only connections go to the end of the queue, writeable // connections go to the start of the queue. Use SecDbPerformRead() and SecDbPerformWrite() if you // can to avoid leaks. SecDbConnectionRef SecDbConnectionAcquire(SecDbRef db, bool readOnly, CFErrorRef *error); +bool SecDbConnectionAcquireRefMigrationSafe(SecDbRef db, bool readOnly, SecDbConnectionRef* dbconnRef, CFErrorRef *error); void SecDbConnectionRelease(SecDbConnectionRef dbconn); // Perform a database read operation, diff --git a/OSX/utilities/src/debugging.h b/OSX/utilities/src/debugging.h index 8c1f411d..1c1bbcc3 100644 --- a/OSX/utilities/src/debugging.h +++ b/OSX/utilities/src/debugging.h @@ -38,9 +38,7 @@ #ifndef _SECURITY_UTILITIES_DEBUGGING_H_ #define _SECURITY_UTILITIES_DEBUGGING_H_ -#if TARGET_OS_OSX -#include -#endif +#include #ifdef KERNEL #include @@ -60,7 +58,6 @@ #endif // NDEBUG #else // !KERNEL -#include #include #include diff --git a/OTAPKIAssetTool/OTAPKIAssetTool-entitlements.plist b/OTAPKIAssetTool/OTAPKIAssetTool-entitlements.plist deleted file mode 100644 index 02347e9d..00000000 --- a/OTAPKIAssetTool/OTAPKIAssetTool-entitlements.plist +++ /dev/null @@ -1,10 +0,0 @@ - - - - - com.apple.private.assets.accessible-asset-types - - com.apple.MobileAsset.PKITrustServices.PKITrustData - - - diff --git a/OTAPKIAssetTool/OTAPKIAssetTool.xcconfig b/OTAPKIAssetTool/OTAPKIAssetTool.xcconfig deleted file mode 100644 index e4ac768f..00000000 --- a/OTAPKIAssetTool/OTAPKIAssetTool.xcconfig +++ /dev/null @@ -1,16 +0,0 @@ -// -// OTAPKIAssetTool.xcconfig -// Security -// -// - -// launchd plist -APPLY_RULES_IN_COPY_FILES = YES -PLIST_FILE_OUTPUT_FORMAT = binary -LAUNCHD_PLIST_INSTALL_DIR = $(DSTROOT)$(SYSTEM_LIBRARY_DIR)/LaunchDaemons - -// We do not want to install OTAPKIAssetTool into the simulator, so only -// define this for non-sim platforms. -OTAPKIASSETTOOL_LAUNCHD_PLIST[sdk=embedded*] = OTAPKIAssetTool/com.apple.OTAPKIAssetTool.plist - -GCC_PREPROCESSOR_DEFINITIONS = $(inherited) CORECRYPTO_DONOT_USE_TRANSPARENT_UNION=1 diff --git a/OTAPKIAssetTool/OTAServiceApp.h b/OTAPKIAssetTool/OTAServiceApp.h deleted file mode 100644 index 7ad689ef..00000000 --- a/OTAPKIAssetTool/OTAServiceApp.h +++ /dev/null @@ -1,46 +0,0 @@ -// -// OTAServiceApp.h -// Security -// -// Created by local on 2/11/13. -// -// - -#import -#import - - - -@interface OTAServiceApp : NSObject -{ - NSArray* _file_list; - NSString* _manifest_file_name; - NSString* _asset_version_file_name; - NSNumber* _current_asset_version; - NSNumber* _next_asset_version; - NSString* _current_asset_directory; - NSString* _assets_directory; - NSFileManager* _fileManager; - uid_t _uid; /* user uid */ - gid_t _gid; - CFTimeInterval _asset_query_retry_interval; - bool _verbose; -} - -@property (readonly) NSArray* file_list; -@property (readonly) NSString* manifest_file_name; -@property (readonly) NSString* asset_version_file_name; -@property (readonly) NSNumber* current_asset_version; -@property (readonly) NSNumber* next_asset_version; -@property (readonly) NSString* current_asset_directory; -@property (readonly) NSString* assets_directory; -@property (readonly) NSFileManager* fileManager; -@property (readonly) uid_t uid; -@property (readonly) gid_t gid; - - -- (id)init:(int)argc withArguments:(const char**)argv; - -- (void)checkInWithActivity; - -@end diff --git a/OTAPKIAssetTool/OTAServiceApp.m b/OTAPKIAssetTool/OTAServiceApp.m deleted file mode 100644 index fb94a5a3..00000000 --- a/OTAPKIAssetTool/OTAServiceApp.m +++ /dev/null @@ -1,1403 +0,0 @@ -// -// OTAServiceApp.m -// Security -// -// - - -#import "OTAServiceApp.h" - -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#if !TARGET_IPHONE_SIMULATOR -#import -#endif - -#import -#import -#import -#import -#import -#import -#import -#import - -#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) { CFRelease(_cf); } } -#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); if (_cf) { (CF) = NULL; CFRelease(_cf); } } - -//#define VERBOSE_LOGGING 1 - -#if VERBOSE_LOGGING - -static void OTAPKI_LOG(const char* sz, ...) -{ - va_list va; - va_start(va, sz); - - FILE* fp = fopen("/tmp/OTAPKITool.log", "a"); - if (NULL != fp) - { - vfprintf(fp, sz, va); - fclose(fp); - } - va_end(va); -} - -#else - -#define OTAPKI_LOG(sz, ...) - -#endif - -//#define NEW_LOCATION 1 - - - -/* ========================================================================== - The following are a set of string constants used by this program. - - kBaseAssetDirectoryPath - This is the full path on the device that - will contain the Assets directory. This - directory was chosen because it is owned - by securityd - - kkManifestFileName - The file name of the manifest file for the - OTA PKI trust asset - - kAllowListFileName - The file name of the asset file that contains - hashes of the allowed leaf certificates whose - trust store root has been removed - - kAssetVersionFileName - The file name of the plist file in the asset - that contains the version number of this - OTA PKI trust asset. It is a plist that is a - dictionary with a single key with a single - key value pair that has the version number - of the asset. This is used to ensure against - anti-replay. - - kBlockKeyFileName - The file name of the asset file that contains - blocked keys. Any certificate with these keys - will be marked as not being trusted. - - kGrayListedKeysFileName - The file name of the asset file that contains - gray listed keys. If a chain has any of these - keys, than the chain will still be approved but - an entry will be added to the details dictionary - noting that the key was gray listed - - - kEVRootsFileName - The file name of the asset file that contains - the list of EV OIDS and their corresponding - certificates. This file sets which certs will - be considered to be EV. - - kCTLogsFileName - The file name of the asset file that contains - the list of Certificate Transparency logs and - their public keys. - - kCertsIndexFileName - The file name of the asset file that contains - a hash table of offsets into the cert table - file. This is used to look up anchor certs. - - kCertsTableFileName - The file name of the asset file that contains - all of the anchor certificates. The - kCertsIndexFileName file is used to find the - correct offset in this file to retrieve a - specific anchor certificate. - - kVersionNumberKey - The dictionary key for the kAssetVersionFileName - file to get the version number - - kVersionDirectoryNamePrefix - - The directory name prefix for all of the - asset directorys - - kPKITrustDataAssetType - The asset identifier of the OTA PKI asset - - -========================================================================== */ - -#if NEW_LOCATION -static const NSString* kBaseAssetDirectoryPath = @"/var/OTAPKI"; -#else -static const NSString* kBaseAssetDirectoryPath = @"/var/Keychains"; -#endif - -static const NSString* kManifestFileName = @"manifest.data"; -static const NSString* kAllowListFileName = @"Allowed.plist"; -static const NSString* kAssetVersionFileName = @"AssetVersion.plist"; -static const NSString* kAppleESCertificatesName = @"AppleESCertificates.plist"; -static const NSString* kBlockKeyFileName = @"Blocked.plist"; -static const NSString* kGrayListedKeysFileName = @"GrayListedKeys.plist"; -static const NSString* kEVRootsFileName = @"EVRoots.plist"; -static const NSString* kCTLogsFileName = @"TrustedCTLogs.plist"; -static const NSString* kCertsIndexFileName = @"certsIndex.data"; -static const NSString* kCertsTableFileName = @"certsTable.data"; -static const NSString* kVersionNumberKey = @"VersionNumber"; -static const NSString* kAssetDirectoryName = @"Assets"; -static const NSString* kAssetDirectoryUser = @"_securityd"; -static const NSString* kAssetDirectoryGroup = @"wheel"; -#if NEW_LOCATION -static const unsigned long kAssetDirectoryPermission = S_IRWXU | S_IRWXG | S_IRWXO; -#else -static const unsigned long kAssetDirectoryPermission = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; -#endif -static const NSString* kVersionDirectoryNamePrefix = @"Version_"; -static const NSString* kPKITrustDataAssetType =@"com.apple.MobileAsset.PKITrustServices.PKITrustData"; - -const char *kOTAPKIAssetToolActivity = "com.apple.OTAPKIAssetTool.asset-check"; -const char *kOTAPKIAssetToolBTAJob = "com.apple.BTA.OTAPKIAssetTool.asset-check"; - -static const UInt8 kApplePKISettingsRootCACert[] = { - 0x30, 0x82, 0x07, 0xca, 0x30, 0x82, 0x05, 0xb2, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x4e, - 0xa1, 0x31, 0xe7, 0xca, 0x50, 0xb8, 0x97, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00, 0x30, 0x81, 0x84, 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x0c, 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x4b, 0x49, 0x20, 0x53, 0x65, - 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x74, 0x79, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x1d, 0x41, 0x70, - 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x13, 0x30, 0x11, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x30, 0x1e, 0x17, - 0x0d, 0x31, 0x33, 0x30, 0x36, 0x32, 0x34, 0x32, 0x33, 0x33, 0x33, 0x33, 0x39, 0x5a, 0x17, 0x0d, - 0x34, 0x33, 0x30, 0x36, 0x31, 0x37, 0x32, 0x33, 0x33, 0x33, 0x33, 0x39, 0x5a, 0x30, 0x81, 0x84, - 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2f, 0x41, 0x70, 0x70, 0x6c, 0x65, - 0x20, 0x50, 0x4b, 0x49, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x52, 0x6f, - 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, - 0x55, 0x04, 0x0b, 0x0c, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x74, 0x79, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, - 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x55, 0x53, 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, - 0x02, 0x82, 0x02, 0x01, 0x00, 0xce, 0x15, 0xf7, 0x6f, 0xd8, 0x42, 0x0c, 0x6f, 0x45, 0xb4, 0x04, - 0x59, 0x24, 0xcb, 0x70, 0x88, 0x84, 0x77, 0xa1, 0x91, 0x54, 0xf4, 0x87, 0x61, 0xb3, 0xd3, 0xfc, - 0xbe, 0xb6, 0x05, 0x3c, 0xb9, 0xb7, 0x7d, 0x7c, 0xbc, 0x0b, 0xe8, 0x87, 0x07, 0xcf, 0x20, 0xbe, - 0xaa, 0xeb, 0x24, 0xc5, 0xe4, 0x5c, 0xcd, 0xcb, 0x89, 0x9f, 0x7a, 0xea, 0xb4, 0x5d, 0x3b, 0x29, - 0x6c, 0xba, 0x4d, 0x15, 0xfb, 0x59, 0xd0, 0x5a, 0xea, 0x41, 0x4e, 0x0d, 0x1d, 0xf7, 0x66, 0x77, - 0xa2, 0x96, 0x56, 0xed, 0xd1, 0x16, 0x7b, 0xea, 0xf5, 0x60, 0xdf, 0x32, 0x9c, 0xa9, 0xfd, 0xbf, - 0xb8, 0x34, 0x6f, 0x57, 0x17, 0xe6, 0x04, 0x37, 0x71, 0x07, 0xc0, 0xe9, 0x0f, 0x3c, 0xed, 0x4f, - 0x31, 0x87, 0x05, 0xa4, 0xed, 0xab, 0xac, 0xd6, 0x50, 0x05, 0x5b, 0xca, 0xd3, 0xf9, 0xd6, 0xaa, - 0xaa, 0x88, 0x57, 0x66, 0xf6, 0x6d, 0x8d, 0x4b, 0x71, 0x29, 0xd4, 0x3d, 0x1d, 0xbc, 0x82, 0x6e, - 0x81, 0xe9, 0x19, 0xf5, 0xe1, 0x12, 0x9f, 0x47, 0xdb, 0x5c, 0xed, 0x88, 0xba, 0x51, 0xe7, 0x3a, - 0xa0, 0x77, 0x2d, 0xe6, 0xcc, 0xb4, 0x34, 0xdf, 0xad, 0xbd, 0x7b, 0xf8, 0xa7, 0x79, 0x51, 0x2d, - 0xe6, 0xc2, 0xee, 0xd2, 0x96, 0xfa, 0x60, 0x60, 0x32, 0x40, 0x41, 0x37, 0x12, 0xeb, 0x63, 0x99, - 0x3d, 0xf3, 0x21, 0xbe, 0xdf, 0xa1, 0x77, 0xe6, 0x81, 0xa9, 0x99, 0x0c, 0x4b, 0x43, 0x0c, 0x05, - 0x6a, 0x6b, 0x8f, 0x05, 0x02, 0xd9, 0x43, 0xab, 0x72, 0x76, 0xca, 0xa7, 0x75, 0x63, 0x85, 0xe3, - 0xa5, 0x5c, 0xc0, 0xd6, 0xd4, 0x1c, 0xeb, 0xac, 0x2c, 0x9a, 0x15, 0x6b, 0x4e, 0x99, 0x74, 0x7d, - 0xd2, 0x69, 0x9f, 0xa8, 0xf7, 0x65, 0xde, 0xeb, 0x36, 0x85, 0xd5, 0x7e, 0x4a, 0x7a, 0x8a, 0xeb, - 0x7c, 0xcd, 0x43, 0x9e, 0x05, 0xdb, 0x34, 0xc3, 0x69, 0xbd, 0xc2, 0xe7, 0xfb, 0xa0, 0x43, 0xb3, - 0xd7, 0x15, 0x28, 0x8a, 0x91, 0xce, 0xd7, 0xa7, 0xa4, 0xcc, 0xf4, 0x1b, 0x37, 0x33, 0x76, 0xc4, - 0x58, 0xb9, 0x2d, 0x89, 0xe2, 0xb6, 0x2c, 0x56, 0x10, 0x96, 0xcc, 0xa6, 0x07, 0x79, 0x11, 0x7d, - 0x26, 0xd2, 0x85, 0x22, 0x19, 0x20, 0xb7, 0xef, 0xc3, 0xd9, 0x4e, 0x18, 0xf3, 0xaa, 0x05, 0xce, - 0x87, 0x99, 0xde, 0x76, 0x90, 0x08, 0x74, 0xac, 0x61, 0x31, 0xf8, 0x51, 0xa0, 0xc9, 0x70, 0xfc, - 0xb9, 0x22, 0xfe, 0xd2, 0x0d, 0xc8, 0x49, 0x64, 0x00, 0xe4, 0xf1, 0x53, 0xfd, 0xa1, 0xe6, 0xff, - 0x8e, 0xd6, 0xde, 0x9e, 0xcc, 0x3d, 0x37, 0x3a, 0x10, 0x62, 0x59, 0xb2, 0x34, 0x8a, 0x1d, 0xf7, - 0x9e, 0xa0, 0xbb, 0xf4, 0x53, 0xd9, 0xb8, 0x18, 0x88, 0x12, 0x5c, 0x92, 0x0d, 0xc9, 0x94, 0x7f, - 0x24, 0xb9, 0x9f, 0xda, 0x07, 0xb6, 0x79, 0x77, 0x09, 0xa3, 0x29, 0x3a, 0x70, 0x63, 0x3b, 0x22, - 0x42, 0x14, 0xd0, 0xf9, 0x7b, 0x90, 0x52, 0x2b, 0x3f, 0x7f, 0xb7, 0x41, 0x20, 0x0d, 0x7e, 0x70, - 0xd7, 0x88, 0x36, 0xa2, 0xe9, 0x81, 0x77, 0xf4, 0xb0, 0x15, 0x43, 0x9c, 0x5f, 0x4d, 0x3e, 0x4f, - 0x83, 0x79, 0x06, 0x73, 0x7a, 0xe7, 0xcb, 0x79, 0x1d, 0xec, 0xa3, 0xce, 0x93, 0x5c, 0x68, 0xbf, - 0x5a, 0xe6, 0x4c, 0x23, 0x86, 0x41, 0x7f, 0xb4, 0xfc, 0xd0, 0x2c, 0x1b, 0x64, 0x39, 0x64, 0xb7, - 0xd2, 0x1d, 0xd0, 0x2d, 0x16, 0x77, 0xfe, 0x4d, 0xad, 0xf0, 0x4f, 0x38, 0xb3, 0xf9, 0x5a, 0xee, - 0x0e, 0x1d, 0xb6, 0xf9, 0x3f, 0xba, 0x77, 0x5a, 0x20, 0xd2, 0x74, 0x1a, 0x4b, 0x5a, 0xaf, 0x62, - 0xb5, 0xd3, 0xef, 0x37, 0x49, 0xfe, 0x1e, 0xcd, 0xb5, 0xba, 0xb5, 0xa6, 0x46, 0x7b, 0x38, 0x63, - 0x62, 0x3c, 0x18, 0x7d, 0x57, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x02, 0x3c, 0x30, 0x82, - 0x02, 0x38, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x35, 0x07, 0x82, - 0xfe, 0x0e, 0x8f, 0xf5, 0xa0, 0x7c, 0x2e, 0xf9, 0x65, 0x7b, 0xa8, 0x48, 0xe8, 0x8f, 0x61, 0xb6, - 0x1c, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, - 0x01, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x35, - 0x07, 0x82, 0xfe, 0x0e, 0x8f, 0xf5, 0xa0, 0x7c, 0x2e, 0xf9, 0x65, 0x7b, 0xa8, 0x48, 0xe8, 0x8f, - 0x61, 0xb6, 0x1c, 0x30, 0x82, 0x01, 0xd3, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0xca, - 0x30, 0x82, 0x01, 0xc6, 0x30, 0x82, 0x01, 0xc2, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x63, - 0x64, 0x05, 0x01, 0x30, 0x82, 0x01, 0xb3, 0x30, 0x82, 0x01, 0x78, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x82, 0x01, 0x6a, 0x1e, 0x82, 0x01, 0x66, 0x00, 0x52, 0x00, - 0x65, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, - 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, - 0x63, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63, 0x00, - 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x62, 0x00, 0x79, 0x00, 0x20, 0x00, 0x61, 0x00, - 0x6e, 0x00, 0x79, 0x00, 0x20, 0x00, 0x70, 0x00, 0x61, 0x00, 0x72, 0x00, 0x74, 0x00, 0x79, 0x00, - 0x20, 0x00, 0x61, 0x00, 0x73, 0x00, 0x73, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x73, 0x00, - 0x20, 0x00, 0x61, 0x00, 0x63, 0x00, 0x63, 0x00, 0x65, 0x00, 0x70, 0x00, 0x74, 0x00, 0x61, 0x00, - 0x6e, 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74, 0x00, - 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x20, 0x00, - 0x61, 0x00, 0x70, 0x00, 0x70, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x62, 0x00, - 0x6c, 0x00, 0x65, 0x00, 0x20, 0x00, 0x73, 0x00, 0x74, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, - 0x61, 0x00, 0x72, 0x00, 0x64, 0x00, 0x20, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6d, 0x00, - 0x73, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, - 0x6e, 0x00, 0x64, 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x73, 0x00, - 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x65, 0x00, 0x2c, 0x00, - 0x20, 0x00, 0x63, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, - 0x63, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x6c, 0x00, - 0x69, 0x00, 0x63, 0x00, 0x79, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, - 0x63, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63, 0x00, - 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x70, 0x00, 0x72, 0x00, - 0x61, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 0x73, 0x00, - 0x74, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, - 0x73, 0x00, 0x2e, 0x30, 0x35, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, - 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x6c, - 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, - 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x6f, 0x8a, - 0xb7, 0x35, 0x73, 0x5a, 0xc5, 0x34, 0xf7, 0x8c, 0xf0, 0xd1, 0x4a, 0x17, 0x52, 0x1c, 0x70, 0xf0, - 0xe0, 0x53, 0xb4, 0x16, 0xde, 0x81, 0xda, 0x2a, 0xa4, 0xf9, 0x5b, 0x0e, 0xa6, 0x17, 0x86, 0x52, - 0xc6, 0x70, 0x73, 0xf3, 0x3f, 0x1c, 0x87, 0x94, 0xdd, 0xfe, 0x02, 0x0b, 0x85, 0xc9, 0xb9, 0xcf, - 0x15, 0x91, 0x05, 0x2e, 0x7e, 0xeb, 0xe6, 0xce, 0x0e, 0x4e, 0xd1, 0xf7, 0xe2, 0xd7, 0xf4, 0x60, - 0xd2, 0xfc, 0x1d, 0xbf, 0xad, 0x61, 0x28, 0xf8, 0x53, 0x31, 0xb3, 0x92, 0xef, 0xa4, 0x05, 0x34, - 0x97, 0x57, 0x97, 0x56, 0x3b, 0x12, 0x20, 0x2d, 0x88, 0x76, 0x81, 0x0e, 0x77, 0x85, 0xf1, 0x37, - 0xc6, 0x19, 0x8b, 0x23, 0xc2, 0x42, 0x55, 0x40, 0xc9, 0x91, 0x5c, 0x78, 0xc5, 0xe6, 0x77, 0xfe, - 0x72, 0x5f, 0xb2, 0x2c, 0x00, 0xf2, 0xe6, 0x8c, 0xcc, 0x02, 0x49, 0xd9, 0x78, 0x20, 0xae, 0xbd, - 0x75, 0x61, 0x6a, 0xaa, 0xc5, 0x71, 0x3e, 0x5d, 0x02, 0xdf, 0xd2, 0x91, 0x5c, 0x0a, 0x85, 0xc9, - 0x59, 0x7d, 0x4e, 0x89, 0x21, 0x59, 0x59, 0xe3, 0xc7, 0xdc, 0xff, 0x1e, 0x62, 0x1e, 0xb9, 0x62, - 0x2c, 0x34, 0x49, 0x15, 0xd9, 0xdf, 0x47, 0x99, 0x39, 0xcc, 0x1a, 0x01, 0xc0, 0xda, 0x48, 0x44, - 0xd4, 0x8b, 0xd3, 0x17, 0x7e, 0x39, 0xf9, 0x00, 0xe1, 0x2a, 0x46, 0xaa, 0x14, 0x22, 0xa1, 0x38, - 0x09, 0x0b, 0xb7, 0x0c, 0x88, 0xa5, 0x73, 0xfd, 0xc4, 0x6b, 0xee, 0x07, 0xb4, 0x1b, 0xb3, 0x4a, - 0xab, 0xae, 0xf6, 0xe7, 0x04, 0x61, 0x4b, 0x34, 0x7a, 0xe4, 0xff, 0xf9, 0x30, 0x28, 0x61, 0x92, - 0x52, 0x58, 0x10, 0x15, 0x3a, 0x9f, 0x0a, 0xaf, 0x15, 0x29, 0x6c, 0x67, 0xc4, 0xb4, 0xcf, 0xe6, - 0xf9, 0x46, 0x68, 0xe2, 0x2a, 0x97, 0x29, 0x16, 0xed, 0x1a, 0x9b, 0x9a, 0x45, 0x70, 0x3c, 0xf2, - 0xdf, 0x29, 0x20, 0x9e, 0x33, 0x4b, 0x5b, 0x8d, 0xf6, 0x19, 0xec, 0x4b, 0xae, 0x1a, 0x2f, 0x53, - 0x03, 0x9a, 0xfd, 0x68, 0x39, 0x58, 0xf7, 0x2e, 0x07, 0x9c, 0xf1, 0x3c, 0x1b, 0x47, 0x43, 0x19, - 0x81, 0x0e, 0x0a, 0xbb, 0x84, 0xa0, 0xda, 0x87, 0xbc, 0x8a, 0x2a, 0xb7, 0x9c, 0xe1, 0xf9, 0xeb, - 0x37, 0xb0, 0x11, 0x20, 0x7e, 0x4c, 0x11, 0x2e, 0x54, 0x30, 0xce, 0xaf, 0x63, 0xed, 0x6a, 0x63, - 0x1f, 0x1e, 0x61, 0x62, 0x04, 0xf3, 0x3a, 0x5f, 0x26, 0x6c, 0x5c, 0xd7, 0xba, 0x4f, 0xf2, 0x61, - 0x26, 0x29, 0x99, 0xea, 0x61, 0x84, 0x0d, 0x68, 0xa2, 0x5d, 0x9b, 0x5c, 0xe7, 0x86, 0x1d, 0xef, - 0xf4, 0x6f, 0x3b, 0x6c, 0x67, 0xf0, 0x70, 0xe9, 0xc5, 0xdc, 0x0a, 0x9d, 0x0f, 0xdc, 0xcc, 0x0e, - 0x7b, 0xf8, 0xc4, 0xee, 0x64, 0xe4, 0xd9, 0x3f, 0x14, 0xae, 0x8f, 0xc8, 0x18, 0x4d, 0xa1, 0xe4, - 0x40, 0x2c, 0xe9, 0x13, 0xc6, 0xc1, 0xe0, 0xb9, 0x13, 0xbe, 0xd9, 0x93, 0x66, 0x56, 0x35, 0x5c, - 0xc1, 0x38, 0x7d, 0xa1, 0xbb, 0x87, 0xa5, 0x90, 0x33, 0x4f, 0xea, 0xb6, 0x37, 0x19, 0x61, 0x81, - 0x40, 0xba, 0xd7, 0x07, 0x69, 0x05, 0x15, 0x96, 0xe9, 0xde, 0x4f, 0x8a, 0x2b, 0x99, 0x5a, 0x17, - 0x3f, 0x9f, 0xcf, 0x86, 0xf5, 0x37, 0x0a, 0xa1, 0x0e, 0x25, 0x65, 0x2d, 0x52, 0xce, 0x87, 0x10, - 0x0f, 0x25, 0xc2, 0x1e, 0x0f, 0x71, 0x93, 0xb5, 0xc0, 0xb3, 0xb4, 0xd1, 0x65, 0xa8, 0xb4, 0xf6, - 0xa5, 0x71, 0xad, 0x45, 0xdb, 0xdf, 0xec, 0xe3, 0x2a, 0x7e, 0x99, 0x96, 0x5a, 0x5d, 0x69, 0xfa, - 0xdb, 0x13, 0x39, 0xb8, 0xf5, 0x58, 0xbb, 0x87, 0x69, 0x8d, 0x2c, 0x6d, 0x39, 0xff, 0x26, 0xce, - 0x2c, 0xa8, 0x5a, 0x7e, 0x4b, 0x3f, 0xed, 0xac, 0x5f, 0xf0, 0xef, 0x48, 0xd3, 0xf8 -}; - - -static const UInt8 kAppleTestPKISettingsRootCACert[] = { - 0x30, 0x82, 0x05, 0xd7, 0x30, 0x82, 0x03, 0xbf, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x26, - 0xfe, 0xf8, 0xda, 0x41, 0xf3, 0x61, 0x90, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00, 0x30, 0x79, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x0c, 0x24, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x4b, 0x49, 0x20, 0x53, 0x65, 0x74, - 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, - 0x54, 0x45, 0x53, 0x54, 0x49, 0x4e, 0x47, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x0c, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, - 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, - 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x34, 0x32, 0x32, 0x32, 0x30, 0x33, 0x31, 0x34, - 0x36, 0x5a, 0x17, 0x0d, 0x34, 0x33, 0x30, 0x34, 0x31, 0x35, 0x32, 0x30, 0x33, 0x31, 0x34, 0x36, - 0x5a, 0x30, 0x79, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x24, 0x41, 0x70, - 0x70, 0x6c, 0x65, 0x20, 0x50, 0x4b, 0x49, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, - 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x54, 0x45, 0x53, 0x54, 0x49, - 0x4e, 0x47, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x1d, 0x41, 0x70, 0x70, - 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x30, 0x82, 0x02, 0x22, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, - 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0x84, 0xbe, 0xc2, - 0x69, 0x9b, 0xec, 0xd5, 0xde, 0x72, 0xf0, 0x4f, 0x78, 0x81, 0x10, 0xa9, 0x56, 0x59, 0x77, 0x9c, - 0x46, 0x95, 0xd7, 0xb7, 0x0b, 0x77, 0x73, 0x02, 0xce, 0xf8, 0xaa, 0x32, 0x89, 0xee, 0xbe, 0xaa, - 0x40, 0x53, 0xf9, 0x2d, 0x96, 0x08, 0xcd, 0x2a, 0xa4, 0x61, 0xd4, 0xfd, 0x7d, 0x67, 0x2a, 0x35, - 0xc1, 0xfc, 0x43, 0xa4, 0x9c, 0xd0, 0xbd, 0xcd, 0x82, 0x27, 0xed, 0xa1, 0x1c, 0x2d, 0x9a, 0x62, - 0xd5, 0x99, 0xbd, 0x74, 0xaa, 0xf3, 0xce, 0x78, 0xc6, 0x47, 0x07, 0x43, 0x04, 0x5b, 0xbc, 0x27, - 0x5e, 0x26, 0x3e, 0x77, 0x90, 0x69, 0x7a, 0xf6, 0xe0, 0x8e, 0xaa, 0xdf, 0x96, 0x12, 0x2c, 0xb2, - 0x8b, 0xb9, 0x7e, 0x17, 0xfe, 0xde, 0x99, 0x67, 0x9b, 0x50, 0x13, 0x5c, 0x8d, 0x15, 0x26, 0x0a, - 0x9f, 0x08, 0x2f, 0x3f, 0x7c, 0x01, 0x2c, 0x3e, 0xa1, 0xba, 0xb1, 0x25, 0x33, 0xe5, 0xd9, 0x39, - 0x37, 0xde, 0x06, 0x3a, 0x63, 0x48, 0xa0, 0x9d, 0x3b, 0xa5, 0x72, 0x46, 0xfb, 0x6e, 0xa2, 0xd4, - 0x74, 0xe6, 0xf1, 0xc1, 0x69, 0xc8, 0x31, 0xff, 0x58, 0x84, 0x3a, 0xc2, 0x6b, 0x9a, 0x0d, 0x19, - 0x76, 0xe4, 0xd4, 0x4d, 0x85, 0xbc, 0x84, 0xf0, 0x07, 0x75, 0x66, 0x5f, 0xd7, 0xea, 0xab, 0x9e, - 0x46, 0xf2, 0x8a, 0x29, 0xab, 0x73, 0x57, 0xaf, 0x95, 0x4f, 0xc7, 0xf3, 0x3b, 0x55, 0xb4, 0x26, - 0x57, 0x68, 0xe9, 0x5a, 0x34, 0xbb, 0xa9, 0x39, 0xb3, 0x57, 0x5f, 0x25, 0x93, 0xd6, 0x34, 0xb7, - 0xd1, 0xc4, 0xd7, 0x70, 0xed, 0x30, 0xdb, 0x21, 0xc1, 0xcc, 0xdf, 0xed, 0xec, 0x37, 0xc5, 0xdc, - 0x0b, 0xc9, 0x85, 0x46, 0x26, 0xa7, 0x51, 0xc8, 0xdd, 0xe6, 0x47, 0xfc, 0x37, 0xd6, 0x73, 0x6f, - 0x91, 0x3d, 0xef, 0xd8, 0xa4, 0xa5, 0x08, 0x32, 0x8c, 0xae, 0x8f, 0x57, 0xf7, 0x99, 0x48, 0xef, - 0x81, 0x44, 0xac, 0x80, 0x42, 0x57, 0x9f, 0x64, 0x77, 0x40, 0x2a, 0xec, 0x03, 0x21, 0x79, 0x01, - 0x0b, 0x87, 0xc3, 0x9d, 0x22, 0xc9, 0xc0, 0x69, 0xe0, 0x34, 0xff, 0x73, 0xdd, 0x1e, 0x1b, 0x0c, - 0xe0, 0x68, 0xf0, 0x8c, 0x7a, 0x4b, 0xcd, 0x1d, 0x3f, 0x38, 0x2d, 0xe8, 0x9b, 0x91, 0xa6, 0xfe, - 0xa8, 0x8b, 0x45, 0x1c, 0xdf, 0xaf, 0x49, 0x34, 0x48, 0x17, 0x02, 0x28, 0xdb, 0xe0, 0x6e, 0x74, - 0x34, 0xea, 0xac, 0x6b, 0x00, 0x45, 0x89, 0xa9, 0xb5, 0x63, 0xbd, 0x2f, 0xe0, 0x58, 0x2e, 0xd3, - 0xc2, 0x74, 0xa2, 0x37, 0x37, 0x62, 0xf6, 0x76, 0x1b, 0x3f, 0xfb, 0x98, 0x64, 0x13, 0xd6, 0x8c, - 0xa0, 0x0c, 0xbc, 0x54, 0x00, 0xe0, 0xf8, 0x63, 0x17, 0x22, 0x44, 0x36, 0xe0, 0x28, 0xa0, 0x7d, - 0x50, 0x9e, 0x50, 0x94, 0xea, 0xd7, 0x62, 0xab, 0x6d, 0x7a, 0x19, 0xa4, 0xa2, 0x74, 0x79, 0x5d, - 0x15, 0x85, 0x21, 0xfe, 0x9a, 0x35, 0x76, 0x40, 0x78, 0x01, 0xe3, 0x46, 0x2f, 0x6f, 0x2d, 0x0a, - 0x1d, 0xac, 0x2e, 0x23, 0xec, 0xb8, 0x48, 0x74, 0xbc, 0xee, 0x29, 0x72, 0xb6, 0xe7, 0x52, 0x8c, - 0xd4, 0x1a, 0x00, 0x34, 0x75, 0x1c, 0x4b, 0x83, 0x50, 0xbb, 0x57, 0x21, 0x9b, 0xd8, 0xb4, 0x75, - 0xf3, 0x98, 0x8a, 0x9b, 0x45, 0xa8, 0x61, 0x50, 0x10, 0xb4, 0xec, 0x91, 0x2e, 0xe7, 0xf2, 0xb8, - 0xb9, 0x62, 0x70, 0xc2, 0x93, 0xe7, 0xd9, 0xf1, 0x02, 0x27, 0xd7, 0xec, 0xde, 0x5b, 0x42, 0xa1, - 0x26, 0x37, 0x41, 0x32, 0x65, 0x11, 0x63, 0x38, 0xbb, 0x6f, 0x23, 0x7a, 0xa0, 0xb7, 0x24, 0xeb, - 0xa8, 0x38, 0x8b, 0xa7, 0x73, 0xe2, 0xc8, 0x30, 0x56, 0x73, 0x6f, 0x17, 0x6e, 0x1a, 0xe5, 0x32, - 0xff, 0xd6, 0xa2, 0x08, 0x7b, 0x6a, 0x23, 0x33, 0x9f, 0x10, 0x05, 0x71, 0xdd, 0x02, 0x03, 0x01, - 0x00, 0x01, 0xa3, 0x63, 0x30, 0x61, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, - 0x14, 0xd2, 0xa5, 0x3b, 0xf2, 0x5d, 0xfd, 0x1f, 0x25, 0xda, 0xfb, 0x06, 0xfb, 0x59, 0x99, 0xc4, - 0xac, 0xc4, 0x0b, 0xac, 0x64, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, - 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, - 0x16, 0x80, 0x14, 0xd2, 0xa5, 0x3b, 0xf2, 0x5d, 0xfd, 0x1f, 0x25, 0xda, 0xfb, 0x06, 0xfb, 0x59, - 0x99, 0xc4, 0xac, 0xc4, 0x0b, 0xac, 0x64, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, - 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x71, 0x10, 0x3c, 0x89, 0xd5, - 0xc0, 0x00, 0xdc, 0x36, 0x1d, 0x93, 0xaa, 0xab, 0x4a, 0xb6, 0xfa, 0xa8, 0x5b, 0x89, 0x1c, 0xb3, - 0x4a, 0x04, 0x2e, 0xb3, 0x25, 0x0f, 0x12, 0x07, 0x29, 0x70, 0x3d, 0x34, 0xd1, 0xdd, 0x7e, 0x30, - 0xfd, 0xf5, 0xfa, 0x94, 0xf4, 0xcb, 0xdb, 0xac, 0x1b, 0xed, 0xe5, 0x11, 0x4a, 0xc8, 0xab, 0x26, - 0xe2, 0x41, 0xcb, 0xa5, 0x74, 0x4b, 0xe1, 0xd2, 0xf3, 0x83, 0x1c, 0x7a, 0xcb, 0x29, 0xd9, 0xd2, - 0xa6, 0x9d, 0x08, 0x95, 0x73, 0x63, 0xe2, 0x9c, 0xeb, 0xa5, 0x82, 0x8b, 0x6c, 0xf4, 0x64, 0x98, - 0x03, 0x53, 0x91, 0x35, 0x04, 0x89, 0x25, 0xa0, 0x1f, 0xdc, 0x42, 0xf7, 0x59, 0x44, 0x63, 0x75, - 0xe6, 0x49, 0x10, 0x66, 0x0f, 0x08, 0x07, 0x39, 0xc4, 0x3e, 0x1f, 0xba, 0x30, 0x42, 0xf8, 0x7a, - 0xc8, 0xbe, 0x6f, 0xdb, 0xec, 0x16, 0xb2, 0x76, 0x84, 0x2c, 0x6e, 0x20, 0xd1, 0xbd, 0xd5, 0x90, - 0x22, 0x0a, 0x90, 0x5c, 0x70, 0x47, 0xc9, 0x2d, 0xe3, 0x77, 0x74, 0xfd, 0xbb, 0x85, 0x1a, 0xd8, - 0x5c, 0x38, 0x94, 0x4c, 0x83, 0x28, 0x23, 0xa5, 0x4f, 0x55, 0x5f, 0xe3, 0x42, 0x80, 0x10, 0xd4, - 0xa5, 0x8d, 0xcf, 0x8b, 0x53, 0x69, 0x6d, 0xc5, 0x37, 0xd2, 0xfa, 0xbb, 0xc0, 0x5a, 0xab, 0x6f, - 0x71, 0x37, 0x92, 0xd4, 0x90, 0xef, 0x5d, 0xf1, 0xc3, 0xb8, 0x64, 0x08, 0xd3, 0xba, 0x36, 0x69, - 0x2b, 0x00, 0xed, 0xad, 0x36, 0x21, 0x38, 0xdf, 0x4a, 0xc6, 0x44, 0xc4, 0x6b, 0xd8, 0xb0, 0x7f, - 0x67, 0x05, 0xaa, 0x6f, 0x9e, 0x8a, 0xf1, 0x81, 0x95, 0x99, 0xb9, 0x56, 0xf4, 0x73, 0xa7, 0xb4, - 0x19, 0xb9, 0x4b, 0xb8, 0x1d, 0x10, 0xa5, 0x88, 0x7c, 0x39, 0xa3, 0x85, 0xe7, 0xba, 0x65, 0x86, - 0xca, 0xf7, 0x0e, 0xe0, 0x0d, 0x73, 0x3f, 0xea, 0x98, 0x88, 0x58, 0x73, 0xfa, 0x68, 0x5b, 0xaa, - 0x8c, 0xfd, 0x3e, 0x22, 0x3e, 0x92, 0xc7, 0xe2, 0x77, 0x14, 0x81, 0xe6, 0xd9, 0xdc, 0xc1, 0xe9, - 0xc0, 0x06, 0x57, 0xb4, 0xca, 0xb6, 0x14, 0x15, 0x16, 0x80, 0x7e, 0xc5, 0x11, 0xa4, 0x05, 0x66, - 0xad, 0x1d, 0xa3, 0xb6, 0xab, 0x2a, 0xbe, 0xd0, 0x52, 0x4e, 0x9e, 0x84, 0x61, 0x6b, 0xf4, 0x34, - 0x23, 0x94, 0x24, 0xc6, 0xc8, 0xb0, 0x94, 0x22, 0x4c, 0x3b, 0xac, 0x85, 0xe3, 0xd4, 0xf7, 0x38, - 0xe5, 0x9a, 0x76, 0xb3, 0x1b, 0xf0, 0xbc, 0x78, 0xc6, 0x6f, 0x11, 0xb3, 0x1a, 0x5c, 0x4f, 0x07, - 0x52, 0x06, 0x92, 0x7a, 0x25, 0x86, 0x91, 0x71, 0x8a, 0xf4, 0x03, 0xce, 0x19, 0x0d, 0xfc, 0xde, - 0x8f, 0xc9, 0x4e, 0x84, 0xf1, 0x17, 0x18, 0x6f, 0x37, 0x56, 0xb9, 0x76, 0x7e, 0x8f, 0xca, 0xde, - 0xd4, 0x1b, 0x2d, 0x8d, 0xcf, 0x12, 0x9f, 0xf9, 0xb9, 0x8b, 0x82, 0x8f, 0x4d, 0xb7, 0x63, 0x26, - 0x8d, 0xda, 0x35, 0x94, 0x18, 0xf9, 0x55, 0xca, 0x39, 0x09, 0xe9, 0x62, 0xe1, 0x00, 0xd8, 0x67, - 0xed, 0x5e, 0x84, 0xc2, 0xe5, 0x8e, 0x46, 0x57, 0xa4, 0xa7, 0x17, 0x70, 0xcf, 0x6d, 0xdf, 0x43, - 0x64, 0x2b, 0x36, 0xe6, 0xf3, 0xc1, 0x4c, 0x7a, 0x7e, 0x9e, 0x47, 0xc4, 0x14, 0x82, 0xbe, 0x94, - 0x73, 0x54, 0xd0, 0x2c, 0xc2, 0x31, 0xc6, 0xd5, 0xc3, 0xd7, 0xa9, 0xef, 0x11, 0x24, 0x2f, 0xd0, - 0x5b, 0xb8, 0x6a, 0x8e, 0x3c, 0xb7, 0x4b, 0x00, 0x9b, 0xc1, 0xca, 0x00, 0x6f, 0xd4, 0x73, 0x93, - 0x2e, 0x39, 0x37, 0x2a, 0x73, 0x44, 0x9b, 0x1b, 0x05, 0x1a, 0x7c, 0x2f, 0xc9, 0x2b, 0x37, 0xf3, - 0xcd, 0x8c, 0x4e, 0xc2, 0x7a, 0x6e, 0xd9, 0xd4, 0xf1, 0x8d, 0x6d, 0x07, 0x4b, 0xb5, 0x09, 0xb9, - 0x48, 0x55, 0xac, 0xc6, 0x7e, 0xbc, 0xc6, 0x76, 0xeb, 0x5f, 0x0f - -}; - -static NSDictionary* VerifyMessage(CFDataRef message, SecPolicyRef policy, CFDataRef cert_data) -{ - NSDictionary* result = nil; - - SecTrustRef trustRef = NULL; - CFDataRef payload = NULL; - CFArrayRef anchors = NULL; - OSStatus status = noErr; - SecCertificateRef aCertRef = NULL; - SecTrustResultType trust_result = kSecTrustResultRecoverableTrustFailure; - - if (NULL == message || NULL == policy || NULL == cert_data) - { - goto out; - } - - status = SecCMSVerifyCopyDataAndAttributes(message, NULL, policy, &trustRef, &payload, NULL); - if (noErr != status || NULL == trustRef || NULL == payload) - { - goto out; - } - - aCertRef = SecCertificateCreateWithData(NULL, cert_data); - if (NULL == aCertRef) - { - goto out; - } - - anchors = CFArrayCreate(kCFAllocatorDefault, (const void **)&aCertRef, 1, &kCFTypeArrayCallBacks); - if (NULL == anchors) - { - goto out; - } - - status = SecTrustSetAnchorCertificates(trustRef, anchors); - if (noErr != status) - { - goto out; - } - - status = SecTrustEvaluate(trustRef, &trust_result); - - if (noErr != status) - { - goto out; - } - - if (trust_result == kSecTrustResultUnspecified) - { - // Life is good and we got back the expected result. - - NSData* property_list_data = CFBridgingRelease(payload); - - NSPropertyListFormat format; - NSError* error = nil; - result = [NSPropertyListSerialization propertyListWithData:property_list_data options:0 format:&format error:&error]; - if (nil != error) - { - result = nil; - } - } - -out: - CFReleaseSafe(aCertRef) - CFReleaseSafe(anchors); - return result; -} - -/* ========================================================================== - Private Methods for the OTAServiceApp class - ========================================================================== */ -@interface OTAServiceApp (PrivateMethods) -- (void)processAssets:(NSArray*)assets; -- (BOOL)checkAssetVersions:(NSString *)assetDir; -- (BOOL)validateAsset:(NSString *)assetDir; -- (BOOL)validateDirectory:(NSString *)assetDir withFiles:(NSArray *)file_names; -- (NSDictionary *)decodeManifest:(NSData *)manifest_file_data; -- (BOOL)checkFileHash:(NSString *)file_path hash:(NSData *)hash; -- (BOOL)installAssetFiles:(NSString *)assetDir; -- (NSString*)getCurrentAssetDirectory; - -@end - -@implementation OTAServiceApp - -@synthesize file_list = _file_list; -@synthesize manifest_file_name = _manifest_file_name; -@synthesize asset_version_file_name = _asset_version_file_name; -@synthesize current_asset_version = _current_asset_version; -@synthesize next_asset_version = _next_asset_version; -@synthesize fileManager = _fileManager; -@synthesize current_asset_directory = _current_asset_directory; -@synthesize assets_directory = _assets_directory; - -/* -------------------------------------------------------------------------- - OTAServiceApp init:withArguments: - - Initialize a new instance of the OTAServiceApp class - -------------------------------------------------------------------------- */ -- (id)init:(int)argc withArguments:(const char**)argv -{ - if ((self = [super init])) - { - _fileManager = [NSFileManager defaultManager]; - - _manifest_file_name = (NSString *)kManifestFileName; - _asset_version_file_name = (NSString *)kAssetVersionFileName; - _file_list = [NSArray arrayWithObjects:kBlockKeyFileName, kGrayListedKeysFileName, - kEVRootsFileName, kCertsIndexFileName, kCertsTableFileName, - kManifestFileName, kAssetVersionFileName, kAppleESCertificatesName, - kAllowListFileName, kCTLogsFileName, nil]; - - _current_asset_version = nil; - _next_asset_version = nil; - _assets_directory = nil; - _current_asset_directory = [self getCurrentAssetDirectory]; - - /* Default interval is one hour */ - _asset_query_retry_interval = 60.0 * 60; - _verbose = false; - - int ch; - while ((ch = getopt(argc, (char * const *)argv, "d:v")) != -1 ) - { - switch (ch) - { - case 'd': - { - char *endptr = NULL; - errno = 0; - CFTimeInterval interval = strtod(optarg, &endptr); - if ((interval == 0 && endptr == optarg) || errno == ERANGE) { - syslog(LOG_ERR, "invalid argument '%s', ignoring", optarg); - } else { - syslog(LOG_NOTICE, "Setting query retry interval to %f seconds", interval); - _asset_query_retry_interval = (CFTimeInterval)interval; - } - } - break; - case 'v': - syslog(LOG_NOTICE, "Enabling verbose logging"); - _verbose = true; - break; - default: - break; - } - } - - struct stat info; -#if NEW_LOCATION - if (stat([kBaseAssetDirectoryPath UTF8String], &info)) - { - OTAPKI_LOG("OTAServiceApp.init:withArguments: stat of %s failed\n", [kBaseAssetDirectoryPath UTF8String]); - - if (mkdir([kBaseAssetDirectoryPath UTF8String], kAssetDirectoryPermission)) - { - OTAPKI_LOG("OTAServiceApp.init:withArguments: mkdir of %s failed\n", [kBaseAssetDirectoryPath UTF8String]); - } - else - { - if (stat([kBaseAssetDirectoryPath UTF8String], &info)) - { - OTAPKI_LOG("OTAServiceApp.init:withArguments: second stat of %s failed\n", [kBaseAssetDirectoryPath UTF8String]); - } - } - } -#else - stat([kBaseAssetDirectoryPath UTF8String], &info); - - _uid = info.st_uid; - _gid = info.st_gid; -#endif - - } - - return self; -} - -#if !TARGET_IPHONE_SIMULATOR - -- (void)registerBackgroundTaskAgentJobWithDelay:(CFTimeInterval)delay -{ - /* - * ELEs are very important, so allow asset queries on any network type and - * construct the job so that it will fire as soon as possible, unless we are - * scheduling a retry after a failure. - */ - xpc_object_t job = xpc_dictionary_create(NULL, NULL, 0); - if (delay != 0) - { - xpc_dictionary_set_double(job, kBackgroundTaskAgentJobWindowStartTime, CFAbsoluteTimeGetCurrent() + delay); - } - xpc_dictionary_set_double(job, kBackgroundTaskAgentJobWindowEndTime, CFAbsoluteTimeGetCurrent() + BACKGROUND_TASK_AGENT_JOB_WINDOW_MAX_TIME_FROM_NOW_SEC); - xpc_dictionary_set_bool(job, kBackgroundTaskAgentNetworkRequired, true); - xpc_dictionary_set_bool(job, kBackgroundTaskAgentCellularAllowed, true); - xpc_dictionary_set_bool(job, kBackgroundTaskAgentAllowedDuringRoaming, true); - xpc_dictionary_set_bool(job, kBackgroundTaskAgentPowerOptLevel, kBackgroundTaskAgentPowerDontCare); - - if (_verbose) - { - char *desc = xpc_copy_description(job); - syslog(LOG_NOTICE, "Adding BTA job %s", desc); - free(desc); - } -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - BackgroundTaskAgentAddJob(kOTAPKIAssetToolBTAJob, job); -#pragma GCC diagnostic pop -} - -#endif - -/* -------------------------------------------------------------------------- - OTAServiceApp checkInWithActivity - - Check in with the XPC activity configured in OTAPKIAssetTool's launchd - plist. This activity will launch OTAPKIAssetTool every three days (with - some leeway decided by the system). At that time, we schedule a - BackgroundTaskAgent job to be notified immediately when the network is - available so we can perform an asset query. - -------------------------------------------------------------------------- */ -- (void)checkInWithActivity -{ -#if !TARGET_IPHONE_SIMULATOR -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - BackgroundTaskAgentInit("com.apple.OTAPKIAssetTool", dispatch_get_main_queue(), ^(const char *job_name, xpc_object_t job) - { - /* - * We're doing real work at this point, so open a transaction so - * that the system (hopefully) won't kill us while we're busy - */ - xpc_transaction_begin(); - - if (self->_verbose) - { - syslog(LOG_NOTICE, "BackgroundTaskAgent job %s fired", job_name); - } - - int64_t job_status = xpc_dictionary_get_int64(job, kBackgroundTaskAgentJobStatus); - if (job_status == kBackgroundTaskAgentJobRequestError) - { - syslog(LOG_ERR, "Failed to create BTA job -- malformed job?"); - } - else if (job_status == kBackgroundTaskAgentJobSatisfied) - { - if (self->_verbose) - { - syslog(LOG_NOTICE, "BTA job %s is satisfied -- performing asset query", job_name); - } - bool shouldReschedule = false; - if ([self run:&shouldReschedule] || !shouldReschedule) - { - if (self->_verbose) - { - syslog(LOG_NOTICE, "Unscheduling BTA job"); - } - BackgroundTaskAgentRemoveJob(kOTAPKIAssetToolBTAJob); - } - else - { - syslog(LOG_NOTICE, "Asset query failed due to network error. Re-scheduling BTA job for another attempt in %f seconds.", self->_asset_query_retry_interval); - [self registerBackgroundTaskAgentJobWithDelay:self->_asset_query_retry_interval]; - } - } - else if (job_status == kBackgroundTaskAgentJobUnsatisfied) - { - /* - * We will receive this if the job expires before we get to do our - * work. We still want to check for new assets as soon as possible, - * so reschedule the job. - */ - if (xpc_dictionary_get_bool(job, kBackgroundTaskAgentJobExpired)) - { - [self registerBackgroundTaskAgentJobWithDelay:0]; - } - } - - xpc_transaction_end(); - }); -#pragma GCC diagnostic pop -#endif - - xpc_activity_register(kOTAPKIAssetToolActivity, XPC_ACTIVITY_CHECK_IN, ^(xpc_activity_t activity) - { - xpc_activity_state_t state = xpc_activity_get_state(activity); - - if (self->_verbose) - { - xpc_object_t criteria = xpc_activity_copy_criteria(activity); - - if (criteria != NULL) - { - char *desc = xpc_copy_description(criteria); - syslog(LOG_NOTICE, "Criteria for XPC activity %s: %s", kOTAPKIAssetToolActivity, desc); - free(desc); - } - else - { - syslog(LOG_NOTICE, "No critera for XPC activity %s", kOTAPKIAssetToolActivity); - } - } - - if (state == XPC_ACTIVITY_STATE_CHECK_IN) - { - /* - * The activity is already configured in the launchd plist, so there - * is nothing to do here - */ - if (self->_verbose) - { - syslog(LOG_NOTICE, "Activity %s in check in state", kOTAPKIAssetToolActivity); - } - } - else if (state == XPC_ACTIVITY_STATE_RUN) - { -#if !TARGET_IPHONE_SIMULATOR -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - xpc_object_t job = BackgroundTaskAgentCopyJob(kOTAPKIAssetToolBTAJob); -#pragma GCC diagnostic pop - if (job == NULL) - { - syslog(LOG_NOTICE, "Activity %s in run state. Scheduling BTA job for earliest network availability.", kOTAPKIAssetToolActivity); - [self registerBackgroundTaskAgentJobWithDelay:0]; - } - else if (self->_verbose) - { - syslog(LOG_NOTICE, "Already have a BTA job registered. Ignoring activity."); - } -#else - /* - * BackgroundTaskAgent doesn't exist on the iOS simulator, so we - * just directly try to find and download new assets. - */ - xpc_transaction_begin(); - bool shouldReschedule = false; - if (![self run:&shouldReschedule]) { - syslog(LOG_NOTICE, "Asset query failed%s.", shouldReschedule ? " due to network issue" : ""); - } - xpc_transaction_end(); -#endif - } - }); -} - -/* -------------------------------------------------------------------------- - OTAServiceApp run - - Run this program and leave. This program will currently run every 3 days, - with some leeway based on network availability. That will provide the - longest time from publisihing a change in the PKI trust setting asset and - having that asset be consumed by a device. - - The program simnply ask the mobile asset daemon if there are any assets - to be processed with the PKITrustDataAssetType. If not this program - will just complete and will be re-run in 3 days. If there is an asset to - process then the asset will be process and then the program will complete. - - Returns false if the operation failed. On return, shouldReschedule is set - to true if the operation failed due to a network error and the caller - should reschedule this operation at a more opportune time. - -------------------------------------------------------------------------- */ -- (bool)run:(bool *)shouldReschedule -{ - @autoreleasepool - { - if (shouldReschedule != NULL) { - *shouldReschedule = false; - } - - syslog(LOG_NOTICE, "OTAPKIAssetTool running"); - if (![[MCProfileConnection sharedConnection] isOTAPKIUpdatesAllowed]) - { - syslog(LOG_NOTICE, "OTAPKIAssetTool: OTAPKI updates are not allowed."); - return false; - } - - ASAssetQuery *assetQuery = [[ASAssetQuery alloc] initWithAssetType:(NSString *)kPKITrustDataAssetType]; - if (assetQuery == nil) - { - syslog(LOG_NOTICE, "OTAPKIAssetTool: Could not create the asset query."); - return false; - } - - // Get the asset synchronously - NSError *error = nil; - NSArray *foundAssets = [assetQuery runQueryAndReturnError:&error]; - if (nil != foundAssets) - { - [self processAssets:foundAssets]; - } - else - { - syslog(LOG_NOTICE, "OTAPKIAssetTool: No assets returned from query: %s", [[error description] UTF8String]); - - NSArray *networkErrorCodes = @[ @(ASErrorNetwork), @(ASErrorNetworkNoConnection), @(ASErrorNetworkTimedOut), @(ASErrorNetworkUnexpectedResponse) ]; - if ([[error domain] isEqualToString:ASErrorDomain] && [networkErrorCodes containsObject:@([error code])]) - { - syslog(LOG_NOTICE, "OTAPKIAssetTool: Query failed due to network error."); - if (shouldReschedule != NULL) { - *shouldReschedule = true; - } - } - return false; - } - - return true; - } -} - -/* -------------------------------------------------------------------------- - OTAServiceApp processAssets: - - If when run is called asset(s) are found they will be processed here. - -------------------------------------------------------------------------- */ -- (void)processAssets:(NSArray*)assets -{ - if (nil == assets) - { - return; - } - - NSError* error = nil; - ASAsset* asset = nil; - int asset_version = 0; - - for (asset in assets) - { - NSDictionary* asset_attributes = asset.attributes; - - NSNumber* contentVersion = [asset_attributes objectForKey:@"ContentVersion"]; - OTAPKI_LOG("In processAssets: about to check the ContentVersion\n"); - if (nil != contentVersion) - { - asset_version = [contentVersion intValue]; - int current_asset_version_number = (nil != _current_asset_version) ? [_current_asset_version intValue] : 0; - - if (asset_version <= current_asset_version_number) - { - syslog(LOG_NOTICE, "OTAPKIAssetTool: content version %d is too small. Current asset version id %d", - asset_version, current_asset_version_number); - - OTAPKI_LOG("In processAssets: content version is too small: current asset version is %d\nContent version is %d\n", - current_asset_version_number, asset_version); - asset = nil; - continue; - } - } - - if (nil == asset) - { - syslog(LOG_NOTICE, "OTAPKIAssetTool: no suitable asset found"); - return; - } - - - // Check to see if the asset needs to be downloaded - if (asset.state == ASAssetStateNotPresent) - { - __block dispatch_semaphore_t sem = dispatch_semaphore_create(0); - - [asset setProgressHandler:^(NSDictionary *state, NSError *anError) - { - if (error != nil) - { - // An error occured. Signal the semaphore to bail - dispatch_semaphore_signal(sem); - } - else if ([[state objectForKey:@"Operation"] isEqualToString:(NSString *) @"OperationCompleted"]) - { - // The download is complete. Signal the semaphore - dispatch_semaphore_signal(sem); - } - }]; - - NSNumber* yesValue = [NSNumber numberWithBool:YES]; - const id keys[] = {ASDownloadOptionAllow3G, ASDownloadOptionAllow4G, ASDownloadOptionPriority, ASDownloadOptionAllowBatteryPower}; - const id values[] = {yesValue, yesValue, ASDownloadPriorityHigh, yesValue}; - - NSDictionary* options = [NSDictionary dictionaryWithObjects:values forKeys:keys count:(sizeof (keys) / sizeof(keys[0]))]; - - [asset beginDownloadWithOptions:options]; - dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); - } - - // Check to see if the asset is now available for processing - if ([asset state] == ASAssetStateInstalled) - { - // Get the asset data directory - NSString* assetDir = [[[asset localURL] URLByAppendingPathComponent:@"PKITrustData"] path]; - if (nil != assetDir) - { - // validate the asset. - OTAPKI_LOG("In processAssets: about to validateAsset\n"); - if ([self validateAsset:assetDir]) - { - OTAPKI_LOG("In processAssets: asset validated installing\n"); - // The asset is valid so install the files - [self installAssetFiles:assetDir]; - - // Signal securityd to idle-exit at it's next opportunity - OTAPKI_LOG("In processAssets: notifying securityd\n"); - int didUpdate = 0; - (void)SecTrustOTAPKIGetUpdatedAsset(&didUpdate); - syslog(LOG_NOTICE, "OTAPKIAssetTool: installed new asset %d", asset_version); - _current_asset_version = contentVersion; - } - else - { - syslog(LOG_NOTICE, "OTAPKIAssetTool: Asset %d did not validate", asset_version); - } - - // regaurdless if the asset is valid. Now that it is - // installed, it needs to be purged to ensure that - // we can retrieve a new updated asset. - [asset purgeAndReturnError:&error]; - } - else - { - syslog(LOG_NOTICE, "OTAPKIAssetTool: Asset directory %s not found", [assetDir UTF8String]); - } - } - } -} - -/* -------------------------------------------------------------------------- - OTAServiceApp checkAssetVersions: - - If when run is called asset(s) are found they will be processed here. - -------------------------------------------------------------------------- */ -- (BOOL)checkAssetVersions:(NSString *)assetDir -{ - BOOL result = NO; - - OTAPKI_LOG("Entering checkAssetVersions\n"); - - if (nil == assetDir || nil == self.current_asset_version) - { - OTAPKI_LOG("checkAssetVersions: parameter error\n"); - return result; - } - - // first get the new version number from the downloaded asset - NSString* next_asset_version_path = [assetDir stringByAppendingPathComponent:self.asset_version_file_name]; - if (![self.fileManager fileExistsAtPath:next_asset_version_path]) - { - // The asset is missing the AssertVersion.plist - // This is an invalid asset - OTAPKI_LOG("checkAssetVersions: could not file asseet version file %s\n", [self.asset_version_file_name UTF8String]); - return result; - } - - NSError* error = nil; - NSInputStream* input_stream = [NSInputStream inputStreamWithFileAtPath:next_asset_version_path]; - [input_stream open]; - NSDictionary* asset_dict = [NSPropertyListSerialization propertyListWithStream:input_stream options:0 format:nil error:&error]; - [input_stream close]; - - if (nil != error) - { - OTAPKI_LOG("checkAssetVersions: error reading asset version file: %s\n", [[error localizedDescription] UTF8String]); - return result; - } - - _next_asset_version = [asset_dict objectForKey:kVersionNumberKey]; - if (nil == _next_asset_version) - { - OTAPKI_LOG("asset_dict did not have a entry with a key of kVersionNumberKey\n"); - return result; - } - - // Check the current asset version against the new asset version. The new asset version MUST be larger than the - // current asset version - NSInteger current_asset_version_value = [self.current_asset_version integerValue]; - NSInteger next_asset_version_value = [self.next_asset_version integerValue]; - - if (next_asset_version_value <= current_asset_version_value) - { - OTAPKI_LOG("heckAssetVersions: assert version too small. current_asset_version_value = %d next_asset_version_value = %d\n", - current_asset_version_value, next_asset_version_value); - return result; - } - - return YES; -} - - -/* -------------------------------------------------------------------------- - OTAServiceApp validateAsset: - - Decode the manifest and verify the file hashes - -------------------------------------------------------------------------- */ -- (BOOL)validateAsset:(NSString *)assetDir -{ - BOOL result = NO; - - OTAPKI_LOG("Enterning validateAsset\n"); - - if (![self validateDirectory:assetDir withFiles:self.file_list]) - { - OTAPKI_LOG("validateAsset param\n"); - return result; - } - - NSString* manifest_file_path = [assetDir stringByAppendingPathComponent:self.manifest_file_name]; - NSError* error = nil; - NSData* manifest_file_data = [NSData dataWithContentsOfFile:manifest_file_path options:0 error:&error]; - if (nil != error) - { - OTAPKI_LOG("validateAsset: could not read manifest file. error = %s\n", [[error localizedDescription] UTF8String]); - return result; - } - - NSDictionary* manifest_data = [self decodeManifest:manifest_file_data]; - if (nil == manifest_data) - { - OTAPKI_LOG("validateAsset: decodeManifest failed!\n"); - return result; - } - - NSString* full_file_path = nil; - NSData* hash = nil; - for (NSString* file_name in self.file_list) - { - if ([file_name isEqualToString:self.manifest_file_name]) - { - continue; - } - - hash = [manifest_data objectForKey:file_name]; - if (nil == hash) - { - OTAPKI_LOG("validateAsset: could not get hash for file %s\n", [file_name UTF8String]); - return result; - } - - full_file_path = [assetDir stringByAppendingPathComponent:file_name]; - if (![self checkFileHash:full_file_path hash:hash]) - { - OTAPKI_LOG("validateAsset: hash for file %s does not match\n", [file_name UTF8String]); - return result; - } - } - - result = [self checkAssetVersions:assetDir]; - return result; -} - -/* -------------------------------------------------------------------------- - OTAServiceApp validateDirectory:withFiles: - - Ensure that a given directory has the files listed in the files_names - parameter - -------------------------------------------------------------------------- */ -- (BOOL)validateDirectory:(NSString *)assetDir withFiles:(NSArray *)file_names -{ - BOOL result = NO; - OTAPKI_LOG("Enterning validateDirectory\n"); - - if (nil == assetDir || nil == file_names) - { - OTAPKI_LOG("validateDirectory param error\n"); - return result; - } - NSError* error = nil; - NSArray* dir_items = [self.fileManager contentsOfDirectoryAtPath:assetDir error:&error]; - if (nil != error) - { - OTAPKI_LOG("validateDirectory: Error calling contentsOfDirectoryAtPath: error = %s\n", [[error localizedDescription] UTF8String]); - return result; - } - - for (NSString* file_name in file_names) - { - if (![dir_items containsObject:file_name]) - { - OTAPKI_LOG("validateDirectory: missing file %s\n", [file_name UTF8String]); - return result; - } - } - - return YES; -} - -/* -------------------------------------------------------------------------- - OTAServiceApp decodeManifest: - - Ensure that the asset manifest blob has it CMS signature verified - -------------------------------------------------------------------------- */ -- (NSDictionary *)decodeManifest:(NSData *)manifest_file_data -{ - NSDictionary* result = nil; - CFDataRef cert_data = NULL; - CFDataRef message = NULL; - SecPolicyRef policy = NULL; - CFBooleanRef mgResult = NULL; - - OTAPKI_LOG("Enterning decodeManifest\n"); - - if (nil == manifest_file_data) - { - OTAPKI_LOG("decodeManifest: parameter error\n"); - goto out; - } - - message = CFBridgingRetain(manifest_file_data); - - policy = SecPolicyCreateOTAPKISigner(); - if (NULL == policy) - { - OTAPKI_LOG("decodeManifest: could not get the SecPolicyCreateOTAPKISigner policyRef\n"); - goto out; - } - - cert_data = CFDataCreate(kCFAllocatorDefault, kApplePKISettingsRootCACert, sizeof(kApplePKISettingsRootCACert)); - if (NULL == cert_data) - { - OTAPKI_LOG("decodeManifest: could not kApplePKISettingsRootCACert data\n"); - goto out; - } - - result = VerifyMessage(message, policy, cert_data); - - if (NULL != result) - { - OTAPKI_LOG("decodeManifest: SecPolicyCreateOTAPKISigner success!\n"); - goto out; - } - - OTAPKI_LOG("decodeManifest: SecPolicyCreateOTAPKISigner failed! Checking to see if this is an internal build\n"); - - // The first attempt did not work so check to see if this is running on an internal build. - if (!MGIsQuestionValid(kMGQAppleInternalInstallCapability)) - { - OTAPKI_LOG("decodeManifest: kMGQAppleInternalInstallCapability had an error\n"); - goto out; - } - - mgResult = MGCopyAnswer(kMGQAppleInternalInstallCapability, NULL); - - if (NULL == mgResult || !CFEqual(mgResult, kCFBooleanTrue)) - { - OTAPKI_LOG("decodeManifest: Not an internal build"); - goto out; - } - - OTAPKI_LOG("decodeManifest: This is an internal build\n"); - - CFReleaseNull(policy); - CFReleaseNull(cert_data); - - policy = SecPolicyCreateTestOTAPKISigner(); - if (NULL == policy) - { - OTAPKI_LOG("decodeManifest: could not SecPolicyCreateTestOTAPKISigner policyRef\n"); - goto out; - } - - cert_data = CFDataCreate(kCFAllocatorDefault, kAppleTestPKISettingsRootCACert, sizeof(kAppleTestPKISettingsRootCACert)); - if (NULL == cert_data) - { - OTAPKI_LOG("decodeManifest: could not kAppleTestPKISettingsRootCACert data\n"); - goto out; - } - - result = VerifyMessage(message, policy, cert_data); - -out: - - CFReleaseSafe(mgResult); - CFReleaseSafe(message); - CFReleaseSafe(policy); - CFReleaseSafe(cert_data); - return result; -} - -/* -------------------------------------------------------------------------- - OTAServiceApp checkFileHash:hash: - - Ensure that the given asset file's hash is the same as in the manifest - -------------------------------------------------------------------------- */ -- (BOOL)checkFileHash:(NSString *)file_path hash:(NSData *)hash -{ - BOOL result = NO; - if (nil == file_path || nil == hash) - { - return result; - } - - NSError* error = nil; - NSData* file_data = [NSData dataWithContentsOfFile:file_path options:0 error:&error]; - if (nil != error) - { - return result; - } - - NSMutableData *digest = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH]; - uint8_t *dp = (digest) ? [digest mutableBytes] : NULL; - if (NULL == dp) - { - return result; - } - - memset(dp, 0, CC_SHA256_DIGEST_LENGTH); - CCDigest(kCCDigestSHA256, - (const uint8_t *)[file_data bytes], - (size_t)[file_data length], dp); - - result = [hash isEqualToData:digest]; - - return result; -} - -/* -------------------------------------------------------------------------- - OTAServiceApp installAssetFiles: - - Copy over the files into the /var/Keychains/Assets directory. - -------------------------------------------------------------------------- */ -- (BOOL)installAssetFiles:(NSString *)assetDir -{ - BOOL result = NO; - - OTAPKI_LOG("Entering installAssetFiles\n"); - - if (nil == assetDir) - { - OTAPKI_LOG("installAssetFiles: parameter error\n"); - return result; - } - - if (nil == self.assets_directory) - { - OTAPKI_LOG("installAssetFiles: no assets directory\n"); - return result; - } - - // Create a temp directory to hold the new asset files. - NSString* tempDir = [self.assets_directory stringByAppendingPathComponent:@"TempAssetDir"]; - NSError* error = nil; - -#if NEW_LOCATION - id values[] = {[NSNumber numberWithUnsignedLong: kAssetDirectoryPermission]}; - id keys[] = {NSFilePosixPermissions}; - - NSDictionary* attributes = [NSDictionary dictionaryWithObjects:values forKeys:keys count:1]; -#else - struct passwd *user_info = getpwnam([kAssetDirectoryUser UTF8String]); - struct group *group_info = getgrnam([kAssetDirectoryGroup UTF8String]); - NSNumber* uid_num = [NSNumber numberWithUnsignedInt: user_info->pw_uid]; - NSNumber* gid_num = [NSNumber numberWithUnsignedInt: group_info->gr_gid]; - - id values[] = {uid_num, gid_num, [NSNumber numberWithUnsignedLong: kAssetDirectoryPermission]}; - id keys[] = {NSFileOwnerAccountID, NSFileGroupOwnerAccountID, NSFilePosixPermissions}; - - NSDictionary* attributes = [NSDictionary dictionaryWithObjects:values forKeys:keys count:3]; -#endif - - - if (![self.fileManager createDirectoryAtPath:tempDir withIntermediateDirectories:YES - attributes:attributes error:&error]) - { - OTAPKI_LOG("installAssetFiles: could not create directory %s\n", [tempDir UTF8String]); - return result; - } - -#ifndef NEW_LOCATION - // Copy all of the asset files to the newly created directory - for (NSString* file_name in self.file_list) - { - NSString* download_assert_path = [assetDir stringByAppendingPathComponent:file_name]; - NSString* asset_path = [tempDir stringByAppendingPathComponent:file_name]; - if ([self.fileManager copyItemAtPath:download_assert_path toPath:asset_path error:&error]) - { - chown([asset_path UTF8String], self.uid, self.gid); - } - else - { - [self.fileManager removeItemAtPath:tempDir error:nil]; - return result; - } - } -#endif // !NEW_LOCATION - - - // Now that all of the files have been copied to the temp directory make a single call - // to rename (move) the temp directory to be the correct version directory. This rename - // allow for reducing a race conditions between this asset code and securityd. - NSInteger new_version_value = [self.next_asset_version integerValue]; - NSString* new_version_dir_name = [NSString stringWithFormat:@"%@%ld", kVersionDirectoryNamePrefix, (long)new_version_value]; - NSString* new_version_dir_path = [self.assets_directory stringByAppendingPathComponent:new_version_dir_name]; - if (![self.fileManager moveItemAtPath:tempDir toPath:new_version_dir_path error:&error]) - { - OTAPKI_LOG("installAssetFiles: could not move path %s\n", [tempDir UTF8String]); - [self.fileManager removeItemAtPath:tempDir error:nil]; - return result; - } - - result = YES; - return result; -} - -/* -------------------------------------------------------------------------- - OTAServiceApp getCurrentAssetDirectory: - - Looks through the /var/Keychains/Assets directory to find latest asset - version directory. If no assets have been downloaded then nil is returned - and the current asset version is set to 0 - -------------------------------------------------------------------------- */ -- (NSString*)getCurrentAssetDirectory -{ - NSString* result = nil; - BOOL isDir = NO; - - OTAPKI_LOG("In getCurrentAssetDirectory\n"); - OTAPKI_LOG("getCurrentAssetDirectory: checking to see if %s exists\n", [kBaseAssetDirectoryPath UTF8String]); - - // Check to see if the base directory is there - if (![self.fileManager fileExistsAtPath:(NSString *)kBaseAssetDirectoryPath isDirectory:&isDir] || !isDir) - { - OTAPKI_LOG("getCurrentAssetDirectory: %s does not exists\n", [kBaseAssetDirectoryPath UTF8String]); - // This might be fatal - return result; - } - - NSError* error = nil; - NSInteger version_number = 0; - NSInteger current_version_number = 0; - int aVerNum = 0; - OSStatus err = noErr; - - _assets_directory = [kBaseAssetDirectoryPath stringByAppendingPathComponent:(NSString *)kAssetDirectoryName]; - - OTAPKI_LOG("getCurrentAssetDirectory: %s does exists\n", [self.assets_directory UTF8String]); - - if ([self.fileManager fileExistsAtPath:self.assets_directory isDirectory:&isDir] && isDir) - { - OTAPKI_LOG("getCurrentAssetDirectory: %s does exists\n", [self.assets_directory UTF8String]); - NSDirectoryEnumerator* dirEnum = [self.fileManager enumeratorAtPath:self.assets_directory]; - [dirEnum skipDescendents]; - - for (NSString* file in dirEnum) - { - if ([file hasPrefix:(NSString *)kVersionDirectoryNamePrefix]) - { - NSString* version_str = [file substringFromIndex:[kVersionDirectoryNamePrefix length]]; - NSInteger aVersion_number = [version_str integerValue]; - if (aVersion_number > version_number) - { - version_number = aVersion_number; - } - } - } - } - else - { -#if NEW_LOCATION - id values[] = {[NSNumber numberWithUnsignedLong: kAssetDirectoryPermission]}; - id keys[] = {NSFilePosixPermissions}; - - NSDictionary* attributes = [NSDictionary dictionaryWithObjects:values forKeys:keys count:1]; -#else - - struct passwd *user_info = getpwnam([kAssetDirectoryUser UTF8String]); - struct group *group_info = getgrnam([kAssetDirectoryGroup UTF8String]); - NSNumber* uid_num = [NSNumber numberWithUnsignedInt: user_info->pw_uid]; - NSNumber* gid_num = [NSNumber numberWithUnsignedInt: group_info->gr_gid]; - - id values[] = {uid_num, gid_num, [NSNumber numberWithUnsignedLong: kAssetDirectoryPermission]}; - id keys[] = {NSFileOwnerAccountID, NSFileGroupOwnerAccountID, NSFilePosixPermissions}; - NSDictionary* attributes = [NSDictionary dictionaryWithObjects:values forKeys:keys count:3]; -#endif - OTAPKI_LOG("getCurrentAssetDirectory: %s does NOT exists\n", [self.assets_directory UTF8String]); - OTAPKI_LOG("getCurrentAssetDirectory: creating %s\n", [self.assets_directory UTF8String]); - - if (![self.fileManager createDirectoryAtPath:self.assets_directory withIntermediateDirectories:YES - attributes:attributes error:&error]) - { - OTAPKI_LOG("getCurrentAssetDirectory: failed to create %s\n", [self.assets_directory UTF8String]); - return result; - } - - } - - err = SecTrustGetOTAPKIAssetVersionNumber(&aVerNum); - if (errSecSuccess == err && aVerNum > 0) - { - current_version_number = aVerNum; - } - - if (version_number < current_version_number) - { - OTAPKI_LOG("The largest OTA version number is smaller than the current version number. This means the system has a newer asset\n"); - version_number = current_version_number; - } - else - { - OTAPKI_LOG("The largest OTA version number is equal to the current version number. The OTA asset is newer than the system asset\n"); - NSString* version_dir_name = [NSString stringWithFormat:@"%@%ld", kVersionDirectoryNamePrefix, (long)version_number]; - result = [self.assets_directory stringByAppendingPathComponent:version_dir_name]; - } - - OTAPKI_LOG("getCurrentAssetDirectory: setting version number to %d\n", version_number); - _current_asset_version = [NSNumber numberWithInteger:version_number]; - return result; -} - -@end diff --git a/OTAPKIAssetTool/OTAServicemain.m b/OTAPKIAssetTool/OTAServicemain.m deleted file mode 100644 index 02714a7b..00000000 --- a/OTAPKIAssetTool/OTAServicemain.m +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2012-2014 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -/* ========================================================================== - main for the OTAService for iOS securityd - ========================================================================== */ - -#import -#import -#import - -#import "OTAServiceApp.h" - -int main(int argc, const char * argv[]) -{ - // OTAServiceApp - @autoreleasepool - { - OTAServiceApp* ota_service_application = [[OTAServiceApp alloc] init:argc withArguments:argv]; - [ota_service_application checkInWithActivity]; - - /* Spin a runloop so events can be delivered */ - CFRunLoopRun(); - } - - return 0; -} - - - diff --git a/OTAPKIAssetTool/com.apple.OTAPKIAssetTool.plist b/OTAPKIAssetTool/com.apple.OTAPKIAssetTool.plist deleted file mode 100644 index cf161728..00000000 --- a/OTAPKIAssetTool/com.apple.OTAPKIAssetTool.plist +++ /dev/null @@ -1,37 +0,0 @@ - - - - - EnablePressuredExit - - EnableTransactions - - POSIXSpawnType - Adaptive - Label - com.apple.OTAPKIAssetTool - ProgramArguments - - /usr/libexec/OTAPKIAssetTool - - Umask - 18 - UserName - _securityd - LaunchEvents - - com.apple.xpc.activity - - com.apple.OTAPKIAssetTool.asset-check - - Priority - Utility - Interval - 259200 - GracePeriod - 3600 - - - - - diff --git a/RegressionTests/Security.plist b/RegressionTests/Security.plist index 9542400f..4db898f3 100644 --- a/RegressionTests/Security.plist +++ b/RegressionTests/Security.plist @@ -137,6 +137,15 @@ EligibleResource NOT (cpuArchitecture BEGINSWITH 'arm') + + TestName + KeychainAnalytics + Command + + BATS_XCTEST_CMD + /AppleInternal/XCTests/com.apple.security/KeychainAnalyticsTests.xctest + + diff --git a/RegressionTests/secitemfunctionality/secitemfunctionality.m b/RegressionTests/secitemfunctionality/secitemfunctionality.m index 96384f8b..59650cbb 100644 --- a/RegressionTests/secitemfunctionality/secitemfunctionality.m +++ b/RegressionTests/secitemfunctionality/secitemfunctionality.m @@ -526,6 +526,10 @@ CheckFindIdentityByReference(void) */ CFRelease(pref); + if(identity) { + CFRelease(identity); + identity = NULL; + } printf("[PASS] %s\n", __FUNCTION__); } diff --git a/SOSCCAuthPlugin/SOSCCAuthPlugin.m b/SOSCCAuthPlugin/SOSCCAuthPlugin.m index 0de5cbcd..e6dd747a 100644 --- a/SOSCCAuthPlugin/SOSCCAuthPlugin.m +++ b/SOSCCAuthPlugin/SOSCCAuthPlugin.m @@ -13,11 +13,18 @@ #import #import #import +#import +#import #import #import "utilities/SecCFRelease.h" #import "utilities/debugging.h" +#if !TARGET_OS_SIMULATOR +SOFT_LINK_FRAMEWORK(PrivateFrameworks, AuthKit); +SOFT_LINK_CLASS(AuthKit, AKAccountManager); +#endif + @implementation SOSCCAuthPlugin - (void) didReceiveAuthenticationResponseParameters: (NSDictionary *) parameters @@ -40,7 +47,21 @@ do_auth = [account aa_isPrimaryAccount]; } - ACLogNotice(@"do_auth %@", do_auth ? @"YES" : @"NO" ); +#if !TARGET_OS_SIMULATOR + // If this is an HSA2 account let cdpd SetCreds + AKAccountManager *manager = [getAKAccountManagerClass() sharedInstance]; + if(manager != nil) { + AKAppleIDSecurityLevel securityLevel = [manager securityLevelForAccount: account]; + if(securityLevel == AKAppleIDSecurityLevelHSA2) { + secnotice("accounts", "Not performing SOSCCSetUserCredentialsAndDSID in accountsd plugin since we're HSA2" ); + do_auth = NO; + } + } else { + secnotice("accounts", "Couldn't softlink AKAccountManager - proceeding with do_auth = %@", do_auth ? @"YES" : @"NO"); + } +#endif + + secnotice("accounts", "do_auth %@", do_auth ? @"YES" : @"NO" ); if (do_auth) { CFErrorRef authError = NULL; diff --git a/Security.exp-in b/Security.exp-in index e9c748cc..de4daeb6 100644 --- a/Security.exp-in +++ b/Security.exp-in @@ -4,23 +4,9 @@ #include "Security/SecAccessControlExports.exp-in" #include "Security/SecureObjectSync/SOSExports.exp-in" -#if TARGET_OS_OSX #include "CSSMOID.exp-in" -#endif -#if TARGET_OS_IPHONE -_CSSMOID_MD5WithRSA -_CSSMOID_SHA1 -_CSSMOID_SHA1WithRSA -_CSSMOID_SHA256WithRSA -_CSSMOID_SHA384WithRSA -_CSSMOID_ECDSA_WithSHA1 -_CSSMOID_ECDSA_WithSHA256 -_CSSMOID_ECDSA_WithSHA384 -_CSSMOID_PKCS5_HMAC_SHA1 -#endif #if TARGET_OS_IPHONE -_DEROidCompare _NtlmCreateClientRequest _NtlmCreateClientResponse __NtlmCreateClientResponse @@ -29,9 +15,21 @@ _NtlmGeneratorCreate _NtlmGeneratorRelease _NtlmGetNegotiatedVersion _OID_PKIX_OCSP_BASIC +_OID_PKIX_OCSP +_OID_PKIX_OCSP_ARCHIVE_CUTOFF +_OID_PKIX_OCSP_CRL +_OID_PKIX_OCSP_NOCHECK +_OID_PKIX_OCSP_NONCE +_OID_PKIX_OCSP_RESPONSE +_OID_PKIX_OCSP_SERVICE_LOCATOR _OID_GOOGLE_OCSP_SCT #endif +_SSLSetALPNProtocols +_SSLCopyALPNProtocols +__SSLProtocolVersionToWireFormatValue +_SSLSetECDSACurves + #if TARGET_OS_IPHONE _SSLAddDistinguishedName _SSLClose @@ -49,6 +47,9 @@ _SSLGetClientSideAuthenticate _SSLGetConnection _SSLGetDatagramWriteSize _SSLGetEnabledCiphers +_SSLSetError +_SSLSetOCSPResponse +_SSLSetSessionTicketsEnabled _SSLGetEncryptionCertificate _SSLGetMaxDatagramRecordSize _SSLGetMinimumDHGroupSize @@ -84,8 +85,6 @@ _SSLGetNPNData _SSLSetALPNData _SSLSetALPNFunc _SSLGetALPNData -_SSLSetALPNProtocols -_SSLCopyALPNProtocols _SSLCopyRequestedPeerName _SSLCopyRequestedPeerNameLength _SSLSetAllowAnonymousCiphers @@ -93,7 +92,6 @@ _SSLSetCertificate _SSLSetClientSideAuthenticate _SSLSetConnection _SSLSetDatagramHelloCookie -_SSLSetECDSACurves _SSLSetEnabledCiphers _SSLSetEncryptionCertificate _SSLSetIOFuncs @@ -154,10 +152,23 @@ __SSLSetRsaBlinding __SSLSetTrustedRoots #endif // TARGET_OS_IPHONE -#if TARGET_OS_OSX // // libsecurity_ssl // + +_SSLGetNumberOfECDSACurves +_SSLGetECDSACurves +_SSLGetNumberOfClientAuthTypes +_SSLGetNegotiatedClientAuthType +_SSLGetClientAuthTypes + +#if TARGET_OS_IPHONE +__SSLCopyCertificateAuthorities +__SSLCopyTrustedRoots +__SSLSetCertificateAuthorities +#endif + +#if TARGET_OS_OSX _SSLAddDistinguishedName _SSLClose _SSLContextGetTypeID @@ -174,6 +185,9 @@ _SSLGetConnection _SSLGetDiffieHellmanParams _SSLGetEnableCertVerify _SSLGetEnabledCiphers +_SSLSetError +_SSLSetOCSPResponse +_SSLSetSessionTicketsEnabled _SSLGetNegotiatedCipher _SSLGetNegotiatedProtocolVersion _SSLGetNumberEnabledCiphers @@ -185,6 +199,7 @@ _SSLGetPeerDomainName _SSLGetPeerDomainNameLength _SSLGetPeerID _SSLGetPeerSecTrust +_SSLGetPSKIdentity _SSLGetProtocolVersion _SSLGetProtocolVersionEnabled _SSLGetProtocolVersionMax @@ -250,12 +265,6 @@ _SSLCopyDistinguishedNames _SSLSetCertificateAuthorities _SSLCopyCertificateAuthorities _SSLGetNegotiatedCurve -_SSLGetNumberOfECDSACurves -_SSLGetECDSACurves -_SSLSetECDSACurves -_SSLGetNumberOfClientAuthTypes -_SSLGetClientAuthTypes -_SSLGetNegotiatedClientAuthType _SSLGetNumberOfSignatureAlgorithms _SSLGetSignatureAlgorithms _SSLNewDatagramContext @@ -301,8 +310,26 @@ _SecAbsoluteTimeFromDateContent _CKKSSetupControlProtocol #if TARGET_OS_IPHONE || (TARGET_OS_OSX && __x86_64__) _OBJC_CLASS_$_CKKSControl +_OBJC_CLASS_$_SecuritydXPCClient +#else +.objc_class_name_CKKSControl +.objc_class_name_SecuritydXPCClient #endif + +#if __OBJC2__ && (TARGET_OS_IPHONE || (TARGET_OS_OSX && __x86_64__)) +_OBJC_CLASS_$_SFTransactionMetric +#endif //__OBJC2__ && IPHONE || OSX + +_OTSetupControlProtocol +_OTDefaultContext +#if TARGET_OS_IPHONE || (TARGET_OS_OSX && __x86_64__) +_OBJC_CLASS_$_OTControl _OBJC_CLASS_$_SecuritydXPCClient +#else +.objc_class_name_OTControl +.objc_class_name_SecuritydXPCClient +#endif + _SecAccessGroupsGetCurrent _SecAccessGroupsSetCurrent _SecSecurityClientGet @@ -313,6 +340,7 @@ _securityd_send_sync_and_do #if TARGET_OS_IOS _SecSecuritySetMusrMode #endif +__SecSetSecuritydTargetUID _SecDERItemCopyOIDDecimalRepresentation _SecDigestCreate @@ -320,12 +348,12 @@ _SecDigestCreate _SecFrameworkCopyResourceContents _SecFrameworkCopyResourceURL #endif +_SecCopyErrorMessageString _SecPKCS12Import _SecRandomCopyBytes #if TARGET_OS_IPHONE _SecSHA1DigestCreate -_SecSHA256DigestCreateFromData #endif _SecTaskCopySigningIdentifier _SecTaskCopyValueForEntitlement @@ -334,9 +362,7 @@ _SecTaskCreateFromSelf _SecTaskCreateWithAuditToken _SecTaskGetCodeSignStatus _SecTaskGetTypeID -#if TARGET_OS_OSX _SecTaskEntitlementsValidated -#endif _kSecRandomDefault @@ -387,6 +413,7 @@ _CMSEncoderSetEncoder _CMSEncoderAddSignedAttributes _CMSEncoderSetSigningTime _CMSEncoderSetAppleCodesigningHashAgility +_CMSEncoderSetAppleCodesigningHashAgilityV2 _CMSEncoderSetCertificateChainMode _CMSEncoderGetCertificateChainMode _CMSEncoderUpdateContent @@ -416,6 +443,7 @@ _CMSDecoderCopySignerTimestampCertificates _CMSEncoderCopySignerTimestamp _CMSEncoderCopySignerTimestampWithPolicy _CMSDecoderCopySignerAppleCodesigningHashAgility +_CMSDecoderCopySignerAppleCodesigningHashAgilityV2 #endif // TARGET_OS_OSX #if TARGET_OS_OSX @@ -661,6 +689,7 @@ _SecTransformExecute _SecTransformExecuteAsync _SecNullTransformCreate _SecDigestTransformCreate +_SecDigestTransformGetTypeID _SecCreateMaskGenerationFunctionTransform _SecTransformCreate _SecTransformRegister @@ -683,6 +712,9 @@ _SecGroupTransformHasMember _kSecDigestTypeAttribute _kSecDigestLengthAttribute _kSecOAEPEncodingParametersAttributeName +_kSecOAEPMessageLengthAttributeName +_kSecOAEPMGF1DigestAlgorithmAttributeName +_kSecNullTransformName _kSecTransformInputAttributeName _kSecTransformDebugAttributeName _kSecTransformOutputAttributeName @@ -703,7 +735,9 @@ _kSecPaddingKey _kSecIVKey _kSecEncryptionMode _SecEncryptTransformCreate +_SecEncryptTransformGetTypeID _SecDecryptTransformCreate +_SecDecryptTransformGetTypeID _SecDecodeTransformCreate _SecEncodeTransformCreate _SecSignTransformCreate @@ -726,6 +760,7 @@ _kSecTransformActionProcessData _SecTransformSetAttributeAction _SecGroupTransformFindLastTransform _SecGroupTransformFindMonitor +_SecTransformConnectTransformsInternal _SecTransformDisconnectTransforms _SecTransformDotForDebugging _SecCreateCollectTransform @@ -773,10 +808,12 @@ _MDS_InstallFile _MDS_RemoveSubservice #endif // TARGET_OS_OSX -#if TARGET_OS_OSX // // libsecurity_keychain // + +#if TARGET_OS_OSX +_ConvertArrayToKeyUsage _SecACLCopyAuthorizations _SecACLCopyContents _SecACLCopySimpleContents @@ -799,7 +836,6 @@ _SecAccessCreateWithOwnerAndACL _SecAccessCreateWithTrustedApplications _SecAccessGetOwnerAndACL _SecAccessGetTypeID -_SecCopyErrorMessageString _SecCreateRecoveryPassword _SecDigestGetData _SecFDERecoveryUnwrapCRSKWithPrivKey @@ -825,11 +861,13 @@ _SecIdentityUpdatePreferenceItem _SecInferLabelFromX509Name _SecItemAdd_ios _SecItemCopyMatching_ios + _SecItemCopyParentCertificates_osx +_SecItemParentCachePurge + _SecItemCopyStoredCertificate -#if TARGET_OS_OSX _SecItemCreateFromAttributeDictionary_osx -#endif +_SecItemDeleteAll _SecItemDelete_ios _SecItemExport _SecItemImport @@ -843,6 +881,7 @@ _SecKeychainAttemptMigrationWithMasterKey _SecKeychainAttributeInfoForItemID _SecKeychainChangeKeyStorePassphrase _SecKeychainChangePassword +_SecKeychainCleanupHandles _SecKeychainCopyAccess _SecKeychainCopyBlob _SecKeychainCopyDefault @@ -953,13 +992,14 @@ _SecKeychainVerifyKeyStorePassphrase _SecPasswordAction _SecPasswordSetInitialAccess _SecRandomCopyData -_SecSHA256DigestCreateFromData _SecUnwrapRecoveryPasswordWithAnswers _SecWrapRecoveryPasswordWithAnswers __SecItemGetPersistentReference _cssmErrorString _cssmPerror _kSecACLAuthorizationAny +_kSecACLAuthorizationChangeACL +_kSecACLAuthorizationChangeOwner _kSecACLAuthorizationDecrypt _kSecACLAuthorizationDelete _kSecACLAuthorizationDerive @@ -1008,6 +1048,11 @@ _kSecOIDAPPLE_EXTENSION_ADC_APPLE_SIGNING _kSecOIDAPPLE_EXTENSION_ADC_DEV_SIGNING _kSecOIDAPPLE_EXTENSION_APPLE_SIGNING _kSecOIDAPPLE_EXTENSION_CODE_SIGNING +_kSecOIDAPPLE_EXTENSION_AAI_INTERMEDIATE +_kSecOIDAPPLE_EXTENSION_APPLEID_INTERMEDIATE +_kSecOIDAPPLE_EXTENSION_INTERMEDIATE_MARKER +_kSecOIDAPPLE_EXTENSION_WWDR_INTERMEDIATE +_kSecOIDAPPLE_EXTENSION_ITMS_INTERMEDIATE _kSecOIDAuthorityInfoAccess _kSecOIDAuthorityKeyIdentifier _kSecOIDBasicConstraints @@ -1129,6 +1174,9 @@ _kSecUseKeychain // libsecurity_asn1 // _SecAsn1OidCompare + +_SecASN1PrintableString +_SecASN1UTF8String #if TARGET_OS_IPHONE _SecAsn1CoderCreate _SecAsn1CoderRelease @@ -1143,6 +1191,101 @@ _kSecAsn1OCSPResponseDataTemplate _kSecAsn1OCSPResponseTemplate _kSecAsn1OCSPSignedRequestTemplate _kSecAsn1OctetStringTemplate + +_kSecAsn1AnyTemplate +_kSecAsn1BMPStringTemplate +_kSecAsn1BitStringTemplate +_kSecAsn1BooleanTemplate +_kSecAsn1EnumeratedTemplate +_kSecAsn1GeneralizedTimeTemplate +_kSecAsn1IA5StringTemplate +_kSecAsn1IntegerTemplate +_kSecAsn1NullTemplate +_kSecAsn1ObjectIDTemplate +_kSecAsn1PointerToAnyTemplate +_kSecAsn1PointerToBMPStringTemplate +_kSecAsn1PointerToBitStringTemplate +_kSecAsn1PointerToBooleanTemplate +_kSecAsn1PointerToEnumeratedTemplate +_kSecAsn1PointerToGeneralizedTimeTemplate +_kSecAsn1PointerToIA5StringTemplate +_kSecAsn1PointerToIntegerTemplate +_kSecAsn1PointerToNullTemplate +_kSecAsn1PointerToObjectIDTemplate +_kSecAsn1PointerToOctetStringTemplate +_kSecAsn1PointerToPrintableStringTemplate +_kSecAsn1PointerToT61StringTemplate +_kSecAsn1PointerToTeletexStringTemplate +_kSecAsn1PointerToUTCTimeTemplate +_kSecAsn1PointerToUTF8StringTemplate +_kSecAsn1PointerToUniversalStringTemplate +_kSecAsn1PointerToVisibleStringTemplate +_kSecAsn1PrintableStringTemplate +_kSecAsn1SequenceOfAnyTemplate +_kSecAsn1SequenceOfBMPStringTemplate +_kSecAsn1SequenceOfBitStringTemplate +_kSecAsn1SequenceOfBooleanTemplate +_kSecAsn1SequenceOfEnumeratedTemplate +_kSecAsn1SequenceOfGeneralizedTimeTemplate +_kSecAsn1SequenceOfIA5StringTemplate +_kSecAsn1SequenceOfIntegerTemplate +_kSecAsn1SequenceOfNullTemplate +_kSecAsn1SequenceOfObjectIDTemplate +_kSecAsn1SequenceOfOctetStringTemplate +_kSecAsn1SequenceOfPrintableStringTemplate +_kSecAsn1SequenceOfT61StringTemplate +_kSecAsn1SequenceOfTeletexStringTemplate +_kSecAsn1SequenceOfUTCTimeTemplate +_kSecAsn1SequenceOfUTF8StringTemplate +_kSecAsn1SequenceOfUniversalStringTemplate +_kSecAsn1SequenceOfVisibleStringTemplate +_kSecAsn1SetOfAnyTemplate +_kSecAsn1SetOfBMPStringTemplate +_kSecAsn1SetOfBitStringTemplate +_kSecAsn1SetOfBooleanTemplate +_kSecAsn1SetOfEnumeratedTemplate +_kSecAsn1SetOfGeneralizedTimeTemplate +_kSecAsn1SetOfIA5StringTemplate +_kSecAsn1SetOfIntegerTemplate +_kSecAsn1SetOfNullTemplate +_kSecAsn1SetOfObjectIDTemplate +_kSecAsn1SetOfOctetStringTemplate +_kSecAsn1SetOfPrintableStringTemplate +_kSecAsn1SetOfT61StringTemplate +_kSecAsn1SetOfTeletexStringTemplate +_kSecAsn1SetOfUTCTimeTemplate +_kSecAsn1SetOfUTF8StringTemplate +_kSecAsn1SetOfUniversalStringTemplate +_kSecAsn1SetOfVisibleStringTemplate +_kSecAsn1SkipTemplate +_kSecAsn1T61StringTemplate +_kSecAsn1TeletexStringTemplate +_kSecAsn1UTCTimeTemplate +_kSecAsn1UTF8StringTemplate +_kSecAsn1UniversalStringTemplate +_kSecAsn1UnsignedIntegerTemplate +_kSecAsn1VisibleStringTemplate + +_SecAsn1AllocCopy +_SecAsn1AllocCopyItem +_SecAsn1AllocItem +_SecAsn1Decode +_SecAsn1Malloc + +_kSecAsn1OCSPCertIDTemplate +_kSecAsn1OCSPCertStatusGoodTemplate +_kSecAsn1OCSPCertStatusUnknownTemplate +_kSecAsn1OCSPDRepliesTemplate +_kSecAsn1OCSPDReplyTemplate +_kSecAsn1OCSPDRequestTemplate +_kSecAsn1OCSPDRequestsTemplate +_kSecAsn1OCSPRequestTemplate +_kSecAsn1OCSPResponseBytesTemplate +_kSecAsn1OCSPRevokedInfoTemplate +_kSecAsn1OCSPSignatureTemplate +_kSecAsn1OCSPSingleResponseTemplate +_kSecAsn1OCSPTbsRequestTemplate + #elif TARGET_OS_OSX _PORT_FreeArena _PORT_NewArena @@ -1196,6 +1339,7 @@ _kSecAsn1DistPointFullNameTemplate _kSecAsn1DistPointRDNTemplate _kSecAsn1DistributionPointTemplate _kSecAsn1EncryptedPrivateKeyInfoTemplate +_kSecAsn1ECDSAPrivateKeyInfoTemplate _kSecAsn1EnumeratedTemplate _kSecAsn1GenNameOtherNameTemplate _kSecAsn1GeneralNameTemplate @@ -1204,6 +1348,7 @@ _kSecAsn1IA5StringTemplate _kSecAsn1IntegerTemplate _kSecAsn1IssuingDistributionPointTemplate _kSecAsn1NameTemplate +_kSecAsn1NameConstraintsTemplate _kSecAsn1NullTemplate _kSecAsn1OCSPBasicResponseTemplate _kSecAsn1OCSPCertIDTemplate @@ -1246,8 +1391,10 @@ _kSecAsn1PointerToUTCTimeTemplate _kSecAsn1PointerToUTF8StringTemplate _kSecAsn1PointerToUniversalStringTemplate _kSecAsn1PointerToVisibleStringTemplate +_kSecAsn1PolicyConstraintsTemplate _kSecAsn1PolicyInformationTemplate _kSecAsn1PolicyQualifierTemplate +_kSecAsn1PolicyMappingsTemplate _kSecAsn1PrintableStringTemplate _kSecAsn1PrivateKeyInfoTemplate _kSecAsn1QC_StatementTemplate @@ -1405,6 +1552,7 @@ _kSecCodeInfoFlags _kSecCodeInfoFormat _kSecCodeInfoDigestAlgorithm _kSecCodeInfoDigestAlgorithms +_kSecCodeInfoPlatformIdentifier _kSecCodeInfoIdentifier _kSecCodeInfoImplicitDesignatedRequirement _kSecCodeInfoMainExecutable @@ -1428,6 +1576,8 @@ _kSecCodeInfoResourceDirectory _kSecGuestAttributeCanonical _kSecGuestAttributeDynamicCode _kSecGuestAttributeDynamicCodeInfoPlist +_kSecGuestAttributeArchitecture +_kSecGuestAttributeSubarchitecture _kSecGuestAttributeHash _kSecGuestAttributeMachPort _kSecGuestAttributePid @@ -1454,6 +1604,7 @@ _SecAssessmentCopyResult _SecAssessmentUpdate _SecAssessmentCopyUpdate _SecAssessmentControl +_SecAssessmentGetTypeID _kSecAssessmentContextKeyOperation _kSecAssessmentOperationTypeExecute _kSecAssessmentOperationTypeInstall @@ -1479,7 +1630,9 @@ _kSecAssessmentUpdateKeyRow _kSecAssessmentUpdateKeyCount _kSecAssessmentUpdateKeyFound _kSecAssessmentAssessmentAuthority +_kSecAssessmentAssessmentAuthorityFlags _kSecAssessmentAssessmentAuthorityOverride +_kSecAssessmentAssessmentAuthorityOriginalVerdict _kSecAssessmentAssessmentAuthorityRow _kSecAssessmentAssessmentFromCache _kSecAssessmentAssessmentOriginator @@ -1498,8 +1651,85 @@ _kSecAssessmentRuleKeyExpires _kSecAssessmentRuleKeyDisabled _kSecAssessmentRuleKeyBookmark _kSecAssessmentContextKeyPrimarySignature +_kDisabledOverride #endif // TARGET_OS_OSX +#if TARGET_OS_IPHONE +_SecCodeCheckValidity +_SecCodeCheckValidityWithErrors +_SecCodeCopyComponent +_SecCodeCopyDesignatedRequirement +_SecCodeCopyHost +_SecCodeCopyInternalRequirement +_SecCodeCopyPath +_SecCodeCopySelf +_SecCodeCopyStaticCode +//_SecCodeCreateWithPID +_SecCodeGetStatus +_SecCodeGetTypeID +_SecCodeMapMemory +_SecCodeSetStatus +_SecCodeValidateFileResource +_SecCopyLastError + +_SecRequirementCopyData +_SecRequirementCopyString +_SecRequirementCreateWithData +_SecRequirementCreateWithString +_SecRequirementCreateWithStringAndErrors +_SecRequirementGetTypeID +_SecStaticCodeCheckValidity +_SecStaticCodeCreateWithPath +_SecStaticCodeGetTypeID +_kSecCFErrorArchitecture +_kSecCFErrorGuestAttributes +_kSecCFErrorInfoPlist +_kSecCFErrorPath +_kSecCFErrorPattern +_kSecCFErrorRequirementSyntax +_kSecCFErrorResourceSeal +_kSecCFErrorResourceSideband +_kSecCodeAttributeArchitecture +_kSecCodeAttributeBundleVersion +_kSecCodeAttributeSubarchitecture +_kSecCodeInfoCMS +_kSecCodeInfoCdHashes +_kSecCodeInfoChangedFiles +_kSecCodeInfoCodeDirectory +_kSecCodeInfoCodeOffset +_kSecCodeInfoDesignatedRequirement +_kSecCodeInfoDigestAlgorithm +_kSecCodeInfoDigestAlgorithms +_kSecCodeInfoDiskRepInfo +_kSecCodeInfoDiskRepNoLibraryValidation +_kSecCodeInfoDiskRepOSPlatform +_kSecCodeInfoDiskRepOSSDKVersion +_kSecCodeInfoDiskRepOSVersionMin +_kSecCodeInfoFlags +_kSecCodeInfoFormat +_kSecCodeInfoImplicitDesignatedRequirement +_kSecCodeInfoMainExecutable +_kSecCodeInfoPList +_kSecCodeInfoPlatformIdentifier +_kSecCodeInfoRequirementData +_kSecCodeInfoRequirements +_kSecCodeInfoResourceDirectory +_kSecCodeInfoSource +_kSecCodeInfoStatus +_kSecCodeInfoTimestamp +_kSecCodeInfoTrust +_kSecGuestAttributeArchitecture +_kSecGuestAttributeAudit +_kSecGuestAttributeCanonical +_kSecGuestAttributeDynamicCode +_kSecGuestAttributeDynamicCodeInfoPlist +_kSecGuestAttributeHash +_kSecGuestAttributeMachPort +_kSecGuestAttributePid +_kSecGuestAttributeSubarchitecture + +#endif // TARGET_OS_IPHONE + #if TARGET_OS_OSX //breadcrumb _SecBreadcrumbCreateFromPassword @@ -1507,10 +1737,6 @@ _SecBreadcrumbCopyPassword _SecBreadcrumbCreateNewEncryptedKey #endif // TARGET_OS_OSX -#if TARGET_OS_IPHONE -_oidAnyExtendedKeyUsage -_oidAnyPolicy -#elif TARGET_OS_OSX // // libDER OIDs // @@ -1544,12 +1770,17 @@ _oidSha224 _oidFee _oidMd5Fee _oidSha1Fee +_oidEcPrime192v1 +_oidEcPrime256v1 +_oidAnsip384r1 +_oidAnsip521r1 _oidSubjectKeyIdentifier _oidKeyUsage _oidPrivateKeyUsagePeriod _oidSubjectAltName _oidIssuerAltName _oidBasicConstraints +_oidNameConstraints _oidCrlDistributionPoints _oidCertificatePolicies _oidAnyPolicy @@ -1582,13 +1813,13 @@ _oidExtendedKeyUsageServerAuth _oidExtendedKeyUsageClientAuth _oidExtendedKeyUsageCodeSigning _oidExtendedKeyUsageEmailProtection +_oidExtendedKeyUsageTimeStamping _oidExtendedKeyUsageOCSPSigning _oidExtendedKeyUsageIPSec _oidExtendedKeyUsageMicrosoftSGC _oidExtendedKeyUsageNetscapeSGC _oidGoogleEmbeddedSignedCertificateTimestamp _oidGoogleOCSPSignedCertificateTimestamp -#endif // TARGET_OS_OSX #if TARGET_OS_OSX // @@ -1612,6 +1843,7 @@ _SecureDownloadCopyURLs _SecureDownloadCopyCreationDate _SecureDownloadGetDownloadSize __SecureDownloadCreateTicketXML +__SecureDownloadParseTicketXML _SecureDownloadCopyTicketLocation #endif // TARGET_OS_OSX @@ -1661,6 +1893,28 @@ _weak_os_log_create _weak_os_log_type_enabled _secLogEnable _secLogDisable + +_ApplyScopeDictionaryForID +_ApplyScopeListForID +_SecLogAPICreate +___security_simulatecrash +___security_simulatecrash_enable +___security_stackshotreport +_api_trace +_secLogEnabled +_CopyCurrentScopePlist + +#endif + +// SecFramework.h +#if TARGET_OS_IPHONE +_SecOSStatusWith +_SecSHA256DigestCreate +_SecSHA256DigestCreateFromData +#endif +#if TARGET_OS_OSX +_SecSHA256DigestCreate +_SecSHA256DigestCreateFromData #endif _secLogObjForScope @@ -1689,8 +1943,58 @@ _SecRKCreateRecoveryKeyString // Analytics // -.objc_class_name_SFSQLite -.objc_class_name_SFAnalyticsLogger +#if __OBJC2__ + +_OBJC_CLASS_$_SFSQLite +_OBJC_METACLASS_$_SFAnalytics +_OBJC_CLASS_$_SFAnalytics +_OBJC_CLASS_$_SFAnalyticsActivityTracker +_OBJC_CLASS_$_SFAnalyticsMultiSampler +_OBJC_CLASS_$_SFAnalyticsSampler +_OBJC_CLASS_$_SFAnalyticsSQLiteStore +_SFAnalyticsMaxEventsToReport +_SFSQLiteJournalSuffixes +_SFAnalyticsSamplerIntervalOncePerReport +_SFAnalyticsTableSuccessCount +_SFAnalyticsTableHardFailures +_SFAnalyticsTableSoftFailures +_SFAnalyticsTableSamples +_SFAnalyticsTableAllEvents +_SFAnalyticsColumnSuccessCount +_SFAnalyticsColumnHardFailureCount +_SFAnalyticsColumnSoftFailureCount +_SFAnalyticsColumnSampleValue +_SFAnalyticsColumnSampleName +_SFAnalyticsEventTime +_SFAnalyticsEventType +_SFAnalyticsEventClassKey +_SFAnalyticsUserDefaultsSuite +_SFAnalyticsFireSamplersNotification +_SFAnalyticsTableSchema +_SFAnalyticsAttributeErrorCode +_SFAnalyticsAttributeErrorDomain +_SFAnalyticsAttributeErrorUnderlyingChain +_SFAnalyticsTopicKeySync +_SFAnaltyicsTopicTrust + +_OBJC_CLASS_$_SOSAnalytics +_CKDKVSPerformanceCountersSampler +_CKDKVSPerfCounterSynchronize +_CKDKVSPerfCounterSynchronizeWithCompletionHandler +_CKDKVSPerfCounterIncomingMessages +_CKDKVSPerfCounterOutgoingMessages +_CKDKVSPerfCounterTotalWaitTimeSynchronize +_CKDKVSPerfCounterLongestWaitTimeSynchronize +_CKDKVSPerfCounterSynchronizeFailures +#endif // __OBJC2__ // Padding _SecPaddingCompute + +// +// Code coverage support +// + +_VPMergeHook* +___llvm_profile_* +_lprofCurFilename* diff --git a/Security.xcodeproj/project.pbxproj b/Security.xcodeproj/project.pbxproj index d86582c7..9b3a5bc6 100644 --- a/Security.xcodeproj/project.pbxproj +++ b/Security.xcodeproj/project.pbxproj @@ -36,6 +36,7 @@ buildPhases = ( ); dependencies = ( + 0C78CCE51FCC97E7008B4B24 /* PBXTargetDependency */, F621D0831ED6ED5B000EA569 /* PBXTargetDependency */, 6C24EF4A1E415109000DE79F /* PBXTargetDependency */, EB27FF261E40716D00EC9E3A /* PBXTargetDependency */, @@ -68,7 +69,10 @@ DCB515D91ED3CC6B001F1152 /* PBXTargetDependency */, 6C24EF4A1E415109000DE79F /* PBXTargetDependency */, DCB515D71ED3CC52001F1152 /* PBXTargetDependency */, + 6CAA8D3F1F8431C9007B6E03 /* PBXTargetDependency */, + 6CAA8CE91F82FD13007B6E03 /* PBXTargetDependency */, DC5225001E40295C0021640A /* PBXTargetDependency */, + 6C7C38811FD88C4700DFFE68 /* PBXTargetDependency */, ); name = Security_executables_osx; productName = Security_executables; @@ -114,6 +118,7 @@ buildPhases = ( ); dependencies = ( + 0C78CCE71FCC97F1008B4B24 /* PBXTargetDependency */, D41257F11E941E7D00781F23 /* PBXTargetDependency */, EB27FF281E40717400EC9E3A /* PBXTargetDependency */, EBF374841DC058C00065D840 /* PBXTargetDependency */, @@ -131,7 +136,6 @@ 0CC827F2138712B100BD99B7 /* PBXTargetDependency */, 52D82BF616A627100078DFE5 /* PBXTargetDependency */, CD0637811A840C6400C81E74 /* PBXTargetDependency */, - 5DDD0BEE16D6748900D6C0D6 /* PBXTargetDependency */, 4C52D0EE16EFCD720079966E /* PBXTargetDependency */, BE197F631911742900BA91D1 /* PBXTargetDependency */, BE4AC9B418B8020400B84964 /* PBXTargetDependency */, @@ -143,6 +147,9 @@ DCB515D01ED3CC36001F1152 /* PBXTargetDependency */, DC5224F91E4029520021640A /* PBXTargetDependency */, EB0D30FA1EF12BFB00C3C17D /* PBXTargetDependency */, + 6CAA8D3D1F8431BC007B6E03 /* PBXTargetDependency */, + 6CAA8CE51F82FD08007B6E03 /* PBXTargetDependency */, + 6C7C38881FD88C5A00DFFE68 /* PBXTargetDependency */, ); name = Security_executables_ios; productName = phase2; @@ -164,10 +171,10 @@ buildPhases = ( ); dependencies = ( - EB58A05E1E74C51F009C10D7 /* PBXTargetDependency */, EB6A6FBB1B90F8EC0045DC68 /* PBXTargetDependency */, 4C541FA10F250C5200E508AE /* PBXTargetDependency */, E7CFF6771C84F66A00E3484E /* PBXTargetDependency */, + EB58A05E1E74C51F009C10D7 /* PBXTargetDependency */, ); name = ios; productName = world; @@ -183,7 +190,6 @@ D41257F51E941E8E00781F23 /* PBXTargetDependency */, EBF374881DC058CC0065D840 /* PBXTargetDependency */, D41AD45C1B978A7A008C7270 /* PBXTargetDependency */, - D41AD4721B978F76008C7270 /* PBXTargetDependency */, D41AD45E1B978A7C008C7270 /* PBXTargetDependency */, D41AD4601B978E18008C7270 /* PBXTargetDependency */, D41AD4621B978E24008C7270 /* PBXTargetDependency */, @@ -209,7 +215,6 @@ EBF374861DC058C50065D840 /* PBXTargetDependency */, D41AD43A1B96721E008C7270 /* PBXTargetDependency */, D41AD4521B9788B2008C7270 /* PBXTargetDependency */, - D41AD45A1B978944008C7270 /* PBXTargetDependency */, D41AD4461B9786A3008C7270 /* PBXTargetDependency */, D41AD43E1B967242008C7270 /* PBXTargetDependency */, D41AD43C1B96723B008C7270 /* PBXTargetDependency */, @@ -385,6 +390,7 @@ EB58A0601E74C8D9009C10D7 /* PBXTargetDependency */, EB10557F1E14DFBE0003C309 /* PBXTargetDependency */, BE9C38D11EB115F4007E2AE1 /* PBXTargetDependency */, + DCDB29761FD8839F00B5D242 /* PBXTargetDependency */, ); name = Security_tests_osx; productName = Security_test_macos; @@ -402,6 +408,7 @@ EB58A0621E74C8E4009C10D7 /* PBXTargetDependency */, EB10557D1E14DFB60003C309 /* PBXTargetDependency */, BE9C38D31EB11605007E2AE1 /* PBXTargetDependency */, + DCDB29781FD883AB00B5D242 /* PBXTargetDependency */, ); name = Security_tests_ios; productName = Security_test_ios; @@ -413,7 +420,6 @@ ); dependencies = ( DC71D9E11D95BAC40065FB93 /* PBXTargetDependency */, - DC5AC1341D835C2300CF422C /* PBXTargetDependency */, DC178BF31D77ABE300B50D50 /* PBXTargetDependency */, BE9C38C81EB115A7007E2AE1 /* PBXTargetDependency */, DC58C4431D77C1F8003C25A4 /* PBXTargetDependency */, @@ -521,6 +527,16 @@ 0C0C88781CCEC5C400617D1B /* si-82-sectrust-ct-data in Resources */ = {isa = PBXBuildFile; fileRef = 0C0C88771CCEC5BD00617D1B /* si-82-sectrust-ct-data */; }; 0C0C88791CCEC5C500617D1B /* si-82-sectrust-ct-data in Resources */ = {isa = PBXBuildFile; fileRef = 0C0C88771CCEC5BD00617D1B /* si-82-sectrust-ct-data */; }; 0C0CECA41DA45ED700C22FBC /* recovery_key.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C0CEC9E1DA45EA200C22FBC /* recovery_key.m */; }; + 0C0DA5CE1FE1EAB9003BD3BB /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; + 0C0DA5CF1FE1F1C5003BD3BB /* OTControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */; }; + 0C0DA5D01FE1F1F3003BD3BB /* CKKSControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */; }; + 0C16371C1FD116B300210823 /* MockCloudKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3502E61E0214C800BC0587 /* MockCloudKit.m */; }; + 0C1637211FD12F1500210823 /* OTCloudStoreTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C16371F1FD12F1500210823 /* OTCloudStoreTests.m */; }; + 0C1637271FD2065400210823 /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; + 0C1637291FD2066A00210823 /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; + 0C16372B1FD2067F00210823 /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; + 0C16372D1FD2069300210823 /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; + 0C1637301FD206BC00210823 /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; 0C2BCBAF1D06401F00ED7A2F /* ioSock.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CE5A65809C79E0600D27A3F /* ioSock.c */; }; 0C2BCBB01D06401F00ED7A2F /* sslAppUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE5A65A09C79E0600D27A3F /* sslAppUtils.cpp */; }; 0C2BCBB41D06401F00ED7A2F /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; @@ -531,19 +547,104 @@ 0C2BCBC91D0648D100ED7A2F /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; 0C2BCBCA1D0648D100ED7A2F /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E43C48C1B00D07000E5ECB2 /* CoreFoundation.framework */; }; 0C2BCBCF1D0648EF00ED7A2F /* dtlsEchoServer.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C2BCBA61D063F7D00ED7A2F /* dtlsEchoServer.c */; }; + 0C36B3212007F2550029F7A2 /* OTPreflightInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C36B3172007EE6C0029F7A2 /* OTPreflightInfo.m */; }; + 0C36B3222007F2570029F7A2 /* OTPreflightInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C36B3172007EE6C0029F7A2 /* OTPreflightInfo.m */; }; 0C3C00731EF3636500AB19FE /* secd-155-otr-negotiation-monitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C3C00721EF3636300AB19FE /* secd-155-otr-negotiation-monitor.m */; }; + 0C46A5712034C6BA00F17112 /* OTControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0E1FCB452400580909 /* OTControl.m */; }; + 0C46A57B2035019800F17112 /* OTLockStateNetworkingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C46A57A2035019800F17112 /* OTLockStateNetworkingTests.m */; }; 0C48990B1E0E0FF300C6CF70 /* SOSTransportCircleCK.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C48990A1E0E0FF300C6CF70 /* SOSTransportCircleCK.h */; }; 0C4899121E0E105D00C6CF70 /* SOSTransportCircleCK.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C4899111E0E105D00C6CF70 /* SOSTransportCircleCK.m */; }; - 0C48991C1E0F384700C6CF70 /* SOSAccountTrustClassic.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C48991B1E0F384700C6CF70 /* SOSAccountTrustClassic.m */; }; 0C4899231E0F386900C6CF70 /* SOSAccountTrustClassic.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C4899221E0F386900C6CF70 /* SOSAccountTrustClassic.h */; }; 0C4899251E0F38FA00C6CF70 /* SOSAccountTrustOctagon.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C4899241E0F38FA00C6CF70 /* SOSAccountTrustOctagon.m */; }; 0C4899271E0F399B00C6CF70 /* SOSAccountTrustOctagon.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C4899261E0F399B00C6CF70 /* SOSAccountTrustOctagon.h */; }; + 0C52C1FF20003BCA003F0733 /* OTTestsBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C52C1FE20003BCA003F0733 /* OTTestsBase.m */; }; + 0C59605A1FB2D8E50095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; + 0C59605C1FB2D9280095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; + 0C59605D1FB2D95D0095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; + 0C59605E1FB2D9990095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; + 0C59605F1FB2D9F60095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; + 0C5960601FB2DA310095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; + 0C5960621FB2E0EC0095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; + 0C5960631FB2E1A70095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; + 0C5960641FB2E2070095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; settings = {ATTRIBUTES = (Weak, ); }; }; + 0C5960651FB2E2800095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; + 0C5960811FB369C50095BA29 /* CKKSHealTLKSharesOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBF2F841F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.m */; }; + 0C5CFB382019610000913B9C /* OTRamping.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C5CFB37201960FF00913B9C /* OTRamping.m */; }; + 0C5CFB392019610000913B9C /* OTRamping.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C5CFB37201960FF00913B9C /* OTRamping.m */; }; 0C5D62F11E81E74800AA4D02 /* SOSInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D8D1D8085F200865A7C /* SOSInternal.m */; }; + 0C5F4FD81F952FEA00AF1616 /* secd-700-sftm.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C5F4FD71F952FEA00AF1616 /* secd-700-sftm.m */; }; + 0C770EBC1FCF7C9800B5F0E2 /* OTCloudStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBE891FC9DA5200580909 /* OTCloudStore.h */; }; + 0C770EC21FCF7C9800B5F0E2 /* OTCloudStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBE891FC9DA5200580909 /* OTCloudStore.h */; }; + 0C770EC41FCF7E2000B5F0E2 /* OTCloudStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C770EC31FCF7E2000B5F0E2 /* OTCloudStore.m */; }; + 0C770EC51FCF7E2000B5F0E2 /* OTCloudStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C770EC31FCF7E2000B5F0E2 /* OTCloudStore.m */; }; 0C78F1CC16A5E1BF00654E08 /* sectask-10-sectask.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C78F1CA16A5E1BF00654E08 /* sectask-10-sectask.c */; }; 0C78F1CD16A5E1BF00654E08 /* sectask-10-sectask.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C78F1CA16A5E1BF00654E08 /* sectask-10-sectask.c */; }; 0C78F1CE16A5E1BF00654E08 /* sectask_ipc.defs in Sources */ = {isa = PBXBuildFile; fileRef = 0C78F1CB16A5E1BF00654E08 /* sectask_ipc.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; }; 0C78F1CF16A5E1BF00654E08 /* sectask_ipc.defs in Sources */ = {isa = PBXBuildFile; fileRef = 0C78F1CB16A5E1BF00654E08 /* sectask_ipc.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; }; 0C78F1D016A5E3EB00654E08 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 107227350D91FE89003CF14F /* libbsm.dylib */; }; + 0C85DFE71FB38BB6000343A7 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; + 0C85DFE81FB38BB6000343A7 /* libsecurityd_ios_NO_AKS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC222C771E034D1F00B09171 /* libsecurityd_ios_NO_AKS.a */; }; + 0C85DFE91FB38BB6000343A7 /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; + 0C85DFEA1FB38BB6000343A7 /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; + 0C85DFEB1FB38BB6000343A7 /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; + 0C85DFEC1FB38BB6000343A7 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + 0C85DFED1FB38BB6000343A7 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF730310EF9CDE300E17471 /* CFNetwork.framework */; }; + 0C85DFEE1FB38BB6000343A7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + 0C85DFF01FB38BB6000343A7 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; + 0C85DFF11FB38BB6000343A7 /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC3502E81E02172C00BC0587 /* OCMock.framework */; }; + 0C85DFF31FB38BB6000343A7 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; }; + 0C85DFF41FB38BB6000343A7 /* libACM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3A1D78F228002223DE /* libACM.a */; }; + 0C85DFF51FB38BB6000343A7 /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; }; + 0C85DFF61FB38BB6000343A7 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246CE1F9AEAE300D63882 /* libDER.a */; }; + 0C85DFF71FB38BB6000343A7 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 107227350D91FE89003CF14F /* libbsm.dylib */; }; + 0C85DFF81FB38BB6000343A7 /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; }; + 0C85DFF91FB38BB6000343A7 /* libctkclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient.a */; }; + 0C85DFFA1FB38BB6000343A7 /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */; }; + 0C85DFFB1FB38BB6000343A7 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; }; + 0C85DFFE1FB38BB6000343A7 /* OCMock.framework in Embed OCMock */ = {isa = PBXBuildFile; fileRef = DC3502E81E02172C00BC0587 /* OCMock.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 0C8A03461FDF42BA0042E8BE /* OTEscrowKeyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8A03451FDF42BA0042E8BE /* OTEscrowKeyTests.m */; }; + 0C8A034D1FDF4CCE0042E8BE /* OTLocalStoreTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8A034C1FDF4CCE0042E8BE /* OTLocalStoreTests.m */; }; + 0C8A034F1FDF60070042E8BE /* OTBottledPeerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8A034E1FDF60070042E8BE /* OTBottledPeerTests.m */; }; + 0C8BBE9F1FC9DBA400580909 /* OTBottledPeer.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE931FC9DA5700580909 /* OTBottledPeer.m */; }; + 0C8BBEA01FC9DBA400580909 /* OTBottledPeer.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE931FC9DA5700580909 /* OTBottledPeer.m */; }; + 0C8BBEA21FC9DBAA00580909 /* OTContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE981FC9DA5A00580909 /* OTContext.m */; }; + 0C8BBEA51FC9DBB100580909 /* OTEscrowKeys.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE961FC9DA5900580909 /* OTEscrowKeys.m */; }; + 0C8BBEA61FC9DBB200580909 /* OTEscrowKeys.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE961FC9DA5900580909 /* OTEscrowKeys.m */; }; + 0C8BBEA71FC9DBB500580909 /* OTIdentity.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE8D1FC9DA5400580909 /* OTIdentity.m */; }; + 0C8BBEA81FC9DBB600580909 /* OTIdentity.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE8D1FC9DA5400580909 /* OTIdentity.m */; }; + 0C8BBEA91FC9DBBF00580909 /* OTLocalStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE8C1FC9DA5400580909 /* OTLocalStore.m */; }; + 0C8BBEAA1FC9DBC000580909 /* OTLocalStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE8C1FC9DA5400580909 /* OTLocalStore.m */; }; + 0C8BBEE61FCA6E0500580909 /* OTContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE981FC9DA5A00580909 /* OTContext.m */; }; + 0C8BBEFF1FCB446400580909 /* SecArgParse.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5BCC461E5380EA00649140 /* SecArgParse.c */; }; + 0C8BBF031FCB446400580909 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; + 0C8BBF091FCB447600580909 /* otctl.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBEF71FCB405700580909 /* otctl.m */; }; + 0C8BBF111FCB4AAA00580909 /* OTControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0E1FCB452400580909 /* OTControl.m */; }; + 0C8BBF121FCB4AAB00580909 /* OTControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0E1FCB452400580909 /* OTControl.m */; }; + 0C8BBF131FCB4AFA00580909 /* OTControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */; }; + 0C8BBF141FCB4AFB00580909 /* OTControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */; }; + 0C8BBF151FCB4B1B00580909 /* OTManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0F1FCB481800580909 /* OTManager.m */; }; + 0C8BBF161FCB4B1C00580909 /* OTManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0F1FCB481800580909 /* OTManager.m */; }; + 0C8BBF171FCB4E5000580909 /* OTControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */; }; + 0C8BBF181FCB4E5000580909 /* OTControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */; }; + 0C8BBF1B1FCB4EC500580909 /* OTControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */; }; + 0C8BBF1C1FCB4F0300580909 /* OTControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0B1FCB452200580909 /* OTControl.h */; }; + 0C8BBF1D1FCB4F0300580909 /* OTControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0C1FCB452200580909 /* OTControlProtocol.h */; }; + 0C8BBF1E1FCB4F0400580909 /* OTControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0B1FCB452200580909 /* OTControl.h */; }; + 0C8BBF1F1FCB4F0400580909 /* OTControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0C1FCB452200580909 /* OTControlProtocol.h */; }; + 0C8BBF201FCB4F1800580909 /* OTControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0B1FCB452200580909 /* OTControl.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 0C8BBF211FCB4F1800580909 /* OTControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0C1FCB452200580909 /* OTControlProtocol.h */; }; + 0C8BBF221FCB4F1800580909 /* OTControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0B1FCB452200580909 /* OTControl.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 0C8BBF231FCB4F1800580909 /* OTControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0C1FCB452200580909 /* OTControlProtocol.h */; }; + 0C8BBF241FCB4FE700580909 /* OTManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF101FCB486B00580909 /* OTManager.h */; }; + 0C8BBF251FCB4FE800580909 /* OTManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF101FCB486B00580909 /* OTManager.h */; }; + 0C8BBF261FCB561C00580909 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */; }; + 0C8BBF2B1FCB575800580909 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */; }; + 0C8BBF2D1FCB5A2900580909 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */; }; + 0C8BBFFD1FCE8F3300580909 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 0CA4EBF3202B8D9C002B1D96 /* CloudKitKeychainSyncingTestsBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CA4EBF2202B8D1D002B1D96 /* CloudKitKeychainSyncingTestsBase.m */; }; + 0CA4EBF4202B8DBE002B1D96 /* CloudKitKeychainSyncingTestsBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CA4EBF2202B8D1D002B1D96 /* CloudKitKeychainSyncingTestsBase.m */; }; + 0CA4EC10202BB5AF002B1D96 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 0CA4EC11202BB5E9002B1D96 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 0CAC5DBF1EB3DA4C00AD884B /* SOSPeerRateLimiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CAC5DBE1EB3DA4C00AD884B /* SOSPeerRateLimiter.m */; }; 0CAD1E1C1E032ADB00537693 /* SOSCloudCircleServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CAA1D8085D800865A7C /* SOSCloudCircleServer.m */; }; 0CAD1E581E1C5C6C00537693 /* SOSCloudCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D891D8085F200865A7C /* SOSCloudCircle.m */; }; @@ -553,10 +654,30 @@ 0CAD1E5C1E1C5CEB00537693 /* secd_77_ids_messaging.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C691D8085D800865A7C /* secd_77_ids_messaging.m */; }; 0CAD1E5D1E1C5CF900537693 /* secd-80-views-alwayson.m in Sources */ = {isa = PBXBuildFile; fileRef = 7281E08B1DFD0A380021E1B7 /* secd-80-views-alwayson.m */; }; 0CAD1E5E1E1C5D0600537693 /* secd-95-escrow-persistence.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C741D8085D800865A7C /* secd-95-escrow-persistence.m */; }; + 0CAEC9D81FD740CF00D1F2CA /* OTContextTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBEAF1FC9DCA400580909 /* OTContextTests.m */; }; + 0CB9754E2023A8DD008D6B48 /* CloudKitKeychainSyncingMockXCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DC08D1C31E64FA8C006237DA /* CloudKitKeychainSyncingMockXCTest.m */; }; + 0CB9754F2023A8F5008D6B48 /* CloudKitMockXCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DC222CA71E08A7D900B09171 /* CloudKitMockXCTest.m */; }; + 0CB975512023B199008D6B48 /* OTRampingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CB975502023B199008D6B48 /* OTRampingTests.m */; }; + 0CBD55B31FE883F200A8CE21 /* SFBehavior.m in Sources */ = {isa = PBXBuildFile; fileRef = EB82A2A51FAFF26900CA64A9 /* SFBehavior.m */; }; + 0CBD55B91FE883F300A8CE21 /* SFBehavior.m in Sources */ = {isa = PBXBuildFile; fileRef = EB82A2A51FAFF26900CA64A9 /* SFBehavior.m */; }; + 0CBDF64D1FFC951200433E0D /* OTBottledPeerTLK.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CBDF64C1FFC951200433E0D /* OTBottledPeerTLK.m */; }; + 0CBFEACA200FCD2D009A60E9 /* SFTransactionMetric.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFTransactionMetric.m */; }; + 0CBFEACB200FCD2D009A60E9 /* SFTransactionMetric.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFTransactionMetric.m */; }; + 0CBFEACC200FCD33009A60E9 /* SFTransactionMetric.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CF0E2E71F8EE40700BD18E4 /* SFTransactionMetric.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 0CBFEACD200FCD33009A60E9 /* SFTransactionMetric.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CF0E2E71F8EE40700BD18E4 /* SFTransactionMetric.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 0CC0445B1FFC4150004A5B63 /* CKKSControl.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9C95B31F79CFD1000D19E5 /* CKKSControl.m */; }; 0CC319241DA46FBF005D42EA /* ProtectedCloudStorage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43DB542E1BB1F85B0083C3F1 /* ProtectedCloudStorage.framework */; }; + 0CCCC7C920261D310024405E /* OT.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CCCC7C820261D310024405E /* OT.m */; }; + 0CCCC7CA20261D310024405E /* OT.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CCCC7C820261D310024405E /* OT.m */; }; 0CCDE7171EEB08220021A946 /* secd-156-timers.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CCDE7161EEB08220021A946 /* secd-156-timers.m */; }; 0CD8CB051ECA50780076F37F /* SOSPeerOTRTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CD8CB041ECA50780076F37F /* SOSPeerOTRTimer.m */; }; 0CD8CB0B1ECA50920076F37F /* SOSPeerOTRTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CD8CB041ECA50780076F37F /* SOSPeerOTRTimer.m */; }; + 0CD9E8001FE05B6600F66C38 /* OTContextRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CD9E7FF1FE05B6600F66C38 /* OTContextRecord.m */; }; + 0CD9E8011FE05B6600F66C38 /* OTContextRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CD9E7FF1FE05B6600F66C38 /* OTContextRecord.m */; }; + 0CE1BCCE1FCE11680017230E /* OTBottledPeerSigned.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE1BCC61FCE11480017230E /* OTBottledPeerSigned.m */; }; + 0CE1BCCF1FCE11690017230E /* OTBottledPeerSigned.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE1BCC61FCE11480017230E /* OTBottledPeerSigned.m */; }; + 0CE407AC1FD4769B00F59B31 /* OTCloudStoreState.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE407AB1FD4769B00F59B31 /* OTCloudStoreState.m */; }; + 0CE407AD1FD4769B00F59B31 /* OTCloudStoreState.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE407AB1FD4769B00F59B31 /* OTCloudStoreState.m */; }; 0CE760481E12F2F300B4381E /* SOSAccountTrustClassic+Expansion.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE760471E12F2F200B4381E /* SOSAccountTrustClassic+Expansion.m */; }; 0CE7604A1E12F30200B4381E /* SOSAccountTrustClassic+Circle.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE760491E12F30200B4381E /* SOSAccountTrustClassic+Circle.m */; }; 0CE7604C1E12F56800B4381E /* SOSAccountTrustClassic+Identity.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE7604B1E12F56800B4381E /* SOSAccountTrustClassic+Identity.m */; }; @@ -576,7 +697,6 @@ 220179EB1E3BF1F100EFB6F3 /* detachedrep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067E11D8CDF7E007602F1 /* detachedrep.cpp */; }; 222F239F1DAC15C5007ACB90 /* SecTaskPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD068031D8CDF7E007602F1 /* SecTaskPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; 222F23A01DAC1603007ACB90 /* SecTaskPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD068031D8CDF7E007602F1 /* SecTaskPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 225394B71E3081F900D3CD9B /* cskernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067CA1D8CDF7E007602F1 /* cskernel.cpp */; }; 225394B81E30820900D3CD9B /* Code.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067A01D8CDF7E007602F1 /* Code.cpp */; }; 225394B91E30821400D3CD9B /* bundlediskrep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067D51D8CDF7E007602F1 /* bundlediskrep.cpp */; }; 225394BA1E30821E00D3CD9B /* cdbuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067B01D8CDF7E007602F1 /* cdbuilder.cpp */; }; @@ -589,7 +709,6 @@ 225394C11E30827600D3CD9B /* filediskrep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067D31D8CDF7E007602F1 /* filediskrep.cpp */; }; 225394C21E30827E00D3CD9B /* kerneldiskrep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067D71D8CDF7E007602F1 /* kerneldiskrep.cpp */; }; 225394C31E30828800D3CD9B /* StaticCode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067A21D8CDF7E007602F1 /* StaticCode.cpp */; }; - 225394C41E30829300D3CD9B /* reqparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067C31D8CDF7E007602F1 /* reqparser.cpp */; }; 225394C51E3082A100D3CD9B /* requirement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067BB1D8CDF7E007602F1 /* requirement.cpp */; }; 225394C61E3082AB00D3CD9B /* Requirements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067A41D8CDF7E007602F1 /* Requirements.cpp */; }; 225394C71E3082B600D3CD9B /* reqdumper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067C51D8CDF7E007602F1 /* reqdumper.cpp */; }; @@ -604,7 +723,6 @@ 225394D01E30836200D3CD9B /* singlediskrep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067DF1D8CDF7E007602F1 /* singlediskrep.cpp */; }; 225394D11E30836F00D3CD9B /* reqreader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067BF1D8CDF7E007602F1 /* reqreader.cpp */; }; 225394D21E30837900D3CD9B /* cserror.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067F11D8CDF7E007602F1 /* cserror.cpp */; }; - 225394D31E3083C600D3CD9B /* SecCodeHost.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785841D778B8000B50D50 /* SecCodeHost.h */; settings = {ATTRIBUTES = (Private, ); }; }; 225394D41E3083D000D3CD9B /* CodeSigning.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785811D778B7F00B50D50 /* CodeSigning.h */; settings = {ATTRIBUTES = (Private, ); }; }; 225394D51E3083DA00D3CD9B /* CSCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785821D778B7F00B50D50 /* CSCommon.h */; settings = {ATTRIBUTES = (Private, ); }; }; 225394D61E3083E300D3CD9B /* SecCode.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785831D778B7F00B50D50 /* SecCode.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -619,7 +737,6 @@ 22A23B3C1E3AAC9800C41830 /* SecCode.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD0678D1D8CDF7E007602F1 /* SecCode.h */; settings = {ATTRIBUTES = (Private, ); }; }; 22A23B3D1E3AAC9800C41830 /* SecStaticCode.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD067901D8CDF7E007602F1 /* SecStaticCode.h */; settings = {ATTRIBUTES = (Private, ); }; }; 22A23B3E1E3AAC9800C41830 /* SecRequirement.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD067931D8CDF7E007602F1 /* SecRequirement.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 22A23B3F1E3AAC9800C41830 /* SecCodeHost.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD067981D8CDF7E007602F1 /* SecCodeHost.h */; settings = {ATTRIBUTES = (Private, ); }; }; 22E337DA1E37FD66001D5637 /* libsecurity_codesigning_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 225394B41E3080A600D3CD9B /* libsecurity_codesigning_ios.a */; }; 24CBF8751E9D4E6100F09F0E /* kc-44-secrecoverypassword.c in Sources */ = {isa = PBXBuildFile; fileRef = 24CBF8731E9D4E4500F09F0E /* kc-44-secrecoverypassword.c */; }; 433E519E1B66D5F600482618 /* AppSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 433E519D1B66D5F600482618 /* AppSupport.framework */; }; @@ -661,28 +778,58 @@ 44A655A61AA4B4C80059D185 /* libctkclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient.a */; }; 470415DC1E5E1534001F3D95 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 470415DB1E5E1534001F3D95 /* main.m */; }; 4710A6D91F34F21700745267 /* CrashReporterSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9391D7F3DF200AFB96E /* CrashReporterSupport.framework */; }; + 471A03EC1F72E35B000A8904 /* SecDbKeychainItemV7.m in Sources */ = {isa = PBXBuildFile; fileRef = 470ACEF31F58C3A600D1D5BD /* SecDbKeychainItemV7.m */; }; + 471A03F21F72E35C000A8904 /* SecDbKeychainItemV7.m in Sources */ = {isa = PBXBuildFile; fileRef = 470ACEF31F58C3A600D1D5BD /* SecDbKeychainItemV7.m */; }; + 472339671FD7155E00CB6A72 /* libprequelite.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 472339611FD7155C00CB6A72 /* libprequelite.dylib */; }; + 472339691FD7156800CB6A72 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 472339681FD7156700CB6A72 /* CoreCDP.framework */; }; 4723C9C21F152EB50082882F /* SFObjCType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4723C9C01F152EB10082882F /* SFObjCType.h */; }; 4723C9C31F152EB60082882F /* SFObjCType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4723C9C01F152EB10082882F /* SFObjCType.h */; }; - 4723C9C41F152EBB0082882F /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; - 4723C9C51F152EBC0082882F /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; 4723C9C61F152EC00082882F /* SFSQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = 4723C9BD1F152EB10082882F /* SFSQLite.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4723C9C71F152EC10082882F /* SFSQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = 4723C9BD1F152EB10082882F /* SFSQLite.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4723C9C81F152ECA0082882F /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; - 4723C9C91F152ECA0082882F /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; 4723C9CA1F152ECE0082882F /* SFSQLiteStatement.h in Headers */ = {isa = PBXBuildFile; fileRef = 4723C9C11F152EB10082882F /* SFSQLiteStatement.h */; }; 4723C9CB1F152ECF0082882F /* SFSQLiteStatement.h in Headers */ = {isa = PBXBuildFile; fileRef = 4723C9C11F152EB10082882F /* SFSQLiteStatement.h */; }; 4723C9CC1F152ED30082882F /* SFSQLiteStatement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BF1F152EB10082882F /* SFSQLiteStatement.m */; }; 4723C9CD1F152ED40082882F /* SFSQLiteStatement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BF1F152EB10082882F /* SFSQLiteStatement.m */; }; 4723C9D41F1531A30082882F /* CKKSLoggerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9D11F1531970082882F /* CKKSLoggerTests.m */; }; - 4723C9DC1F1540CE0082882F /* SFAnalyticsLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 4723C9DA1F1540CE0082882F /* SFAnalyticsLogger.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4723C9DD1F1540CE0082882F /* SFAnalyticsLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 4723C9DA1F1540CE0082882F /* SFAnalyticsLogger.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4723C9E01F1540CE0082882F /* SFAnalyticsLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalyticsLogger.m */; }; - 4723C9E11F1540CE0082882F /* SFAnalyticsLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalyticsLogger.m */; }; + 4727FBBA1F9918590003AE36 /* KeychainCryptoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4727FBB91F9918590003AE36 /* KeychainCryptoTests.m */; }; + 4727FBC51F991C470003AE36 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBC41F991C460003AE36 /* Foundation.framework */; }; + 4727FBC61F991DE90003AE36 /* libsecdRegressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EDB11D80D58400B0A59C /* libsecdRegressions.a */; }; + 4727FBC71F991E3A0003AE36 /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; + 4727FBC81F991E460003AE36 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; + 4727FBC91F991E5A0003AE36 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + 4727FBCB1F991F510003AE36 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBCA1F991F510003AE36 /* Security.framework */; }; + 4727FBCD1F991F660003AE36 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBCC1F991F660003AE36 /* libsqlite3.dylib */; }; + 4727FBCE1F991F820003AE36 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBCF1F991F820003AE36 /* SecurityFoundation.framework */; }; + 4727FBD11F991F990003AE36 /* libMobileGestalt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBD01F991F990003AE36 /* libMobileGestalt.dylib */; }; + 4727FBD31F9920290003AE36 /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBD21F9920290003AE36 /* CloudKit.framework */; }; + 4727FBD51F9920510003AE36 /* ProtocolBuffer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBD41F9920510003AE36 /* ProtocolBuffer.framework */; }; + 4727FBD61F9920960003AE36 /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; + 4727FBD71F99209C0003AE36 /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; + 4727FBD91F9920BC0003AE36 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBD81F9920BB0003AE36 /* SystemConfiguration.framework */; }; + 4727FBDB1F9920CC0003AE36 /* WirelessDiagnostics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBDA1F9920CB0003AE36 /* WirelessDiagnostics.framework */; }; + 4727FBDD1F9920F20003AE36 /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBDC1F9920F10003AE36 /* libaks_acl.a */; }; + 4727FBDF1F99211D0003AE36 /* libaks.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBDE1F99211D0003AE36 /* libaks.a */; }; + 4727FBE11F9921300003AE36 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE01F99212F0003AE36 /* IOKit.framework */; }; + 4727FBE31F9921660003AE36 /* MobileKeyBag.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE21F9921660003AE36 /* MobileKeyBag.framework */; }; + 4727FBE51F99217B0003AE36 /* SharedWebCredentials.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE41F99217A0003AE36 /* SharedWebCredentials.framework */; }; + 4727FBE71F99218A0003AE36 /* ApplePushService.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE61F9921890003AE36 /* ApplePushService.framework */; }; + 4727FBE91F9921D10003AE36 /* libACM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE81F9921D00003AE36 /* libACM.a */; }; + 4727FBEA1F9922190003AE36 /* libregressionBase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCBFD1D8C648C00070CB0 /* libregressionBase.a */; }; + 4727FBEB1F99227F0003AE36 /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; + 4727FBEC1F99235B0003AE36 /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; + 4727FBED1F99249A0003AE36 /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; + 4727FBEE1F9924DA0003AE36 /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; + 4727FBEF1F9924FB0003AE36 /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; + 473337791FDAFBCC00E19F30 /* SFKeychainControlManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 473337771FDAFBCC00E19F30 /* SFKeychainControlManager.h */; }; + 4733377A1FDAFBCC00E19F30 /* SFKeychainControlManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 473337771FDAFBCC00E19F30 /* SFKeychainControlManager.h */; }; + 4733377B1FDAFBCC00E19F30 /* SFKeychainControlManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 473337781FDAFBCC00E19F30 /* SFKeychainControlManager.m */; }; + 4733377C1FDAFBCC00E19F30 /* SFKeychainControlManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 473337781FDAFBCC00E19F30 /* SFKeychainControlManager.m */; }; + 473337841FDB29C400E19F30 /* KeychainCheck.m in Sources */ = {isa = PBXBuildFile; fileRef = 473337831FDB29A200E19F30 /* KeychainCheck.m */; }; 474B5FC61E662E48007546F8 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; 474B5FC71E662E67007546F8 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 474B5FBF1E662E21007546F8 /* SecurityFoundation.framework */; }; 474B5FC81E662E79007546F8 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; - 475F37201EE8F23900248FB5 /* SFAnalyticsLogging.plist in Resources */ = {isa = PBXBuildFile; fileRef = 475F371F1EE8F23900248FB5 /* SFAnalyticsLogging.plist */; }; - 475F37211EE8F23900248FB5 /* SFAnalyticsLogging.plist in Resources */ = {isa = PBXBuildFile; fileRef = 475F371F1EE8F23900248FB5 /* SFAnalyticsLogging.plist */; }; + 475F37201EE8F23900248FB5 /* SFAnalytics.plist in Resources */ = {isa = PBXBuildFile; fileRef = 475F371F1EE8F23900248FB5 /* SFAnalytics.plist */; }; + 475F37211EE8F23900248FB5 /* SFAnalytics.plist in Resources */ = {isa = PBXBuildFile; fileRef = 475F371F1EE8F23900248FB5 /* SFAnalytics.plist */; }; 476541651F339F6300413F65 /* SecdWatchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = 476541631F339F6300413F65 /* SecdWatchdog.h */; }; 476541701F33B59300413F65 /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; 476541711F33B59500413F65 /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; @@ -700,41 +847,89 @@ 47702B291E5F463400B29577 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; 47702B371E5F495C00B29577 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 47702B351E5F495C00B29577 /* main.m */; }; 47702B391E5F4B2200B29577 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; - 4771ECCC1F17CD0E00840998 /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; 4771ECCD1F17CD0E00840998 /* SFSQLiteStatement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BF1F152EB10082882F /* SFSQLiteStatement.m */; }; - 4771ECCE1F17CD2100840998 /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; - 4771ECD91F17CE5100840998 /* SFAnalyticsLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalyticsLogger.m */; }; - 479108B71EE879F9008CEFA0 /* CKKSAnalyticsLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 479108B51EE879F9008CEFA0 /* CKKSAnalyticsLogger.h */; }; - 479108B81EE879F9008CEFA0 /* CKKSAnalyticsLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 479108B51EE879F9008CEFA0 /* CKKSAnalyticsLogger.h */; }; - 479108B91EE879F9008CEFA0 /* CKKSAnalyticsLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 479108B61EE879F9008CEFA0 /* CKKSAnalyticsLogger.m */; }; - 479108BA1EE879F9008CEFA0 /* CKKSAnalyticsLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 479108B61EE879F9008CEFA0 /* CKKSAnalyticsLogger.m */; }; + 477A1F5220320E4A00ACD81D /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 477A1F4C20320E4900ACD81D /* Accounts.framework */; }; + 477A1F5320320E5100ACD81D /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; }; + 477A1FE4203763A500ACD81D /* KeychainAPITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 477A1FE1203763A500ACD81D /* KeychainAPITests.m */; }; + 477A1FE5203763A500ACD81D /* KeychainAPITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 477A1FE1203763A500ACD81D /* KeychainAPITests.m */; }; + 477A1FED2037A0E000ACD81D /* KeychainXCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 477A1FEC2037A0E000ACD81D /* KeychainXCTest.m */; }; + 477A1FEE2037A0E000ACD81D /* KeychainXCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 477A1FEC2037A0E000ACD81D /* KeychainXCTest.m */; }; + 478D42761FD72A8100CAB645 /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; + 478D42771FD72A8100CAB645 /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; + 478D42781FD72A8100CAB645 /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; + 478D42791FD72A8100CAB645 /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; + 478D427A1FD72A8100CAB645 /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; + 478D427B1FD72A8100CAB645 /* KeychainCryptoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4727FBB91F9918590003AE36 /* KeychainCryptoTests.m */; }; + 478D427C1FD72A8100CAB645 /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; + 478D427E1FD72A8100CAB645 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 472339681FD7156700CB6A72 /* CoreCDP.framework */; }; + 478D427F1FD72A8100CAB645 /* libprequelite.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 472339611FD7155C00CB6A72 /* libprequelite.dylib */; }; + 478D42801FD72A8100CAB645 /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47D1838B1FB3827700CFCD89 /* OCMock.framework */; }; + 478D42811FD72A8100CAB645 /* libregressionBase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCBFD1D8C648C00070CB0 /* libregressionBase.a */; }; + 478D42821FD72A8100CAB645 /* libACM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE81F9921D00003AE36 /* libACM.a */; }; + 478D42831FD72A8100CAB645 /* ApplePushService.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE61F9921890003AE36 /* ApplePushService.framework */; }; + 478D42841FD72A8100CAB645 /* SharedWebCredentials.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE41F99217A0003AE36 /* SharedWebCredentials.framework */; }; + 478D42851FD72A8100CAB645 /* MobileKeyBag.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE21F9921660003AE36 /* MobileKeyBag.framework */; }; + 478D42861FD72A8100CAB645 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE01F99212F0003AE36 /* IOKit.framework */; }; + 478D42871FD72A8100CAB645 /* libaks.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBDE1F99211D0003AE36 /* libaks.a */; }; + 478D42881FD72A8100CAB645 /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBDC1F9920F10003AE36 /* libaks_acl.a */; }; + 478D42891FD72A8100CAB645 /* WirelessDiagnostics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBDA1F9920CB0003AE36 /* WirelessDiagnostics.framework */; }; + 478D428A1FD72A8100CAB645 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBD81F9920BB0003AE36 /* SystemConfiguration.framework */; }; + 478D428B1FD72A8100CAB645 /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; + 478D428C1FD72A8100CAB645 /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; + 478D428D1FD72A8100CAB645 /* ProtocolBuffer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBD41F9920510003AE36 /* ProtocolBuffer.framework */; }; + 478D428E1FD72A8100CAB645 /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBD21F9920290003AE36 /* CloudKit.framework */; }; + 478D42901FD72A8100CAB645 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBCF1F991F820003AE36 /* SecurityFoundation.framework */; }; + 478D42911FD72A8100CAB645 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBCC1F991F660003AE36 /* libsqlite3.dylib */; }; + 478D42921FD72A8100CAB645 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBCA1F991F510003AE36 /* Security.framework */; }; + 478D42931FD72A8100CAB645 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + 478D42941FD72A8100CAB645 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; + 478D42951FD72A8100CAB645 /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; + 478D42961FD72A8100CAB645 /* libsecdRegressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EDB11D80D58400B0A59C /* libsecdRegressions.a */; }; + 478D42971FD72A8100CAB645 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBC41F991C460003AE36 /* Foundation.framework */; }; + 478D429E1FD72C4800CAB645 /* CrashReporterSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9391D7F3DF200AFB96E /* CrashReporterSupport.framework */; }; + 478D429F1FD72C8400CAB645 /* AppleSystemInfo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3F1D78F2FF002223DE /* AppleSystemInfo.framework */; }; + 479108B71EE879F9008CEFA0 /* CKKSAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 479108B51EE879F9008CEFA0 /* CKKSAnalytics.h */; }; + 479108B81EE879F9008CEFA0 /* CKKSAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 479108B51EE879F9008CEFA0 /* CKKSAnalytics.h */; }; + 479108B91EE879F9008CEFA0 /* CKKSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 479108B61EE879F9008CEFA0 /* CKKSAnalytics.m */; }; + 479108BA1EE879F9008CEFA0 /* CKKSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 479108B61EE879F9008CEFA0 /* CKKSAnalytics.m */; }; + 47922D211FAA76000008F7E0 /* SecDbKeychainSerializedMetadata.proto in Resources */ = {isa = PBXBuildFile; fileRef = 47922D201FAA75FF0008F7E0 /* SecDbKeychainSerializedMetadata.proto */; }; + 47922D2D1FAA77970008F7E0 /* SecDbKeychainSerializedSecretData.proto in Resources */ = {isa = PBXBuildFile; fileRef = 47922D2C1FAA77970008F7E0 /* SecDbKeychainSerializedSecretData.proto */; }; + 47922D421FAA7C240008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D371FAA7C040008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h */; }; + 47922D431FAA7C260008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D371FAA7C040008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h */; }; + 47922D441FAA7C2C0008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D361FAA7C030008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m */; }; + 47922D451FAA7C2E0008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D361FAA7C030008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m */; }; + 47922D461FAA7C340008F7E0 /* SecDbKeychainSerializedMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D3B1FAA7C100008F7E0 /* SecDbKeychainSerializedMetadata.h */; }; + 47922D471FAA7C350008F7E0 /* SecDbKeychainSerializedMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D3B1FAA7C100008F7E0 /* SecDbKeychainSerializedMetadata.h */; }; + 47922D481FAA7C3C0008F7E0 /* SecDbKeychainSerializedMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D3A1FAA7C0F0008F7E0 /* SecDbKeychainSerializedMetadata.m */; }; + 47922D491FAA7C3D0008F7E0 /* SecDbKeychainSerializedMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D3A1FAA7C0F0008F7E0 /* SecDbKeychainSerializedMetadata.m */; }; + 47922D4A1FAA7C430008F7E0 /* SecDbKeychainSerializedSecretData.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D3E1FAA7C1A0008F7E0 /* SecDbKeychainSerializedSecretData.h */; }; + 47922D4B1FAA7C440008F7E0 /* SecDbKeychainSerializedSecretData.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D3E1FAA7C1A0008F7E0 /* SecDbKeychainSerializedSecretData.h */; }; + 47922D4C1FAA7C4A0008F7E0 /* SecDbKeychainSerializedSecretData.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D3F1FAA7C1B0008F7E0 /* SecDbKeychainSerializedSecretData.m */; }; + 47922D4D1FAA7C4B0008F7E0 /* SecDbKeychainSerializedSecretData.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D3F1FAA7C1B0008F7E0 /* SecDbKeychainSerializedSecretData.m */; }; + 47922D4F1FAA7D5C0008F7E0 /* SecDbKeychainSerializedItemV7.proto in Resources */ = {isa = PBXBuildFile; fileRef = 47922D4E1FAA7D5C0008F7E0 /* SecDbKeychainSerializedItemV7.proto */; }; + 47922D541FAA7E060008F7E0 /* SecDbKeychainSerializedItemV7.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D501FAA7DF60008F7E0 /* SecDbKeychainSerializedItemV7.h */; }; + 47922D551FAA7E070008F7E0 /* SecDbKeychainSerializedItemV7.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D501FAA7DF60008F7E0 /* SecDbKeychainSerializedItemV7.h */; }; + 47922D561FAA7E0D0008F7E0 /* SecDbKeychainSerializedItemV7.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D511FAA7DF70008F7E0 /* SecDbKeychainSerializedItemV7.m */; }; + 47922D571FAA7E0E0008F7E0 /* SecDbKeychainSerializedItemV7.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D511FAA7DF70008F7E0 /* SecDbKeychainSerializedItemV7.m */; }; 479DA1721EBBA8D10065C98F /* CKKSManifest.m in Sources */ = {isa = PBXBuildFile; fileRef = 47CEED1F1E60DE900044EAB4 /* CKKSManifest.m */; }; 479DA1781EBBA8D30065C98F /* CKKSManifest.m in Sources */ = {isa = PBXBuildFile; fileRef = 47CEED1F1E60DE900044EAB4 /* CKKSManifest.m */; }; + 47A05B161FDB5D9E00D0816E /* SFKeychainControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 47A05B101FDB5A8B00D0816E /* SFKeychainControl.h */; }; + 47A05B171FDB5D9F00D0816E /* SFKeychainControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 47A05B101FDB5A8B00D0816E /* SFKeychainControl.h */; }; + 47A05B181FDB5DBC00D0816E /* SFKeychainControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 47A05B101FDB5A8B00D0816E /* SFKeychainControl.h */; }; 47A0ABA81E6F7B24001B388C /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 474B5FBF1E662E21007546F8 /* SecurityFoundation.framework */; }; - 47B011971F17D7810030B49F /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; - 47B011981F17D78D0030B49F /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; 47B011991F17D78D0030B49F /* SFSQLiteStatement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BF1F152EB10082882F /* SFSQLiteStatement.m */; }; - 47B0119A1F17D7E80030B49F /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; - 47B0119B1F17D7F10030B49F /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; - 47B0119C1F17D7F10030B49F /* SFSQLiteStatement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BF1F152EB10082882F /* SFSQLiteStatement.m */; }; - 47B011A71F17D8980030B49F /* SFAnalyticsLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalyticsLogger.m */; }; - 47B011AD1F17D8A00030B49F /* SFAnalyticsLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalyticsLogger.m */; }; 47B90C901F350966006500BC /* CrashReporterSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9391D7F3DF200AFB96E /* CrashReporterSupport.framework */; }; - 47B90C951F3509C1006500BC /* CrashReporterSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9391D7F3DF200AFB96E /* CrashReporterSupport.framework */; }; 47C51B871EEA657D0032D9E5 /* SecurityUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 47C51B861EEA657D0032D9E5 /* SecurityUnitTests.m */; }; 47C51B891EEA657D0032D9E5 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; 47D13F631E8447FB0063B6E2 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; + 47D183911FB3827800CFCD89 /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47D1838B1FB3827700CFCD89 /* OCMock.framework */; }; + 47DE88DA1FA7B07400DD3254 /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; 47E553741EDF674700749715 /* CKKSManifestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 476E918D1E7343B200B4E4D3 /* CKKSManifestTests.m */; }; 483E798F1DC87605005C0008 /* secd-67-prefixedKeyIDs.m in Sources */ = {isa = PBXBuildFile; fileRef = 483E79891DC875F2005C0008 /* secd-67-prefixedKeyIDs.m */; }; 48776C811DA5BC0E00CC09B9 /* SOSAccountRecovery.m in Sources */ = {isa = PBXBuildFile; fileRef = 48776C801DA5BC0E00CC09B9 /* SOSAccountRecovery.m */; }; - 48C2F9391E4BCFDA0093D70C /* accountCirclesViewsPrint.m in Sources */ = {isa = PBXBuildFile; fileRef = 48C2F9321E4BCFC30093D70C /* accountCirclesViewsPrint.m */; }; - 48C2F93A1E4BCFDC0093D70C /* accountCirclesViewsPrint.m in Sources */ = {isa = PBXBuildFile; fileRef = 48C2F9321E4BCFC30093D70C /* accountCirclesViewsPrint.m */; }; - 48C2F93B1E4BCFE80093D70C /* accountCirclesViewsPrint.m in Sources */ = {isa = PBXBuildFile; fileRef = 48C2F9321E4BCFC30093D70C /* accountCirclesViewsPrint.m */; }; - 48C2F93C1E4BD00F0093D70C /* accountCirclesViewsPrint.h in Headers */ = {isa = PBXBuildFile; fileRef = 48C2F9331E4BCFC30093D70C /* accountCirclesViewsPrint.h */; }; 48CC589F1DA5FF2700EBD9DB /* secd-66-account-recovery.m in Sources */ = {isa = PBXBuildFile; fileRef = 48CC58971DA5FF0B00EBD9DB /* secd-66-account-recovery.m */; }; 48E617211DBEC6BA0098EAAD /* SOSBackupInformation.m in Sources */ = {isa = PBXBuildFile; fileRef = 48E6171A1DBEC40D0098EAAD /* SOSBackupInformation.m */; }; 48E617221DBEC6C60098EAAD /* SOSBackupInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 48E6171B1DBEC40D0098EAAD /* SOSBackupInformation.h */; }; - 4AF7000015AFB73800B9D400 /* SecOTRIdentityPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFF615AFB73800B9D400 /* SecOTRIdentityPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4AF7000115AFB73800B9D400 /* SecOTRMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFF715AFB73800B9D400 /* SecOTRMath.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4AF7000315AFB73800B9D400 /* SecOTRPacketData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFF915AFB73800B9D400 /* SecOTRPacketData.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4AF7000415AFB73800B9D400 /* SecOTRPackets.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFFA15AFB73800B9D400 /* SecOTRPackets.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -743,7 +938,7 @@ 4AF7FFFD15AFB73800B9D400 /* SecOTR.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFF315AFB73800B9D400 /* SecOTR.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4AF7FFFE15AFB73800B9D400 /* SecOTRDHKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFF415AFB73800B9D400 /* SecOTRDHKey.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4AF7FFFF15AFB73800B9D400 /* SecOTRErrors.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFF515AFB73800B9D400 /* SecOTRErrors.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4C0B906E0ACCBD240077CD03 /* SecFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C0B906C0ACCBD240077CD03 /* SecFramework.h */; }; + 4C0B906E0ACCBD240077CD03 /* SecFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C0B906C0ACCBD240077CD03 /* SecFramework.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4C0CC642174C580200CC799A /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; }; 4C12828D0BB4957D00985BB0 /* SecTrustSettingsPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C12828C0BB4957D00985BB0 /* SecTrustSettingsPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4C198F220ACDB4BF00AAB142 /* Certificate.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4C198F1D0ACDB4BF00AAB142 /* Certificate.strings */; }; @@ -751,7 +946,7 @@ 4C1B442D0BB9CAF900461B82 /* SecTrustStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1B442C0BB9CAF900461B82 /* SecTrustStore.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4C2215220F3A612C00835155 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB740680A4749C800D641BB /* libsqlite3.dylib */; }; 4C2F81D50BF121D2003C4F77 /* SecRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C2F81D40BF121D2003C4F77 /* SecRandom.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4C32C1030A4976BF002891BD /* certextensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C28BCD60986EBCB0020C665 /* certextensions.h */; }; + 4C32C1030A4976BF002891BD /* certextensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C28BCD60986EBCB0020C665 /* certextensions.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4C32C1240A4976BF002891BD /* SecBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C696B3709BFA94F000CBC75 /* SecBase.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4C32C1250A4976BF002891BD /* SecCertificate.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C8FD03D099D5C91006867B6 /* SecCertificate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4C32C1260A4976BF002891BD /* SecTrust.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C8FD03E099D5C91006867B6 /* SecTrust.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -911,12 +1106,10 @@ 4CE5A66009C79E0600D27A3F /* ioSock.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CE5A65809C79E0600D27A3F /* ioSock.c */; }; 4CE5A66109C79E0600D27A3F /* sslAppUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE5A65A09C79E0600D27A3F /* sslAppUtils.cpp */; }; 4CE7EA791AEAF39C0067F5BD /* SecItemBackup.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CE7EA561AEAE8D60067F5BD /* SecItemBackup.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4CEF4CA80C5551FE00062475 /* SecCertificateInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CEF4CA70C5551FE00062475 /* SecCertificateInternal.h */; }; + 4CEF4CA80C5551FE00062475 /* SecCertificateInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CEF4CA70C5551FE00062475 /* SecCertificateInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; 4CF0484C0A5D988F00268236 /* SecItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CF0484A0A5D988F00268236 /* SecItem.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4CF048800A5F016300268236 /* SecItemPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CF0487F0A5F016300268236 /* SecItemPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4CF41D0C0BBB4022005F3248 /* SecCertificatePath.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CF41D0A0BBB4022005F3248 /* SecCertificatePath.h */; }; 4CF4C19D171E0EA600877419 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; }; - 4CFBF6100D5A951100969BBE /* SecPolicyInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CFBF5F10D5A92E100969BBE /* SecPolicyInternal.h */; }; 52222CD0167BDAEC00EDD09C /* SpringBoardServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52222CC0167BDAE100EDD09C /* SpringBoardServices.framework */; }; 522B280E1E64B4BF002B5638 /* secd-230-keybagtable.m in Sources */ = {isa = PBXBuildFile; fileRef = 522B28081E64B48E002B5638 /* secd-230-keybagtable.m */; }; 524492941AFD6D480043695A /* der_plist.h in Headers */ = {isa = PBXBuildFile; fileRef = 524492931AFD6D480043695A /* der_plist.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -955,18 +1148,30 @@ 5E8B53A51AA0B8A600345E7B /* libcoreauthd_test_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E8B53A41AA0B8A600345E7B /* libcoreauthd_test_client.a */; }; 5EAFA4D31EF1605A002DC188 /* LocalAuthentication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5EAFA4CD1EF16059002DC188 /* LocalAuthentication.framework */; }; 5EBE247D1B00CCAE0007DB0E /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 5EBE247C1B00CCAE0007DB0E /* main.c */; }; - 6C0B0C491E253832007F95E5 /* AwdMetadata-0x60-Keychain.bin in CopyFiles */ = {isa = PBXBuildFile; fileRef = 6C3446551E2534E800F9522B /* AwdMetadata-0x60-Keychain.bin */; }; 6C0B0C4B1E253848007F95E5 /* AwdMetadata-0x60-Keychain.bin in CopyFiles */ = {isa = PBXBuildFile; fileRef = 6C3446551E2534E800F9522B /* AwdMetadata-0x60-Keychain.bin */; }; + 6C1260FD1F7DA42D001B2EEC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + 6C13AE471F8E9F5F00F047E3 /* supd.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69517E1F758E1000F68F91 /* supd.m */; }; + 6C13AE481F8E9FC800F047E3 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; 6C1520D41DCCF71400C85C6D /* secd.8 in Install man8 page */ = {isa = PBXBuildFile; fileRef = 6C1520CD1DCCF57A00C85C6D /* secd.8 */; }; 6C1F93111DD5E41A00585608 /* libDiagnosticMessagesClient.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3C1D78F25C002223DE /* libDiagnosticMessagesClient.dylib */; }; 6C3446301E24F6BE00F9522B /* CKKSRateLimiterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C34462F1E24F6BE00F9522B /* CKKSRateLimiterTests.m */; }; 6C3446461E25346C00F9522B /* CKKSRateLimiter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CC185971E24E87D009657D8 /* CKKSRateLimiter.h */; }; 6C3446471E25346C00F9522B /* CKKSRateLimiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CC185981E24E87D009657D8 /* CKKSRateLimiter.m */; }; + 6C4605A51F882B9B001421B6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + 6C4605BC1F882DB6001421B6 /* SFAnalyticsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C1A29FC1F882788002312D8 /* SFAnalyticsTests.m */; }; + 6C4605BD1F882DC3001421B6 /* SupdTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C758CB01F8826100075BD78 /* SupdTests.m */; }; 6C588D7F1EAA14AA00D7E322 /* RateLimiterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C588D791EAA149F00D7E322 /* RateLimiterTests.m */; }; 6C588D801EAA20AB00D7E322 /* RateLimiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CC7F5B31E9F99EE0014AE63 /* RateLimiter.m */; }; 6C588D811EAA20AC00D7E322 /* RateLimiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CC7F5B31E9F99EE0014AE63 /* RateLimiter.m */; }; 6C5B36BA1E2F9B95008AD443 /* WirelessDiagnostics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C0B0C3D1E2537C6007F95E5 /* WirelessDiagnostics.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 6C5B36C01E2F9BEA008AD443 /* WirelessDiagnostics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C0B0C3D1E2537C6007F95E5 /* WirelessDiagnostics.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 6C73F48A2006B839003D5D63 /* SOSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C7BB0032006B4EE004D1B6B /* SOSAnalytics.m */; }; + 6C73F48B2006B83A003D5D63 /* SOSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C7BB0032006B4EE004D1B6B /* SOSAnalytics.m */; }; + 6C73F48C2006B83D003D5D63 /* SOSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C7BB0032006B4EE004D1B6B /* SOSAnalytics.m */; }; + 6C73F48D2006B83E003D5D63 /* SOSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C7BB0032006B4EE004D1B6B /* SOSAnalytics.m */; }; + 6C73F48F2006B910003D5D63 /* SOSAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C7BB0042006B4EF004D1B6B /* SOSAnalytics.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6C73F4902006B911003D5D63 /* SOSAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C7BB0042006B4EF004D1B6B /* SOSAnalytics.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6C7FD5DF1F87FA42002C2285 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; 6C869A751F50CAF400957298 /* SOSEnsureBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C860C7A1F4F63DB004100A1 /* SOSEnsureBackup.m */; }; 6C869A761F50CAF500957298 /* SOSEnsureBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C860C7A1F4F63DB004100A1 /* SOSEnsureBackup.m */; }; 6C869A791F54C37900957298 /* AWDKeychainSOSKeychainBackupFailed.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C869A771F54C2D700957298 /* AWDKeychainSOSKeychainBackupFailed.m */; }; @@ -978,8 +1183,9 @@ 6C8CC3B41E2F913D009025C5 /* AWDKeychainCKKSRateLimiterOverload.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C3446521E2534E800F9522B /* AWDKeychainCKKSRateLimiterOverload.m */; }; 6C8CC3B51E2F913D009025C5 /* AWDKeychainCKKSRateLimiterTopWriters.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C3446541E2534E800F9522B /* AWDKeychainCKKSRateLimiterTopWriters.m */; }; 6C8CC3B61E2F98C2009025C5 /* ProtocolBuffer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C0B0C441E2537CC007F95E5 /* ProtocolBuffer.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 6C8CE6C11FA248DA0032ADF0 /* SFAnalyticsActivityTracker+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C8CE6BB1FA248B50032ADF0 /* SFAnalyticsActivityTracker+Internal.h */; }; + 6C8CE6C21FA248DB0032ADF0 /* SFAnalyticsActivityTracker+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C8CE6BB1FA248B50032ADF0 /* SFAnalyticsActivityTracker+Internal.h */; }; 6C98083E1E788AEB00E70590 /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; - 6C9808491E788AEB00E70590 /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; 6C98084A1E788AEB00E70590 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; 6C98084C1E788AEB00E70590 /* libsecurityd_ios_NO_AKS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC222C771E034D1F00B09171 /* libsecurityd_ios_NO_AKS.a */; }; 6C98084D1E788AEB00E70590 /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; @@ -999,7 +1205,6 @@ 6C98085B1E788AEB00E70590 /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */; }; 6C98085C1E788AEB00E70590 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; }; 6C98087A1E788AFD00E70590 /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; - 6C9808851E788AFD00E70590 /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; 6C9808861E788AFD00E70590 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; 6C9808881E788AFD00E70590 /* libsecurityd_ios_NO_AKS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC222C771E034D1F00B09171 /* libsecurityd_ios_NO_AKS.a */; }; 6C9808891E788AFD00E70590 /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; @@ -1020,13 +1225,84 @@ 6C9808981E788AFD00E70590 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; }; 6C9808A51E788CD100E70590 /* CKKSCloudKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CCDF7911E3C2D69003F2555 /* CKKSCloudKitTests.m */; }; 6C9808A61E788CD200E70590 /* CKKSCloudKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CCDF7911E3C2D69003F2555 /* CKKSCloudKitTests.m */; }; + 6C9AA7A11F7C1D9000D08296 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C9AA7A01F7C1D9000D08296 /* main.m */; }; + 6C9AA7A51F7C6F7F00D08296 /* SecArgParse.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5BCC461E5380EA00649140 /* SecArgParse.c */; }; + 6CAA8CDD1F82EDEF007B6E03 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; + 6CAA8CEE1F83E417007B6E03 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; + 6CAA8CEF1F83E65D007B6E03 /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; + 6CAA8CF01F83E65E007B6E03 /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; + 6CAA8CF41F83E799007B6E03 /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; + 6CAA8CF61F83E79D007B6E03 /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; + 6CAA8CF71F83E79E007B6E03 /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; + 6CAA8CF81F83E7A9007B6E03 /* SFAnalyticsSQLiteStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */; }; + 6CAA8CF91F83E7AA007B6E03 /* SFAnalyticsSQLiteStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */; }; + 6CAA8CFA1F83E7AC007B6E03 /* SFAnalyticsSQLiteStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */; }; + 6CAA8CFC1F83E7EA007B6E03 /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; + 6CAA8CFD1F83E7EB007B6E03 /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; + 6CAA8CFE1F83E800007B6E03 /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; + 6CAA8CFF1F83E800007B6E03 /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; + 6CAA8D0D1F83EC57007B6E03 /* SFSQLiteStatement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BF1F152EB10082882F /* SFSQLiteStatement.m */; }; + 6CAA8D131F83ECD4007B6E03 /* SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalytics.m */; }; + 6CAA8D141F83ECD5007B6E03 /* SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalytics.m */; }; + 6CAA8D151F83ECD9007B6E03 /* SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalytics.m */; }; + 6CAA8D271F843002007B6E03 /* supd.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69517E1F758E1000F68F91 /* supd.m */; }; + 6CAA8D351F84306C007B6E03 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C6951801F758E1000F68F91 /* main.m */; }; + 6CAA8D371F843196007B6E03 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; + 6CAA8D3A1F8431A7007B6E03 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + 6CAA8D3B1F8431AE007B6E03 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D40B6A881E2B5F9900CD6EE5 /* Foundation.framework */; }; 6CAB39C71E521BEA00566A79 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; 6CB5F47B1E402E6700DBF3F0 /* KeychainEntitledTestRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CB5F47A1E402E5700DBF3F0 /* KeychainEntitledTestRunner.m */; }; + 6CB96BAC1F966D6500E11457 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C6951801F758E1000F68F91 /* main.m */; }; + 6CB96BB21F966DA400E11457 /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; + 6CB96BB31F966DA400E11457 /* SFSQLiteStatement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BF1F152EB10082882F /* SFSQLiteStatement.m */; }; + 6CB96BB61F966E4300E11457 /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; + 6CBF65391FA147E500A68667 /* SFAnalyticsActivityTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CBF65371FA147E500A68667 /* SFAnalyticsActivityTracker.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6CBF653A1FA147E500A68667 /* SFAnalyticsActivityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CBF65381FA147E500A68667 /* SFAnalyticsActivityTracker.m */; }; + 6CBF65401FA1480C00A68667 /* SFAnalyticsActivityTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CBF65371FA147E500A68667 /* SFAnalyticsActivityTracker.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6CBF65411FA1481100A68667 /* SFAnalyticsActivityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CBF65381FA147E500A68667 /* SFAnalyticsActivityTracker.m */; }; + 6CBF65421FA2255800A68667 /* SFAnalyticsActivityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CBF65381FA147E500A68667 /* SFAnalyticsActivityTracker.m */; }; + 6CBF65431FA2257100A68667 /* SFAnalyticsActivityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CBF65381FA147E500A68667 /* SFAnalyticsActivityTracker.m */; }; + 6CBF65441FA2257200A68667 /* SFAnalyticsActivityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CBF65381FA147E500A68667 /* SFAnalyticsActivityTracker.m */; }; + 6CBF65451FA2257500A68667 /* SFAnalyticsActivityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CBF65381FA147E500A68667 /* SFAnalyticsActivityTracker.m */; }; 6CC1859E1E24E8EB009657D8 /* CKKSRateLimiter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CC185971E24E87D009657D8 /* CKKSRateLimiter.h */; }; 6CC1859F1E24E8EB009657D8 /* CKKSRateLimiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CC185981E24E87D009657D8 /* CKKSRateLimiter.m */; }; + 6CC952481FB4CB2C0051A823 /* SFAnalytics+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CC952421FB4C5CA0051A823 /* SFAnalytics+Internal.h */; }; + 6CC952491FB4CB2D0051A823 /* SFAnalytics+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CC952421FB4C5CA0051A823 /* SFAnalytics+Internal.h */; }; 6CCDF78C1E3C26BC003F2555 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6CCDF78B1E3C26BC003F2555 /* XCTest.framework */; }; 6CCDF78D1E3C26C2003F2555 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D40B6A881E2B5F9900CD6EE5 /* Foundation.framework */; }; + 6CDB5FF51FA78D1A00410924 /* SFAnalyticsMultiSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */; }; + 6CDB5FF61FA78D1B00410924 /* SFAnalyticsMultiSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */; }; + 6CDB5FF71FA78D2100410924 /* SFAnalyticsMultiSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */; }; + 6CDB5FF81FA78D2300410924 /* SFAnalyticsMultiSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */; }; + 6CDB5FF91FA78D2400410924 /* SFAnalyticsMultiSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */; }; + 6CDB5FFA1FA78D2500410924 /* SFAnalyticsMultiSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */; }; + 6CDB5FFB1FA78D2C00410924 /* SFAnalyticsMultiSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CDB5FF41FA78CB500410924 /* SFAnalyticsMultiSampler.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6CDB5FFC1FA78D2D00410924 /* SFAnalyticsMultiSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CDB5FF41FA78CB500410924 /* SFAnalyticsMultiSampler.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6CDB600F1FA92D2B00410924 /* securityuploadd.8 in Copy Manpage */ = {isa = PBXBuildFile; fileRef = 6C5B10211F9164F5009B091E /* securityuploadd.8 */; }; + 6CDB60111FA9386200410924 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; + 6CDB601A1FA93A1800410924 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 6CB96BB41F966E0C00E11457 /* libsqlite3.tbd */; }; + 6CDB601B1FA93A2000410924 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 6CFDC4561F907E1D00646DBB /* libprequelite.tbd */; }; + 6CDF8DEF1F96495600140B54 /* SFAnalyticsSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */; }; + 6CDF8DF01F96495700140B54 /* SFAnalyticsSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */; }; + 6CDF8DF11F96498300140B54 /* SFAnalyticsSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */; }; + 6CDF8DF21F9649AB00140B54 /* SFAnalyticsSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */; }; + 6CDF8DF31F9649C000140B54 /* SFAnalyticsSQLiteStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */; }; + 6CDF8DF41F9649C000140B54 /* SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalytics.m */; }; 6CE22D701E49206600974785 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6CE22D6F1E49206600974785 /* UIKit.framework */; }; + 6CE3654B1FA100D00012F6AB /* SFAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 4723C9DA1F1540CE0082882F /* SFAnalytics.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6CE3654C1FA100D10012F6AB /* SFAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 4723C9DA1F1540CE0082882F /* SFAnalytics.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6CE3654D1FA100E50012F6AB /* SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalytics.m */; }; + 6CE3654E1FA100E50012F6AB /* SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalytics.m */; }; + 6CE3654F1FA100F10012F6AB /* SFAnalyticsDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C69518F1F75A8C100F68F91 /* SFAnalyticsDefines.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6CE365501FA100F20012F6AB /* SFAnalyticsDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C69518F1F75A8C100F68F91 /* SFAnalyticsDefines.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6CE365511FA100FE0012F6AB /* SFAnalyticsSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CDF8DE51F95562B00140B54 /* SFAnalyticsSampler.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6CE365521FA100FF0012F6AB /* SFAnalyticsSampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CDF8DE51F95562B00140B54 /* SFAnalyticsSampler.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6CE365531FA101080012F6AB /* SFAnalyticsSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */; }; + 6CE365541FA101090012F6AB /* SFAnalyticsSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */; }; + 6CE365551FA101730012F6AB /* SFAnalyticsSQLiteStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C69518E1F75A7DC00F68F91 /* SFAnalyticsSQLiteStore.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6CE365561FA101740012F6AB /* SFAnalyticsSQLiteStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C69518E1F75A7DC00F68F91 /* SFAnalyticsSQLiteStore.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6CE365571FA1017D0012F6AB /* SFAnalyticsSQLiteStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */; }; + 6CE365581FA1017E0012F6AB /* SFAnalyticsSQLiteStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */; }; 6CF4A0B81E45488B00ECD7B5 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4A0B71E45488B00ECD7B5 /* AppDelegate.m */; }; 6CF4A0BB1E45488B00ECD7B5 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4A0BA1E45488B00ECD7B5 /* main.m */; }; 6CF4A0BE1E45488B00ECD7B5 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CF4A0BD1E45488B00ECD7B5 /* ViewController.m */; }; @@ -1038,6 +1314,7 @@ 6CF4A0ED1E4549F300ECD7B5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6CF4A0EB1E4549F300ECD7B5 /* Main.storyboard */; }; 6CF4A0EF1E4549F300ECD7B5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6CF4A0EE1E4549F300ECD7B5 /* Assets.xcassets */; }; 6CF4A0F21E4549F300ECD7B5 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6CF4A0F01E4549F300ECD7B5 /* LaunchScreen.storyboard */; }; + 6CFDC4551F907D2600646DBB /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; 7200D76F177B9999009BB396 /* ManagedConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72C3EC2D1705F24E0040C87C /* ManagedConfiguration.framework */; }; 724340BA1ED3FEC800F8F566 /* SecSMIME.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17870D1D778FA900B50D50 /* SecSMIME.h */; settings = {ATTRIBUTES = (Private, ); }; }; 7281E0871DFD01800021E1B7 /* SOSAccountGetSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 7281E0861DFD015A0021E1B7 /* SOSAccountGetSet.m */; }; @@ -1047,15 +1324,8 @@ 7281E0901DFD0E0A0021E1B7 /* CKDKVSProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A5F4C71C0CFF3200F3BEBB /* CKDKVSProxy.m */; }; 7281E0911DFD0E510021E1B7 /* CKDSimulatedStore.m in Sources */ = {isa = PBXBuildFile; fileRef = E7FE40C41DC804E400F0F5B6 /* CKDSimulatedStore.m */; }; 7281E0971DFD0FD00021E1B7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; - 728B56A216D59979008FA3AB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; - 72C3EC2E1705F24E0040C87C /* ManagedConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72C3EC2D1705F24E0040C87C /* ManagedConfiguration.framework */; }; - 72CD2BBE16D59AE30064EEE1 /* OTAServiceApp.m in Sources */ = {isa = PBXBuildFile; fileRef = 72CD2BBB16D59AE30064EEE1 /* OTAServiceApp.m */; }; - 72CD2BBF16D59AE30064EEE1 /* OTAServicemain.m in Sources */ = {isa = PBXBuildFile; fileRef = 72CD2BBD16D59AE30064EEE1 /* OTAServicemain.m */; }; - 72CD2BCD16D59AF30064EEE1 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; - 72CD2BCE16D59B010064EEE1 /* MobileAsset.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7273402816CAFB3C0096622A /* MobileAsset.framework */; }; 72CDF5131EC679A4002D233B /* sec_action.h in Headers */ = {isa = PBXBuildFile; fileRef = 7221843F1EC6782A004C7BED /* sec_action.h */; }; 72CDF5191EC679A8002D233B /* sec_action.c in Sources */ = {isa = PBXBuildFile; fileRef = 7221843E1EC6782A004C7BED /* sec_action.c */; }; - 72DF9EFE178360230054641E /* libMobileGestalt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E7D690911652E06A0079537A /* libMobileGestalt.dylib */; }; 78F92F11195128D70023B54B /* SecECKeyPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 78F92F10195128D70023B54B /* SecECKeyPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; 7901791812D51F7200CA4D44 /* SecCmsBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 7901790E12D51F7200CA4D44 /* SecCmsBase.h */; settings = {ATTRIBUTES = (Private, ); }; }; 7901791912D51F7200CA4D44 /* SecCmsContentInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7901790F12D51F7200CA4D44 /* SecCmsContentInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -1115,6 +1385,13 @@ BE22FBD11EE2084100893431 /* Config.m in Sources */ = {isa = PBXBuildFile; fileRef = BE22FBD01EE2084100893431 /* Config.m */; }; BE22FC041EE3584400893431 /* mark.m in Sources */ = {isa = PBXBuildFile; fileRef = BE22FBFC1EE23D9100893431 /* mark.m */; }; BE25C41618B83491003320E0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + BE2AD2B31FDA07EF00739F96 /* OTBottledPeerRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = BE2AD2B11FDA07EF00739F96 /* OTBottledPeerRecord.h */; }; + BE2AD2BA1FDA080800739F96 /* OTBottledPeerRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = BE2AD2B21FDA07EF00739F96 /* OTBottledPeerRecord.m */; }; + BE2AD2BB1FDA080900739F96 /* OTBottledPeerRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = BE2AD2B21FDA07EF00739F96 /* OTBottledPeerRecord.m */; }; + BE3405AC1FD7258900933DAC /* OTBottle.proto in Sources */ = {isa = PBXBuildFile; fileRef = BE3405A11FD71CC800933DAC /* OTBottle.proto */; }; + BE3405AD1FD725A700933DAC /* OTBottleContents.proto in Sources */ = {isa = PBXBuildFile; fileRef = BE3405A51FD720C900933DAC /* OTBottleContents.proto */; }; + BE3405AE1FD725EC00933DAC /* OTBottle.proto in Sources */ = {isa = PBXBuildFile; fileRef = BE3405A11FD71CC800933DAC /* OTBottle.proto */; }; + BE3405AF1FD725F000933DAC /* OTBottleContents.proto in Sources */ = {isa = PBXBuildFile; fileRef = BE3405A51FD720C900933DAC /* OTBottleContents.proto */; }; BE405EE21DC2F10E00E227B1 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; }; BE405EE31DC2F11E00E227B1 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; }; BE442BAE18B7FDB800F24DAE /* libMobileGestalt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E7D690911652E06A0079537A /* libMobileGestalt.dylib */; }; @@ -1131,9 +1408,29 @@ BE6215BE1DB6E69100961E15 /* si-84-sectrust-allowlist.m in Sources */ = {isa = PBXBuildFile; fileRef = BE6215BD1DB6E69100961E15 /* si-84-sectrust-allowlist.m */; }; BE759DCB1917E38D00801E02 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE451314471B000DE34E /* CoreGraphics.framework */; }; BE8ABDD81DC2DD9100EC2D58 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; }; + BEA74211202525CD00EC7993 /* si-88-sectrust-valid-data in Resources */ = {isa = PBXBuildFile; fileRef = BEB9EA2E1FFF1AF600676593 /* si-88-sectrust-valid-data */; }; + BEA74217202525DC00EC7993 /* si-88-sectrust-valid-data in Resources */ = {isa = PBXBuildFile; fileRef = BEB9EA2E1FFF1AF600676593 /* si-88-sectrust-valid-data */; }; + BEB0B0D71FFC3D9A007E6A83 /* OTPrivateKey.proto in Sources */ = {isa = PBXBuildFile; fileRef = BEB0B0CE1FFC37E3007E6A83 /* OTPrivateKey.proto */; }; + BEB0B0D81FFC3DD3007E6A83 /* OTPrivateKey.proto in Sources */ = {isa = PBXBuildFile; fileRef = BEB0B0CE1FFC37E3007E6A83 /* OTPrivateKey.proto */; }; + BEB0B0DB1FFC45C2007E6A83 /* OTPrivateKey+SF.h in Headers */ = {isa = PBXBuildFile; fileRef = BEB0B0D91FFC45C2007E6A83 /* OTPrivateKey+SF.h */; }; + BEB0B0DD1FFC45D7007E6A83 /* OTPrivateKey+SF.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB0B0DA1FFC45C2007E6A83 /* OTPrivateKey+SF.m */; }; + BEB0B0DE1FFC45D8007E6A83 /* OTPrivateKey+SF.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB0B0DA1FFC45C2007E6A83 /* OTPrivateKey+SF.m */; }; + BEB9E9EC1FFF195C00676593 /* si-88-sectrust-valid.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB9E9E51FFF193D00676593 /* si-88-sectrust-valid.m */; }; + BEB9EA2F1FFF1AF700676593 /* si-88-sectrust-valid-data in Resources */ = {isa = PBXBuildFile; fileRef = BEB9EA2E1FFF1AF600676593 /* si-88-sectrust-valid-data */; }; + BEB9EA301FFF1B0800676593 /* si-88-sectrust-valid-data in Resources */ = {isa = PBXBuildFile; fileRef = BEB9EA2E1FFF1AF600676593 /* si-88-sectrust-valid-data */; }; BED208D81EDF950E00753952 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; BED208D91EDF950E00753952 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; BED208E81EDF974500753952 /* manifeststresstest.m in Sources */ = {isa = PBXBuildFile; fileRef = BED208E71EDF971600753952 /* manifeststresstest.m */; }; + BEE4B18C1FFD585800777D39 /* OTAuthenticatedCiphertext.proto in Sources */ = {isa = PBXBuildFile; fileRef = BEE4B1861FFD57D800777D39 /* OTAuthenticatedCiphertext.proto */; }; + BEE4B18D1FFD588000777D39 /* OTAuthenticatedCiphertext.proto in Sources */ = {isa = PBXBuildFile; fileRef = BEE4B1861FFD57D800777D39 /* OTAuthenticatedCiphertext.proto */; }; + BEE4B1921FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.h in Headers */ = {isa = PBXBuildFile; fileRef = BEE4B1901FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.h */; }; + BEE4B1931FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.h in Headers */ = {isa = PBXBuildFile; fileRef = BEE4B1901FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.h */; }; + BEE4B1941FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE4B1911FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.m */; }; + BEE4B1951FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE4B1911FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.m */; }; + BEE4B1981FFDAFE600777D39 /* SFPublicKey+SPKI.h in Headers */ = {isa = PBXBuildFile; fileRef = BEE4B1961FFDAFE600777D39 /* SFPublicKey+SPKI.h */; }; + BEE4B1991FFDAFE600777D39 /* SFPublicKey+SPKI.h in Headers */ = {isa = PBXBuildFile; fileRef = BEE4B1961FFDAFE600777D39 /* SFPublicKey+SPKI.h */; }; + BEE4B19A1FFDAFE600777D39 /* SFECPublicKey+SPKI.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE4B1971FFDAFE600777D39 /* SFECPublicKey+SPKI.m */; }; + BEE4B19B1FFDAFE600777D39 /* SFECPublicKey+SPKI.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE4B1971FFDAFE600777D39 /* SFECPublicKey+SPKI.m */; }; BEE523D91DACAA2500DD0AA3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789221D7799A600B50D50 /* libz.dylib */; }; BEE523DC1DACAA9200DD0AA3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789221D7799A600B50D50 /* libz.dylib */; }; BEEB47D91EA189F5004AA5C6 /* SecTrustStatusCodes.c in Sources */ = {isa = PBXBuildFile; fileRef = BEEB47D71EA189F5004AA5C6 /* SecTrustStatusCodes.c */; }; @@ -1204,7 +1501,6 @@ D4096E011ED5F0B5000AC459 /* si-60-cms.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DD81D8085FC00865A7C /* si-60-cms.c */; }; D4096E021ED5F207000AC459 /* si-64-ossl-cms.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DE71D8085FC00865A7C /* si-64-ossl-cms.c */; }; D4096E031ED5F21C000AC459 /* si-65-cms-cert-policy.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DE81D8085FC00865A7C /* si-65-cms-cert-policy.c */; }; - D40B6A821E2B5F5600CD6EE5 /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; D40B6A831E2B5F5B00CD6EE5 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; D40B6A8D1E2B63D900CD6EE5 /* libtrustd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4ADA3191E2B41670031CEA3 /* libtrustd.a */; }; D40B6A8E1E2B643500CD6EE5 /* libtrustd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4ADA3191E2B41670031CEA3 /* libtrustd.a */; }; @@ -1218,11 +1514,13 @@ D40B6A9B1E2B690E00CD6EE5 /* SecuritydXPC.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E9A1D8085FC00865A7C /* SecuritydXPC.c */; }; D40B6A9D1E2B6A2700CD6EE5 /* login.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E8271D7A4F0E00AFB96E /* login.framework */; }; D40B6A9E1E2B6A6F00CD6EE5 /* libtrustd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4ADA3191E2B41670031CEA3 /* libtrustd.a */; }; + D4119E78202BDF490048587B /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; + D4119E79202BDF580048587B /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; + D4119E882032A8FA0048587B /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47D1838B1FB3827700CFCD89 /* OCMock.framework */; }; D41257D01E9410A300781F23 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D40B6A881E2B5F9900CD6EE5 /* Foundation.framework */; }; D41257D91E9412B800781F23 /* trustd.c in Sources */ = {isa = PBXBuildFile; fileRef = D4BEECE61E93093A00F76D1A /* trustd.c */; }; D41257DA1E9412DC00781F23 /* libtrustd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4ADA3191E2B41670031CEA3 /* libtrustd.a */; }; D41257DB1E9412E700781F23 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; - D41257DC1E94130C00781F23 /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; D41257DE1E94132900781F23 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB740680A4749C800D641BB /* libsqlite3.dylib */; }; D41257DF1E94133600781F23 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF730310EF9CDE300E17471 /* CFNetwork.framework */; }; D41257E01E94136000781F23 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; }; @@ -1240,7 +1538,7 @@ D43B88721E72298500F86F19 /* MobileAsset.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7273402816CAFB3C0096622A /* MobileAsset.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; D43DBEFB1E99D1CA00C04AEA /* asynchttp.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBED51E99D17100C04AEA /* asynchttp.c */; }; D43DBEFC1E99D1CA00C04AEA /* nameconstraints.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBED71E99D17100C04AEA /* nameconstraints.c */; }; - D43DBEFD1E99D1CA00C04AEA /* OTATrustUtilities.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBED91E99D17100C04AEA /* OTATrustUtilities.c */; }; + D43DBEFD1E99D1CA00C04AEA /* OTATrustUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = D43DBED91E99D17100C04AEA /* OTATrustUtilities.m */; }; D43DBEFE1E99D1CA00C04AEA /* personalization.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEDB1E99D17100C04AEA /* personalization.c */; }; D43DBEFF1E99D1CA00C04AEA /* policytree.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEDD1E99D17100C04AEA /* policytree.c */; }; D43DBF001E99D1CA00C04AEA /* SecCAIssuerCache.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEDF1E99D17200C04AEA /* SecCAIssuerCache.c */; }; @@ -1254,13 +1552,41 @@ D43DBF081E99D1CA00C04AEA /* SecPolicyServer.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEEF1E99D17300C04AEA /* SecPolicyServer.c */; }; D43DBF091E99D1CA00C04AEA /* SecRevocationDb.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEF11E99D17300C04AEA /* SecRevocationDb.c */; }; D43DBF0A1E99D1CA00C04AEA /* SecRevocationServer.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEF31E99D17300C04AEA /* SecRevocationServer.c */; }; - D43DBF0B1E99D1CA00C04AEA /* SecTrustLoggingServer.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEF51E99D17300C04AEA /* SecTrustLoggingServer.c */; }; + D43DBF0B1E99D1CA00C04AEA /* SecTrustLoggingServer.m in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEF51E99D17300C04AEA /* SecTrustLoggingServer.m */; }; D43DBF0C1E99D1CA00C04AEA /* SecTrustServer.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEF71E99D17300C04AEA /* SecTrustServer.c */; }; D43DBF0D1E99D1CA00C04AEA /* SecTrustStoreServer.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEF91E99D17300C04AEA /* SecTrustStoreServer.c */; }; D447C4101D3094740082FC1D /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; D450686A1E948D2200FA7675 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; + D453C3901FEC66AE00DE349B /* trust_update.m in Sources */ = {isa = PBXBuildFile; fileRef = D453C38A1FEC669300DE349B /* trust_update.m */; }; + D4574AA0203E618B006D9B82 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + D4574AA1203E6893006D9B82 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + D4574AA2203E68C8006D9B82 /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A94C6D4203CC2590066E391 /* AuthKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + D4574AA3203E68E0006D9B82 /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A94C6D4203CC2590066E391 /* AuthKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; D45917E41DC13E6700752D25 /* SecCertificateRequest.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E3E1D8085FC00865A7C /* SecCertificateRequest.c */; }; D459A1781E9FFE60009ED74B /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */; }; + D46246971F9AE2E400D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246911F9AE2E400D63882 /* libDER.a */; }; + D46246A31F9AE59E00D63882 /* oids.h in Headers */ = {isa = PBXBuildFile; fileRef = D46246A21F9AE49E00D63882 /* oids.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D46246A61F9AE61000D63882 /* oids.c in Sources */ = {isa = PBXBuildFile; fileRef = D462469C1F9AE45900D63882 /* oids.c */; }; + D46246A71F9AE62000D63882 /* oids.c in Sources */ = {isa = PBXBuildFile; fileRef = D462469C1F9AE45900D63882 /* oids.c */; }; + D46246A81F9AE64000D63882 /* oids.h in Headers */ = {isa = PBXBuildFile; fileRef = D46246A21F9AE49E00D63882 /* oids.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D46246AA1F9AE6CA00D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246A91F9AE6C900D63882 /* libDER.a */; }; + D46246B51F9AE74000D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246AF1F9AE73F00D63882 /* libDER.a */; }; + D46246B61F9AE75100D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246AF1F9AE73F00D63882 /* libDER.a */; }; + D46246B71F9AE76500D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246AF1F9AE73F00D63882 /* libDER.a */; }; + D46246B81F9AE77900D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246AF1F9AE73F00D63882 /* libDER.a */; }; + D46246B91F9AE79000D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246AF1F9AE73F00D63882 /* libDER.a */; }; + D46246BA1F9AE7A000D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246AF1F9AE73F00D63882 /* libDER.a */; }; + D46246BB1F9AE7B300D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246AF1F9AE73F00D63882 /* libDER.a */; }; + D46246BC1F9AE82B00D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246AF1F9AE73F00D63882 /* libDER.a */; }; + D46246BD1F9AE83600D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246AF1F9AE73F00D63882 /* libDER.a */; }; + D46246BE1F9AE86400D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246AF1F9AE73F00D63882 /* libDER.a */; }; + D46246C91F9AEA5300D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246C31F9AEA5200D63882 /* libDER.a */; }; + D46246D41F9AEAE300D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246CE1F9AEAE300D63882 /* libDER.a */; }; + D46246D91F9AED5D00D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246CE1F9AEAE300D63882 /* libDER.a */; }; + D479F6E21F980FAB00388D28 /* Trust.strings in Resources */ = {isa = PBXBuildFile; fileRef = D479F6DF1F980F8F00388D28 /* Trust.strings */; }; + D479F6E31F981FD600388D28 /* OID.strings in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4C198F1F0ACDB4BF00AAB142 /* OID.strings */; }; + D479F6E41F981FD600388D28 /* Certificate.strings in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4C198F1D0ACDB4BF00AAB142 /* Certificate.strings */; }; + D479F6E51F981FD600388D28 /* Trust.strings in CopyFiles */ = {isa = PBXBuildFile; fileRef = D479F6DF1F980F8F00388D28 /* Trust.strings */; }; D47CA65D1EB036450038E2BB /* libMobileGestalt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D47CA65C1EB036450038E2BB /* libMobileGestalt.dylib */; }; D47E69401E92F75D002C8CF6 /* si-61-pkcs12.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DD91D8085FC00865A7C /* si-61-pkcs12.c */; }; D47F514C1C3B812500A7CEFE /* SecCFAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = D47F514B1C3B812500A7CEFE /* SecCFAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -1268,7 +1594,7 @@ D487B9881DFA2902000410A1 /* SecInternalReleasePriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BCC771D8C68CF00070CB0 /* SecInternalReleasePriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; D487FBB81DB8357300D4BB0B /* si-29-sectrust-sha1-deprecation.m in Sources */ = {isa = PBXBuildFile; fileRef = D487FBB71DB8357300D4BB0B /* si-29-sectrust-sha1-deprecation.m */; }; D487FBBA1DB835B500D4BB0B /* si-29-sectrust-sha1-deprecation.h in Headers */ = {isa = PBXBuildFile; fileRef = D487FBB91DB835B500D4BB0B /* si-29-sectrust-sha1-deprecation.h */; }; - D48E4E241E42F0620011B4BA /* si-62-csr.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DDA1D8085FC00865A7C /* si-62-csr.c */; }; + D48E4E241E42F0620011B4BA /* si-62-csr.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DDA1D8085FC00865A7C /* si-62-csr.m */; }; D4AA64361E95D92600D317ED /* com.apple.trustd.sb in Copy Sandbox */ = {isa = PBXBuildFile; fileRef = D41257EB1E941CF200781F23 /* com.apple.trustd.sb */; }; D4AA643C1E95D93100D317ED /* com.apple.trustd.plist in Copy LaunchDaemon Files */ = {isa = PBXBuildFile; fileRef = D41257EA1E941CF200781F23 /* com.apple.trustd.plist */; }; D4AA643D1E95D93900D317ED /* com.apple.trustd.agent.plist in Copy LaunchAgent */ = {isa = PBXBuildFile; fileRef = D41257E91E941CF200781F23 /* com.apple.trustd.agent.plist */; }; @@ -1285,6 +1611,14 @@ D4ADA3311E2B43450031CEA3 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF730310EF9CDE300E17471 /* CFNetwork.framework */; }; D4B858671D370D9A003B2D95 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4B858661D370D9A003B2D95 /* MobileCoreServices.framework */; }; D4BEECE81E93094500F76D1A /* trustd.c in Sources */ = {isa = PBXBuildFile; fileRef = D4BEECE61E93093A00F76D1A /* trustd.c */; }; + D4C263CE1F95300F001317EA /* SecErrorMessages.strings in Resources */ = {isa = PBXBuildFile; fileRef = D4C263CC1F952F6C001317EA /* SecErrorMessages.strings */; }; + D4C263CF1F953019001317EA /* SecDebugErrorMessages.strings in Resources */ = {isa = PBXBuildFile; fileRef = D4C263C81F952E64001317EA /* SecDebugErrorMessages.strings */; }; + D4C6C5C81FB2AD5E007EA57E /* si-87-sectrust-name-constraints in Resources */ = {isa = PBXBuildFile; fileRef = D4C6C5C71FB2AD3F007EA57E /* si-87-sectrust-name-constraints */; }; + D4C6C5C91FB2AD6D007EA57E /* si-87-sectrust-name-constraints in Resources */ = {isa = PBXBuildFile; fileRef = D4C6C5C71FB2AD3F007EA57E /* si-87-sectrust-name-constraints */; }; + D4C6C5CA1FB2AD7A007EA57E /* si-87-sectrust-name-constraints in Resources */ = {isa = PBXBuildFile; fileRef = D4C6C5C71FB2AD3F007EA57E /* si-87-sectrust-name-constraints */; }; + D4C6C5CD1FB3B423007EA57E /* libarchive.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4C6C5CB1FB3B3CC007EA57E /* libarchive.tbd */; }; + D4C6C5CF1FB3B44D007EA57E /* libarchive.2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D4C6C5CE1FB3B44C007EA57E /* libarchive.2.dylib */; }; + D4C6C5D01FB3B45E007EA57E /* libarchive.2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D4C6C5CE1FB3B44C007EA57E /* libarchive.2.dylib */; }; D4C7CD661E71E92D00139817 /* MobileAsset.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7273402816CAFB3C0096622A /* MobileAsset.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; D4CFAA7E1E660BB3004746AA /* si-32-sectrust-pinning-required.m in Sources */ = {isa = PBXBuildFile; fileRef = D4CFAA7D1E660BB3004746AA /* si-32-sectrust-pinning-required.m */; }; D4D718351E04A721000AE7A6 /* spbkdf-01-hmac-sha256.c in Sources */ = {isa = PBXBuildFile; fileRef = D4D718341E04A721000AE7A6 /* spbkdf-01-hmac-sha256.c */; }; @@ -1292,14 +1626,19 @@ D4D886C01CEB9F7200DC7583 /* ssl-policy-certs in Resources */ = {isa = PBXBuildFile; fileRef = D4D886BE1CEB9F3B00DC7583 /* ssl-policy-certs */; }; D4D886E91CEBDD2A00DC7583 /* nist-certs in Resources */ = {isa = PBXBuildFile; fileRef = D4D886E81CEBDD2A00DC7583 /* nist-certs */; }; D4D886EA1CEBDE0800DC7583 /* nist-certs in Resources */ = {isa = PBXBuildFile; fileRef = D4D886E81CEBDD2A00DC7583 /* nist-certs */; }; - D4D96ED51F478BAF004B5F01 /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; D4EC94FB1CEA482D0083E753 /* si-20-sectrust-policies-data in Resources */ = {isa = PBXBuildFile; fileRef = D4EC94FA1CEA482D0083E753 /* si-20-sectrust-policies-data */; }; D4EC94FE1CEA48760083E753 /* si-20-sectrust-policies-data in Resources */ = {isa = PBXBuildFile; fileRef = D4EC94FA1CEA482D0083E753 /* si-20-sectrust-policies-data */; }; D4FBBD621DD661A7004408F7 /* CMSEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D4FBBD601DD66196004408F7 /* CMSEncoder.h */; settings = {ATTRIBUTES = (Private, ); }; }; D4FBBD631DD661AD004408F7 /* CMSDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D4FBBD611DD66196004408F7 /* CMSDecoder.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DA19DAEF1FCFA420008E82EE /* CKKSControl.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9C95B31F79CFD1000D19E5 /* CKKSControl.m */; }; + DA19DAF01FCFA425008E82EE /* CKKSControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */; }; DA30D6851DF8CA4100EC6B43 /* KeychainSyncAccountUpdater.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30D6841DF8CA4100EC6B43 /* KeychainSyncAccountUpdater.m */; }; - DAD3BD011F9830BB00DF29BA /* CKKSControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */; }; - DAD3BD021F9830BC00DF29BA /* CKKSControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */; }; + DA6AA1651FE88AFB004565B0 /* CKKSControlServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6AA15E1FE88AF9004565B0 /* CKKSControlServer.m */; }; + DA6AA1661FE88AFB004565B0 /* CKKSControlServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6AA15E1FE88AF9004565B0 /* CKKSControlServer.m */; }; + DA6AA1671FE88AFB004565B0 /* CKKSControlServer.h in Headers */ = {isa = PBXBuildFile; fileRef = DA6AA1641FE88AFA004565B0 /* CKKSControlServer.h */; }; + DA6AA1681FE88AFB004565B0 /* CKKSControlServer.h in Headers */ = {isa = PBXBuildFile; fileRef = DA6AA1641FE88AFA004565B0 /* CKKSControlServer.h */; }; + DAB27AE11FA29EE300DEBBDE /* SOSControlServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DAB27AE01FA29EB800DEBBDE /* SOSControlServer.m */; }; + DAEE055C1FAD3FC700DF27F3 /* AutoreleaseTest.c in Sources */ = {isa = PBXBuildFile; fileRef = DAEE05551FAD3FC500DF27F3 /* AutoreleaseTest.c */; }; DC0067C11D87879D005AF8DB /* ucspServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC6A82811D87734600418608 /* ucspServer.cpp */; }; DC0067C21D8787A4005AF8DB /* ucspNotifyReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC6A82831D87734600418608 /* ucspNotifyReceiver.cpp */; }; DC0067D11D8788B7005AF8DB /* ucspClientC.c in Sources */ = {isa = PBXBuildFile; fileRef = DC6A82801D87734600418608 /* ucspClientC.c */; }; @@ -1421,8 +1760,6 @@ DC0BC6611D8B755200070CB0 /* ckutilities.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC6131D8B755200070CB0 /* ckutilities.c */; }; DC0BC6621D8B755200070CB0 /* ckutilities.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6141D8B755200070CB0 /* ckutilities.h */; }; DC0BC6631D8B755200070CB0 /* Crypt.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6151D8B755200070CB0 /* Crypt.h */; }; - DC0BC6641D8B755200070CB0 /* CryptKitSA.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6161D8B755200070CB0 /* CryptKitSA.h */; }; - DC0BC6651D8B755200070CB0 /* CryptKit.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6171D8B755200070CB0 /* CryptKit.h */; }; DC0BC6661D8B755200070CB0 /* CryptKitAsn1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC6181D8B755200070CB0 /* CryptKitAsn1.cpp */; }; DC0BC6671D8B755200070CB0 /* CryptKitAsn1.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6191D8B755200070CB0 /* CryptKitAsn1.h */; }; DC0BC6681D8B755200070CB0 /* CryptKitDER.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC61A1D8B755200070CB0 /* CryptKitDER.cpp */; }; @@ -1873,6 +2210,8 @@ DC0BCDB51D8C6A5B00070CB0 /* not_on_this_platorm.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCDB41D8C6A5B00070CB0 /* not_on_this_platorm.c */; }; DC1002AF1D8E18870025549C /* libsecurity_codesigning.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD0677F1D8CDF19007602F1 /* libsecurity_codesigning.a */; }; DC1002D81D8E1A670025549C /* SecTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 107226D10D91DB32003CF14F /* SecTask.h */; }; + DC124DCD20059BA900BE8DAC /* OctagonControlServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DC124DC220059B8700BE8DAC /* OctagonControlServer.m */; }; + DC124DCE20059BA900BE8DAC /* OctagonControlServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DC124DC220059B8700BE8DAC /* OctagonControlServer.m */; }; DC14478A1F5764C600236DB4 /* CKKSResultOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1447881F5764C600236DB4 /* CKKSResultOperation.h */; }; DC14478B1F5764C600236DB4 /* CKKSResultOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1447881F5764C600236DB4 /* CKKSResultOperation.h */; }; DC14478C1F5764C600236DB4 /* CKKSResultOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1447891F5764C600236DB4 /* CKKSResultOperation.m */; }; @@ -1908,7 +2247,6 @@ DC17853C1D778A3100B50D50 /* mds_schema.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17853A1D778A3100B50D50 /* mds_schema.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC17853D1D778A3100B50D50 /* mds.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17853B1D778A3100B50D50 /* mds.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC1785401D778A4E00B50D50 /* SecureDownload.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17853F1D778A4E00B50D50 /* SecureDownload.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC1785431D778A7400B50D50 /* oids.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785421D778A7400B50D50 /* oids.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC17854E1D778ACD00B50D50 /* SecAccess.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785451D778ACD00B50D50 /* SecAccess.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC17854F1D778ACD00B50D50 /* SecACL.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785461D778ACD00B50D50 /* SecACL.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC1785501D778ACD00B50D50 /* SecCertificateOIDs.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785471D778ACD00B50D50 /* SecCertificateOIDs.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1941,7 +2279,6 @@ DC1785871D778B8000B50D50 /* CodeSigning.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785811D778B7F00B50D50 /* CodeSigning.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC1785881D778B8000B50D50 /* CSCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785821D778B7F00B50D50 /* CSCommon.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC1785891D778B8000B50D50 /* SecCode.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785831D778B7F00B50D50 /* SecCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC17858A1D778B8000B50D50 /* SecCodeHost.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785841D778B8000B50D50 /* SecCodeHost.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC17858B1D778B8000B50D50 /* SecRequirement.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785851D778B8000B50D50 /* SecRequirement.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC17858C1D778B8000B50D50 /* SecStaticCode.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785861D778B8000B50D50 /* SecStaticCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC1785901D778B9D00B50D50 /* CMSDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17858E1D778B9D00B50D50 /* CMSDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1984,8 +2321,6 @@ DC17871D1D778FAA00B50D50 /* SecCmsSignerInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17870C1D778FA900B50D50 /* SecCmsSignerInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC17871E1D778FAA00B50D50 /* SecSMIME.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17870D1D778FA900B50D50 /* SecSMIME.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC17871F1D778FAA00B50D50 /* tsaSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17870E1D778FA900B50D50 /* tsaSupport.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC1787201D778FAA00B50D50 /* tsaSupportPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17870F1D778FA900B50D50 /* tsaSupportPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC1787211D778FAA00B50D50 /* tsaTemplates.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787101D778FA900B50D50 /* tsaTemplates.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC1787231D778FC900B50D50 /* mdspriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787221D778FC900B50D50 /* mdspriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC1787261D778FDE00B50D50 /* SecManifest.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787241D778FDE00B50D50 /* SecManifest.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC1787271D778FDE00B50D50 /* SecureDownloadInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787251D778FDE00B50D50 /* SecureDownloadInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -2005,7 +2340,6 @@ DC1787431D77906C00B50D50 /* cssmapplePriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787421D77906C00B50D50 /* cssmapplePriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC17874E1D7790A500B50D50 /* CSCommonPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787441D7790A500B50D50 /* CSCommonPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC17874F1D7790A500B50D50 /* SecAssessment.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787451D7790A500B50D50 /* SecAssessment.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC1787501D7790A500B50D50 /* SecCodeHostLib.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787461D7790A500B50D50 /* SecCodeHostLib.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC1787511D7790A500B50D50 /* SecCodePriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787471D7790A500B50D50 /* SecCodePriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC1787521D7790A500B50D50 /* SecCodeSigner.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787481D7790A500B50D50 /* SecCodeSigner.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC1787551D7790A500B50D50 /* SecRequirementPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17874B1D7790A500B50D50 /* SecRequirementPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -2102,7 +2436,7 @@ DC222C3B1E034D1F00B09171 /* SOSChangeTracker.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D4F1D8085F200865A7C /* SOSChangeTracker.c */; }; DC222C3D1E034D1F00B09171 /* SOSEngine.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D561D8085F200865A7C /* SOSEngine.c */; }; DC222C401E034D1F00B09171 /* SecDbItem.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C8E1D8085D800865A7C /* SecDbItem.c */; }; - DC222C411E034D1F00B09171 /* SecDbKeychainItem.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C901D8085D800865A7C /* SecDbKeychainItem.c */; }; + DC222C411E034D1F00B09171 /* SecDbKeychainItem.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C901D8085D800865A7C /* SecDbKeychainItem.m */; }; DC222C421E034D1F00B09171 /* SecDbQuery.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C921D8085D800865A7C /* SecDbQuery.c */; }; DC222C431E034D1F00B09171 /* SecItemBackupServer.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9C1D8085D800865A7C /* SecItemBackupServer.c */; }; DC222C441E034D1F00B09171 /* SecItemDataSource.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C941D8085D800865A7C /* SecItemDataSource.c */; }; @@ -2145,6 +2479,16 @@ DC2353311ECA658B00D7C1BE /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; DC2353321ECA659000D7C1BE /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; DC2353331ECA659000D7C1BE /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; + DC2670F21F3E6EC500816EED /* debugging.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BCC531D8C68CF00070CB0 /* debugging.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DC2670F51F3E711400816EED /* SOSAccountCloudParameters.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D1A1D8085F200865A7C /* SOSAccountCloudParameters.m */; }; + DC2670F61F3E714000816EED /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; + DC2670F71F3E721800816EED /* SOSAccountTrustClassic.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C48991B1E0F384700C6CF70 /* SOSAccountTrustClassic.m */; }; + DC2670F81F3E723B00816EED /* SOSAccountDer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D1C1D8085F200865A7C /* SOSAccountDer.m */; }; + DC2670FB1F3E72C000816EED /* SOSCircleDer.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D351D8085F200865A7C /* SOSCircleDer.c */; }; + DC2670FC1F3E72C400816EED /* SOSCircleDer.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D341D8085F200865A7C /* SOSCircleDer.h */; }; + DC2671001F3E766E00816EED /* SecOTRSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFFB15AFB73800B9D400 /* SecOTRSession.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DC2671071F3E8A0900816EED /* SecECKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CD3BA601106FF4D00BE8B75 /* SecECKey.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DC26710E1F3E932D00816EED /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; DC2C5F4B1F0D935200FEBDA7 /* CKKSControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF7A89F1F04502300CABE89 /* CKKSControlProtocol.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC2C5F511F0D935300FEBDA7 /* CKKSControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF7A89F1F04502300CABE89 /* CKKSControlProtocol.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC2C5F5D1F0EB97E00FEBDA7 /* CKKSNotifier.h in Headers */ = {isa = PBXBuildFile; fileRef = DC2C5F5A1F0EB97E00FEBDA7 /* CKKSNotifier.h */; }; @@ -2153,9 +2497,9 @@ DC2C5F611F0EB97E00FEBDA7 /* CKKSNotifier.m in Sources */ = {isa = PBXBuildFile; fileRef = DC2C5F5B1F0EB97E00FEBDA7 /* CKKSNotifier.m */; }; DC2D438F1F0EEC2A0005D382 /* MockCloudKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3502E61E0214C800BC0587 /* MockCloudKit.m */; }; DC2D43951F0EEC300005D382 /* MockCloudKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3502E61E0214C800BC0587 /* MockCloudKit.m */; }; + DC337B1F1EA04E2100B3A1F0 /* SecBase64.h in Headers */ = {isa = PBXBuildFile; fileRef = 18351B8F14CB65870097860E /* SecBase64.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC3502B81E0208BE00BC0587 /* CKKSTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3502B71E0208BE00BC0587 /* CKKSTests.m */; }; DC3502C51E020D5100BC0587 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; - DC3502C81E020D5B00BC0587 /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; DC3502CA1E020DC100BC0587 /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */; }; DC3502CF1E020E2900BC0587 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DC3502D21E02113900BC0587 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; @@ -2186,14 +2530,7 @@ DC3A81D71D99D58A000C7419 /* libcoretls_cfhelpers.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC3A81D41D99D567000C7419 /* libcoretls_cfhelpers.dylib */; }; DC3A81EC1D99F568000C7419 /* libcoretls.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CFC029B1D41650700E6283B /* libcoretls.dylib */; }; DC3C72E21D8374D600F6A832 /* SecureTransportPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1786FD1D778F5000B50D50 /* SecureTransportPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC3C72E31D8376D700F6A832 /* SOSTypes.h in Copy SecurityObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D8F1D8085F200865A7C /* SOSTypes.h */; }; - DC3C72E41D8376DE00F6A832 /* SOSBackupSliceKeyBag.h in Copy SecurityObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D2A1D8085F200865A7C /* SOSBackupSliceKeyBag.h */; }; - DC3C72E51D8376E600F6A832 /* SOSCloudCircle.h in Copy SecurityObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D8A1D8085F200865A7C /* SOSCloudCircle.h */; }; - DC3C72E61D8376EC00F6A832 /* SOSCloudCircleInternal.h in Copy SecurityObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D8B1D8085F200865A7C /* SOSCloudCircleInternal.h */; }; - DC3C72E71D8376F300F6A832 /* SOSPeerInfo.h in Copy SecurityObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D641D8085F200865A7C /* SOSPeerInfo.h */; }; - DC3C72E81D8376F900F6A832 /* SOSViews.h in Copy SecurityObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D4B1D8085F200865A7C /* SOSViews.h */; }; DC3C72E91D83776B00F6A832 /* SOSBackupSliceKeyBag.h in Copy SecureObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D2A1D8085F200865A7C /* SOSBackupSliceKeyBag.h */; }; - DC3C72EA1D83777100F6A832 /* SOSPeerInfoV2.h in Copy SecureObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D681D8085F200865A7C /* SOSPeerInfoV2.h */; }; DC3C72EB1D83777600F6A832 /* SOSCloudCircle.h in Copy SecureObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D8A1D8085F200865A7C /* SOSCloudCircle.h */; }; DC3C72EC1D83777B00F6A832 /* SOSPeerInfo.h in Copy SecureObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D641D8085F200865A7C /* SOSPeerInfo.h */; }; DC3C72ED1D83778100F6A832 /* SOSViews.h in Copy SecureObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D4B1D8085F200865A7C /* SOSViews.h */; }; @@ -2212,7 +2549,6 @@ DC3C7AB61D838C2D00F6A832 /* SecAsn1Types.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785151D77895A00B50D50 /* SecAsn1Types.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC3C7AB71D838C5C00F6A832 /* secasn1t.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787681D77911D00B50D50 /* secasn1t.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC3C7AB81D838C6F00F6A832 /* oidsalg.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785111D77895A00B50D50 /* oidsalg.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC3C7AB91D838C8D00F6A832 /* oids.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785421D778A7400B50D50 /* oids.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC3C7ABA1D838C9F00F6A832 /* sslTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1786FB1D778F3C00B50D50 /* sslTypes.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC3C7C901D83957F00F6A832 /* NSFileHandle+Formatting.m in Sources */ = {isa = PBXBuildFile; fileRef = E78A9AD91D34959200006B5B /* NSFileHandle+Formatting.m */; }; DC3D748C1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC3D748A1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.h */; }; @@ -2249,7 +2585,7 @@ DC52E7CC1D80BCDF00B0A59C /* SecDbQuery.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C921D8085D800865A7C /* SecDbQuery.c */; }; DC52E7CD1D80BCE700B0A59C /* SecItemDataSource.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C941D8085D800865A7C /* SecItemDataSource.c */; }; DC52E7CF1D80BCFD00B0A59C /* SOSEngine.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D561D8085F200865A7C /* SOSEngine.c */; }; - DC52E7D31D80BD1800B0A59C /* SecDbKeychainItem.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C901D8085D800865A7C /* SecDbKeychainItem.c */; }; + DC52E7D31D80BD1800B0A59C /* SecDbKeychainItem.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C901D8085D800865A7C /* SecDbKeychainItem.m */; }; DC52E7D41D80BD1D00B0A59C /* iCloudTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB31D8085D800865A7C /* iCloudTrace.c */; }; DC52E7D61D80BD2800B0A59C /* SecuritydXPC.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E9A1D8085FC00865A7C /* SecuritydXPC.c */; }; DC52E7D71D80BD2D00B0A59C /* SecItemServer.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9A1D8085D800865A7C /* SecItemServer.c */; }; @@ -2384,7 +2720,7 @@ DC52ECBD1D80D22600B0A59C /* si-42-identity.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DD11D8085FC00865A7C /* si-42-identity.c */; }; DC52ECBE1D80D22600B0A59C /* si-43-persistent.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DD21D8085FC00865A7C /* si-43-persistent.c */; }; DC52ECC31D80D22600B0A59C /* si-50-secrandom.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DD71D8085FC00865A7C /* si-50-secrandom.c */; }; - DC52ECC71D80D22600B0A59C /* si-63-scep.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DDE1D8085FC00865A7C /* si-63-scep.c */; }; + DC52ECC71D80D22600B0A59C /* si-63-scep.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DDE1D8085FC00865A7C /* si-63-scep.m */; }; DC52ECCD1D80D22600B0A59C /* si-69-keydesc.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DF91D8085FC00865A7C /* si-69-keydesc.c */; }; DC52ECD01D80D22600B0A59C /* si-72-syncableitems.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DFC1D8085FC00865A7C /* si-72-syncableitems.c */; }; DC52ECD11D80D22600B0A59C /* si-73-secpasswordgenerate.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DFD1D8085FC00865A7C /* si-73-secpasswordgenerate.c */; }; @@ -2393,7 +2729,7 @@ DC52ECD51D80D22600B0A59C /* si-78-query-attrs.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E011D8085FC00865A7C /* si-78-query-attrs.c */; }; DC52ECD61D80D22600B0A59C /* si-80-empty-data.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E021D8085FC00865A7C /* si-80-empty-data.c */; }; DC52ECD91D80D22600B0A59C /* si-82-token-ag.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E051D8085FC00865A7C /* si-82-token-ag.c */; }; - DC52ECDD1D80D22600B0A59C /* si-89-cms-hash-agility.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E0B1D8085FC00865A7C /* si-89-cms-hash-agility.c */; }; + DC52ECDD1D80D22600B0A59C /* si-89-cms-hash-agility.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E0B1D8085FC00865A7C /* si-89-cms-hash-agility.m */; }; DC52ECDE1D80D22600B0A59C /* si-90-emcs.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E0D1D8085FC00865A7C /* si-90-emcs.m */; }; DC52ECDF1D80D22600B0A59C /* si-95-cms-basic.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E0E1D8085FC00865A7C /* si-95-cms-basic.c */; }; DC52ECE11D80D2F000B0A59C /* otr-00-identity.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DA71D8085FC00865A7C /* otr-00-identity.c */; }; @@ -2518,24 +2854,6 @@ DC58C43E1D77BED0003C25A4 /* csparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC58C43B1D77BED0003C25A4 /* csparser.cpp */; }; DC59E9A41D91C6F0001BDDF5 /* libCMS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1002D71D8E19F20025549C /* libCMS.a */; }; DC59E9A71D91C7C7001BDDF5 /* libCMS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1002D71D8E19F20025549C /* libCMS.a */; }; - DC59E9FE1D91CA0A001BDDF5 /* DER_Keys.c in Sources */ = {isa = PBXBuildFile; fileRef = DC59E9ED1D91CA0A001BDDF5 /* DER_Keys.c */; }; - DC59EA011D91CA0A001BDDF5 /* DER_CertCrl.c in Sources */ = {isa = PBXBuildFile; fileRef = DC59E9F01D91CA0A001BDDF5 /* DER_CertCrl.c */; }; - DC59EA031D91CA0A001BDDF5 /* DER_Decode.c in Sources */ = {isa = PBXBuildFile; fileRef = DC59E9F21D91CA0A001BDDF5 /* DER_Decode.c */; }; - DC59EA051D91CA0A001BDDF5 /* DER_Encode.c in Sources */ = {isa = PBXBuildFile; fileRef = DC59E9F41D91CA0A001BDDF5 /* DER_Encode.c */; }; - DC59EA0A1D91CA0A001BDDF5 /* DER_Digest.c in Sources */ = {isa = PBXBuildFile; fileRef = DC59E9F91D91CA0A001BDDF5 /* DER_Digest.c */; }; - DC59EA0B1D91CA0A001BDDF5 /* oids.c in Sources */ = {isa = PBXBuildFile; fileRef = DC59E9FA1D91CA0A001BDDF5 /* oids.c */; }; - DC59EA771D91CC6D001BDDF5 /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; - DC59EA7B1D91CC9F001BDDF5 /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; - DC59EA7E1D91CCB2001BDDF5 /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; - DC59EA821D91CD24001BDDF5 /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; - DC59EA851D91CD35001BDDF5 /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; - DC59EA881D91CD7E001BDDF5 /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; - DC59EA8B1D91CD93001BDDF5 /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; - DC59EA8E1D91CDC1001BDDF5 /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; - DC59EA911D91CDCF001BDDF5 /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; - DC59EA941D91CDE0001BDDF5 /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; - DC59EA971D91CDFA001BDDF5 /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; - DC59EA9A1D91CE94001BDDF5 /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; DC5ABDCC1D832E4000CF422C /* srCdsaUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC5ABD781D832D5800CF422C /* srCdsaUtils.cpp */; }; DC5ABDCD1D832E4000CF422C /* createFVMaster.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5ABD7A1D832D5800CF422C /* createFVMaster.c */; }; DC5ABDCE1D832E4000CF422C /* mds_install.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC5ABD7D1D832D5800CF422C /* mds_install.cpp */; }; @@ -2905,11 +3223,16 @@ DC8834911D8A21AB00CE0ACA /* oidsalg.c in Sources */ = {isa = PBXBuildFile; fileRef = DC8834491D8A21AA00CE0ACA /* oidsalg.c */; }; DC8834931D8A21AB00CE0ACA /* oidsattr.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88344B1D8A21AA00CE0ACA /* oidsattr.c */; }; DC8834961D8A21AB00CE0ACA /* oidsocsp.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88344E1D8A21AA00CE0ACA /* oidsocsp.c */; }; + DC8EB58D1F70743100080CF2 /* SOSPeerInfoV2.h in Copy SecureObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D681D8085F200865A7C /* SOSPeerInfoV2.h */; }; DC9036B31D9DFED600B6C234 /* ss_types.defs in Headers */ = {isa = PBXBuildFile; fileRef = DC6A82771D87733C00418608 /* ss_types.defs */; settings = {ATTRIBUTES = (Public, ); }; }; DC9082C41EA0277600D0C1C5 /* CKKSZoneChangeFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9082C31EA0276000D0C1C5 /* CKKSZoneChangeFetcher.m */; }; DC9082C51EA0277700D0C1C5 /* CKKSZoneChangeFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9082C31EA0276000D0C1C5 /* CKKSZoneChangeFetcher.m */; }; DC9082C61EA027DB00D0C1C5 /* CKKSZoneChangeFetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9082C21EA0276000D0C1C5 /* CKKSZoneChangeFetcher.h */; }; DC9082C71EA027DC00D0C1C5 /* CKKSZoneChangeFetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9082C21EA0276000D0C1C5 /* CKKSZoneChangeFetcher.h */; }; + DC926F071F33F7C20012A315 /* SecCodeHost.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD067981D8CDF7E007602F1 /* SecCodeHost.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DC926F081F33F7D30012A315 /* SecCodeHost.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD067981D8CDF7E007602F1 /* SecCodeHost.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DC926F091F33FA8D0012A315 /* CKKSControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */; }; + DC926F0A1F33FA8E0012A315 /* CKKSControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */; }; DC94BCCA1F10448600E07CEB /* CloudKitCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = DC94BCC81F10448600E07CEB /* CloudKitCategories.h */; }; DC94BCCB1F10448600E07CEB /* CloudKitCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = DC94BCC81F10448600E07CEB /* CloudKitCategories.h */; }; DC94BCCC1F10448600E07CEB /* CloudKitCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = DC94BCC91F10448600E07CEB /* CloudKitCategories.m */; }; @@ -2926,14 +3249,10 @@ DC9C95971F748D0B000D19E5 /* CKKSServerValidationRecoveryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9C95951F748D0B000D19E5 /* CKKSServerValidationRecoveryTests.m */; }; DC9C95B41F79CFD1000D19E5 /* CKKSControl.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9C95B21F79CFD1000D19E5 /* CKKSControl.h */; }; DC9C95B51F79CFD1000D19E5 /* CKKSControl.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9C95B21F79CFD1000D19E5 /* CKKSControl.h */; }; - DC9C95B61F79CFD1000D19E5 /* CKKSControl.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9C95B31F79CFD1000D19E5 /* CKKSControl.m */; }; - DC9C95B71F79CFD1000D19E5 /* CKKSControl.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9C95B31F79CFD1000D19E5 /* CKKSControl.m */; }; DC9C95BD1F79DC5A000D19E5 /* CKKSControl.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9C95B21F79CFD1000D19E5 /* CKKSControl.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC9C95BE1F79DC5F000D19E5 /* CKKSControl.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9C95B21F79CFD1000D19E5 /* CKKSControl.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC9C95BF1F79DC88000D19E5 /* CKKSControl.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9C95B31F79CFD1000D19E5 /* CKKSControl.m */; }; DC9C95C01F79DC89000D19E5 /* CKKSControl.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9C95B31F79CFD1000D19E5 /* CKKSControl.m */; }; - DC9C95C11F79DD4B000D19E5 /* CKKSControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */; }; - DC9C95C21F79DD4D000D19E5 /* CKKSControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */; }; DC9FD3231F8587A500C8AAC8 /* CKKSSerializedKey.proto in Sources */ = {isa = PBXBuildFile; fileRef = DC4D49D81F857728007AF2B8 /* CKKSSerializedKey.proto */; }; DC9FD32C1F85990A00C8AAC8 /* CKKSPeer.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9FD3291F8598F300C8AAC8 /* CKKSPeer.m */; }; DC9FD32D1F85990B00C8AAC8 /* CKKSPeer.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9FD3291F8598F300C8AAC8 /* CKKSPeer.m */; }; @@ -2966,6 +3285,12 @@ DCB221581E8B08C9001598BC /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; DCB221591E8B08CA001598BC /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; DCB2215A1E8B08CB001598BC /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; + DCB332381F46804600178C30 /* SOSSysdiagnose.h in Headers */ = {isa = PBXBuildFile; fileRef = DCB332371F46804000178C30 /* SOSSysdiagnose.h */; }; + DCB3323B1F4681AE00178C30 /* SecOTR.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFF315AFB73800B9D400 /* SecOTR.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DCB3323C1F46833E00178C30 /* SecLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78E661D8085FC00865A7C /* SecLogging.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DCB332451F47856B00178C30 /* libSOSCommands.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EC341D80CFB200B0A59C /* libSOSCommands.a */; }; + DCB332591F478C3C00178C30 /* SOSUserKeygen.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D2B1D8085F200865A7C /* SOSUserKeygen.m */; }; + DCB3325A1F478C4100178C30 /* SOSUserKeygen.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D2C1D8085F200865A7C /* SOSUserKeygen.h */; }; DCB3407D1D8A24F70054D16E /* Authorization.c in Sources */ = {isa = PBXBuildFile; fileRef = DCB3406F1D8A24F70054D16E /* Authorization.c */; }; DCB340841D8A24F70054D16E /* Authorization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCB340761D8A24F70054D16E /* Authorization.cpp */; }; DCB340871D8A24F70054D16E /* trampolineClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCB340791D8A24F70054D16E /* trampolineClient.cpp */; }; @@ -3305,7 +3630,6 @@ DCB344A51D8A35270054D16E /* si-20-sectrust-provisioning.h in Headers */ = {isa = PBXBuildFile; fileRef = DCB344701D8A35270054D16E /* si-20-sectrust-provisioning.h */; }; DCB344A61D8A35270054D16E /* si-33-keychain-backup.c in Sources */ = {isa = PBXBuildFile; fileRef = DCB344711D8A35270054D16E /* si-33-keychain-backup.c */; }; DCB344A71D8A35270054D16E /* si-34-one-true-keychain.c in Sources */ = {isa = PBXBuildFile; fileRef = DCB344721D8A35270054D16E /* si-34-one-true-keychain.c */; }; - DCB502331FDA156B008F8E4F /* AutoreleaseTest.c in Sources */ = {isa = PBXBuildFile; fileRef = DCB5022C1FDA155D008F8E4F /* AutoreleaseTest.c */; }; DCB515DE1ED3CF86001F1152 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; DCB515DF1ED3CF95001F1152 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; DCB515E01ED3D111001F1152 /* client.c in Sources */ = {isa = PBXBuildFile; fileRef = 7908507F0CA87CF00083CC4D /* client.c */; }; @@ -3332,7 +3656,6 @@ DCBF2F7D1F90084D00ED0CA4 /* CKKSTLKSharingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBF2F7C1F90084D00ED0CA4 /* CKKSTLKSharingTests.m */; }; DCBF2F851F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCBF2F831F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.h */; }; DCBF2F861F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCBF2F831F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.h */; }; - DCBF2F871F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBF2F841F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.m */; }; DCBF2F881F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBF2F841F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.m */; }; DCC093791D80B02100F984E4 /* SecOnOSX.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78E671D8085FC00865A7C /* SecOnOSX.h */; }; DCC0937A1D80B07200F984E4 /* SecOTRSessionPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFFC15AFB73800B9D400 /* SecOTRSessionPriv.h */; }; @@ -3400,7 +3723,6 @@ DCC78EDD1D808AEC00865A7C /* SecDigest.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E481D8085FC00865A7C /* SecDigest.c */; }; DCC78EDE1D808AF100865A7C /* SecDH.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E461D8085FC00865A7C /* SecDH.c */; }; DCC78EDF1D808AF800865A7C /* SecCertificateRequest.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E3E1D8085FC00865A7C /* SecCertificateRequest.c */; }; - DCC78EE01D808B0000865A7C /* SecCertificatePath.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E3B1D8085FC00865A7C /* SecCertificatePath.c */; }; DCC78EE11D808B0900865A7C /* SecCertificate.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E381D8085FC00865A7C /* SecCertificate.c */; }; DCC78EE21D808B0E00865A7C /* SecCTKKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E441D8085FC00865A7C /* SecCTKKey.c */; }; DCC78EE31D808B1300865A7C /* SecCMS.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E421D8085FC00865A7C /* SecCMS.c */; }; @@ -3408,7 +3730,6 @@ DCC78EE51D808B2100865A7C /* SecBase64.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E351D8085FC00865A7C /* SecBase64.c */; }; DCC78EE61D808B2A00865A7C /* SecAccessControl.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E301D8085FC00865A7C /* SecAccessControl.c */; }; DCC78EE71D808B2F00865A7C /* secViewDisplay.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D9E1D8085F200865A7C /* secViewDisplay.c */; }; - DCC78EE81D808B3500865A7C /* secToolFileIO.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D931D8085F200865A7C /* secToolFileIO.c */; }; DCCA5E841E539EE7009EE93D /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCCA5E831E539EE7009EE93D /* AppKit.framework */; }; DCCBFA1E1DBA95CD001DD54D /* kc-20-item-delete-stress.c in Sources */ = {isa = PBXBuildFile; fileRef = DCCBFA1D1DBA95CD001DD54D /* kc-20-item-delete-stress.c */; }; DCCBFA391DBAE445001DD54D /* SecInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6416F00BB357D5001C83FD /* SecInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -3513,7 +3834,6 @@ DCD068641D8CDF7E007602F1 /* detachedrep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067E11D8CDF7E007602F1 /* detachedrep.cpp */; }; DCD068651D8CDF7E007602F1 /* piddiskrep.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD067E21D8CDF7E007602F1 /* piddiskrep.h */; }; DCD068661D8CDF7E007602F1 /* piddiskrep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067E31D8CDF7E007602F1 /* piddiskrep.cpp */; }; - DCD068691D8CDF7E007602F1 /* SecCodeHostLib.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD067E71D8CDF7E007602F1 /* SecCodeHostLib.h */; }; DCD0686E1D8CDF7E007602F1 /* csdatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD067EE1D8CDF7E007602F1 /* csdatabase.h */; }; DCD0686F1D8CDF7E007602F1 /* csdatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067EF1D8CDF7E007602F1 /* csdatabase.cpp */; }; DCD068701D8CDF7E007602F1 /* cserror.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD067F01D8CDF7E007602F1 /* cserror.h */; }; @@ -3631,7 +3951,6 @@ DCD06A781D8CE309007602F1 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DCD06A791D8CE30F007602F1 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E43C48C1B00D07000E5ECB2 /* CoreFoundation.framework */; }; DCD06A7A1D8CE318007602F1 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; - DCD06B3D1D8E0D7D007602F1 /* debugging.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06AB11D8E0D7D007602F1 /* debugging.h */; settings = {ATTRIBUTES = (Public, ); }; }; DCD06B3E1D8E0D7D007602F1 /* FileLockTransaction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD06AB21D8E0D7D007602F1 /* FileLockTransaction.cpp */; }; DCD06B3F1D8E0D7D007602F1 /* FileLockTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06AB31D8E0D7D007602F1 /* FileLockTransaction.h */; settings = {ATTRIBUTES = (Public, ); }; }; DCD06B401D8E0D7D007602F1 /* CSPDLTransaction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD06AB41D8E0D7D007602F1 /* CSPDLTransaction.cpp */; }; @@ -3817,7 +4136,6 @@ DCD66DBA1D82052000DB1393 /* SecPolicyLeafCallbacks.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E7F1D8085FC00865A7C /* SecPolicyLeafCallbacks.c */; }; DCD66DBB1D82052700DB1393 /* SecPolicy.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E7E1D8085FC00865A7C /* SecPolicy.c */; }; DCD66DBC1D82052B00DB1393 /* SecKeyAdaptors.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E621D8085FC00865A7C /* SecKeyAdaptors.c */; }; - DCD66DBD1D82053100DB1393 /* SecCertificatePath.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E3B1D8085FC00865A7C /* SecCertificatePath.c */; }; DCD66DBE1D82053700DB1393 /* SecBase64.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E351D8085FC00865A7C /* SecBase64.c */; }; DCD66DBF1D82053E00DB1393 /* SecDigest.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E481D8085FC00865A7C /* SecDigest.c */; }; DCD66DC01D82054500DB1393 /* SecCertificate.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E381D8085FC00865A7C /* SecCertificate.c */; }; @@ -3836,13 +4154,18 @@ DCD6C4B41EC5302500414FEE /* CKKSNearFutureScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD6C4B11EC5302500414FEE /* CKKSNearFutureScheduler.m */; }; DCD6C4B51EC5302500414FEE /* CKKSNearFutureScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD6C4B11EC5302500414FEE /* CKKSNearFutureScheduler.m */; }; DCD6C4B71EC5319600414FEE /* CKKSNearFutureSchedulerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD6C4B61EC5319600414FEE /* CKKSNearFutureSchedulerTests.m */; }; + DCD7EE841F4E46F9007D9804 /* accountCirclesViewsPrint.m in Sources */ = {isa = PBXBuildFile; fileRef = 48C2F9321E4BCFC30093D70C /* accountCirclesViewsPrint.m */; }; + DCD7EE851F4E47D2007D9804 /* reqparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067C31D8CDF7E007602F1 /* reqparser.cpp */; }; + DCD7EE981F4F4DE9007D9804 /* SecBase64.h in Headers */ = {isa = PBXBuildFile; fileRef = 18351B8F14CB65870097860E /* SecBase64.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DCD7EE991F4F4E03007D9804 /* ocspTemplates.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787661D77911D00B50D50 /* ocspTemplates.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DCD7EE9A1F4F5156007D9804 /* oidsocsp.h in Headers */ = {isa = PBXBuildFile; fileRef = DC88344F1D8A21AA00CE0ACA /* oidsocsp.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DCD7EEA41F4F58D7007D9804 /* SecLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78E661D8085FC00865A7C /* SecLogging.h */; settings = {ATTRIBUTES = (Private, ); }; }; DCD8A0CF1E09EA1800E4FA0A /* SecKeybagSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9E1D8085D800865A7C /* SecKeybagSupport.c */; }; DCD8A1321E09EE0F00E4FA0A /* SOSPeerInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D631D8085F200865A7C /* SOSPeerInfo.m */; }; DCD8A1511E09EE0F00E4FA0A /* SOSViews.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D4A1D8085F200865A7C /* SOSViews.m */; }; DCD8A15A1E09EE0F00E4FA0A /* SOSAccountTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D151D8085F200865A7C /* SOSAccountTransaction.h */; }; DCD8A15C1E09EE0F00E4FA0A /* SOSBackupSliceKeyBag.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D2A1D8085F200865A7C /* SOSBackupSliceKeyBag.h */; }; DCD8A15D1E09EE0F00E4FA0A /* SOSCircle.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D321D8085F200865A7C /* SOSCircle.h */; }; - DCD8A15E1E09EE0F00E4FA0A /* SOSCircleDer.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D341D8085F200865A7C /* SOSCircleDer.h */; }; DCD8A15F1E09EE0F00E4FA0A /* SOSCirclePriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D311D8085F200865A7C /* SOSCirclePriv.h */; }; DCD8A1601E09EE0F00E4FA0A /* SOSCircleRings.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D331D8085F200865A7C /* SOSCircleRings.h */; }; DCD8A1611E09EE0F00E4FA0A /* SOSCircleV2.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D301D8085F200865A7C /* SOSCircleV2.h */; }; @@ -3867,13 +4190,11 @@ DCD8A1851E09EE0F00E4FA0A /* SOSRingDER.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D411D8085F200865A7C /* SOSRingDER.h */; }; DCD8A1861E09EE0F00E4FA0A /* SOSRingPeerInfoUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D431D8085F200865A7C /* SOSRingPeerInfoUtils.h */; }; DCD8A1871E09EE0F00E4FA0A /* SOSRingTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D451D8085F200865A7C /* SOSRingTypes.h */; }; - DCD8A1881E09EE0F00E4FA0A /* SOSAccountPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = CD9021471DE27A9E00F81DC4 /* SOSAccountPriv.h */; }; DCD8A1891E09EE0F00E4FA0A /* SOSRingUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D471D8085F200865A7C /* SOSRingUtils.h */; }; DCD8A18A1E09EE0F00E4FA0A /* SOSRingV0.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D491D8085F200865A7C /* SOSRingV0.h */; }; DCD8A18B1E09EE0F00E4FA0A /* SOSTransport.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D751D8085F200865A7C /* SOSTransport.h */; }; DCD8A1901E09EE0F00E4FA0A /* SOSAccountTrust.h in Headers */ = {isa = PBXBuildFile; fileRef = CD31F8611DCD4C1400414B46 /* SOSAccountTrust.h */; }; DCD8A1931E09EE0F00E4FA0A /* SOSTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D8F1D8085F200865A7C /* SOSTypes.h */; }; - DCD8A1941E09EE0F00E4FA0A /* SOSUserKeygen.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D2C1D8085F200865A7C /* SOSUserKeygen.h */; }; DCD8A1951E09EE0F00E4FA0A /* SOSViews.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D4B1D8085F200865A7C /* SOSViews.h */; }; DCD8A19A1E09EE9800E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; DCD8A19D1E09EEC800E4FA0A /* SOSBackupSliceKeyBag.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D291D8085F200865A7C /* SOSBackupSliceKeyBag.m */; }; @@ -3881,14 +4202,11 @@ DCD8A19F1E09EF0F00E4FA0A /* SOSInternal.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D8D1D8085F200865A7C /* SOSInternal.m */; }; DCD8A1A01E09EF3500E4FA0A /* SOSCloudKeychainClient.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CF61D8085F200865A7C /* SOSCloudKeychainClient.c */; }; DCD8A1A11E09EF5C00E4FA0A /* SOSCloudKeychainConstants.c in Sources */ = {isa = PBXBuildFile; fileRef = E7A5F4D71C0D01B000F3BEBB /* SOSCloudKeychainConstants.c */; }; - DCD8A1A31E09EF7800E4FA0A /* SOSSysdiagnose.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D8C1D8085F200865A7C /* SOSSysdiagnose.m */; }; DCD8A1A41E09EF9000E4FA0A /* SOSPeerInfoCollections.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D6A1D8085F200865A7C /* SOSPeerInfoCollections.c */; }; DCD8A1A51E09EFAE00E4FA0A /* SOSPeerInfoV2.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D671D8085F200865A7C /* SOSPeerInfoV2.m */; }; DCD8A1A61E09EFD700E4FA0A /* SOSKVSKeys.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D721D8085F200865A7C /* SOSKVSKeys.m */; }; DCD8A1A71E09F01300E4FA0A /* SOSPeerInfoSecurityProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D6F1D8085F200865A7C /* SOSPeerInfoSecurityProperties.m */; }; - DCD8A1A81E09F03100E4FA0A /* SOSUserKeygen.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D2B1D8085F200865A7C /* SOSUserKeygen.m */; }; DCD8A1A91E09F04700E4FA0A /* SOSECWrapUnwrap.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D881D8085F200865A7C /* SOSECWrapUnwrap.c */; }; - DCD8A1AC1E09F09200E4FA0A /* SOSCircleDer.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D351D8085F200865A7C /* SOSCircleDer.c */; }; DCD8A1AE1E09F0C500E4FA0A /* SOSRingDER.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D401D8085F200865A7C /* SOSRingDER.c */; }; DCD8A1AF1E09F0DC00E4FA0A /* SOSRingUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D461D8085F200865A7C /* SOSRingUtils.c */; }; DCD8A1B01E09F0F400E4FA0A /* SOSRingTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D441D8085F200865A7C /* SOSRingTypes.m */; }; @@ -3907,7 +4225,6 @@ DCD8A1BD1E09F1D600E4FA0A /* SOSFullPeerInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D611D8085F200865A7C /* SOSFullPeerInfo.m */; }; DCD8A1C21E09F23B00E4FA0A /* SOSRecoveryKeyBag.m in Sources */ = {isa = PBXBuildFile; fileRef = 48776C731DA5BB4200CC09B9 /* SOSRecoveryKeyBag.m */; }; DCD8A1C71E09F2B400E4FA0A /* SOSTransport.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D741D8085F200865A7C /* SOSTransport.m */; }; - DCD8A1DA1E09F54700E4FA0A /* SOSAccountDer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D1C1D8085F200865A7C /* SOSAccountDer.m */; }; DCD8A1DB1E09F5D100E4FA0A /* SOSAccountTrust.m in Sources */ = {isa = PBXBuildFile; fileRef = CD31F8601DCD4C1400414B46 /* SOSAccountTrust.m */; }; DCD8A1DC1E09F5E500E4FA0A /* SOSAccount.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D131D8085F200865A7C /* SOSAccount.h */; }; DCD8A1DD1E09F73F00E4FA0A /* SOSPeerInfoDER.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D661D8085F200865A7C /* SOSPeerInfoDER.h */; }; @@ -3916,7 +4233,6 @@ DCD8A1E01E09F76800E4FA0A /* SOSPeerInfoRingState.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D6E1D8085F200865A7C /* SOSPeerInfoRingState.h */; }; DCD8A1E11E09F76D00E4FA0A /* SOSPeerInfoSecurityProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D701D8085F200865A7C /* SOSPeerInfoSecurityProperties.h */; }; DCD8A1E21E09F78A00E4FA0A /* SOSTransportCircle.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D791D8085F200865A7C /* SOSTransportCircle.h */; }; - DCD8A1E31E09F7E700E4FA0A /* SOSAccountCloudParameters.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D1A1D8085F200865A7C /* SOSAccountCloudParameters.m */; }; DCD8A1E41E09F80B00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; DCD8A1E71E09F85400E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; DCD8A1EA1E09F87B00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; @@ -3927,12 +4243,22 @@ DCD8A1F91E09F98E00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; DCD8A1FC1E09FA0B00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; DCD8A1FF1E09FA6100E4FA0A /* secViewDisplay.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D9E1D8085F200865A7C /* secViewDisplay.c */; }; - DCD8A2001E09FA7900E4FA0A /* secToolFileIO.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D931D8085F200865A7C /* secToolFileIO.c */; }; DCD8A2011E09FAD900E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; DCD8A2041E09FB0D00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; DCD8A20A1E09FB5900E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; settings = {ATTRIBUTES = (Weak, ); }; }; DCD8A20B1E09FB5A00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; DCD8A20C1E09FB6600E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; + DCDB296C1FD8820400B5D242 /* SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalytics.m */; }; + DCDB296E1FD8821400B5D242 /* SFAnalyticsActivityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CBF65381FA147E500A68667 /* SFAnalyticsActivityTracker.m */; }; + DCDB29701FD8821800B5D242 /* SFAnalyticsMultiSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */; }; + DCDB29721FD8821D00B5D242 /* SFAnalyticsSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */; }; + DCDB29741FD8822200B5D242 /* SFAnalyticsSQLiteStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */; }; + DCDB29791FD8844C00B5D242 /* client.c in Sources */ = {isa = PBXBuildFile; fileRef = 7908507F0CA87CF00083CC4D /* client.c */; }; + DCDB297A1FD8845600B5D242 /* client_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC844AEC1E81F315007AAB71 /* client_endpoint.m */; }; + DCDB297B1FD8847100B5D242 /* SecTask.c in Sources */ = {isa = PBXBuildFile; fileRef = 107226D00D91DB32003CF14F /* SecTask.c */; }; + DCDB297C1FD8848A00B5D242 /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; + DCDB297D1FD8849A00B5D242 /* SFSQLiteStatement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BF1F152EB10082882F /* SFSQLiteStatement.m */; }; + DCDB297E1FD8849D00B5D242 /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; DCDCC7E31D9B54EE006487E8 /* secd-202-recoverykey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCDCC7DD1D9B54DF006487E8 /* secd-202-recoverykey.m */; }; DCDCC7E51D9B5526006487E8 /* SOSAccountSync.m in Sources */ = {isa = PBXBuildFile; fileRef = DCDCC7E41D9B551C006487E8 /* SOSAccountSync.m */; }; DCDCC8331D9B6A00006487E8 /* libcoretls.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CFC029B1D41650700E6283B /* libcoretls.dylib */; }; @@ -3946,6 +4272,12 @@ DCDCCB3E1DF25DA0006E840E /* ApplePushService.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC9EBA231DEE36FE00D0F733 /* ApplePushService.framework */; }; DCDCCB8F1DF7B8D4006E840E /* CKKSItem.h in Headers */ = {isa = PBXBuildFile; fileRef = DCDCCB8D1DF7B8D4006E840E /* CKKSItem.h */; }; DCDCCB901DF7B8D4006E840E /* CKKSItem.m in Sources */ = {isa = PBXBuildFile; fileRef = DCDCCB8E1DF7B8D4006E840E /* CKKSItem.m */; }; + DCDD59CC1F69ACF70060641E /* SOSCloudCircleInternal.h in Copy SecureObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D8B1D8085F200865A7C /* SOSCloudCircleInternal.h */; }; + DCDD59CD1F69ACF70060641E /* SOSTypes.h in Copy SecureObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D8F1D8085F200865A7C /* SOSTypes.h */; }; + DCDD59CE1F69ACF70060641E /* SOSViews.h in Copy SecureObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D4B1D8085F200865A7C /* SOSViews.h */; }; + DCDD59CF1F69ACF70060641E /* SOSPeerInfo.h in Copy SecureObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D641D8085F200865A7C /* SOSPeerInfo.h */; }; + DCDD59D01F69ACF70060641E /* SOSCloudCircle.h in Copy SecureObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D8A1D8085F200865A7C /* SOSCloudCircle.h */; }; + DCDD59D21F69ACF70060641E /* SOSBackupSliceKeyBag.h in Copy SecureObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D2A1D8085F200865A7C /* SOSBackupSliceKeyBag.h */; }; DCDF0A4F1D81D76F007AF174 /* Security.exp-in in Sources */ = {isa = PBXBuildFile; fileRef = 4CB7405F0A47498100D641BB /* Security.exp-in */; }; DCE278DD1ED789EF0083B485 /* CKKSCurrentItemPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = DCE278DB1ED789EF0083B485 /* CKKSCurrentItemPointer.h */; }; DCE278DE1ED789EF0083B485 /* CKKSCurrentItemPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = DCE278DB1ED789EF0083B485 /* CKKSCurrentItemPointer.h */; }; @@ -4120,6 +4452,10 @@ DCE4E94A1D7F3E8E00AFB96E /* com.apple.security.keychain-circle-notification.plist in Resources */ = {isa = PBXBuildFile; fileRef = DCE4E9461D7F3E8700AFB96E /* com.apple.security.keychain-circle-notification.plist */; }; DCE4E94B1D7F3E8E00AFB96E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DCE4E9471D7F3E8700AFB96E /* InfoPlist.strings */; }; DCE4E9711D7F3EBB00AFB96E /* com.apple.security.keychain-circle-notification.plist in Install launchd plist */ = {isa = PBXBuildFile; fileRef = DCE4E9461D7F3E8700AFB96E /* com.apple.security.keychain-circle-notification.plist */; }; + DCE5DC0F1EA80256006308A6 /* SOSSysdiagnose.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D8C1D8085F200865A7C /* SOSSysdiagnose.m */; }; + DCE5DC101EA802DA006308A6 /* secToolFileIO.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D921D8085F200865A7C /* secToolFileIO.h */; }; + DCE5DC111EA80348006308A6 /* accountCirclesViewsPrint.h in Headers */ = {isa = PBXBuildFile; fileRef = 48C2F9331E4BCFC30093D70C /* accountCirclesViewsPrint.h */; }; + DCE5DC121EA80369006308A6 /* libSOSCommands.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EC341D80CFB200B0A59C /* libSOSCommands.a */; }; DCE7F2091F21726500DDB0F7 /* CKKSAPSReceiverTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DCE7F2081F21726500DDB0F7 /* CKKSAPSReceiverTests.m */; }; DCE809F31D9342BE00F91177 /* com.apple.securityd.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = DCEE1E851D93424D00DC0EB7 /* com.apple.securityd.plist */; }; DCEA5D551E2826DB0089CF55 /* CKKSSIV.h in Headers */ = {isa = PBXBuildFile; fileRef = DCEA5D531E2826DB0089CF55 /* CKKSSIV.h */; }; @@ -4138,7 +4474,6 @@ DCEDE3921D80B10E00C3826E /* SecOTRDHKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFF415AFB73800B9D400 /* SecOTRDHKey.h */; }; DCEDE3931D80B11200C3826E /* SecOTR.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFF315AFB73800B9D400 /* SecOTR.h */; }; DCEDE3941D80B11800C3826E /* SecPasswordGenerate.h in Headers */ = {isa = PBXBuildFile; fileRef = CDDE9BC31729AB910013B0E8 /* SecPasswordGenerate.h */; }; - DCEDE3951D80B12000C3826E /* secToolFileIO.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D921D8085F200865A7C /* secToolFileIO.h */; }; DCEDE3961D80B12600C3826E /* SecTrustInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78E921D8085FC00865A7C /* SecTrustInternal.h */; }; DCEE1E861D93427400DC0EB7 /* com.apple.securityd.plist in Resources */ = {isa = PBXBuildFile; fileRef = DCE4E80D1D7A4E3A00AFB96E /* com.apple.securityd.plist */; }; DCF7839D1D88B60D00E694BB /* aesCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF783151D88B60D00E694BB /* aesCommon.h */; }; @@ -4454,7 +4789,7 @@ DCF789481D88D17C00E694BB /* AppleX509TPBuiltin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCF789471D88D17C00E694BB /* AppleX509TPBuiltin.cpp */; }; DCF7A8A01F04502400CABE89 /* CKKSControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF7A89F1F04502300CABE89 /* CKKSControlProtocol.h */; }; DCF7A8A11F04502400CABE89 /* CKKSControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF7A89F1F04502300CABE89 /* CKKSControlProtocol.h */; }; - DCF7A8A51F0451AC00CABE89 /* CKKSControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */; }; + DCFABF8E20081E2F001128B5 /* CKKSDeviceStateUploadTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFABF8D20081E2F001128B5 /* CKKSDeviceStateUploadTests.m */; }; DCFAEDCF1D999859005187E4 /* SOSAccountGhost.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFAEDC81D999851005187E4 /* SOSAccountGhost.m */; }; DCFAEDD21D99991F005187E4 /* secd-668-ghosts.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFAEDD11D9998DD005187E4 /* secd-668-ghosts.m */; }; DCFAEDD61D99A47A005187E4 /* secd-36-ks-encrypt.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFAEDD51D99A464005187E4 /* secd-36-ks-encrypt.m */; }; @@ -4581,6 +4916,12 @@ EB10559E1E14E39D0003C309 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E43C48C1B00D07000E5ECB2 /* CoreFoundation.framework */; }; EB10559F1E14E3A80003C309 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; EB108F261E6CE4D2003B0456 /* KCPairingTest.m in Sources */ = {isa = PBXBuildFile; fileRef = EB413B7E1E663A8300592085 /* KCPairingTest.m */; }; + EB10A3E520356E2000E84270 /* OTConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = EB10A3E320356E2000E84270 /* OTConstants.h */; settings = {ATTRIBUTES = (Private, ); }; }; + EB10A3E620356E2000E84270 /* OTConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = EB10A3E420356E2000E84270 /* OTConstants.m */; }; + EB10A3E720356E6500E84270 /* OTConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = EB10A3E420356E2000E84270 /* OTConstants.m */; }; + EB10A3E820356E6500E84270 /* OTConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = EB10A3E420356E2000E84270 /* OTConstants.m */; }; + EB10A3E920356E7A00E84270 /* OTConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = EB10A3E420356E2000E84270 /* OTConstants.m */; }; + EB10A3FC2035789B00E84270 /* OTConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = EB10A3E320356E2000E84270 /* OTConstants.h */; settings = {ATTRIBUTES = (Private, ); }; }; EB27FF2D1E407FF600EC9E3A /* ckksctl.m in Sources */ = {isa = PBXBuildFile; fileRef = EB27FF0C1E402C8000EC9E3A /* ckksctl.m */; }; EB27FF311E408DC700EC9E3A /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; EB2CA4DA1D2C28F100AB770F /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; }; @@ -4599,10 +4940,42 @@ EB433A2E1CC325E900A7EACE /* secitemstresstest.entitlements in Resources */ = {isa = PBXBuildFile; fileRef = EB433A2D1CC325E900A7EACE /* secitemstresstest.entitlements */; }; EB48C1A51E573EE400EC5E57 /* whoami.m in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA911D80CC2A00B0A59C /* whoami.m */; }; EB48C1A61E573EEC00EC5E57 /* sos.m in Sources */ = {isa = PBXBuildFile; fileRef = EB48C19E1E573EDC00EC5E57 /* sos.m */; }; + EB49B2B1202D8780003F34A0 /* secdmockaks.m in Sources */ = {isa = PBXBuildFile; fileRef = EB49B2B0202D8780003F34A0 /* secdmockaks.m */; }; + EB49B2BB202D8894003F34A0 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; + EB49B2BC202DEF14003F34A0 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 6CB96BB41F966E0C00E11457 /* libsqlite3.tbd */; }; + EB49B2BD202DEF29003F34A0 /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; + EB49B2BE202DEF29003F34A0 /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; + EB49B2BF202DEF67003F34A0 /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; + EB49B2C0202DEF7D003F34A0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + EB49B2C1202DEF8D003F34A0 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; + EB49B2C2202DF002003F34A0 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246911F9AE2E400D63882 /* libDER.a */; }; + EB49B2C7202DF0E9003F34A0 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; + EB49B2CD202DF0F9003F34A0 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; }; + EB49B2D0202DF14D003F34A0 /* SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalytics.m */; }; + EB49B2D1202DF15F003F34A0 /* SFAnalyticsActivityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CBF65381FA147E500A68667 /* SFAnalyticsActivityTracker.m */; }; + EB49B2D2202DF17D003F34A0 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; + EB49B2D3202DF1AC003F34A0 /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; + EB49B2D4202DF1C1003F34A0 /* client.c in Sources */ = {isa = PBXBuildFile; fileRef = 7908507F0CA87CF00083CC4D /* client.c */; }; + EB49B2D5202DF1D8003F34A0 /* SecTask.c in Sources */ = {isa = PBXBuildFile; fileRef = 107226D00D91DB32003CF14F /* SecTask.c */; }; + EB49B2D7202DF1F7003F34A0 /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; + EB49B2D8202DF1F7003F34A0 /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; + EB49B2D9202DF1F7003F34A0 /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; + EB49B2DB202DF20F003F34A0 /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; + EB49B2DD202DF259003F34A0 /* libbsm.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = EB49B2DC202DF251003F34A0 /* libbsm.tbd */; }; + EB49B2E0202DF5D7003F34A0 /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; + EB49B2E2202DFDA3003F34A0 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */; }; + EB49B2E5202DFEB3003F34A0 /* mockaks.m in Sources */ = {isa = PBXBuildFile; fileRef = EB49B2E4202DFE7F003F34A0 /* mockaks.m */; }; + EB49B308202FF421003F34A0 /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47D1838B1FB3827700CFCD89 /* OCMock.framework */; }; + EB49B310202FF4AC003F34A0 /* OCMock.framework in Embedded OCMock */ = {isa = PBXBuildFile; fileRef = DC3502E81E02172C00BC0587 /* OCMock.framework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; EB4B6E201DC0682A00AFC494 /* SecADWrapper.c in Sources */ = {isa = PBXBuildFile; fileRef = EBF3749A1DC064200065D840 /* SecADWrapper.c */; }; EB4B6E261DC0683600AFC494 /* SecADWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = EBF3749B1DC064200065D840 /* SecADWrapper.h */; }; + EB4E0CDB1FF36A9700CDCACC /* CKKSReachabilityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = EB4E0CD51FF36A1900CDCACC /* CKKSReachabilityTracker.m */; }; + EB4E0CDC1FF36A9700CDCACC /* CKKSReachabilityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = EB4E0CD51FF36A1900CDCACC /* CKKSReachabilityTracker.m */; }; EB58A0511E74BF07009C10D7 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; EB59D6731E95F01600997EAC /* libcompression.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = EB59D66B1E95EF2900997EAC /* libcompression.dylib */; }; + EB5E3BCC2003C67A00F1631B /* SecSignpost.h in Headers */ = {isa = PBXBuildFile; fileRef = EB5E3BC62003C66300F1631B /* SecSignpost.h */; settings = {ATTRIBUTES = (Private, ); }; }; + EB5E3BCD2003C67B00F1631B /* SecSignpost.h in Headers */ = {isa = PBXBuildFile; fileRef = EB5E3BC62003C66300F1631B /* SecSignpost.h */; settings = {ATTRIBUTES = (Private, ); }; }; + EB6667C7204CD69F000B404F /* testPlistDER.m in Sources */ = {isa = PBXBuildFile; fileRef = EB6667BE204CD65E000B404F /* testPlistDER.m */; }; EB6928C51D9C9C6E00062A18 /* SecRecoveryKey.h in Headers */ = {isa = PBXBuildFile; fileRef = EB6928BE1D9C9C5900062A18 /* SecRecoveryKey.h */; settings = {ATTRIBUTES = (Private, ); }; }; EB6928C61D9C9C6F00062A18 /* SecRecoveryKey.h in Headers */ = {isa = PBXBuildFile; fileRef = EB6928BE1D9C9C5900062A18 /* SecRecoveryKey.h */; settings = {ATTRIBUTES = (Private, ); }; }; EB6928CA1D9C9E1800062A18 /* rk_01_recoverykey.m in Sources */ = {isa = PBXBuildFile; fileRef = EB6928C91D9C9D9D00062A18 /* rk_01_recoverykey.m */; }; @@ -4615,7 +4988,6 @@ EB75B48A1E75405100E469CC /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; EB75B48C1E75407C00E469CC /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; EB75B48D1E75408900E469CC /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; - EB75B48E1E75408C00E469CC /* libDER_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; }; EB75B48F1E75409A00E469CC /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB740680A4749C800D641BB /* libsqlite3.dylib */; }; EB75B4901E7540AA00E469CC /* libctkclient_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDC1AA0A45C0021AA26 /* libctkclient_test.a */; }; EB75B4911E7540BF00E469CC /* libcoreauthd_test_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E8B53A41AA0B8A600345E7B /* libcoreauthd_test_client.a */; }; @@ -4626,8 +4998,6 @@ EB78D3F91E600E93009AFE05 /* SOSCloudCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D891D8085F200865A7C /* SOSCloudCircle.m */; }; EB7AE6F81E86DACC00B80B15 /* SecPLWrappers.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7AE6F61E86D55400B80B15 /* SecPLWrappers.m */; }; EB7AE6F91E86DAD200B80B15 /* SecPLWrappers.h in Headers */ = {isa = PBXBuildFile; fileRef = EB7AE6F71E86D55400B80B15 /* SecPLWrappers.h */; }; - EB7F50C51DB8800A003D787D /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */; }; - EB7F50CC1DB88A03003D787D /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9411D7F3E6E00AFB96E /* CoreCDP.framework */; }; EB9C02481E8A15B40040D3C6 /* secd-37-pairing-initial-sync.m in Sources */ = {isa = PBXBuildFile; fileRef = EB9C02421E8A112A0040D3C6 /* secd-37-pairing-initial-sync.m */; }; EB9C1D7B1BDFD0E000F89272 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; EB9C1D7E1BDFD0E100F89272 /* secbackupntest.m in Sources */ = {isa = PBXBuildFile; fileRef = EB9C1D7D1BDFD0E100F89272 /* secbackupntest.m */; }; @@ -4684,7 +5054,7 @@ outputFiles = ( "$(BUILT_PRODUCTS_DIR)/$(PRODUCT_NAME).$(CURRENT_ARCH).exp", ); - script = "#!/bin/sh\n\nfor file in ${HEADER_SEARCH_PATHS[@]} ; do\nHEADER_SEARCH_OPTIONS=\"${HEADER_SEARCH_OPTIONS} -I${file}\"\ndone\n\nxcrun clang -E -Xpreprocessor -P -x c -arch ${CURRENT_ARCH} ${HEADER_SEARCH_OPTIONS} ${OTHER_INPUT_FILE_FLAGS} ${INPUT_FILE_PATH} -o ${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.${CURRENT_ARCH}.exp\n"; + script = "#!/bin/sh\n\nfor file in ${HEADER_SEARCH_PATHS[@]} ; do\nHEADER_SEARCH_OPTIONS=\"${HEADER_SEARCH_OPTIONS} -I${file}\"\ndone\n\nfor prep in ${GCC_PREPROCESSOR_DEFINITIONS[@]} ; do\nPREPROCESSOR=\"${PREPROCESSOR} -D${prep}\"\ndone\n\nxcrun clang -E -Xpreprocessor -P -x objective-c -arch ${CURRENT_ARCH} ${HEADER_SEARCH_OPTIONS} ${OTHER_INPUT_FILE_FLAGS} ${PREPROCESSOR} ${INPUT_FILE_PATH} -o ${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.${CURRENT_ARCH}.exp\n"; }; DC9FD3201F85818000C8AAC8 /* PBXBuildRule */ = { isa = PBXBuildRule; @@ -4719,7 +5089,7 @@ outputFiles = ( "$(BUILT_PRODUCTS_DIR)/$(PRODUCT_NAME).$(CURRENT_ARCH).exp", ); - script = "#!/bin/sh\n\nfor file in ${HEADER_SEARCH_PATHS[@]} ; do\nHEADER_SEARCH_OPTIONS=\"${HEADER_SEARCH_OPTIONS} -I${file}\"\ndone\n\nxcrun clang -E -Xpreprocessor -P -x c -arch ${CURRENT_ARCH} ${HEADER_SEARCH_OPTIONS} ${OTHER_INPUT_FILE_FLAGS} ${INPUT_FILE_PATH} -o ${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.${CURRENT_ARCH}.exp\n"; + script = "#!/bin/sh\n\nfor file in ${HEADER_SEARCH_PATHS[@]} ; do\nHEADER_SEARCH_OPTIONS=\"${HEADER_SEARCH_OPTIONS} -I${file}\"\ndone\n\nfor prep in ${GCC_PREPROCESSOR_DEFINITIONS[@]} ; do\nPREPROCESSOR=\"${PREPROCESSOR} -D${prep}\"\ndone\n\nxcrun clang -E -Xpreprocessor -P -x objective-c -arch ${CURRENT_ARCH} ${HEADER_SEARCH_OPTIONS} ${OTHER_INPUT_FILE_FLAGS} ${PREPROCESSOR} ${INPUT_FILE_PATH} -o ${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.${CURRENT_ARCH}.exp\n"; }; /* End PBXBuildRule section */ @@ -4759,6 +5129,62 @@ remoteGlobalIDString = 0C0BDB2E175685B000BC1A7E; remoteInfo = secdtests; }; + 0C78CCE41FCC97E7008B4B24 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 0C8BBEFD1FCB446400580909; + remoteInfo = otctl; + }; + 0C78CCE61FCC97F1008B4B24 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 0C8BBEFD1FCB446400580909; + remoteInfo = otctl; + }; + 0C85DFD51FB38BB6000343A7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC222C371E034D1F00B09171; + remoteInfo = libsecurityd_ios_NO_AKS; + }; + 0C85DFD91FB38BB6000343A7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1_not_installed; + }; + 0C85DFDB1FB38BB6000343A7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; + }; + 0C85DFDD1FB38BB6000343A7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; + }; + 0C85DFDF1FB38BB6000343A7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = SecureObjectSyncServer; + }; + 0C85DFE11FB38BB6000343A7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCC78EA81D8088E200865A7C; + remoteInfo = security; + }; 0C99B73F131C984900584CF4 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -4801,6 +5227,34 @@ remoteGlobalIDString = 4381690B1B4EDCBD00C54D58; remoteInfo = SOSCCAuthPlugin; }; + 478D426E1FD72A8100CAB645 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52EDA61D80D58400B0A59C; + remoteInfo = secdRegressions; + }; + 478D42701FD72A8100CAB645 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; + remoteInfo = regressionBase; + }; + 478D42721FD72A8100CAB645 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd_ios; + }; + 478D42741FD72A8100CAB645 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCC78EA81D8088E200865A7C; + remoteInfo = security; + }; 47C51B8A1EEA657D0032D9E5 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -4808,6 +5262,34 @@ remoteGlobalIDString = DC1789031D77980500B50D50; remoteInfo = Security_osx; }; + 47DE88CD1FA7AD6200DD3254 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCC78EA81D8088E200865A7C; + remoteInfo = security; + }; + 47DE88D41FA7AD7000DD3254 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd_ios; + }; + 47DE88D61FA7ADAC00DD3254 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; + remoteInfo = regressionBase; + }; + 47DE88D81FA7ADBB00DD3254 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52EDA61D80D58400B0A59C; + remoteInfo = secdRegressions; + }; 4C52D0ED16EFCD720079966E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -4871,13 +5353,6 @@ remoteGlobalIDString = 5346480017331E1100FE9172; remoteInfo = KeychainSyncAccountNotification; }; - 5DDD0BED16D6748900D6C0D6 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 728B56A016D59979008FA3AB; - remoteInfo = OTAPKIAssetTool; - }; 5E10995319A5E80B00A60E2B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -4906,12 +5381,19 @@ remoteGlobalIDString = 6CCDF7831E3C25FA003F2555; remoteInfo = KeychainEntitledTestRunner; }; - 6C98082E1E788AEB00E70590 /* PBXContainerItemProxy */ = { + 6C7C38801FD88C4700DFFE68 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6C46056B1F882B9B001421B6; + remoteInfo = KeychainAnalyticsTests; + }; + 6C7C38871FD88C5A00DFFE68 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER_not_installed; + remoteGlobalIDString = 6C46056B1F882B9B001421B6; + remoteInfo = KeychainAnalyticsTests; }; 6C9808301E788AEB00E70590 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -4955,13 +5437,6 @@ remoteGlobalIDString = DC222C371E034D1F00B09171; remoteInfo = libsecurityd_ios_NO_AKS; }; - 6C98086A1E788AFD00E70590 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER_not_installed; - }; 6C98086C1E788AFD00E70590 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -5018,6 +5493,41 @@ remoteGlobalIDString = 6CF4A0DF1E4549F200ECD7B5; remoteInfo = KeychainEntitledTestApp_ios; }; + 6C9A49B11FAB647D00239D58 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; + }; + 6CAA8CE41F82FD08007B6E03 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6C9AA79D1F7C1D8F00D08296; + remoteInfo = supdctl; + }; + 6CAA8CE81F82FD13007B6E03 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6C9AA79D1F7C1D8F00D08296; + remoteInfo = supdctl; + }; + 6CAA8D3C1F8431BC007B6E03 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6CAA8D1F1F842FB3007B6E03; + remoteInfo = supd; + }; + 6CAA8D3E1F8431C9007B6E03 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6CAA8D1F1F842FB3007B6E03; + remoteInfo = supd; + }; ACBAF6FD1E941E090007BA2F /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -5158,13 +5668,6 @@ remoteGlobalIDString = D4ADA3181E2B41670031CEA3; remoteInfo = libtrustd; }; - D41257E31E941A8400781F23 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER_not_installed; - }; D41257E51E941ACC00781F23 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -5291,13 +5794,6 @@ remoteGlobalIDString = 52D82BDD16A621F70078DFE5; remoteInfo = CloudKeychainProxy; }; - D41AD4591B978944008C7270 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 728B56A016D59979008FA3AB; - remoteInfo = OTAPKIAssetTool; - }; D41AD45B1B978A7A008C7270 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -5361,13 +5857,6 @@ remoteGlobalIDString = 5EBE24791B00CCAE0007DB0E; remoteInfo = secacltests; }; - D41AD4711B978F76008C7270 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 728B56A016D59979008FA3AB; - remoteInfo = OTAPKIAssetTool; - }; DA30D6811DF8C93500EC6B43 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -5634,13 +6123,6 @@ remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; remoteInfo = SecureObjectSyncServer; }; - DC0B62951D90B6DB00D43BCB /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC1785041D77873100B50D50; - remoteInfo = copyHeadersToSystem; - }; DC0BB4431ED4D74A0035F886 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -5865,19 +6347,40 @@ remoteGlobalIDString = DC222C371E034D1F00B09171; remoteInfo = libsecurityd_ios_NO_AKS; }; - DC3502C31E020D4D00BC0587 /* PBXContainerItemProxy */ = { + DC26710F1F3E933700816EED /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; remoteGlobalIDString = DC8834011D8A218F00CE0ACA; remoteInfo = ASN1_not_installed; }; - DC3502C61E020D5600BC0587 /* PBXContainerItemProxy */ = { + DC34CD2C20326C2C00302481 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER_not_installed; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = SecureObjectSyncServer; + }; + DC34CD3320326C3100302481 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; + }; + DC34CD3520326C3B00302481 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; + }; + DC3502C31E020D4D00BC0587 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1_not_installed; }; DC3502CD1E020E2200BC0587 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -6033,90 +6536,6 @@ remoteGlobalIDString = 79DC33610D4E6EEA0039E4BC; remoteInfo = libCMS; }; - DC59EA751D91CC5E001BDDF5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER; - }; - DC59EA781D91CC78001BDDF5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER; - }; - DC59EA7C1D91CCAA001BDDF5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER; - }; - DC59EA801D91CD16001BDDF5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER; - }; - DC59EA831D91CD2C001BDDF5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER; - }; - DC59EA861D91CD76001BDDF5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER; - }; - DC59EA891D91CD89001BDDF5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER; - }; - DC59EA8C1D91CDB9001BDDF5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER; - }; - DC59EA8F1D91CDC6001BDDF5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER; - }; - DC59EA921D91CDD6001BDDF5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER; - }; - DC59EA951D91CDEE001BDDF5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER; - }; - DC59EA981D91CE8C001BDDF5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER; - }; DC5ABE1B1D832F5E00CF422C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -6173,13 +6592,6 @@ remoteGlobalIDString = DC5AC04F1D8352D900CF422C; remoteInfo = securityd_macos; }; - DC5AC1331D835C2300CF422C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC1785041D77873100B50D50; - remoteInfo = copyHeadersToSystem; - }; DC61096A1D78E60C002223DE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -6579,20 +6991,6 @@ remoteGlobalIDString = DC8834011D8A218F00CE0ACA; remoteInfo = ASN1_not_installed; }; - DC71DA081D95BEE00065FB93 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER_not_installed; - }; - DC71DA0A1D95BEF60065FB93 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER_not_installed; - }; DC71DA0C1D95DD670065FB93 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -6621,6 +7019,13 @@ remoteGlobalIDString = DC8834011D8A218F00CE0ACA; remoteInfo = ASN1_not_installed; }; + DCB332461F47857D00178C30 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52EC211D80CFB200B0A59C; + remoteInfo = SOSCommands; + }; DCB340181D8A248C0054D16E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -6957,6 +7362,20 @@ remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; remoteInfo = SecureObjectSyncFramework; }; + DCDB29751FD8839F00B5D242 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 0C85DFD11FB38BB6000343A7; + remoteInfo = OTTests_osx; + }; + DCDB29771FD883AB00B5D242 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 0C85DFD11FB38BB6000343A7; + remoteInfo = OTTests_osx; + }; DCE4E6A91D7A38E700AFB96E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -7027,6 +7446,13 @@ remoteGlobalIDString = DCE4E9101D7F3D5300AFB96E; remoteInfo = "Keychain Circle Notification"; }; + DCE5DC161EA804E5006308A6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52EC211D80CFB200B0A59C; + remoteInfo = SOSCommands; + }; DCF785001D88B80600E694BB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -7482,13 +7908,6 @@ remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; remoteInfo = SecureObjectSyncFramework; }; - EBFBC2B71E76588200A34469 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC59E9AC1D91C9DC001BDDF5; - remoteInfo = DER_not_installed; - }; EBFBC2B91E76588A00A34469 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -7550,6 +7969,26 @@ ); runOnlyForDeploymentPostprocessing = 1; }; + 0C85DFFD1FB38BB6000343A7 /* Embed OCMock */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 0C85DFFE1FB38BB6000343A7 /* OCMock.framework in Embed OCMock */, + ); + name = "Embed OCMock"; + runOnlyForDeploymentPostprocessing = 0; + }; + 0C8BBF041FCB446400580909 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; 470415CD1E5E14B5001F3D95 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -7771,16 +8210,6 @@ ); runOnlyForDeploymentPostprocessing = 1; }; - 6C0B0C481E2537E2007F95E5 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /System/Library/AWD/Metadata; - dstSubfolderSpec = 0; - files = ( - 6C0B0C491E253832007F95E5 /* AwdMetadata-0x60-Keychain.bin in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 1; - }; 6C0B0C4A1E253840007F95E5 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -7802,6 +8231,26 @@ name = "Install man8 page"; runOnlyForDeploymentPostprocessing = 1; }; + 6C9AA79C1F7C1D8F00D08296 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 6CAA8D1E1F842FB3007B6E03 /* Copy Manpage */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + 6CDB600F1FA92D2B00410924 /* securityuploadd.8 in Copy Manpage */, + ); + name = "Copy Manpage"; + runOnlyForDeploymentPostprocessing = 1; + }; 6CCDF7821E3C25FA003F2555 /* Copy BATS Test Discovery plist */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -7933,28 +8382,15 @@ ); runOnlyForDeploymentPostprocessing = 1; }; - DC17886F1D77934100B50D50 /* Copy SecurityObjectSync Headers */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = PrivateHeaders/SecureObjectSync; - dstSubfolderSpec = 1; - files = ( - DC3C72E81D8376F900F6A832 /* SOSViews.h in Copy SecurityObjectSync Headers */, - DC3C72E71D8376F300F6A832 /* SOSPeerInfo.h in Copy SecurityObjectSync Headers */, - DC3C72E61D8376EC00F6A832 /* SOSCloudCircleInternal.h in Copy SecurityObjectSync Headers */, - DC3C72E51D8376E600F6A832 /* SOSCloudCircle.h in Copy SecurityObjectSync Headers */, - DC3C72E41D8376DE00F6A832 /* SOSBackupSliceKeyBag.h in Copy SecurityObjectSync Headers */, - DC3C72E31D8376D700F6A832 /* SOSTypes.h in Copy SecurityObjectSync Headers */, - ); - name = "Copy SecurityObjectSync Headers"; - runOnlyForDeploymentPostprocessing = 1; - }; DC1789E81D77A0E700B50D50 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = en.lproj; dstSubfolderSpec = 7; files = ( + D479F6E31F981FD600388D28 /* OID.strings in CopyFiles */, + D479F6E41F981FD600388D28 /* Certificate.strings in CopyFiles */, + D479F6E51F981FD600388D28 /* Trust.strings in CopyFiles */, DC1789E91D77A0F300B50D50 /* CloudKeychain.strings in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; @@ -8340,7 +8776,7 @@ name = "Install launchd plist"; runOnlyForDeploymentPostprocessing = 1; }; - E73288DD1AED7215008CE839 /* Copy SecureObjectSync Headers */ = { + DCF7F5D11F69AC28001042E9 /* Copy SecureObjectSync Headers */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = PrivateHeaders/SecureObjectSync; @@ -8351,12 +8787,28 @@ DC3C72ED1D83778100F6A832 /* SOSViews.h in Copy SecureObjectSync Headers */, DC3C72EC1D83777B00F6A832 /* SOSPeerInfo.h in Copy SecureObjectSync Headers */, DC3C72EB1D83777600F6A832 /* SOSCloudCircle.h in Copy SecureObjectSync Headers */, - DC3C72EA1D83777100F6A832 /* SOSPeerInfoV2.h in Copy SecureObjectSync Headers */, DC3C72E91D83776B00F6A832 /* SOSBackupSliceKeyBag.h in Copy SecureObjectSync Headers */, ); name = "Copy SecureObjectSync Headers"; runOnlyForDeploymentPostprocessing = 0; }; + E73288DD1AED7215008CE839 /* Copy SecureObjectSync Headers */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = PrivateHeaders/SecureObjectSync; + dstSubfolderSpec = 1; + files = ( + DC8EB58D1F70743100080CF2 /* SOSPeerInfoV2.h in Copy SecureObjectSync Headers */, + DCDD59CC1F69ACF70060641E /* SOSCloudCircleInternal.h in Copy SecureObjectSync Headers */, + DCDD59CD1F69ACF70060641E /* SOSTypes.h in Copy SecureObjectSync Headers */, + DCDD59CE1F69ACF70060641E /* SOSViews.h in Copy SecureObjectSync Headers */, + DCDD59CF1F69ACF70060641E /* SOSPeerInfo.h in Copy SecureObjectSync Headers */, + DCDD59D01F69ACF70060641E /* SOSCloudCircle.h in Copy SecureObjectSync Headers */, + DCDD59D21F69ACF70060641E /* SOSBackupSliceKeyBag.h in Copy SecureObjectSync Headers */, + ); + name = "Copy SecureObjectSync Headers"; + runOnlyForDeploymentPostprocessing = 0; + }; E7CFF7211C86602B00E3484E /* Install BATS Tests */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -8412,6 +8864,17 @@ ); runOnlyForDeploymentPostprocessing = 1; }; + EB49B30E202FF484003F34A0 /* Embedded OCMock */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + EB49B310202FF4AC003F34A0 /* OCMock.framework in Embedded OCMock */, + ); + name = "Embedded OCMock"; + runOnlyForDeploymentPostprocessing = 0; + }; EB76B7561DCB0C6900C43FBC /* Install man8 page */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -8516,29 +8979,78 @@ 0C0C88771CCEC5BD00617D1B /* si-82-sectrust-ct-data */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "si-82-sectrust-ct-data"; path = "../OSX/shared_regressions/si-82-sectrust-ct-data"; sourceTree = ""; }; 0C0CEC9D1DA45EA200C22FBC /* recovery_key.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = recovery_key.h; sourceTree = ""; }; 0C0CEC9E1DA45EA200C22FBC /* recovery_key.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = recovery_key.m; sourceTree = ""; }; + 0C16371F1FD12F1500210823 /* OTCloudStoreTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTCloudStoreTests.m; path = ot/tests/OTCloudStoreTests.m; sourceTree = ""; }; 0C2BCBA51D063F7D00ED7A2F /* dtlsEchoClient.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = dtlsEchoClient.c; sourceTree = ""; }; 0C2BCBA61D063F7D00ED7A2F /* dtlsEchoServer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = dtlsEchoServer.c; sourceTree = ""; }; 0C2BCBA71D063F7D00ED7A2F /* README */ = {isa = PBXFileReference; lastKnownFileType = text; path = README; sourceTree = ""; }; 0C2BCBB91D06401F00ED7A2F /* dtlsEchoClient */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dtlsEchoClient; sourceTree = BUILT_PRODUCTS_DIR; }; 0C2BCBCE1D0648D100ED7A2F /* dtlsEchoServer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dtlsEchoServer; sourceTree = BUILT_PRODUCTS_DIR; }; + 0C36B3172007EE6C0029F7A2 /* OTPreflightInfo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTPreflightInfo.m; path = ot/OTPreflightInfo.m; sourceTree = ""; }; + 0C36B3202007EE9B0029F7A2 /* OTPreflightInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTPreflightInfo.h; path = ot/OTPreflightInfo.h; sourceTree = ""; }; 0C3C00721EF3636300AB19FE /* secd-155-otr-negotiation-monitor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-155-otr-negotiation-monitor.m"; sourceTree = ""; }; + 0C46A57A2035019800F17112 /* OTLockStateNetworkingTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTLockStateNetworkingTests.m; path = ot/tests/OTLockStateNetworkingTests.m; sourceTree = ""; }; 0C48990A1E0E0FF300C6CF70 /* SOSTransportCircleCK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSTransportCircleCK.h; sourceTree = ""; }; 0C4899111E0E105D00C6CF70 /* SOSTransportCircleCK.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSTransportCircleCK.m; sourceTree = ""; }; 0C48991B1E0F384700C6CF70 /* SOSAccountTrustClassic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SOSAccountTrustClassic.m; path = SecureObjectSync/SOSAccountTrustClassic.m; sourceTree = ""; }; 0C4899221E0F386900C6CF70 /* SOSAccountTrustClassic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SOSAccountTrustClassic.h; path = SecureObjectSync/SOSAccountTrustClassic.h; sourceTree = ""; }; 0C4899241E0F38FA00C6CF70 /* SOSAccountTrustOctagon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SOSAccountTrustOctagon.m; path = SecureObjectSync/SOSAccountTrustOctagon.m; sourceTree = ""; }; 0C4899261E0F399B00C6CF70 /* SOSAccountTrustOctagon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SOSAccountTrustOctagon.h; path = SecureObjectSync/SOSAccountTrustOctagon.h; sourceTree = ""; }; + 0C52C1FE20003BCA003F0733 /* OTTestsBase.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTTestsBase.m; path = ot/tests/OTTestsBase.m; sourceTree = ""; }; + 0C52C20520004248003F0733 /* OTTestsBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTTestsBase.h; path = ot/tests/OTTestsBase.h; sourceTree = ""; }; + 0C5CFB37201960FF00913B9C /* OTRamping.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTRamping.m; path = ot/OTRamping.m; sourceTree = ""; }; + 0C5CFB3F201962FF00913B9C /* OTRamping.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTRamping.h; path = ot/OTRamping.h; sourceTree = ""; }; + 0C5F4FD71F952FEA00AF1616 /* secd-700-sftm.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "secd-700-sftm.m"; sourceTree = ""; }; 0C664AB2175926B20092D3D9 /* secdtests-entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "secdtests-entitlements.plist"; sourceTree = ""; }; + 0C770EC31FCF7E2000B5F0E2 /* OTCloudStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTCloudStore.m; path = ot/OTCloudStore.m; sourceTree = ""; }; 0C78F1C916A5E13400654E08 /* sectask_regressions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sectask_regressions.h; sourceTree = ""; }; 0C78F1CA16A5E1BF00654E08 /* sectask-10-sectask.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "sectask-10-sectask.c"; sourceTree = ""; }; 0C78F1CB16A5E1BF00654E08 /* sectask_ipc.defs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.mig; path = sectask_ipc.defs; sourceTree = ""; }; + 0C85E0031FB38BB6000343A7 /* OTTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OTTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 0C85E0041FB38BB7000343A7 /* OTTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; name = "OTTests-Info.plist"; path = "/Users/ma/git/security/OTTests-Info.plist"; sourceTree = ""; }; + 0C8A03451FDF42BA0042E8BE /* OTEscrowKeyTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTEscrowKeyTests.m; path = ot/tests/OTEscrowKeyTests.m; sourceTree = ""; }; + 0C8A034C1FDF4CCE0042E8BE /* OTLocalStoreTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTLocalStoreTests.m; path = ot/tests/OTLocalStoreTests.m; sourceTree = ""; }; + 0C8A034E1FDF60070042E8BE /* OTBottledPeerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTBottledPeerTests.m; path = ot/tests/OTBottledPeerTests.m; sourceTree = ""; }; + 0C8BBE891FC9DA5200580909 /* OTCloudStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTCloudStore.h; path = ot/OTCloudStore.h; sourceTree = ""; }; + 0C8BBE8A1FC9DA5300580909 /* OTIdentity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTIdentity.h; path = ot/OTIdentity.h; sourceTree = ""; }; + 0C8BBE8B1FC9DA5300580909 /* OTContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTContext.h; path = ot/OTContext.h; sourceTree = ""; }; + 0C8BBE8C1FC9DA5400580909 /* OTLocalStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTLocalStore.m; path = ot/OTLocalStore.m; sourceTree = ""; }; + 0C8BBE8D1FC9DA5400580909 /* OTIdentity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTIdentity.m; path = ot/OTIdentity.m; sourceTree = ""; }; + 0C8BBE8E1FC9DA5500580909 /* OTLocalStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTLocalStore.h; path = ot/OTLocalStore.h; sourceTree = ""; }; + 0C8BBE921FC9DA5700580909 /* OTEscrowKeys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTEscrowKeys.h; path = ot/OTEscrowKeys.h; sourceTree = ""; }; + 0C8BBE931FC9DA5700580909 /* OTBottledPeer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTBottledPeer.m; path = ot/OTBottledPeer.m; sourceTree = ""; }; + 0C8BBE951FC9DA5800580909 /* OTBottledPeer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTBottledPeer.h; path = ot/OTBottledPeer.h; sourceTree = ""; }; + 0C8BBE961FC9DA5900580909 /* OTEscrowKeys.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTEscrowKeys.m; path = ot/OTEscrowKeys.m; sourceTree = ""; }; + 0C8BBE971FC9DA5A00580909 /* OTDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTDefines.h; path = ot/OTDefines.h; sourceTree = ""; }; + 0C8BBE981FC9DA5A00580909 /* OTContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTContext.m; path = ot/OTContext.m; sourceTree = ""; }; + 0C8BBEAF1FC9DCA400580909 /* OTContextTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTContextTests.m; path = ot/tests/OTContextTests.m; sourceTree = ""; }; + 0C8BBEF71FCB405700580909 /* otctl.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = otctl.m; sourceTree = ""; }; + 0C8BBEF81FCB407700580909 /* otctl-Entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "otctl-Entitlements.plist"; sourceTree = ""; }; + 0C8BBF081FCB446400580909 /* otctl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = otctl; sourceTree = BUILT_PRODUCTS_DIR; }; + 0C8BBF0B1FCB452200580909 /* OTControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTControl.h; path = ot/OTControl.h; sourceTree = ""; }; + 0C8BBF0C1FCB452200580909 /* OTControlProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTControlProtocol.h; path = ot/OTControlProtocol.h; sourceTree = ""; }; + 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTControlProtocol.m; path = ot/OTControlProtocol.m; sourceTree = ""; }; + 0C8BBF0E1FCB452400580909 /* OTControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTControl.m; path = ot/OTControl.m; sourceTree = ""; }; + 0C8BBF0F1FCB481800580909 /* OTManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTManager.m; path = ot/OTManager.m; sourceTree = ""; }; + 0C8BBF101FCB486B00580909 /* OTManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTManager.h; path = ot/OTManager.h; sourceTree = ""; }; + 0CA4EBF1202B8D1C002B1D96 /* CloudKitKeychainSyncingTestsBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CloudKitKeychainSyncingTestsBase.h; sourceTree = ""; }; + 0CA4EBF2202B8D1D002B1D96 /* CloudKitKeychainSyncingTestsBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CloudKitKeychainSyncingTestsBase.m; sourceTree = ""; }; 0CAC5DBE1EB3DA4C00AD884B /* SOSPeerRateLimiter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SOSPeerRateLimiter.m; sourceTree = ""; }; 0CAC5DC51EB3DB3C00AD884B /* SOSPeerRateLimiter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSPeerRateLimiter.h; sourceTree = ""; }; 0CAD1E221E032D4000537693 /* AggregateDictionary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AggregateDictionary.framework; path = "../../Library/Developer/Xcode/iOS DeviceSupport/11.0 (15A168)/Symbols/System/Library/PrivateFrameworks/AggregateDictionary.framework"; sourceTree = ""; }; 0CB321F01464A95F00587CD3 /* CreateCerts.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = CreateCerts.sh; sourceTree = ""; }; + 0CB975502023B199008D6B48 /* OTRampingTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTRampingTests.m; path = ot/tests/OTRampingTests.m; sourceTree = ""; }; + 0CBDF64C1FFC951200433E0D /* OTBottledPeerTLK.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTBottledPeerTLK.m; path = ot/tests/OTBottledPeerTLK.m; sourceTree = ""; }; + 0CCCC7C720261D050024405E /* OT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OT.h; path = ot/OT.h; sourceTree = ""; }; + 0CCCC7C820261D310024405E /* OT.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OT.m; path = ot/OT.m; sourceTree = ""; }; 0CCDE7161EEB08220021A946 /* secd-156-timers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "secd-156-timers.m"; sourceTree = ""; }; 0CD8CB041ECA50780076F37F /* SOSPeerOTRTimer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SOSPeerOTRTimer.m; sourceTree = ""; }; 0CD8CB0C1ECA50D10076F37F /* SOSPeerOTRTimer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSPeerOTRTimer.h; sourceTree = ""; }; + 0CD9E7FF1FE05B6600F66C38 /* OTContextRecord.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTContextRecord.m; path = ot/OTContextRecord.m; sourceTree = ""; }; + 0CD9E8071FE05B8700F66C38 /* OTContextRecord.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTContextRecord.h; path = ot/OTContextRecord.h; sourceTree = ""; }; + 0CE1BCC61FCE11480017230E /* OTBottledPeerSigned.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTBottledPeerSigned.m; path = ot/OTBottledPeerSigned.m; sourceTree = ""; }; + 0CE1BCCD1FCE11610017230E /* OTBottledPeerSigned.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTBottledPeerSigned.h; path = ot/OTBottledPeerSigned.h; sourceTree = ""; }; + 0CE407AB1FD4769B00F59B31 /* OTCloudStoreState.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTCloudStoreState.m; path = ot/OTCloudStoreState.m; sourceTree = ""; }; + 0CE407B31FD476E000F59B31 /* OTCloudStoreState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTCloudStoreState.h; path = ot/OTCloudStoreState.h; sourceTree = ""; }; 0CE760471E12F2F200B4381E /* SOSAccountTrustClassic+Expansion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "SOSAccountTrustClassic+Expansion.m"; path = "SecureObjectSync/SOSAccountTrustClassic+Expansion.m"; sourceTree = ""; }; 0CE760491E12F30200B4381E /* SOSAccountTrustClassic+Circle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "SOSAccountTrustClassic+Circle.m"; path = "SecureObjectSync/SOSAccountTrustClassic+Circle.m"; sourceTree = ""; }; 0CE7604B1E12F56800B4381E /* SOSAccountTrustClassic+Identity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "SOSAccountTrustClassic+Identity.m"; path = "SecureObjectSync/SOSAccountTrustClassic+Identity.m"; sourceTree = ""; }; @@ -8547,6 +9059,10 @@ 0CE760511E1314F700B4381E /* SOSAccountTrustClassic+Identity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "SOSAccountTrustClassic+Identity.h"; path = "SecureObjectSync/SOSAccountTrustClassic+Identity.h"; sourceTree = ""; }; 0CE760531E13155100B4381E /* SOSAccountTrustClassic+Circle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "SOSAccountTrustClassic+Circle.h"; path = "SecureObjectSync/SOSAccountTrustClassic+Circle.h"; sourceTree = ""; }; 0CE760551E1316E900B4381E /* SOSAccountTrustClassic+Retirement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "SOSAccountTrustClassic+Retirement.h"; path = "SecureObjectSync/SOSAccountTrustClassic+Retirement.h"; sourceTree = ""; }; + 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libprequelite.tbd; path = usr/lib/libprequelite.tbd; sourceTree = SDKROOT; }; + 0CE98BAD1FA93AA900CF1D54 /* CKKSTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; name = "CKKSTests-Info.plist"; path = "/Volumes/Data/ma/git/security/CKKSTests-Info.plist"; sourceTree = ""; }; + 0CF0E2E31F8EE3B000BD18E4 /* SFTransactionMetric.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFTransactionMetric.m; sourceTree = ""; }; + 0CF0E2E71F8EE40700BD18E4 /* SFTransactionMetric.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFTransactionMetric.h; sourceTree = ""; }; 0CFC029B1D41650700E6283B /* libcoretls.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcoretls.dylib; path = usr/lib/libcoretls.dylib; sourceTree = SDKROOT; }; 107226D00D91DB32003CF14F /* SecTask.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecTask.c; sourceTree = ""; }; 107226D10D91DB32003CF14F /* SecTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecTask.h; path = sectask/SecTask.h; sourceTree = ""; }; @@ -8554,7 +9070,6 @@ 18351B8F14CB65870097860E /* SecBase64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecBase64.h; sourceTree = ""; }; 225394B41E3080A600D3CD9B /* libsecurity_codesigning_ios.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_codesigning_ios.a; sourceTree = BUILT_PRODUCTS_DIR; }; 2281820D17B4686C0067C9C9 /* BackgroundTaskAgent.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BackgroundTaskAgent.framework; path = System/Library/PrivateFrameworks/BackgroundTaskAgent.framework; sourceTree = SDKROOT; }; - 22C002A31AC9D33100B3469E /* OTAPKIAssetTool.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = OTAPKIAssetTool.xcconfig; sourceTree = ""; }; 24CBF8731E9D4E4500F09F0E /* kc-44-secrecoverypassword.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "kc-44-secrecoverypassword.c"; path = "regressions/kc-44-secrecoverypassword.c"; sourceTree = ""; }; 433E519D1B66D5F600482618 /* AppSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppSupport.framework; path = System/Library/PrivateFrameworks/AppSupport.framework; sourceTree = SDKROOT; }; 4381690C1B4EDCBD00C54D58 /* SOSCCAuthPlugin.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SOSCCAuthPlugin.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -8571,7 +9086,11 @@ 470415CF1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = seckeychainnetworkextensionstest; sourceTree = BUILT_PRODUCTS_DIR; }; 470415DB1E5E1534001F3D95 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RegressionTests/seckeychainnetworkextensionstest/main.m; sourceTree = SOURCE_ROOT; }; 470415DD1E5E15B3001F3D95 /* seckeychainnetworkextensionstest.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; name = seckeychainnetworkextensionstest.entitlements; path = RegressionTests/seckeychainnetworkextensionstest/seckeychainnetworkextensionstest.entitlements; sourceTree = SOURCE_ROOT; }; + 470ACEF21F58C3A600D1D5BD /* SecDbKeychainItemV7.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecDbKeychainItemV7.h; sourceTree = ""; }; + 470ACEF31F58C3A600D1D5BD /* SecDbKeychainItemV7.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecDbKeychainItemV7.m; sourceTree = ""; }; 471024D91E79CB6D00844C09 /* CKKSTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSTests.h; sourceTree = ""; }; + 472339611FD7155C00CB6A72 /* libprequelite.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libprequelite.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.Internal.sdk/usr/lib/libprequelite.dylib; sourceTree = DEVELOPER_DIR; }; + 472339681FD7156700CB6A72 /* CoreCDP.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreCDP.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.Internal.sdk/System/Library/PrivateFrameworks/CoreCDP.framework; sourceTree = DEVELOPER_DIR; }; 4723C9BC1F152EB10082882F /* SFSQLite.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFSQLite.m; sourceTree = ""; }; 4723C9BD1F152EB10082882F /* SFSQLite.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFSQLite.h; sourceTree = ""; }; 4723C9BE1F152EB10082882F /* SFObjCType.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFObjCType.m; sourceTree = ""; }; @@ -8579,11 +9098,34 @@ 4723C9C01F152EB10082882F /* SFObjCType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFObjCType.h; sourceTree = ""; }; 4723C9C11F152EB10082882F /* SFSQLiteStatement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFSQLiteStatement.h; sourceTree = ""; }; 4723C9D11F1531970082882F /* CKKSLoggerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSLoggerTests.m; sourceTree = ""; }; - 4723C9DA1F1540CE0082882F /* SFAnalyticsLogger.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFAnalyticsLogger.h; sourceTree = ""; }; - 4723C9DB1F1540CE0082882F /* SFAnalyticsLogger.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFAnalyticsLogger.m; sourceTree = ""; }; + 4723C9DA1F1540CE0082882F /* SFAnalytics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFAnalytics.h; sourceTree = ""; }; + 4723C9DB1F1540CE0082882F /* SFAnalytics.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFAnalytics.m; sourceTree = ""; }; + 4727FBB71F9918580003AE36 /* secdxctests_ios.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = secdxctests_ios.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 4727FBB91F9918590003AE36 /* KeychainCryptoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KeychainCryptoTests.m; sourceTree = ""; }; + 4727FBBB1F9918590003AE36 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4727FBC41F991C460003AE36 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 4727FBCA1F991F510003AE36 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; + 4727FBCC1F991F660003AE36 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.sdk/usr/lib/libsqlite3.dylib; sourceTree = DEVELOPER_DIR; }; + 4727FBCF1F991F820003AE36 /* SecurityFoundation.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SecurityFoundation.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4727FBD01F991F990003AE36 /* libMobileGestalt.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libMobileGestalt.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.sdk/usr/lib/libMobileGestalt.dylib; sourceTree = DEVELOPER_DIR; }; + 4727FBD21F9920290003AE36 /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.sdk/System/Library/Frameworks/CloudKit.framework; sourceTree = DEVELOPER_DIR; }; + 4727FBD41F9920510003AE36 /* ProtocolBuffer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ProtocolBuffer.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.Internal.sdk/System/Library/PrivateFrameworks/ProtocolBuffer.framework; sourceTree = DEVELOPER_DIR; }; + 4727FBD81F9920BB0003AE36 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.Internal.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = DEVELOPER_DIR; }; + 4727FBDA1F9920CB0003AE36 /* WirelessDiagnostics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WirelessDiagnostics.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.Internal.sdk/System/Library/PrivateFrameworks/WirelessDiagnostics.framework; sourceTree = DEVELOPER_DIR; }; + 4727FBDC1F9920F10003AE36 /* libaks_acl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libaks_acl.a; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.Internal.sdk/usr/local/lib/libaks_acl.a; sourceTree = DEVELOPER_DIR; }; + 4727FBDE1F99211D0003AE36 /* libaks.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libaks.a; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.Internal.sdk/usr/local/lib/libaks.a; sourceTree = DEVELOPER_DIR; }; + 4727FBE01F99212F0003AE36 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.Internal.sdk/System/Library/Frameworks/IOKit.framework; sourceTree = DEVELOPER_DIR; }; + 4727FBE21F9921660003AE36 /* MobileKeyBag.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileKeyBag.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.Internal.sdk/System/Library/PrivateFrameworks/MobileKeyBag.framework; sourceTree = DEVELOPER_DIR; }; + 4727FBE41F99217A0003AE36 /* SharedWebCredentials.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SharedWebCredentials.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.Internal.sdk/System/Library/PrivateFrameworks/SharedWebCredentials.framework; sourceTree = DEVELOPER_DIR; }; + 4727FBE61F9921890003AE36 /* ApplePushService.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplePushService.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.Internal.sdk/System/Library/PrivateFrameworks/ApplePushService.framework; sourceTree = DEVELOPER_DIR; }; + 4727FBE81F9921D00003AE36 /* libACM.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libACM.a; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.Internal.sdk/usr/local/lib/libACM.a; sourceTree = DEVELOPER_DIR; }; + 473337771FDAFBCC00E19F30 /* SFKeychainControlManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFKeychainControlManager.h; sourceTree = ""; }; + 473337781FDAFBCC00E19F30 /* SFKeychainControlManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFKeychainControlManager.m; sourceTree = ""; }; + 473337821FDB29A200E19F30 /* KeychainCheck.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeychainCheck.h; sourceTree = ""; }; + 473337831FDB29A200E19F30 /* KeychainCheck.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KeychainCheck.m; sourceTree = ""; }; 4738AE241E732D7E006BD53D /* SharedWebCredentials.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SharedWebCredentials.framework; path = System/Library/PrivateFrameworks/SharedWebCredentials.framework; sourceTree = SDKROOT; }; 474B5FBF1E662E21007546F8 /* SecurityFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SecurityFoundation.framework; path = ../../Builds/iphoneos11.0.internal/SecurityFoundation.framework; sourceTree = ""; }; - 475F371F1EE8F23900248FB5 /* SFAnalyticsLogging.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = SFAnalyticsLogging.plist; sourceTree = ""; }; + 475F371F1EE8F23900248FB5 /* SFAnalytics.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = SFAnalytics.plist; sourceTree = ""; }; 476541631F339F6300413F65 /* SecdWatchdog.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecdWatchdog.h; sourceTree = ""; }; 476541641F339F6300413F65 /* SecdWatchdog.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecdWatchdog.m; sourceTree = ""; }; 476D87391E6750E200190352 /* CKKSManifestLeafRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSManifestLeafRecord.h; sourceTree = ""; }; @@ -8595,13 +9137,32 @@ 47702B2E1E5F492C00B29577 /* seckeychainnetworkextensionunauthorizedaccesstest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = seckeychainnetworkextensionunauthorizedaccesstest; sourceTree = BUILT_PRODUCTS_DIR; }; 47702B351E5F495C00B29577 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RegressionTests/seckeychainnetworkextensionunauthorizedaccesstest/main.m; sourceTree = SOURCE_ROOT; }; 47702B381E5F499A00B29577 /* seckeychainnetworkextensionunauthorizedaccesstest.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; name = seckeychainnetworkextensionunauthorizedaccesstest.entitlements; path = RegressionTests/seckeychainnetworkextensionunauthorizedaccesstest/seckeychainnetworkextensionunauthorizedaccesstest.entitlements; sourceTree = SOURCE_ROOT; }; - 479108B51EE879F9008CEFA0 /* CKKSAnalyticsLogger.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CKKSAnalyticsLogger.h; path = ckks/CKKSAnalyticsLogger.h; sourceTree = ""; }; - 479108B61EE879F9008CEFA0 /* CKKSAnalyticsLogger.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = CKKSAnalyticsLogger.m; path = ckks/CKKSAnalyticsLogger.m; sourceTree = ""; }; + 477A1F4C20320E4900ACD81D /* Accounts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accounts.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.Internal.sdk/System/Library/Frameworks/Accounts.framework; sourceTree = DEVELOPER_DIR; }; + 477A1FE1203763A500ACD81D /* KeychainAPITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KeychainAPITests.m; sourceTree = ""; }; + 477A1FEB2037A0E000ACD81D /* KeychainXCTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeychainXCTest.h; sourceTree = ""; }; + 477A1FEC2037A0E000ACD81D /* KeychainXCTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KeychainXCTest.m; sourceTree = ""; }; + 478D429C1FD72A8100CAB645 /* secdxctests_mac.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = secdxctests_mac.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 479108B51EE879F9008CEFA0 /* CKKSAnalytics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CKKSAnalytics.h; path = ckks/CKKSAnalytics.h; sourceTree = ""; }; + 479108B61EE879F9008CEFA0 /* CKKSAnalytics.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = CKKSAnalytics.m; path = ckks/CKKSAnalytics.m; sourceTree = ""; }; + 47922D171FAA65120008F7E0 /* SecDbKeychainAKSSerializedWrappedKey.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = SecDbKeychainAKSSerializedWrappedKey.proto; sourceTree = ""; }; + 47922D201FAA75FF0008F7E0 /* SecDbKeychainSerializedMetadata.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = SecDbKeychainSerializedMetadata.proto; sourceTree = ""; }; + 47922D2C1FAA77970008F7E0 /* SecDbKeychainSerializedSecretData.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = SecDbKeychainSerializedSecretData.proto; sourceTree = ""; }; + 47922D361FAA7C030008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecDbKeychainSerializedAKSWrappedKey.m; sourceTree = ""; }; + 47922D371FAA7C040008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecDbKeychainSerializedAKSWrappedKey.h; sourceTree = ""; }; + 47922D3A1FAA7C0F0008F7E0 /* SecDbKeychainSerializedMetadata.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecDbKeychainSerializedMetadata.m; sourceTree = ""; }; + 47922D3B1FAA7C100008F7E0 /* SecDbKeychainSerializedMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecDbKeychainSerializedMetadata.h; sourceTree = ""; }; + 47922D3E1FAA7C1A0008F7E0 /* SecDbKeychainSerializedSecretData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecDbKeychainSerializedSecretData.h; sourceTree = ""; }; + 47922D3F1FAA7C1B0008F7E0 /* SecDbKeychainSerializedSecretData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecDbKeychainSerializedSecretData.m; sourceTree = ""; }; + 47922D4E1FAA7D5C0008F7E0 /* SecDbKeychainSerializedItemV7.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = SecDbKeychainSerializedItemV7.proto; sourceTree = ""; }; + 47922D501FAA7DF60008F7E0 /* SecDbKeychainSerializedItemV7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecDbKeychainSerializedItemV7.h; sourceTree = ""; }; + 47922D511FAA7DF70008F7E0 /* SecDbKeychainSerializedItemV7.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecDbKeychainSerializedItemV7.m; sourceTree = ""; }; + 47A05B101FDB5A8B00D0816E /* SFKeychainControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFKeychainControl.h; sourceTree = ""; }; 47C51B841EEA657D0032D9E5 /* SecurityUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SecurityUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 47C51B861EEA657D0032D9E5 /* SecurityUnitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecurityUnitTests.m; sourceTree = ""; }; 47C51B881EEA657D0032D9E5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 47CEED1E1E60DE900044EAB4 /* CKKSManifest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSManifest.h; sourceTree = ""; }; 47CEED1F1E60DE900044EAB4 /* CKKSManifest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSManifest.m; sourceTree = ""; }; + 47D1838B1FB3827700CFCD89 /* OCMock.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OCMock.framework; path = Platforms/iPhoneOS.platform/Developer/AppleInternal/Library/Frameworks/OCMock.framework; sourceTree = DEVELOPER_DIR; }; 48284A041D1DB06E00C76CB7 /* README_os_log_prefs.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README_os_log_prefs.txt; path = OSX/sec/os_log/README_os_log_prefs.txt; sourceTree = ""; }; 483E79891DC875F2005C0008 /* secd-67-prefixedKeyIDs.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "secd-67-prefixedKeyIDs.m"; sourceTree = ""; }; 485B64081DC16E8300B771B9 /* SOSKeyedPubKeyIdentifier.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SOSKeyedPubKeyIdentifier.c; sourceTree = ""; }; @@ -8735,7 +9296,6 @@ 4CEF4CA70C5551FE00062475 /* SecCertificateInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCertificateInternal.h; sourceTree = ""; }; 4CF0484A0A5D988F00268236 /* SecItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecItem.h; path = keychain/SecItem.h; sourceTree = ""; }; 4CF0487F0A5F016300268236 /* SecItemPriv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SecItemPriv.h; path = keychain/SecItemPriv.h; sourceTree = ""; }; - 4CF41D0A0BBB4022005F3248 /* SecCertificatePath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCertificatePath.h; sourceTree = ""; }; 4CF4C19C171E0EA600877419 /* Accounts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accounts.framework; path = System/Library/Frameworks/Accounts.framework; sourceTree = SDKROOT; }; 4CF730310EF9CDE300E17471 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; 4CFBF5F10D5A92E100969BBE /* SecPolicyInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecPolicyInternal.h; sourceTree = ""; }; @@ -8756,8 +9316,8 @@ 5346481C173322BD00FE9172 /* KeychainSyncAccountNotification.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeychainSyncAccountNotification.h; sourceTree = ""; }; 5346481D173322BD00FE9172 /* KeychainSyncAccountNotification.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeychainSyncAccountNotification.m; sourceTree = ""; }; 53C0E1F2177FAC2C00F8A018 /* English */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/CloudKeychain.strings; sourceTree = ""; }; - 5DDD0BDD16D6740E00D6C0D6 /* com.apple.OTAPKIAssetTool.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.OTAPKIAssetTool.plist; sourceTree = ""; }; - 5DDD0BDE16D6740E00D6C0D6 /* OTAPKIAssetTool-entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "OTAPKIAssetTool-entitlements.plist"; sourceTree = ""; }; + 5A94C6D1203CC1C60066E391 /* AOSAccountsLite.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AOSAccountsLite.framework; path = System/Library/PrivateFrameworks/AOSAccountsLite.framework; sourceTree = SDKROOT; }; + 5A94C6D4203CC2590066E391 /* AuthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AuthKit.framework; path = System/Library/PrivateFrameworks/AuthKit.framework; sourceTree = SDKROOT; }; 5E10992519A5E55800A60E2B /* ISACLProtectedItems.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ISACLProtectedItems.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 5E10992919A5E55800A60E2B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5E10994E19A5E5CE00A60E2B /* ISProtectedItems.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = ISProtectedItems.plist; sourceTree = ""; }; @@ -8777,7 +9337,10 @@ 5EBE247C1B00CCAE0007DB0E /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; 6C0B0C3D1E2537C6007F95E5 /* WirelessDiagnostics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WirelessDiagnostics.framework; path = System/Library/PrivateFrameworks/WirelessDiagnostics.framework; sourceTree = SDKROOT; }; 6C0B0C441E2537CC007F95E5 /* ProtocolBuffer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ProtocolBuffer.framework; path = System/Library/PrivateFrameworks/ProtocolBuffer.framework; sourceTree = SDKROOT; }; + 6C1260F21F7D5F25001B2EEC /* securityuploadd-osx.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "securityuploadd-osx.plist"; sourceTree = ""; }; + 6C1260FA1F7D631D001B2EEC /* securityuploadd-ios.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "securityuploadd-ios.plist"; sourceTree = ""; }; 6C1520CD1DCCF57A00C85C6D /* secd.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = secd.8; sourceTree = ""; }; + 6C1A29FC1F882788002312D8 /* SFAnalyticsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFAnalyticsTests.m; sourceTree = ""; }; 6C34462F1E24F6BE00F9522B /* CKKSRateLimiterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSRateLimiterTests.m; sourceTree = ""; }; 6C34464F1E2534E800F9522B /* AWDKeychainCKKSRateLimiterAggregatedScores.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AWDKeychainCKKSRateLimiterAggregatedScores.h; path = analytics/awd/AWDKeychainCKKSRateLimiterAggregatedScores.h; sourceTree = ""; }; 6C3446501E2534E800F9522B /* AWDKeychainCKKSRateLimiterAggregatedScores.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AWDKeychainCKKSRateLimiterAggregatedScores.m; path = analytics/awd/AWDKeychainCKKSRateLimiterAggregatedScores.m; sourceTree = ""; }; @@ -8787,27 +9350,57 @@ 6C3446541E2534E800F9522B /* AWDKeychainCKKSRateLimiterTopWriters.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AWDKeychainCKKSRateLimiterTopWriters.m; path = analytics/awd/AWDKeychainCKKSRateLimiterTopWriters.m; sourceTree = ""; }; 6C3446551E2534E800F9522B /* AwdMetadata-0x60-Keychain.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = "AwdMetadata-0x60-Keychain.bin"; path = "analytics/awd/AwdMetadata-0x60-Keychain.bin"; sourceTree = ""; }; 6C3446561E2534E800F9522B /* AWDMetricIds_Keychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AWDMetricIds_Keychain.h; path = analytics/awd/AWDMetricIds_Keychain.h; sourceTree = ""; }; + 6C4605B81F882B9B001421B6 /* KeychainAnalyticsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KeychainAnalyticsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 6C5232D41E3C183F00330DB1 /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks/CloudKit.framework; sourceTree = DEVELOPER_DIR; }; 6C588D791EAA149F00D7E322 /* RateLimiterTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RateLimiterTests.m; sourceTree = ""; }; + 6C5B101B1F91613E009B091E /* supdctl-Entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "supdctl-Entitlements.plist"; sourceTree = ""; }; + 6C5B10211F9164F5009B091E /* securityuploadd.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = securityuploadd.8; sourceTree = ""; }; + 6C69517C1F758E1000F68F91 /* supdProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = supdProtocol.h; sourceTree = ""; }; + 6C69517D1F758E1000F68F91 /* supd.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = supd.h; sourceTree = ""; }; + 6C69517E1F758E1000F68F91 /* supd.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = supd.m; sourceTree = ""; }; + 6C6951801F758E1000F68F91 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 6C6951821F758E1000F68F91 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFAnalyticsSQLiteStore.m; sourceTree = ""; }; + 6C69518E1F75A7DC00F68F91 /* SFAnalyticsSQLiteStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFAnalyticsSQLiteStore.h; sourceTree = ""; }; + 6C69518F1F75A8C100F68F91 /* SFAnalyticsDefines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFAnalyticsDefines.h; sourceTree = ""; }; + 6C758CB01F8826100075BD78 /* SupdTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SupdTests.m; sourceTree = ""; }; + 6C758CB21F8826100075BD78 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6C7BB0032006B4EE004D1B6B /* SOSAnalytics.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SOSAnalytics.m; path = Analytics/Clients/SOSAnalytics.m; sourceTree = SOURCE_ROOT; }; + 6C7BB0042006B4EF004D1B6B /* SOSAnalytics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SOSAnalytics.h; path = Analytics/Clients/SOSAnalytics.h; sourceTree = SOURCE_ROOT; }; 6C860C741F4F63AD004100A1 /* SOSEnsureBackup.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSEnsureBackup.h; sourceTree = ""; }; 6C860C7A1F4F63DB004100A1 /* SOSEnsureBackup.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SOSEnsureBackup.m; sourceTree = ""; }; 6C869A771F54C2D700957298 /* AWDKeychainSOSKeychainBackupFailed.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AWDKeychainSOSKeychainBackupFailed.m; path = analytics/awd/AWDKeychainSOSKeychainBackupFailed.m; sourceTree = ""; }; 6C869A781F54C2D700957298 /* AWDKeychainSOSKeychainBackupFailed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AWDKeychainSOSKeychainBackupFailed.h; path = analytics/awd/AWDKeychainSOSKeychainBackupFailed.h; sourceTree = ""; }; + 6C8CE6BB1FA248B50032ADF0 /* SFAnalyticsActivityTracker+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SFAnalyticsActivityTracker+Internal.h"; sourceTree = ""; }; + 6C8CE6C31FA24A670032ADF0 /* SFAnalyticsSampler+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SFAnalyticsSampler+Internal.h"; sourceTree = ""; }; 6C9808611E788AEB00E70590 /* CKKSCloudKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CKKSCloudKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 6C98089D1E788AFD00E70590 /* CKKSCloudKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CKKSCloudKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 6C9AA79E1F7C1D8F00D08296 /* supdctl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = supdctl; sourceTree = BUILT_PRODUCTS_DIR; }; + 6C9AA7A01F7C1D9000D08296 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 6CA2B9431E9F9F5700C43444 /* RateLimiter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RateLimiter.h; sourceTree = ""; }; + 6CAA8D201F842FB3007B6E03 /* securityuploadd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = securityuploadd; sourceTree = BUILT_PRODUCTS_DIR; }; 6CB5F4751E4025AB00DBF3F0 /* CKKSCloudKitTestsInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = CKKSCloudKitTestsInfo.plist; sourceTree = ""; }; 6CB5F4781E402E5700DBF3F0 /* KeychainCKKS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = KeychainCKKS.plist; path = testrunner/KeychainCKKS.plist; sourceTree = ""; }; 6CB5F4791E402E5700DBF3F0 /* KeychainEntitledTestRunner-Entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "KeychainEntitledTestRunner-Entitlements.plist"; sourceTree = ""; }; 6CB5F47A1E402E5700DBF3F0 /* KeychainEntitledTestRunner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeychainEntitledTestRunner.m; sourceTree = ""; }; + 6CB96BB41F966E0C00E11457 /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; }; + 6CBF65371FA147E500A68667 /* SFAnalyticsActivityTracker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFAnalyticsActivityTracker.h; sourceTree = ""; }; + 6CBF65381FA147E500A68667 /* SFAnalyticsActivityTracker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFAnalyticsActivityTracker.m; sourceTree = ""; }; 6CC185971E24E87D009657D8 /* CKKSRateLimiter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSRateLimiter.h; sourceTree = ""; }; 6CC185981E24E87D009657D8 /* CKKSRateLimiter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSRateLimiter.m; sourceTree = ""; }; 6CC7F5B31E9F99EE0014AE63 /* RateLimiter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RateLimiter.m; sourceTree = ""; }; + 6CC952421FB4C5CA0051A823 /* SFAnalytics+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SFAnalytics+Internal.h"; sourceTree = ""; }; 6CCDF7841E3C25FA003F2555 /* KeychainEntitledTestRunner */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = KeychainEntitledTestRunner; sourceTree = BUILT_PRODUCTS_DIR; }; 6CCDF78B1E3C26BC003F2555 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/MacOSX.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 6CCDF7911E3C2D69003F2555 /* CKKSCloudKitTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSCloudKitTests.m; sourceTree = ""; }; 6CD8D3B11EB22114009AC7DC /* AWDKeychainSecDbMarkedCorrupt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AWDKeychainSecDbMarkedCorrupt.h; path = analytics/awd/AWDKeychainSecDbMarkedCorrupt.h; sourceTree = ""; }; 6CD8D3B21EB22114009AC7DC /* AWDKeychainSecDbMarkedCorrupt.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AWDKeychainSecDbMarkedCorrupt.m; path = analytics/awd/AWDKeychainSecDbMarkedCorrupt.m; sourceTree = ""; }; + 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SFAnalyticsMultiSampler.m; sourceTree = ""; }; + 6CDB5FF31FA78CB500410924 /* SFAnalyticsMultiSampler+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SFAnalyticsMultiSampler+Internal.h"; sourceTree = ""; }; + 6CDB5FF41FA78CB500410924 /* SFAnalyticsMultiSampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SFAnalyticsMultiSampler.h; sourceTree = ""; }; + 6CDB600E1FA92C1700410924 /* securityuploadd-Entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "securityuploadd-Entitlements.plist"; sourceTree = ""; }; + 6CDF8DE51F95562B00140B54 /* SFAnalyticsSampler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFAnalyticsSampler.h; sourceTree = ""; }; + 6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFAnalyticsSampler.m; sourceTree = ""; }; 6CE22D6F1E49206600974785 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.0.Internal.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; 6CF4A0B41E45488B00ECD7B5 /* KeychainEntitledTestApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KeychainEntitledTestApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 6CF4A0B61E45488B00ECD7B5 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; @@ -8828,18 +9421,16 @@ 6CF4A0EE1E4549F300ECD7B5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 6CF4A0F11E4549F300ECD7B5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 6CF4A0F31E4549F300ECD7B5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6CFDC4561F907E1D00646DBB /* libprequelite.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libprequelite.tbd; path = usr/lib/libprequelite.tbd; sourceTree = SDKROOT; }; 7221843E1EC6782A004C7BED /* sec_action.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sec_action.c; path = src/sec_action.c; sourceTree = ""; }; 7221843F1EC6782A004C7BED /* sec_action.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sec_action.h; path = src/sec_action.h; sourceTree = ""; }; 7273402816CAFB3C0096622A /* MobileAsset.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileAsset.framework; path = System/Library/PrivateFrameworks/MobileAsset.framework; sourceTree = SDKROOT; }; 7281E0861DFD015A0021E1B7 /* SOSAccountGetSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSAccountGetSet.m; sourceTree = ""; }; 7281E08B1DFD0A380021E1B7 /* secd-80-views-alwayson.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-80-views-alwayson.m"; sourceTree = ""; }; 7281E08E1DFD0D810021E1B7 /* secd-210-keyinterest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-210-keyinterest.m"; sourceTree = ""; }; - 728B56A116D59979008FA3AB /* OTAPKIAssetTool */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = OTAPKIAssetTool; sourceTree = BUILT_PRODUCTS_DIR; }; 72B368BD179891FC004C37CE /* AggregateDictionary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AggregateDictionary.framework; path = System/Library/PrivateFrameworks/AggregateDictionary.framework; sourceTree = SDKROOT; }; 72C3EC2D1705F24E0040C87C /* ManagedConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ManagedConfiguration.framework; path = System/Library/PrivateFrameworks/ManagedConfiguration.framework; sourceTree = SDKROOT; }; - 72CD2BBB16D59AE30064EEE1 /* OTAServiceApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTAServiceApp.m; sourceTree = ""; }; - 72CD2BBC16D59AE30064EEE1 /* OTAServiceApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTAServiceApp.h; sourceTree = ""; }; - 72CD2BBD16D59AE30064EEE1 /* OTAServicemain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTAServicemain.m; sourceTree = ""; }; + 72D1E5F3202FE43C003A38C5 /* secdmock_db_version_10_5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = secdmock_db_version_10_5.h; sourceTree = ""; }; 78F92F10195128D70023B54B /* SecECKeyPriv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecECKeyPriv.h; sourceTree = ""; }; 7901790E12D51F7200CA4D44 /* SecCmsBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsBase.h; sourceTree = ""; }; 7901790F12D51F7200CA4D44 /* SecCmsContentInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsContentInfo.h; sourceTree = ""; }; @@ -8899,6 +9490,14 @@ BE22FBD01EE2084100893431 /* Config.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Config.m; path = manifeststresstest/Config.m; sourceTree = ""; }; BE22FBFC1EE23D9100893431 /* mark.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = mark.m; path = manifeststresstest/mark.m; sourceTree = ""; }; BE22FC031EE23DA600893431 /* mark.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = mark.h; path = manifeststresstest/mark.h; sourceTree = ""; }; + BE2AD2B11FDA07EF00739F96 /* OTBottledPeerRecord.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTBottledPeerRecord.h; path = ot/OTBottledPeerRecord.h; sourceTree = ""; }; + BE2AD2B21FDA07EF00739F96 /* OTBottledPeerRecord.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTBottledPeerRecord.m; path = ot/OTBottledPeerRecord.m; sourceTree = ""; }; + BE3405A11FD71CC800933DAC /* OTBottle.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = OTBottle.proto; sourceTree = ""; }; + BE3405A31FD71DA400933DAC /* OTBottle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTBottle.m; sourceTree = ""; }; + BE3405A41FD71DA600933DAC /* OTBottle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTBottle.h; sourceTree = ""; }; + BE3405A51FD720C900933DAC /* OTBottleContents.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = OTBottleContents.proto; sourceTree = ""; }; + BE3405A61FD7210200933DAC /* OTBottleContents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTBottleContents.h; sourceTree = ""; }; + BE3405A71FD7210300933DAC /* OTBottleContents.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTBottleContents.m; sourceTree = ""; }; BE442BC118B7FDB800F24DAE /* swcagent */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = swcagent; sourceTree = BUILT_PRODUCTS_DIR; }; BE4AC9A118B7FFAD00B84964 /* swcagent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = swcagent.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; BE4AC9AD18B7FFC800B84964 /* com.apple.security.swcagent.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = com.apple.security.swcagent.plist; sourceTree = ""; }; @@ -8906,9 +9505,23 @@ BE6215BD1DB6E69100961E15 /* si-84-sectrust-allowlist.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "si-84-sectrust-allowlist.m"; sourceTree = ""; }; BE8351D41EC0EEDD00ACD5FD /* framework_requiring_modern_objc_runtime.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = framework_requiring_modern_objc_runtime.xcconfig; path = xcconfig/framework_requiring_modern_objc_runtime.xcconfig; sourceTree = ""; }; BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; + BEB0B0CE1FFC37E3007E6A83 /* OTPrivateKey.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = OTPrivateKey.proto; sourceTree = ""; }; + BEB0B0D41FFC3D32007E6A83 /* OTPrivateKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTPrivateKey.m; sourceTree = ""; }; + BEB0B0D51FFC3D33007E6A83 /* OTPrivateKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTPrivateKey.h; sourceTree = ""; }; + BEB0B0D91FFC45C2007E6A83 /* OTPrivateKey+SF.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "OTPrivateKey+SF.h"; path = "ot/OTPrivateKey+SF.h"; sourceTree = ""; }; + BEB0B0DA1FFC45C2007E6A83 /* OTPrivateKey+SF.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "OTPrivateKey+SF.m"; path = "ot/OTPrivateKey+SF.m"; sourceTree = ""; }; + BEB9E9E51FFF193D00676593 /* si-88-sectrust-valid.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "si-88-sectrust-valid.m"; path = "OSX/shared_regressions/si-88-sectrust-valid.m"; sourceTree = SOURCE_ROOT; }; + BEB9EA2E1FFF1AF600676593 /* si-88-sectrust-valid-data */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "si-88-sectrust-valid-data"; sourceTree = ""; }; BED208DD1EDF950E00753952 /* manifeststresstest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = manifeststresstest; sourceTree = BUILT_PRODUCTS_DIR; }; BED208E61EDF971600753952 /* manifeststresstest.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; name = manifeststresstest.entitlements; path = manifeststresstest/manifeststresstest.entitlements; sourceTree = ""; }; BED208E71EDF971600753952 /* manifeststresstest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = manifeststresstest.m; path = manifeststresstest/manifeststresstest.m; sourceTree = ""; }; + BEE4B1861FFD57D800777D39 /* OTAuthenticatedCiphertext.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = OTAuthenticatedCiphertext.proto; sourceTree = ""; }; + BEE4B18E1FFD5F9000777D39 /* OTAuthenticatedCiphertext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTAuthenticatedCiphertext.h; sourceTree = ""; }; + BEE4B18F1FFD5F9100777D39 /* OTAuthenticatedCiphertext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTAuthenticatedCiphertext.m; sourceTree = ""; }; + BEE4B1901FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "OTAuthenticatedCiphertext+SF.h"; path = "ot/OTAuthenticatedCiphertext+SF.h"; sourceTree = ""; }; + BEE4B1911FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "OTAuthenticatedCiphertext+SF.m"; path = "ot/OTAuthenticatedCiphertext+SF.m"; sourceTree = ""; }; + BEE4B1961FFDAFE600777D39 /* SFPublicKey+SPKI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SFPublicKey+SPKI.h"; path = "ot/SFPublicKey+SPKI.h"; sourceTree = ""; }; + BEE4B1971FFDAFE600777D39 /* SFECPublicKey+SPKI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "SFECPublicKey+SPKI.m"; path = "ot/SFECPublicKey+SPKI.m"; sourceTree = ""; }; BEEB47D71EA189F5004AA5C6 /* SecTrustStatusCodes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecTrustStatusCodes.c; sourceTree = ""; }; BEEB47D81EA189F5004AA5C6 /* SecTrustStatusCodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecTrustStatusCodes.h; sourceTree = ""; }; BEF88C281EAFFC3F00357577 /* TrustedPeers.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TrustedPeers.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -8987,6 +9600,7 @@ D40B6A871E2B5F9900CD6EE5 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks/CoreFoundation.framework; sourceTree = DEVELOPER_DIR; }; D40B6A881E2B5F9900CD6EE5 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; D41149A01E7C935D00C078C7 /* AppleiPhoneDeviceCACertificates.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppleiPhoneDeviceCACertificates.h; sourceTree = ""; }; + D4119E72202BDF2B0048587B /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; D41257CF1E9410A300781F23 /* trustd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = trustd; sourceTree = BUILT_PRODUCTS_DIR; }; D41257E91E941CF200781F23 /* com.apple.trustd.agent.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.trustd.agent.plist; path = OSX/trustd/macOS/com.apple.trustd.agent.plist; sourceTree = ""; }; D41257EA1E941CF200781F23 /* com.apple.trustd.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.trustd.plist; path = OSX/trustd/macOS/com.apple.trustd.plist; sourceTree = ""; }; @@ -9001,7 +9615,7 @@ D43DBED61E99D17100C04AEA /* asynchttp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = asynchttp.h; path = OSX/sec/securityd/asynchttp.h; sourceTree = ""; }; D43DBED71E99D17100C04AEA /* nameconstraints.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nameconstraints.c; path = OSX/sec/securityd/nameconstraints.c; sourceTree = ""; }; D43DBED81E99D17100C04AEA /* nameconstraints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = nameconstraints.h; path = OSX/sec/securityd/nameconstraints.h; sourceTree = ""; }; - D43DBED91E99D17100C04AEA /* OTATrustUtilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = OTATrustUtilities.c; path = OSX/sec/securityd/OTATrustUtilities.c; sourceTree = ""; }; + D43DBED91E99D17100C04AEA /* OTATrustUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTATrustUtilities.m; path = OSX/sec/securityd/OTATrustUtilities.m; sourceTree = ""; }; D43DBEDA1E99D17100C04AEA /* OTATrustUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTATrustUtilities.h; path = OSX/sec/securityd/OTATrustUtilities.h; sourceTree = ""; }; D43DBEDB1E99D17100C04AEA /* personalization.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = personalization.c; path = OSX/sec/securityd/personalization.c; sourceTree = ""; }; D43DBEDC1E99D17100C04AEA /* personalization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = personalization.h; path = OSX/sec/securityd/personalization.h; sourceTree = ""; }; @@ -9029,14 +9643,26 @@ D43DBEF21E99D17300C04AEA /* SecRevocationDb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecRevocationDb.h; path = OSX/sec/securityd/SecRevocationDb.h; sourceTree = ""; }; D43DBEF31E99D17300C04AEA /* SecRevocationServer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecRevocationServer.c; path = OSX/sec/securityd/SecRevocationServer.c; sourceTree = ""; }; D43DBEF41E99D17300C04AEA /* SecRevocationServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecRevocationServer.h; path = OSX/sec/securityd/SecRevocationServer.h; sourceTree = ""; }; - D43DBEF51E99D17300C04AEA /* SecTrustLoggingServer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecTrustLoggingServer.c; path = OSX/sec/securityd/SecTrustLoggingServer.c; sourceTree = ""; }; + D43DBEF51E99D17300C04AEA /* SecTrustLoggingServer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SecTrustLoggingServer.m; path = OSX/sec/securityd/SecTrustLoggingServer.m; sourceTree = ""; }; D43DBEF61E99D17300C04AEA /* SecTrustLoggingServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecTrustLoggingServer.h; path = OSX/sec/securityd/SecTrustLoggingServer.h; sourceTree = ""; }; D43DBEF71E99D17300C04AEA /* SecTrustServer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecTrustServer.c; path = OSX/sec/securityd/SecTrustServer.c; sourceTree = ""; }; D43DBEF81E99D17300C04AEA /* SecTrustServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecTrustServer.h; path = OSX/sec/securityd/SecTrustServer.h; sourceTree = ""; }; D43DBEF91E99D17300C04AEA /* SecTrustStoreServer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecTrustStoreServer.c; path = OSX/sec/securityd/SecTrustStoreServer.c; sourceTree = ""; }; D43DBEFA1E99D17300C04AEA /* SecTrustStoreServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecTrustStoreServer.h; path = OSX/sec/securityd/SecTrustStoreServer.h; sourceTree = ""; }; + D43DDE511F620F09009742A5 /* SecPolicyChecks.list */ = {isa = PBXFileReference; lastKnownFileType = text; path = SecPolicyChecks.list; sourceTree = ""; }; + D43DDE581F638061009742A5 /* SecPolicy.list */ = {isa = PBXFileReference; lastKnownFileType = text; path = SecPolicy.list; sourceTree = ""; }; D45068681E948A9E00FA7675 /* entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = entitlements.plist; path = OSX/trustd/macOS/entitlements.plist; sourceTree = ""; }; D45068691E948ACE00FA7675 /* entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = entitlements.plist; path = OSX/trustd/iOS/entitlements.plist; sourceTree = ""; }; + D453C38A1FEC669300DE349B /* trust_update.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = trust_update.m; sourceTree = ""; }; + D453C47F1FFD857400DE349B /* security_tool_commands.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = security_tool_commands.h; path = OSX/utilities/SecurityTool/security_tool_commands.h; sourceTree = SOURCE_ROOT; }; + D46246911F9AE2E400D63882 /* libDER.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libDER.a; path = usr/local/lib/security_libDER/libDER.a; sourceTree = SDKROOT; }; + D462469C1F9AE45900D63882 /* oids.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = oids.c; sourceTree = ""; }; + D46246A21F9AE49E00D63882 /* oids.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = oids.h; path = trust/oids.h; sourceTree = ""; }; + D46246A91F9AE6C900D63882 /* libDER.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libDER.a; path = usr/local/lib/security_libDER/libDER.a; sourceTree = SDKROOT; }; + D46246AF1F9AE73F00D63882 /* libDER.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libDER.a; path = usr/local/lib/security_libDER/libDER.a; sourceTree = SDKROOT; }; + D46246C31F9AEA5200D63882 /* libDER.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libDER.a; path = usr/local/lib/security_libDER/libDER.a; sourceTree = SDKROOT; }; + D46246CE1F9AEAE300D63882 /* libDER.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libDER.a; path = usr/local/lib/security_libDER/libDER.a; sourceTree = SDKROOT; }; + D479F6E01F980F8F00388D28 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/Trust.strings; sourceTree = ""; }; D47C56AB1DCA831C00E18518 /* lib_ios_x64.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = lib_ios_x64.xcconfig; path = xcconfig/lib_ios_x64.xcconfig; sourceTree = ""; }; D47C56AF1DCA841D00E18518 /* lib_ios_x64_shim.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = lib_ios_x64_shim.xcconfig; path = xcconfig/lib_ios_x64_shim.xcconfig; sourceTree = ""; }; D47C56FB1DCA8F4900E18518 /* all_arches.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = all_arches.xcconfig; path = xcconfig/all_arches.xcconfig; sourceTree = ""; }; @@ -9051,6 +9677,12 @@ D4ADA3191E2B41670031CEA3 /* libtrustd.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libtrustd.a; sourceTree = BUILT_PRODUCTS_DIR; }; D4B858661D370D9A003B2D95 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.0.Internal.sdk/System/Library/Frameworks/MobileCoreServices.framework; sourceTree = DEVELOPER_DIR; }; D4BEECE61E93093A00F76D1A /* trustd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = trustd.c; path = OSX/trustd/trustd.c; sourceTree = ""; }; + D4C263C51F8FF2A9001317EA /* generateErrStrings.pl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.perl; name = generateErrStrings.pl; path = OSX/lib/generateErrStrings.pl; sourceTree = ""; usesTabs = 1; }; + D4C263C81F952E64001317EA /* SecDebugErrorMessages.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = SecDebugErrorMessages.strings; path = derived_src/SecDebugErrorMessages.strings; sourceTree = BUILT_PRODUCTS_DIR; }; + D4C263CD1F952F6C001317EA /* SecErrorMessages.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = SecErrorMessages.strings; path = derived_src/English.lproj/SecErrorMessages.strings; sourceTree = BUILT_PRODUCTS_DIR; }; + D4C6C5C71FB2AD3F007EA57E /* si-87-sectrust-name-constraints */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "si-87-sectrust-name-constraints"; sourceTree = ""; }; + D4C6C5CB1FB3B3CC007EA57E /* libarchive.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libarchive.tbd; path = usr/lib/libarchive.tbd; sourceTree = SDKROOT; }; + D4C6C5CE1FB3B44C007EA57E /* libarchive.2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libarchive.2.dylib; path = /usr/lib/libarchive.2.dylib; sourceTree = SDKROOT; }; D4C8A1511E66709800CD6DF1 /* si-32-sectrust-pinning-required.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "si-32-sectrust-pinning-required.h"; sourceTree = ""; }; D4CFAA7D1E660BB3004746AA /* si-32-sectrust-pinning-required.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "si-32-sectrust-pinning-required.m"; sourceTree = ""; }; D4D718341E04A721000AE7A6 /* spbkdf-01-hmac-sha256.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "spbkdf-01-hmac-sha256.c"; sourceTree = ""; }; @@ -9064,6 +9696,12 @@ DA30D6781DF8C8FB00EC6B43 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; DA30D6831DF8CA4100EC6B43 /* KeychainSyncAccountUpdater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeychainSyncAccountUpdater.h; sourceTree = ""; }; DA30D6841DF8CA4100EC6B43 /* KeychainSyncAccountUpdater.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeychainSyncAccountUpdater.m; sourceTree = ""; }; + DA6AA15E1FE88AF9004565B0 /* CKKSControlServer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSControlServer.m; sourceTree = ""; }; + DA6AA1641FE88AFA004565B0 /* CKKSControlServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSControlServer.h; sourceTree = ""; }; + DAB27ADA1FA29EB700DEBBDE /* SOSControlServer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSControlServer.h; sourceTree = ""; }; + DAB27AE01FA29EB800DEBBDE /* SOSControlServer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SOSControlServer.m; sourceTree = ""; }; + DAEE05551FAD3FC500DF27F3 /* AutoreleaseTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = AutoreleaseTest.c; sourceTree = ""; }; + DAEE055B1FAD3FC600DF27F3 /* AutoreleaseTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutoreleaseTest.h; sourceTree = ""; }; DC0067911D87816C005AF8DB /* macos_legacy_lib.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = macos_legacy_lib.xcconfig; path = xcconfig/macos_legacy_lib.xcconfig; sourceTree = ""; }; DC0067C01D87876F005AF8DB /* libsecurityd_server.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurityd_server.a; sourceTree = BUILT_PRODUCTS_DIR; }; DC0067D01D878898005AF8DB /* libsecurityd_ucspc.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurityd_ucspc.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -9134,8 +9772,6 @@ DC0BC6131D8B755200070CB0 /* ckutilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ckutilities.c; sourceTree = ""; }; DC0BC6141D8B755200070CB0 /* ckutilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ckutilities.h; sourceTree = ""; }; DC0BC6151D8B755200070CB0 /* Crypt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Crypt.h; sourceTree = ""; }; - DC0BC6161D8B755200070CB0 /* CryptKitSA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptKitSA.h; sourceTree = ""; }; - DC0BC6171D8B755200070CB0 /* CryptKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptKit.h; sourceTree = ""; }; DC0BC6181D8B755200070CB0 /* CryptKitAsn1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptKitAsn1.cpp; sourceTree = ""; }; DC0BC6191D8B755200070CB0 /* CryptKitAsn1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptKitAsn1.h; sourceTree = ""; }; DC0BC61A1D8B755200070CB0 /* CryptKitDER.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptKitDER.cpp; sourceTree = ""; }; @@ -9578,6 +10214,8 @@ DC0BCD551D8C697100070CB0 /* su-40-secdb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "su-40-secdb.c"; sourceTree = ""; }; DC0BCD561D8C697100070CB0 /* su-41-secdb-stress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "su-41-secdb-stress.c"; sourceTree = ""; }; DC0BCDB41D8C6A5B00070CB0 /* not_on_this_platorm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = not_on_this_platorm.c; sourceTree = ""; }; + DC124DC120059B8700BE8DAC /* OctagonControlServer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OctagonControlServer.h; path = ot/OctagonControlServer.h; sourceTree = ""; }; + DC124DC220059B8700BE8DAC /* OctagonControlServer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OctagonControlServer.m; path = ot/OctagonControlServer.m; sourceTree = ""; }; DC1447881F5764C600236DB4 /* CKKSResultOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSResultOperation.h; sourceTree = ""; }; DC1447891F5764C600236DB4 /* CKKSResultOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSResultOperation.m; sourceTree = ""; }; DC1447941F5766D200236DB4 /* NSOperationCategories.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NSOperationCategories.h; sourceTree = ""; }; @@ -9587,7 +10225,6 @@ DC15F79B1E68EAD5003B9A40 /* CKKSTests+API.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CKKSTests+API.m"; sourceTree = ""; }; DC1784421D77869A00B50D50 /* libsecurity_smime.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libsecurity_smime.xcodeproj; path = OSX/libsecurity_smime/libsecurity_smime.xcodeproj; sourceTree = ""; }; DC1784AE1D7786C700B50D50 /* libsecurity_cms.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libsecurity_cms.xcodeproj; path = OSX/libsecurity_cms/libsecurity_cms.xcodeproj; sourceTree = ""; }; - DC1785051D77873100B50D50 /* Security.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Security.framework; sourceTree = BUILT_PRODUCTS_DIR; }; DC1785111D77895A00B50D50 /* oidsalg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = oidsalg.h; path = OSX/libsecurity_asn1/lib/oidsalg.h; sourceTree = ""; }; DC1785121D77895A00B50D50 /* oidsattr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = oidsattr.h; path = OSX/libsecurity_asn1/lib/oidsattr.h; sourceTree = ""; }; DC1785131D77895A00B50D50 /* SecAsn1Coder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecAsn1Coder.h; path = OSX/libsecurity_asn1/lib/SecAsn1Coder.h; sourceTree = ""; }; @@ -9610,7 +10247,6 @@ DC17853A1D778A3100B50D50 /* mds_schema.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mds_schema.h; path = OSX/libsecurity_mds/lib/mds_schema.h; sourceTree = ""; }; DC17853B1D778A3100B50D50 /* mds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mds.h; path = OSX/libsecurity_mds/lib/mds.h; sourceTree = ""; }; DC17853F1D778A4E00B50D50 /* SecureDownload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecureDownload.h; path = OSX/libsecurity_manifest/lib/SecureDownload.h; sourceTree = ""; }; - DC1785421D778A7400B50D50 /* oids.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oids.h; sourceTree = ""; }; DC1785451D778ACD00B50D50 /* SecAccess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecAccess.h; path = OSX/libsecurity_keychain/lib/SecAccess.h; sourceTree = ""; }; DC1785461D778ACD00B50D50 /* SecACL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecACL.h; path = OSX/libsecurity_keychain/lib/SecACL.h; sourceTree = ""; }; DC1785471D778ACD00B50D50 /* SecCertificateOIDs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCertificateOIDs.h; path = OSX/libsecurity_keychain/lib/SecCertificateOIDs.h; sourceTree = ""; }; @@ -9643,7 +10279,6 @@ DC1785811D778B7F00B50D50 /* CodeSigning.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CodeSigning.h; path = lib/CodeSigning.h; sourceTree = ""; }; DC1785821D778B7F00B50D50 /* CSCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSCommon.h; path = lib/CSCommon.h; sourceTree = ""; }; DC1785831D778B7F00B50D50 /* SecCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCode.h; path = lib/SecCode.h; sourceTree = ""; }; - DC1785841D778B8000B50D50 /* SecCodeHost.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCodeHost.h; path = lib/SecCodeHost.h; sourceTree = ""; }; DC1785851D778B8000B50D50 /* SecRequirement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecRequirement.h; path = lib/SecRequirement.h; sourceTree = ""; }; DC1785861D778B8000B50D50 /* SecStaticCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecStaticCode.h; path = lib/SecStaticCode.h; sourceTree = ""; }; DC17858E1D778B9D00B50D50 /* CMSDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CMSDecoder.h; path = OSX/libsecurity_cms/lib/CMSDecoder.h; sourceTree = ""; }; @@ -9693,7 +10328,6 @@ DC1787421D77906C00B50D50 /* cssmapplePriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cssmapplePriv.h; path = OSX/libsecurity_cssm/lib/cssmapplePriv.h; sourceTree = ""; }; DC1787441D7790A500B50D50 /* CSCommonPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSCommonPriv.h; path = lib/CSCommonPriv.h; sourceTree = ""; }; DC1787451D7790A500B50D50 /* SecAssessment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecAssessment.h; path = lib/SecAssessment.h; sourceTree = ""; }; - DC1787461D7790A500B50D50 /* SecCodeHostLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCodeHostLib.h; path = lib/SecCodeHostLib.h; sourceTree = ""; }; DC1787471D7790A500B50D50 /* SecCodePriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCodePriv.h; path = lib/SecCodePriv.h; sourceTree = ""; }; DC1787481D7790A500B50D50 /* SecCodeSigner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCodeSigner.h; path = lib/SecCodeSigner.h; sourceTree = ""; }; DC17874B1D7790A500B50D50 /* SecRequirementPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecRequirementPriv.h; path = lib/SecRequirementPriv.h; sourceTree = ""; }; @@ -9824,7 +10458,6 @@ DC378B371DEFADB500A3DAFA /* CKKSZoneStateEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSZoneStateEntry.m; sourceTree = ""; }; DC378B3A1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSIncomingQueueEntry.h; sourceTree = ""; }; DC378B3B1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSIncomingQueueEntry.m; sourceTree = ""; }; - DC3832C01DB6E69800385F63 /* module.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; DC3A4B581D91E9FB00E46D4A /* com.apple.CodeSigningHelper.xpc */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = com.apple.CodeSigningHelper.xpc; sourceTree = BUILT_PRODUCTS_DIR; }; DC3A4B5F1D91EAC500E46D4A /* CodeSigningHelper-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "CodeSigningHelper-Info.plist"; sourceTree = ""; }; DC3A4B601D91EAC500E46D4A /* com.apple.CodeSigningHelper.sb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = com.apple.CodeSigningHelper.sb; sourceTree = ""; }; @@ -9872,22 +10505,6 @@ DC58C43B1D77BED0003C25A4 /* csparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = csparser.cpp; path = OSX/lib/plugins/csparser.cpp; sourceTree = ""; }; DC58C43C1D77BED0003C25A4 /* csparser.exp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.exports; name = csparser.exp; path = OSX/lib/plugins/csparser.exp; sourceTree = ""; }; DC58C4411D77BFA4003C25A4 /* security_macos.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = security_macos.xcconfig; path = OSX/config/security_macos.xcconfig; sourceTree = ""; }; - DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libDER_not_installed.a; sourceTree = BUILT_PRODUCTS_DIR; }; - DC59E9ED1D91CA0A001BDDF5 /* DER_Keys.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = DER_Keys.c; sourceTree = ""; }; - DC59E9EE1D91CA0A001BDDF5 /* DER_Keys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DER_Keys.h; sourceTree = ""; }; - DC59E9EF1D91CA0A001BDDF5 /* asn1Types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = asn1Types.h; sourceTree = ""; }; - DC59E9F01D91CA0A001BDDF5 /* DER_CertCrl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = DER_CertCrl.c; sourceTree = ""; }; - DC59E9F11D91CA0A001BDDF5 /* DER_CertCrl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DER_CertCrl.h; sourceTree = ""; }; - DC59E9F21D91CA0A001BDDF5 /* DER_Decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = DER_Decode.c; sourceTree = ""; }; - DC59E9F31D91CA0A001BDDF5 /* DER_Decode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DER_Decode.h; sourceTree = ""; }; - DC59E9F41D91CA0A001BDDF5 /* DER_Encode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = DER_Encode.c; sourceTree = ""; }; - DC59E9F51D91CA0A001BDDF5 /* DER_Encode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DER_Encode.h; sourceTree = ""; }; - DC59E9F61D91CA0A001BDDF5 /* libDER_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libDER_config.h; sourceTree = ""; }; - DC59E9F71D91CA0A001BDDF5 /* libDER.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libDER.h; sourceTree = ""; }; - DC59E9F81D91CA0A001BDDF5 /* DER_Digest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DER_Digest.h; sourceTree = ""; }; - DC59E9F91D91CA0A001BDDF5 /* DER_Digest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = DER_Digest.c; sourceTree = ""; }; - DC59E9FA1D91CA0A001BDDF5 /* oids.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = oids.c; sourceTree = ""; }; - DC59E9FC1D91CA0A001BDDF5 /* oidsPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oidsPriv.h; sourceTree = ""; }; DC59EA731D91CBD0001BDDF5 /* libcrypto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcrypto.dylib; path = usr/lib/libcrypto.dylib; sourceTree = SDKROOT; }; DC5ABD781D832D5800CF422C /* srCdsaUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = srCdsaUtils.cpp; sourceTree = ""; }; DC5ABD791D832D5800CF422C /* srCdsaUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = srCdsaUtils.h; sourceTree = ""; }; @@ -10224,6 +10841,8 @@ DCAD9B481F8D95F200C5E2AE /* CloudKitKeychainSyncingFixupTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CloudKitKeychainSyncingFixupTests.m; sourceTree = ""; }; DCB2214A1E8B0861001598BC /* server_xpc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = server_xpc.m; sourceTree = ""; }; DCB2215B1E8B098D001598BC /* server_endpoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = server_endpoint.h; sourceTree = ""; }; + DCB332361F467CC200178C30 /* macos_tapi_hacks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = macos_tapi_hacks.h; path = OSX/macos_tapi_hacks.h; sourceTree = ""; }; + DCB332371F46804000178C30 /* SOSSysdiagnose.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSSysdiagnose.h; sourceTree = ""; }; DCB3406D1D8A24DF0054D16E /* libsecurity_authorization.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_authorization.a; sourceTree = BUILT_PRODUCTS_DIR; }; DCB3406F1D8A24F70054D16E /* Authorization.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Authorization.c; path = lib/Authorization.c; sourceTree = ""; }; DCB340761D8A24F70054D16E /* Authorization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Authorization.cpp; path = lib/Authorization.cpp; sourceTree = ""; }; @@ -10574,8 +11193,6 @@ DCB344701D8A35270054D16E /* si-20-sectrust-provisioning.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "si-20-sectrust-provisioning.h"; path = "regressions/si-20-sectrust-provisioning.h"; sourceTree = ""; }; DCB344711D8A35270054D16E /* si-33-keychain-backup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "si-33-keychain-backup.c"; path = "regressions/si-33-keychain-backup.c"; sourceTree = ""; }; DCB344721D8A35270054D16E /* si-34-one-true-keychain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "si-34-one-true-keychain.c"; path = "regressions/si-34-one-true-keychain.c"; sourceTree = ""; }; - DCB5022C1FDA155D008F8E4F /* AutoreleaseTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = AutoreleaseTest.c; sourceTree = ""; }; - DCB502321FDA155E008F8E4F /* AutoreleaseTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutoreleaseTest.h; sourceTree = ""; }; DCB5D9391E4A9A3400BE22AB /* CKKSSynchronizeOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSSynchronizeOperation.h; sourceTree = ""; }; DCB5D93A1E4A9A3400BE22AB /* CKKSSynchronizeOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSSynchronizeOperation.m; sourceTree = ""; }; DCBDB3B01E57C67500B61300 /* CKKSKeychainView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSKeychainView.h; sourceTree = ""; }; @@ -10658,7 +11275,7 @@ DCC78C811D8085D800865A7C /* entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = entitlements.plist; sourceTree = ""; }; DCC78C8E1D8085D800865A7C /* SecDbItem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecDbItem.c; sourceTree = ""; }; DCC78C8F1D8085D800865A7C /* SecDbItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecDbItem.h; sourceTree = ""; }; - DCC78C901D8085D800865A7C /* SecDbKeychainItem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecDbKeychainItem.c; sourceTree = ""; }; + DCC78C901D8085D800865A7C /* SecDbKeychainItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecDbKeychainItem.m; sourceTree = ""; }; DCC78C911D8085D800865A7C /* SecDbKeychainItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecDbKeychainItem.h; sourceTree = ""; }; DCC78C921D8085D800865A7C /* SecDbQuery.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecDbQuery.c; sourceTree = ""; }; DCC78C931D8085D800865A7C /* SecDbQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecDbQuery.h; sourceTree = ""; }; @@ -10889,10 +11506,10 @@ DCC78DD71D8085FC00865A7C /* si-50-secrandom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-50-secrandom.c"; sourceTree = ""; }; DCC78DD81D8085FC00865A7C /* si-60-cms.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-60-cms.c"; sourceTree = ""; }; DCC78DD91D8085FC00865A7C /* si-61-pkcs12.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-61-pkcs12.c"; sourceTree = ""; }; - DCC78DDA1D8085FC00865A7C /* si-62-csr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-62-csr.c"; sourceTree = ""; }; + DCC78DDA1D8085FC00865A7C /* si-62-csr.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "si-62-csr.m"; sourceTree = ""; }; DCC78DDB1D8085FC00865A7C /* getcacert-mdes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "getcacert-mdes.h"; sourceTree = ""; }; DCC78DDC1D8085FC00865A7C /* getcacert-mdesqa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "getcacert-mdesqa.h"; sourceTree = ""; }; - DCC78DDE1D8085FC00865A7C /* si-63-scep.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-63-scep.c"; sourceTree = ""; }; + DCC78DDE1D8085FC00865A7C /* si-63-scep.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "si-63-scep.m"; sourceTree = ""; }; DCC78DDF1D8085FC00865A7C /* si-63-scep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "si-63-scep.h"; sourceTree = ""; }; DCC78DE01D8085FC00865A7C /* attached_no_data_signed_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = attached_no_data_signed_data.h; sourceTree = ""; }; DCC78DE11D8085FC00865A7C /* attached_signed_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = attached_signed_data.h; sourceTree = ""; }; @@ -10934,7 +11551,7 @@ DCC78E081D8085FC00865A7C /* si-85-sectrust-ssl-policy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "si-85-sectrust-ssl-policy.h"; sourceTree = ""; }; DCC78E091D8085FC00865A7C /* si-87-sectrust-name-constraints.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "si-87-sectrust-name-constraints.m"; sourceTree = ""; }; DCC78E0A1D8085FC00865A7C /* si-87-sectrust-name-constraints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "si-87-sectrust-name-constraints.h"; sourceTree = ""; }; - DCC78E0B1D8085FC00865A7C /* si-89-cms-hash-agility.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-89-cms-hash-agility.c"; sourceTree = ""; }; + DCC78E0B1D8085FC00865A7C /* si-89-cms-hash-agility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "si-89-cms-hash-agility.m"; sourceTree = ""; }; DCC78E0C1D8085FC00865A7C /* si-89-cms-hash-agility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "si-89-cms-hash-agility.h"; sourceTree = ""; }; DCC78E0D1D8085FC00865A7C /* si-90-emcs.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "si-90-emcs.m"; sourceTree = ""; }; DCC78E0E1D8085FC00865A7C /* si-95-cms-basic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-95-cms-basic.c"; sourceTree = ""; }; @@ -10967,7 +11584,6 @@ DCC78E321D8085FC00865A7C /* SecAccessControlExports.exp-in */ = {isa = PBXFileReference; lastKnownFileType = text; path = "SecAccessControlExports.exp-in"; sourceTree = ""; }; DCC78E351D8085FC00865A7C /* SecBase64.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecBase64.c; sourceTree = ""; }; DCC78E381D8085FC00865A7C /* SecCertificate.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecCertificate.c; sourceTree = ""; }; - DCC78E3B1D8085FC00865A7C /* SecCertificatePath.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecCertificatePath.c; sourceTree = ""; }; DCC78E3E1D8085FC00865A7C /* SecCertificateRequest.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecCertificateRequest.c; sourceTree = ""; }; DCC78E401D8085FC00865A7C /* SecCFAllocator.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecCFAllocator.c; sourceTree = ""; }; DCC78E421D8085FC00865A7C /* SecCMS.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecCMS.c; sourceTree = ""; }; @@ -11253,7 +11869,6 @@ DCD06A511D8CE281007602F1 /* libcodehost.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libcodehost.a; sourceTree = BUILT_PRODUCTS_DIR; }; DCD06A741D8CE2D5007602F1 /* gkunpack */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gkunpack; sourceTree = BUILT_PRODUCTS_DIR; }; DCD06AB01D8E0D53007602F1 /* libsecurity_utilities.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_utilities.a; sourceTree = BUILT_PRODUCTS_DIR; }; - DCD06AB11D8E0D7D007602F1 /* debugging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = debugging.h; path = ../../utilities/src/debugging.h; sourceTree = ""; }; DCD06AB21D8E0D7D007602F1 /* FileLockTransaction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = FileLockTransaction.cpp; sourceTree = ""; }; DCD06AB31D8E0D7D007602F1 /* FileLockTransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileLockTransaction.h; sourceTree = ""; }; DCD06AB41D8E0D7D007602F1 /* CSPDLTransaction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = CSPDLTransaction.cpp; sourceTree = ""; }; @@ -11364,6 +11979,7 @@ DCD6C4B01EC5302400414FEE /* CKKSNearFutureScheduler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSNearFutureScheduler.h; sourceTree = ""; }; DCD6C4B11EC5302500414FEE /* CKKSNearFutureScheduler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSNearFutureScheduler.m; sourceTree = ""; }; DCD6C4B61EC5319600414FEE /* CKKSNearFutureSchedulerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSNearFutureSchedulerTests.m; sourceTree = ""; }; + DCD7EE9B1F4F51D9007D9804 /* ios_tapi_hacks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ios_tapi_hacks.h; sourceTree = ""; }; DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSecureObjectSyncFramework.a; sourceTree = BUILT_PRODUCTS_DIR; }; DCDCC7DD1D9B54DF006487E8 /* secd-202-recoverykey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-202-recoverykey.m"; sourceTree = ""; }; DCDCC7E41D9B551C006487E8 /* SOSAccountSync.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSAccountSync.m; sourceTree = ""; }; @@ -11782,6 +12398,7 @@ DCF789471D88D17C00E694BB /* AppleX509TPBuiltin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AppleX509TPBuiltin.cpp; path = OSX/libsecurity_apple_x509_tp/lib/AppleX509TPBuiltin.cpp; sourceTree = ""; }; DCF7A89F1F04502300CABE89 /* CKKSControlProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSControlProtocol.h; sourceTree = ""; }; DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSControlProtocol.m; sourceTree = ""; }; + DCFABF8D20081E2F001128B5 /* CKKSDeviceStateUploadTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSDeviceStateUploadTests.m; sourceTree = ""; }; DCFAEDC81D999851005187E4 /* SOSAccountGhost.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSAccountGhost.m; sourceTree = ""; }; DCFAEDC91D999851005187E4 /* SOSAccountGhost.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSAccountGhost.h; sourceTree = ""; }; DCFAEDD11D9998DD005187E4 /* secd-668-ghosts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-668-ghosts.m"; sourceTree = ""; }; @@ -11808,7 +12425,6 @@ E75C0E801C6FC31D00E6953B /* KCSRPContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KCSRPContext.h; sourceTree = ""; }; E75C0E811C6FC31D00E6953B /* KCSRPContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KCSRPContext.m; sourceTree = ""; }; E75C0E841C71325000E6953B /* KeychainCircle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeychainCircle.h; sourceTree = ""; }; - E75E498A1C8F76360001A34F /* libDER.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libDER.a; path = ../../../../../usr/local/lib/libDER.a; sourceTree = ""; }; E75E498C1C8F76680001A34F /* libASN1.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libASN1.a; path = ../../../../../usr/local/lib/libASN1.a; sourceTree = ""; }; E76638AE1DD67B7100B769D3 /* security-sysdiagnose.entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "security-sysdiagnose.entitlements.plist"; sourceTree = ""; }; E7676DB519411DF300498DD4 /* SecServerEncryptionSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecServerEncryptionSupport.h; sourceTree = ""; }; @@ -11879,6 +12495,8 @@ EB10557A1E14DF640003C309 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; EB108F121E6CE48B003B0456 /* KCParing.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = KCParing.plist; path = Tests/KCParing.plist; sourceTree = ""; }; EB108F411E6CE4D2003B0456 /* KCPairingTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KCPairingTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + EB10A3E320356E2000E84270 /* OTConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTConstants.h; path = ot/OTConstants.h; sourceTree = ""; }; + EB10A3E420356E2000E84270 /* OTConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTConstants.m; path = ot/OTConstants.m; sourceTree = ""; }; EB27FF0C1E402C8000EC9E3A /* ckksctl.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ckksctl.m; sourceTree = ""; }; EB27FF111E402CD300EC9E3A /* ckksctl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ckksctl; sourceTree = BUILT_PRODUCTS_DIR; }; EB27FF2F1E408CC900EC9E3A /* ckksctl-Entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "ckksctl-Entitlements.plist"; sourceTree = ""; }; @@ -11897,7 +12515,19 @@ EB433A281CC3243600A7EACE /* secitemstresstest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secitemstresstest; sourceTree = BUILT_PRODUCTS_DIR; }; EB433A2D1CC325E900A7EACE /* secitemstresstest.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = secitemstresstest.entitlements; path = secitemstresstest/secitemstresstest.entitlements; sourceTree = ""; }; EB48C19E1E573EDC00EC5E57 /* sos.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = sos.m; sourceTree = ""; }; + EB49B2AE202D877F003F34A0 /* secdmockaks.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = secdmockaks.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + EB49B2B0202D8780003F34A0 /* secdmockaks.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = secdmockaks.m; sourceTree = ""; }; + EB49B2B2202D8780003F34A0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + EB49B2CE202DF111003F34A0 /* CoreFollowUp.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFollowUp.framework; path = System/Library/PrivateFrameworks/CoreFollowUp.framework; sourceTree = SDKROOT; }; + EB49B2DC202DF251003F34A0 /* libbsm.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libbsm.tbd; path = usr/lib/libbsm.tbd; sourceTree = SDKROOT; }; + EB49B2DE202DF286003F34A0 /* CoreFollowUpUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFollowUpUI.framework; path = System/Library/PrivateFrameworks/CoreFollowUpUI.framework; sourceTree = SDKROOT; }; + EB49B2E4202DFE7F003F34A0 /* mockaks.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = mockaks.m; sourceTree = ""; }; + EB49B303202FB8DE003F34A0 /* mockaks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mockaks.h; sourceTree = ""; }; + EB4E0CD41FF36A1900CDCACC /* CKKSReachabilityTracker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSReachabilityTracker.h; sourceTree = ""; }; + EB4E0CD51FF36A1900CDCACC /* CKKSReachabilityTracker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSReachabilityTracker.m; sourceTree = ""; }; EB59D66B1E95EF2900997EAC /* libcompression.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcompression.dylib; path = usr/lib/libcompression.dylib; sourceTree = SDKROOT; }; + EB5E3BC62003C66300F1631B /* SecSignpost.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecSignpost.h; path = base/SecSignpost.h; sourceTree = ""; }; + EB6667BE204CD65E000B404F /* testPlistDER.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = testPlistDER.m; sourceTree = ""; }; EB6928BE1D9C9C5900062A18 /* SecRecoveryKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecRecoveryKey.h; sourceTree = ""; }; EB6928BF1D9C9C5900062A18 /* SecRecoveryKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecRecoveryKey.m; sourceTree = ""; }; EB6928C91D9C9D9D00062A18 /* rk_01_recoverykey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = rk_01_recoverykey.m; path = Regressions/rk_01_recoverykey.m; sourceTree = ""; }; @@ -11909,6 +12539,8 @@ EB7AE6F71E86D55400B80B15 /* SecPLWrappers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecPLWrappers.h; path = src/SecPLWrappers.h; sourceTree = ""; }; EB8021411D3D90BB008540C4 /* Security.iOS.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; name = Security.iOS.modulemap; path = Modules/Security.iOS.modulemap; sourceTree = ""; }; EB8021421D3D90BB008540C4 /* Security.macOS.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; name = Security.macOS.modulemap; path = Modules/Security.macOS.modulemap; sourceTree = ""; }; + EB82A2A41FAFF26900CA64A9 /* SFBehavior.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFBehavior.h; sourceTree = ""; }; + EB82A2A51FAFF26900CA64A9 /* SFBehavior.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFBehavior.m; sourceTree = ""; }; EB9C02421E8A112A0040D3C6 /* secd-37-pairing-initial-sync.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-37-pairing-initial-sync.m"; sourceTree = ""; }; EB9C1D7A1BDFD0E000F89272 /* secbackupntest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secbackupntest; sourceTree = BUILT_PRODUCTS_DIR; }; EB9C1D7D1BDFD0E100F89272 /* secbackupntest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = secbackupntest.m; sourceTree = ""; }; @@ -11925,6 +12557,7 @@ EBCF73F11CE45F8600BED7CA /* secitemfunctionality.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = secitemfunctionality.entitlements; path = secitemfunctionality/secitemfunctionality.entitlements; sourceTree = ""; }; EBCF73F21CE45F8600BED7CA /* secitemfunctionality.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = secitemfunctionality.m; path = secitemfunctionality/secitemfunctionality.m; sourceTree = ""; }; EBCF73FC1CE45F9C00BED7CA /* secitemfunctionality */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secitemfunctionality; sourceTree = BUILT_PRODUCTS_DIR; }; + EBD8AD632004B45500588BBA /* SecurityCustomSignposts.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; name = SecurityCustomSignposts.plist; path = base/SecurityCustomSignposts.plist; sourceTree = ""; }; EBE54D771BE33227000C4856 /* libmis.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libmis.dylib; path = usr/lib/libmis.dylib; sourceTree = SDKROOT; }; EBEEEE351EA31A8300E15F5C /* SOSControlHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSControlHelper.h; sourceTree = ""; }; EBEEEE361EA31A8300E15F5C /* SOSControlHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SOSControlHelper.m; sourceTree = ""; }; @@ -11959,7 +12592,6 @@ 438168C51B4ED43B00C54D58 /* CoreFoundation.framework in Frameworks */, EB3409B01C1D627400D77661 /* Foundation.framework in Frameworks */, DCD22D8B1D8CCC58001C9B81 /* libASN1_not_installed.a in Frameworks */, - DC59EA911D91CDCF001BDDF5 /* libDER_not_installed.a in Frameworks */, DC59E9A71D91C7C7001BDDF5 /* libCMS.a in Frameworks */, DC00ABD71D821F3F00513D74 /* libsecurity.a in Frameworks */, DC00ABD81D821F4300513D74 /* libsecdRegressions.a in Frameworks */, @@ -11972,11 +12604,13 @@ 0C0BDB8D1756A66100BC1A7E /* CFNetwork.framework in Frameworks */, 0C0BDB911756A8A400BC1A7E /* IOKit.framework in Frameworks */, 0C0BDB931756A8C900BC1A7E /* SystemConfiguration.framework in Frameworks */, + D46246B81F9AE77900D63882 /* libDER.a in Frameworks */, 5E8B53A51AA0B8A600345E7B /* libcoreauthd_test_client.a in Frameworks */, 4432B15F1A014D55000958DC /* libaks_acl.a in Frameworks */, 0C0BDB8F1756A6D500BC1A7E /* libMobileGestalt.dylib in Frameworks */, 0C0BDB881756A51000BC1A7E /* libsqlite3.dylib in Frameworks */, BE8ABDD81DC2DD9100EC2D58 /* libz.dylib in Frameworks */, + 0C59605D1FB2D95D0095BA29 /* libprequelite.tbd in Frameworks */, 4469FBFF1AA0A4820021AA26 /* libctkclient_test.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -12001,6 +12635,41 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 0C85DFE51FB38BB6000343A7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0C85DFE71FB38BB6000343A7 /* libASN1_not_installed.a in Frameworks */, + 0C85DFE81FB38BB6000343A7 /* libsecurityd_ios_NO_AKS.a in Frameworks */, + 0C85DFE91FB38BB6000343A7 /* libSecureObjectSyncFramework.a in Frameworks */, + 0C85DFEA1FB38BB6000343A7 /* libSecureObjectSyncServer.a in Frameworks */, + 0C85DFEB1FB38BB6000343A7 /* libsecurity.a in Frameworks */, + 0C85DFEC1FB38BB6000343A7 /* libutilities.a in Frameworks */, + 0C85DFED1FB38BB6000343A7 /* CFNetwork.framework in Frameworks */, + 0C85DFEE1FB38BB6000343A7 /* Foundation.framework in Frameworks */, + 0C85DFF01FB38BB6000343A7 /* IOKit.framework in Frameworks */, + 0C85DFF11FB38BB6000343A7 /* OCMock.framework in Frameworks */, + 0C0DA5CE1FE1EAB9003BD3BB /* SecurityFoundation.framework in Frameworks */, + 0C85DFF31FB38BB6000343A7 /* SystemConfiguration.framework in Frameworks */, + 0C85DFF41FB38BB6000343A7 /* libACM.a in Frameworks */, + 0C85DFF51FB38BB6000343A7 /* libaks_acl.a in Frameworks */, + 0C85DFF61FB38BB6000343A7 /* libDER.a in Frameworks */, + 0C85DFF71FB38BB6000343A7 /* libbsm.dylib in Frameworks */, + 0C85DFF81FB38BB6000343A7 /* libcoreauthd_client.a in Frameworks */, + 0C85DFF91FB38BB6000343A7 /* libctkclient.a in Frameworks */, + 0C85DFFA1FB38BB6000343A7 /* libsqlite3.0.dylib in Frameworks */, + 0C85DFFB1FB38BB6000343A7 /* libz.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0C8BBF021FCB446400580909 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0C8BBF031FCB446400580909 /* Security.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 225394AF1E3080A600D3CD9B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -12027,6 +12696,40 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4727FBB41F9918580003AE36 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 477A1F5220320E4A00ACD81D /* Accounts.framework in Frameworks */, + 472339691FD7156800CB6A72 /* CoreCDP.framework in Frameworks */, + 472339671FD7155E00CB6A72 /* libprequelite.dylib in Frameworks */, + 47D183911FB3827800CFCD89 /* OCMock.framework in Frameworks */, + 4727FBEA1F9922190003AE36 /* libregressionBase.a in Frameworks */, + 4727FBE91F9921D10003AE36 /* libACM.a in Frameworks */, + 4727FBE71F99218A0003AE36 /* ApplePushService.framework in Frameworks */, + 4727FBE51F99217B0003AE36 /* SharedWebCredentials.framework in Frameworks */, + 4727FBE31F9921660003AE36 /* MobileKeyBag.framework in Frameworks */, + 4727FBE11F9921300003AE36 /* IOKit.framework in Frameworks */, + 4727FBDF1F99211D0003AE36 /* libaks.a in Frameworks */, + 4727FBDD1F9920F20003AE36 /* libaks_acl.a in Frameworks */, + 4727FBDB1F9920CC0003AE36 /* WirelessDiagnostics.framework in Frameworks */, + 4727FBD91F9920BC0003AE36 /* SystemConfiguration.framework in Frameworks */, + 4727FBD71F99209C0003AE36 /* libSecureObjectSyncServer.a in Frameworks */, + 4727FBD61F9920960003AE36 /* libSecureObjectSyncFramework.a in Frameworks */, + 4727FBD51F9920510003AE36 /* ProtocolBuffer.framework in Frameworks */, + 4727FBD31F9920290003AE36 /* CloudKit.framework in Frameworks */, + 4727FBD11F991F990003AE36 /* libMobileGestalt.dylib in Frameworks */, + 4727FBCE1F991F820003AE36 /* SecurityFoundation.framework in Frameworks */, + 4727FBCD1F991F660003AE36 /* libsqlite3.dylib in Frameworks */, + 4727FBCB1F991F510003AE36 /* Security.framework in Frameworks */, + 4727FBC91F991E5A0003AE36 /* libutilities.a in Frameworks */, + 4727FBC81F991E460003AE36 /* libsecurityd_ios.a in Frameworks */, + 4727FBC71F991E3A0003AE36 /* libsecurity.a in Frameworks */, + 4727FBC61F991DE90003AE36 /* libsecdRegressions.a in Frameworks */, + 4727FBC51F991C470003AE36 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 47702B1B1E5F409700B29577 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -12043,6 +12746,41 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 478D427D1FD72A8100CAB645 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 477A1F5320320E5100ACD81D /* Accounts.framework in Frameworks */, + 478D429F1FD72C8400CAB645 /* AppleSystemInfo.framework in Frameworks */, + 478D429E1FD72C4800CAB645 /* CrashReporterSupport.framework in Frameworks */, + 478D427E1FD72A8100CAB645 /* CoreCDP.framework in Frameworks */, + 478D427F1FD72A8100CAB645 /* libprequelite.dylib in Frameworks */, + 478D42801FD72A8100CAB645 /* OCMock.framework in Frameworks */, + 478D42811FD72A8100CAB645 /* libregressionBase.a in Frameworks */, + 478D42821FD72A8100CAB645 /* libACM.a in Frameworks */, + 478D42831FD72A8100CAB645 /* ApplePushService.framework in Frameworks */, + 478D42841FD72A8100CAB645 /* SharedWebCredentials.framework in Frameworks */, + 478D42851FD72A8100CAB645 /* MobileKeyBag.framework in Frameworks */, + 478D42861FD72A8100CAB645 /* IOKit.framework in Frameworks */, + 478D42871FD72A8100CAB645 /* libaks.a in Frameworks */, + 478D42881FD72A8100CAB645 /* libaks_acl.a in Frameworks */, + 478D42891FD72A8100CAB645 /* WirelessDiagnostics.framework in Frameworks */, + 478D428A1FD72A8100CAB645 /* SystemConfiguration.framework in Frameworks */, + 478D428B1FD72A8100CAB645 /* libSecureObjectSyncServer.a in Frameworks */, + 478D428C1FD72A8100CAB645 /* libSecureObjectSyncFramework.a in Frameworks */, + 478D428D1FD72A8100CAB645 /* ProtocolBuffer.framework in Frameworks */, + 478D428E1FD72A8100CAB645 /* CloudKit.framework in Frameworks */, + 478D42901FD72A8100CAB645 /* SecurityFoundation.framework in Frameworks */, + 478D42911FD72A8100CAB645 /* libsqlite3.dylib in Frameworks */, + 478D42921FD72A8100CAB645 /* Security.framework in Frameworks */, + 478D42931FD72A8100CAB645 /* libutilities.a in Frameworks */, + 478D42941FD72A8100CAB645 /* libsecurityd_ios.a in Frameworks */, + 478D42951FD72A8100CAB645 /* libsecurity.a in Frameworks */, + 478D42961FD72A8100CAB645 /* libsecdRegressions.a in Frameworks */, + 478D42971FD72A8100CAB645 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 47C51B811EEA657D0032D9E5 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -12060,8 +12798,8 @@ DC3A81D51D99D568000C7419 /* libcoretls_cfhelpers.dylib in Frameworks */, 5296CB4E1655B8F5009912AF /* libMobileGestalt.dylib in Frameworks */, DCD8A19A1E09EE9800E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */, - DC59EA771D91CC6D001BDDF5 /* libDER_not_installed.a in Frameworks */, 0C78F1D016A5E3EB00654E08 /* libbsm.dylib in Frameworks */, + D46246971F9AE2E400D63882 /* libDER.a in Frameworks */, DCD22D771D8CC9CD001C9B81 /* libASN1_not_installed.a in Frameworks */, 44A655831AA4B4BB0059D185 /* libctkclient.a in Frameworks */, DC59E9A41D91C6F0001BDDF5 /* libCMS.a in Frameworks */, @@ -12106,7 +12844,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 47B90C951F3509C1006500BC /* CrashReporterSupport.framework in Frameworks */, + D4C6C5CF1FB3B44D007EA57E /* libarchive.2.dylib in Frameworks */, D40B6A8E1E2B643500CD6EE5 /* libtrustd.a in Frameworks */, DC00ABB31D821E0400513D74 /* libSharedRegressions.a in Frameworks */, EBE9019C1C2285DB007308C6 /* AggregateDictionary.framework in Frameworks */, @@ -12116,8 +12854,8 @@ DCD22D9A1D8CCFC1001C9B81 /* libutilities.a in Frameworks */, DC00ABB51D821E0B00513D74 /* libSecureObjectSyncServer.a in Frameworks */, DCD8A1F91E09F98E00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */, + D46246B51F9AE74000D63882 /* libDER.a in Frameworks */, DCD22D9B1D8CCFCB001C9B81 /* libASN1_not_installed.a in Frameworks */, - DC59EA851D91CD35001BDDF5 /* libDER_not_installed.a in Frameworks */, DC65E7771D8CB82500152EF0 /* libregressionBase.a in Frameworks */, 438168C01B4ED42C00C54D58 /* CoreFoundation.framework in Frameworks */, DCD22D9C1D8CCFD6001C9B81 /* libutilitiesRegressions.a in Frameworks */, @@ -12159,8 +12897,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 0C59605C1FB2D9280095BA29 /* libprequelite.tbd in Frameworks */, 47D13F631E8447FB0063B6E2 /* SecurityFoundation.framework in Frameworks */, - EB7F50C51DB8800A003D787D /* CoreCDP.framework in Frameworks */, EBE9019A1C22852C007308C6 /* AggregateDictionary.framework in Frameworks */, 438168BB1B4ED42300C54D58 /* CoreFoundation.framework in Frameworks */, DC00AB8E1D821D4900513D74 /* libSOSCommands.a in Frameworks */, @@ -12223,9 +12961,11 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 0C8BBF261FCB561C00580909 /* CoreCDP.framework in Frameworks */, + 0C59605A1FB2D8E50095BA29 /* libprequelite.tbd in Frameworks */, + D46246BA1F9AE7A000D63882 /* libDER.a in Frameworks */, DCCD34001E4001AD00AA4AD1 /* libACM.a in Frameworks */, DCAB14271E40039600C81511 /* libASN1_not_installed.a in Frameworks */, - DC59EA8E1D91CDC1001BDDF5 /* libDER_not_installed.a in Frameworks */, EBF2D73C1C1E2B47006AB6FF /* Foundation.framework in Frameworks */, DCD22D801D8CCB0F001C9B81 /* libutilities.a in Frameworks */, DC00ABCC1D821F0B00513D74 /* libsecurityd_ios.a in Frameworks */, @@ -12242,11 +12982,28 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 6C46059B1F882B9B001421B6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D4574AA3203E68E0006D9B82 /* AuthKit.framework in Frameworks */, + D4574AA1203E6893006D9B82 /* Accounts.framework in Frameworks */, + D4119E79202BDF580048587B /* libz.tbd in Frameworks */, + 6CDB601B1FA93A2000410924 /* libprequelite.tbd in Frameworks */, + 6CDB601A1FA93A1800410924 /* libsqlite3.tbd in Frameworks */, + 6CDB60111FA9386200410924 /* Security.framework in Frameworks */, + D4119E882032A8FA0048587B /* OCMock.framework in Frameworks */, + 6C13AE481F8E9FC800F047E3 /* libutilities.a in Frameworks */, + 6C4605A51F882B9B001421B6 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 6C9808481E788AEB00E70590 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 6C9808491E788AEB00E70590 /* libDER_not_installed.a in Frameworks */, + 6CAA8CDD1F82EDEF007B6E03 /* Security.framework in Frameworks */, + D46246BC1F9AE82B00D63882 /* libDER.a in Frameworks */, 6C98084A1E788AEB00E70590 /* libASN1_not_installed.a in Frameworks */, 6C98084C1E788AEB00E70590 /* libsecurityd_ios_NO_AKS.a in Frameworks */, 6C98084D1E788AEB00E70590 /* libSecureObjectSyncFramework.a in Frameworks */, @@ -12264,6 +13021,7 @@ 6C9808581E788AEB00E70590 /* libbsm.dylib in Frameworks */, 6C9808591E788AEB00E70590 /* libcoreauthd_client.a in Frameworks */, 6C98085A1E788AEB00E70590 /* libctkclient.a in Frameworks */, + 0C5960651FB2E2800095BA29 /* libprequelite.tbd in Frameworks */, 6C98085B1E788AEB00E70590 /* libsqlite3.0.dylib in Frameworks */, 6C98085C1E788AEB00E70590 /* libz.dylib in Frameworks */, ); @@ -12273,7 +13031,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 6C9808851E788AFD00E70590 /* libDER_not_installed.a in Frameworks */, + 6CAA8CEE1F83E417007B6E03 /* Security.framework in Frameworks */, + D46246BD1F9AE83600D63882 /* libDER.a in Frameworks */, 6C9808861E788AFD00E70590 /* libASN1_not_installed.a in Frameworks */, 6C9808881E788AFD00E70590 /* libsecurityd_ios_NO_AKS.a in Frameworks */, 6C9808891E788AFD00E70590 /* libSecureObjectSyncFramework.a in Frameworks */, @@ -12291,11 +13050,34 @@ 6C9808941E788AFD00E70590 /* libbsm.dylib in Frameworks */, 6C9808951E788AFD00E70590 /* libcoreauthd_client.a in Frameworks */, 6C9808961E788AFD00E70590 /* libctkclient.a in Frameworks */, + 0C59605F1FB2D9F60095BA29 /* libprequelite.tbd in Frameworks */, 6C9808971E788AFD00E70590 /* libsqlite3.0.dylib in Frameworks */, 6C9808981E788AFD00E70590 /* libz.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; + 6C9AA79B1F7C1D8F00D08296 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6C7FD5DF1F87FA42002C2285 /* Security.framework in Frameworks */, + 6C1260FD1F7DA42D001B2EEC /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6CAA8D1D1F842FB3007B6E03 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D4574AA2203E68C8006D9B82 /* AuthKit.framework in Frameworks */, + D4574AA0203E618B006D9B82 /* Accounts.framework in Frameworks */, + D4119E78202BDF490048587B /* libz.tbd in Frameworks */, + 6CAA8D3B1F8431AE007B6E03 /* Foundation.framework in Frameworks */, + 6CAA8D3A1F8431A7007B6E03 /* libutilities.a in Frameworks */, + 6CAA8D371F843196007B6E03 /* Security.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 6CCDF7811E3C25FA003F2555 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -12322,18 +13104,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 728B569E16D59979008FA3AB /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 72DF9EFE178360230054641E /* libMobileGestalt.dylib in Frameworks */, - 72C3EC2E1705F24E0040C87C /* ManagedConfiguration.framework in Frameworks */, - 72CD2BCE16D59B010064EEE1 /* MobileAsset.framework in Frameworks */, - 72CD2BCD16D59AF30064EEE1 /* Security.framework in Frameworks */, - 728B56A216D59979008FA3AB /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 790851B40CA9859F0083CC4D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -12346,7 +13116,6 @@ DC00AB821D821C9500513D74 /* libSecureObjectSyncServer.a in Frameworks */, DCD8A1E71E09F85400E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */, DC00AB831D821C9A00513D74 /* libSWCAgent.a in Frameworks */, - DC59EA7E1D91CCB2001BDDF5 /* libDER_not_installed.a in Frameworks */, 790851EE0CA9B3410083CC4D /* Security.framework in Frameworks */, E71F3E3116EA69A900FAF9B4 /* SystemConfiguration.framework in Frameworks */, 4CAF66190F3A6FCD0064A534 /* IOKit.framework in Frameworks */, @@ -12454,11 +13223,11 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D46246AA1F9AE6CA00D63882 /* libDER.a in Frameworks */, D41258011E94230400781F23 /* IOKit.framework in Frameworks */, D41257E01E94136000781F23 /* libz.dylib in Frameworks */, D41257DF1E94133600781F23 /* CFNetwork.framework in Frameworks */, D41257DE1E94132900781F23 /* libsqlite3.dylib in Frameworks */, - D41257DC1E94130C00781F23 /* libDER_not_installed.a in Frameworks */, D41257DB1E9412E700781F23 /* libutilities.a in Frameworks */, D41257DA1E9412DC00781F23 /* libtrustd.a in Frameworks */, D41257E21E94138600781F23 /* CoreFoundation.framework in Frameworks */, @@ -12666,7 +13435,6 @@ files = ( CD9F2AFB1DF24BAF00AD3577 /* Foundation.framework in Frameworks */, DCD22D4B1D8CBF54001C9B81 /* libASN1_not_installed.a in Frameworks */, - D4D96ED51F478BAF004B5F01 /* libDER_not_installed.a in Frameworks */, DC00AB6F1D821C3400513D74 /* libSecItemShimOSX.a in Frameworks */, DC00AB701D821C3800513D74 /* libSecOtrOSX.a in Frameworks */, DC00AB6B1D821C1A00513D74 /* libSecTrustOSX.a in Frameworks */, @@ -12711,6 +13479,7 @@ DC3A81D61D99D57F000C7419 /* libcoretls.dylib in Frameworks */, DC3A81D71D99D58A000C7419 /* libcoretls_cfhelpers.dylib in Frameworks */, DC1789291D779A2800B50D50 /* libctkclient.a in Frameworks */, + D46246C91F9AEA5300D63882 /* libDER.a in Frameworks */, DC17891D1D77999700B50D50 /* libpam.dylib in Frameworks */, DC17891F1D77999D00B50D50 /* libsqlite3.dylib in Frameworks */, DC1789211D7799A100B50D50 /* libxar.dylib in Frameworks */, @@ -12731,8 +13500,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D46246BE1F9AE86400D63882 /* libDER.a in Frameworks */, 47A0ABA81E6F7B24001B388C /* SecurityFoundation.framework in Frameworks */, - DC3502C81E020D5B00BC0587 /* libDER_not_installed.a in Frameworks */, DC3502C51E020D5100BC0587 /* libASN1_not_installed.a in Frameworks */, DC222C7A1E034EF700B09171 /* libsecurityd_ios_NO_AKS.a in Frameworks */, DC0984FD1E1DB6DF00140ADC /* libSecureObjectSyncFramework.a in Frameworks */, @@ -12740,6 +13509,7 @@ DC3502D61E02118000BC0587 /* libsecurity.a in Frameworks */, DC3502CF1E020E2900BC0587 /* libutilities.a in Frameworks */, DC222C351E02418100B09171 /* CFNetwork.framework in Frameworks */, + 0C8BBF2B1FCB575800580909 /* CoreCDP.framework in Frameworks */, DC3502DF1E02129F00BC0587 /* Foundation.framework in Frameworks */, DC3502D21E02113900BC0587 /* IOKit.framework in Frameworks */, DC3502E91E02172C00BC0587 /* OCMock.framework in Frameworks */, @@ -12749,6 +13519,7 @@ DC222C361E02419B00B09171 /* libbsm.dylib in Frameworks */, DC3502E41E02130600BC0587 /* libcoreauthd_client.a in Frameworks */, DC3502E21E0212D100BC0587 /* libctkclient.a in Frameworks */, + 0C5960601FB2DA310095BA29 /* libprequelite.tbd in Frameworks */, DC3502CA1E020DC100BC0587 /* libsqlite3.0.dylib in Frameworks */, DC222C321E0240D300B09171 /* libz.dylib in Frameworks */, ); @@ -12879,13 +13650,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - DC59E9E81D91C9DC001BDDF5 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; DC5ABDC21D832DAB00CF422C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -12933,6 +13697,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 0CA4EC10202BB5AF002B1D96 /* Accounts.framework in Frameworks */, + 0C8BBF2D1FCB5A2900580909 /* CoreCDP.framework in Frameworks */, + 0C5960631FB2E1A70095BA29 /* libprequelite.tbd in Frameworks */, 47B90C901F350966006500BC /* CrashReporterSupport.framework in Frameworks */, 474B5FC81E662E79007546F8 /* SecurityFoundation.framework in Frameworks */, D43B88721E72298500F86F19 /* MobileAsset.framework in Frameworks */, @@ -12942,8 +13709,8 @@ DC610A3B1D78F234002223DE /* libACM.a in Frameworks */, DC610A391D78F1B7002223DE /* libaks.a in Frameworks */, DC610A2C1D78F129002223DE /* libaks_acl.a in Frameworks */, + D46246B91F9AE79000D63882 /* libDER.a in Frameworks */, DCD22D601D8CC2EF001C9B81 /* libASN1_not_installed.a in Frameworks */, - DC59EA941D91CDE0001BDDF5 /* libDER_not_installed.a in Frameworks */, DCD22D611D8CC2F8001C9B81 /* libbsm.dylib in Frameworks */, DC610A2B1D78F129002223DE /* libcoreauthd_test_client.a in Frameworks */, DC610A2F1D78F129002223DE /* libctkclient_test.a in Frameworks */, @@ -12956,6 +13723,7 @@ DC00ABE81D821F7D00513D74 /* libsecurityd_ios.a in Frameworks */, D40B6A901E2B673500CD6EE5 /* libtrustd.a in Frameworks */, DCD22D631D8CC33A001C9B81 /* libSOSRegressions.a in Frameworks */, + DCB332451F47856B00178C30 /* libSOSCommands.a in Frameworks */, DCD22D641D8CC341001C9B81 /* libutilities.a in Frameworks */, DCD22D651D8CC349001C9B81 /* libutilitiesRegressions.a in Frameworks */, DCDCCB3A1DF25D1D006E840E /* ApplePushService.framework in Frameworks */, @@ -13048,7 +13816,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DC59EA9A1D91CE94001BDDF5 /* libDER_not_installed.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -13131,8 +13898,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 0C5960621FB2E0EC0095BA29 /* libprequelite.tbd in Frameworks */, 6C1F93111DD5E41A00585608 /* libDiagnosticMessagesClient.dylib in Frameworks */, - EB7F50CC1DB88A03003D787D /* CoreCDP.framework in Frameworks */, DCE4E6AE1D7A3C6A00AFB96E /* AppleSystemInfo.framework in Frameworks */, DCE4E6AD1D7A3B9700AFB96E /* libaks.a in Frameworks */, DCE4E6AC1D7A3B5000AFB96E /* libACM.a in Frameworks */, @@ -13162,6 +13929,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D4C6C5CD1FB3B423007EA57E /* libarchive.tbd in Frameworks */, + D46246B71F9AE76500D63882 /* libDER.a in Frameworks */, DC3A81EC1D99F568000C7419 /* libcoretls.dylib in Frameworks */, DCE4E7C61D7A468300AFB96E /* libaks.a in Frameworks */, DCE4E75E1D7A43B500AFB96E /* CoreFoundation.framework in Frameworks */, @@ -13170,7 +13939,7 @@ DCE4E7541D7A43B500AFB96E /* Foundation.framework in Frameworks */, DCE4E7681D7A43B500AFB96E /* IOKit.framework in Frameworks */, DC65E7751D8CB81000152EF0 /* libregressionBase.a in Frameworks */, - DC59EA8B1D91CD93001BDDF5 /* libDER_not_installed.a in Frameworks */, + DC26710E1F3E932D00816EED /* libASN1_not_installed.a in Frameworks */, DC00ABC71D821EF400513D74 /* libSharedRegressions.a in Frameworks */, DCD22D551D8CC148001C9B81 /* libsecurity_keychain_regressions.a in Frameworks */, DC63CAF81D91A15F00C03317 /* libsecurity_cms_regressions.a in Frameworks */, @@ -13185,10 +13954,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D46246BB1F9AE7B300D63882 /* libDER.a in Frameworks */, DCD22D5F1D8CC294001C9B81 /* libsecurity_ssl_regressions.a in Frameworks */, DCE4E7E41D7A4B8F00AFB96E /* Foundation.framework in Frameworks */, DCE4E7EF1D7A4BCB00AFB96E /* libaks.a in Frameworks */, - DC59EA971D91CDFA001BDDF5 /* libDER_not_installed.a in Frameworks */, DC65E7C21D8CBB5800152EF0 /* libregressionBase.a in Frameworks */, DCE4E7EC1D7A4BB800AFB96E /* Security.framework in Frameworks */, DCE4E7EB1D7A4BB200AFB96E /* SecurityFoundation.framework in Frameworks */, @@ -13205,17 +13974,19 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 0CA4EC11202BB5E9002B1D96 /* Accounts.framework in Frameworks */, + 0C5960641FB2E2070095BA29 /* libprequelite.tbd in Frameworks */, 4710A6D91F34F21700745267 /* CrashReporterSupport.framework in Frameworks */, D41D36711EB14D87007FA978 /* libDiagnosticMessagesClient.tbd in Frameworks */, 474B5FC61E662E48007546F8 /* SecurityFoundation.framework in Frameworks */, 6C5B36C01E2F9BEA008AD443 /* WirelessDiagnostics.framework in Frameworks */, CD9F2AF91DF249B400AD3577 /* Foundation.framework in Frameworks */, DCE4E8281D7A4F1600AFB96E /* login.framework in Frameworks */, + D46246D91F9AED5D00D63882 /* libDER.a in Frameworks */, DCE4E8251D7A4EE400AFB96E /* libACM.a in Frameworks */, DCE4E8241D7A4ECD00AFB96E /* libaks.a in Frameworks */, DCE4E8231D7A4EC900AFB96E /* libaks_acl.a in Frameworks */, DCD22D711D8CC78E001C9B81 /* libASN1_not_installed.a in Frameworks */, - DC59EA7B1D91CC9F001BDDF5 /* libDER_not_installed.a in Frameworks */, DCE4E8201D7A4EAC00AFB96E /* libcoreauthd_client.a in Frameworks */, DCE4E81F1D7A4EA700AFB96E /* libctkclient.a in Frameworks */, DCE4E81C1D7A4E8F00AFB96E /* libsqlite3.0.dylib in Frameworks */, @@ -13231,6 +14002,7 @@ DCD22D721D8CC804001C9B81 /* SystemConfiguration.framework in Frameworks */, DCE4E80F1D7A4E4600AFB96E /* Security.framework in Frameworks */, DC4DB16A1E26E9F900CD6769 /* ProtocolBuffer.framework in Frameworks */, + 0C8BBFFD1FCE8F3300580909 /* CoreCDP.framework in Frameworks */, DCE4E82C1D7A56FF00AFB96E /* AppleSystemInfo.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -13239,6 +14011,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D46246D41F9AEAE300D63882 /* libDER.a in Frameworks */, D40B6A9A1E2B68E800CD6EE5 /* libbsm.dylib in Frameworks */, D40B6A991E2B68A400CD6EE5 /* libz.dylib in Frameworks */, D40B6A981E2B687F00CD6EE5 /* libDiagnosticMessagesClient.dylib in Frameworks */, @@ -13246,7 +14019,6 @@ D40B6A9E1E2B6A6F00CD6EE5 /* libtrustd.a in Frameworks */, D40B6A931E2B67E500CD6EE5 /* libutilities.a in Frameworks */, D40B6A831E2B5F5B00CD6EE5 /* libASN1_not_installed.a in Frameworks */, - D40B6A821E2B5F5600CD6EE5 /* libDER_not_installed.a in Frameworks */, D40B6A9D1E2B6A2700CD6EE5 /* login.framework in Frameworks */, D4ADA3311E2B43450031CEA3 /* CFNetwork.framework in Frameworks */, D4ADA3301E2B433B0031CEA3 /* Security.framework in Frameworks */, @@ -13351,6 +14123,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D4C6C5D01FB3B45E007EA57E /* libarchive.2.dylib in Frameworks */, + 0C59605E1FB2D9990095BA29 /* libprequelite.tbd in Frameworks */, D40B6A8F1E2B643D00CD6EE5 /* libtrustd.a in Frameworks */, DC00ABC01D821EBE00513D74 /* libSharedRegressions.a in Frameworks */, EBE9019B1C2285D4007308C6 /* AggregateDictionary.framework in Frameworks */, @@ -13361,7 +14135,7 @@ DC00ABC11D821EC300513D74 /* libsecurityd_ios.a in Frameworks */, DC00ABC21D821EC600513D74 /* libSecureObjectSyncServer.a in Frameworks */, DCD8A1F31E09F91700E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */, - DC59EA881D91CD7E001BDDF5 /* libDER_not_installed.a in Frameworks */, + D46246B61F9AE75100D63882 /* libDER.a in Frameworks */, DCD22D931D8CCD17001C9B81 /* libASN1_not_installed.a in Frameworks */, DCD22D941D8CCDFA001C9B81 /* libutilities.a in Frameworks */, DC17890B1D77980500B50D50 /* Security.framework in Frameworks */, @@ -13428,7 +14202,6 @@ DC00ABA51D821DCD00513D74 /* libsecurity.a in Frameworks */, DCD8A1F61E09F96900E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */, DCD22D541D8CC0FC001C9B81 /* libutilities.a in Frameworks */, - DC59EA821D91CD24001BDDF5 /* libDER_not_installed.a in Frameworks */, DCD22D531D8CC0EF001C9B81 /* libASN1_not_installed.a in Frameworks */, E7F482A11C7543E500390FDB /* libsqlite3.dylib in Frameworks */, E7F482A31C7544E600390FDB /* libctkclient_test.a in Frameworks */, @@ -13465,7 +14238,6 @@ EB75B4891E75402400E469CC /* IOKit.framework in Frameworks */, EB75B48A1E75405100E469CC /* libsecurity.a in Frameworks */, EB75B48C1E75407C00E469CC /* libutilities.a in Frameworks */, - EB75B48E1E75408C00E469CC /* libDER_not_installed.a in Frameworks */, EB75B48D1E75408900E469CC /* libASN1_not_installed.a in Frameworks */, EB75B48F1E75409A00E469CC /* libsqlite3.dylib in Frameworks */, EB75B4901E7540AA00E469CC /* libctkclient_test.a in Frameworks */, @@ -13510,6 +14282,27 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + EB49B2AB202D877F003F34A0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EB49B2C2202DF002003F34A0 /* libDER.a in Frameworks */, + EB49B2BD202DEF29003F34A0 /* libSecureObjectSyncFramework.a in Frameworks */, + EB49B2BE202DEF29003F34A0 /* libSecureObjectSyncServer.a in Frameworks */, + EB49B2BB202D8894003F34A0 /* libsecurityd_ios.a in Frameworks */, + EB49B2BF202DEF67003F34A0 /* libsecurity.a in Frameworks */, + EB49B2C1202DEF8D003F34A0 /* libASN1_not_installed.a in Frameworks */, + EB49B2C0202DEF7D003F34A0 /* libutilities.a in Frameworks */, + EB49B308202FF421003F34A0 /* OCMock.framework in Frameworks */, + EB49B2E2202DFDA3003F34A0 /* CoreCDP.framework in Frameworks */, + EB49B2D2202DF17D003F34A0 /* SecurityFoundation.framework in Frameworks */, + EB49B2CD202DF0F9003F34A0 /* SystemConfiguration.framework in Frameworks */, + EB49B2C7202DF0E9003F34A0 /* IOKit.framework in Frameworks */, + EB49B2DD202DF259003F34A0 /* libbsm.tbd in Frameworks */, + EB49B2BC202DEF14003F34A0 /* libsqlite3.tbd in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; EB9C1D771BDFD0E000F89272 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -13548,6 +14341,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DC2670F61F3E714000816EED /* libSecureObjectSyncServer.a in Frameworks */, + DCE5DC121EA80369006308A6 /* libSOSCommands.a in Frameworks */, EBF3747E1DC057B40065D840 /* Security.framework in Frameworks */, E76638A81DD679BC00B769D3 /* libutilities.a in Frameworks */, ); @@ -13603,6 +14398,102 @@ path = regressions; sourceTree = ""; }; + 0C7CEA391FE9CE3900125C79 /* behavior */ = { + isa = PBXGroup; + children = ( + EB82A2A41FAFF26900CA64A9 /* SFBehavior.h */, + EB82A2A51FAFF26900CA64A9 /* SFBehavior.m */, + ); + path = behavior; + sourceTree = ""; + }; + 0C8BBE831FC9DA1700580909 /* Octagon Trust */ = { + isa = PBXGroup; + children = ( + 0CCCC7C720261D050024405E /* OT.h */, + 0CCCC7C820261D310024405E /* OT.m */, + EB10A3E320356E2000E84270 /* OTConstants.h */, + EB10A3E420356E2000E84270 /* OTConstants.m */, + DC124DC120059B8700BE8DAC /* OctagonControlServer.h */, + DC124DC220059B8700BE8DAC /* OctagonControlServer.m */, + BEE4B1901FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.h */, + BEE4B1911FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.m */, + 0C8BBE951FC9DA5800580909 /* OTBottledPeer.h */, + 0C8BBE931FC9DA5700580909 /* OTBottledPeer.m */, + BE2AD2B11FDA07EF00739F96 /* OTBottledPeerRecord.h */, + BE2AD2B21FDA07EF00739F96 /* OTBottledPeerRecord.m */, + 0CE1BCCD1FCE11610017230E /* OTBottledPeerSigned.h */, + 0CE1BCC61FCE11480017230E /* OTBottledPeerSigned.m */, + 0C8BBE891FC9DA5200580909 /* OTCloudStore.h */, + 0C770EC31FCF7E2000B5F0E2 /* OTCloudStore.m */, + 0CE407B31FD476E000F59B31 /* OTCloudStoreState.h */, + 0CE407AB1FD4769B00F59B31 /* OTCloudStoreState.m */, + 0C8BBE8B1FC9DA5300580909 /* OTContext.h */, + 0C8BBE981FC9DA5A00580909 /* OTContext.m */, + 0CD9E8071FE05B8700F66C38 /* OTContextRecord.h */, + 0CD9E7FF1FE05B6600F66C38 /* OTContextRecord.m */, + 0C8BBF0B1FCB452200580909 /* OTControl.h */, + 0C8BBF0E1FCB452400580909 /* OTControl.m */, + 0C8BBF0C1FCB452200580909 /* OTControlProtocol.h */, + 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */, + 0C8BBE971FC9DA5A00580909 /* OTDefines.h */, + 0C8BBE921FC9DA5700580909 /* OTEscrowKeys.h */, + 0C8BBE961FC9DA5900580909 /* OTEscrowKeys.m */, + 0C8BBE8A1FC9DA5300580909 /* OTIdentity.h */, + 0C8BBE8D1FC9DA5400580909 /* OTIdentity.m */, + 0C8BBE8E1FC9DA5500580909 /* OTLocalStore.h */, + 0C8BBE8C1FC9DA5400580909 /* OTLocalStore.m */, + 0C8BBF101FCB486B00580909 /* OTManager.h */, + 0C8BBF0F1FCB481800580909 /* OTManager.m */, + 0C36B3202007EE9B0029F7A2 /* OTPreflightInfo.h */, + 0C36B3172007EE6C0029F7A2 /* OTPreflightInfo.m */, + BEB0B0D91FFC45C2007E6A83 /* OTPrivateKey+SF.h */, + BEB0B0DA1FFC45C2007E6A83 /* OTPrivateKey+SF.m */, + 0C5CFB3F201962FF00913B9C /* OTRamping.h */, + 0C5CFB37201960FF00913B9C /* OTRamping.m */, + BE34059B1FD71BA700933DAC /* Protocol Buffers */, + BEE4B1971FFDAFE600777D39 /* SFECPublicKey+SPKI.m */, + BEE4B1961FFDAFE600777D39 /* SFPublicKey+SPKI.h */, + 0C8BBEB11FC9DCAC00580909 /* tests */, + ); + name = "Octagon Trust"; + sourceTree = ""; + }; + 0C8BBEB11FC9DCAC00580909 /* tests */ = { + isa = PBXGroup; + children = ( + 0C8A034E1FDF60070042E8BE /* OTBottledPeerTests.m */, + 0CBDF64C1FFC951200433E0D /* OTBottledPeerTLK.m */, + 0C16371F1FD12F1500210823 /* OTCloudStoreTests.m */, + 0C8BBEAF1FC9DCA400580909 /* OTContextTests.m */, + 0C8A03451FDF42BA0042E8BE /* OTEscrowKeyTests.m */, + 0C8A034C1FDF4CCE0042E8BE /* OTLocalStoreTests.m */, + 0C46A57A2035019800F17112 /* OTLockStateNetworkingTests.m */, + 0CB975502023B199008D6B48 /* OTRampingTests.m */, + 0C52C20520004248003F0733 /* OTTestsBase.h */, + 0C52C1FE20003BCA003F0733 /* OTTestsBase.m */, + ); + name = tests; + sourceTree = ""; + }; + 0C8BBEF61FCB402900580909 /* otctl */ = { + isa = PBXGroup; + children = ( + 0C8BBEF71FCB405700580909 /* otctl.m */, + 0C8BBEF81FCB407700580909 /* otctl-Entitlements.plist */, + ); + path = otctl; + sourceTree = ""; + }; + 0CF0E2DD1F8EE37C00BD18E4 /* Signin Metrics */ = { + isa = PBXGroup; + children = ( + 0CF0E2E31F8EE3B000BD18E4 /* SFTransactionMetric.m */, + 0CF0E2E71F8EE40700BD18E4 /* SFTransactionMetric.h */, + ); + path = "Signin Metrics"; + sourceTree = ""; + }; 107226CF0D91DB32003CF14F /* sectask */ = { isa = PBXGroup; children = ( @@ -13636,10 +14527,24 @@ 4723C9B51F152E8E0082882F /* Analytics */ = { isa = PBXGroup; children = ( + 6C7BAFFD2006B4D4004D1B6B /* Clients */, 4723C9BB1F152E9E0082882F /* SQLite */, - 4723C9DA1F1540CE0082882F /* SFAnalyticsLogger.h */, - 4723C9DB1F1540CE0082882F /* SFAnalyticsLogger.m */, - 475F371F1EE8F23900248FB5 /* SFAnalyticsLogging.plist */, + 475F371F1EE8F23900248FB5 /* SFAnalytics.plist */, + 4723C9DA1F1540CE0082882F /* SFAnalytics.h */, + 6CC952421FB4C5CA0051A823 /* SFAnalytics+Internal.h */, + 4723C9DB1F1540CE0082882F /* SFAnalytics.m */, + 6CBF65371FA147E500A68667 /* SFAnalyticsActivityTracker.h */, + 6C8CE6BB1FA248B50032ADF0 /* SFAnalyticsActivityTracker+Internal.h */, + 6CBF65381FA147E500A68667 /* SFAnalyticsActivityTracker.m */, + 6C69518F1F75A8C100F68F91 /* SFAnalyticsDefines.h */, + 6CDB5FF41FA78CB500410924 /* SFAnalyticsMultiSampler.h */, + 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */, + 6CDB5FF31FA78CB500410924 /* SFAnalyticsMultiSampler+Internal.h */, + 6CDF8DE51F95562B00140B54 /* SFAnalyticsSampler.h */, + 6C8CE6C31FA24A670032ADF0 /* SFAnalyticsSampler+Internal.h */, + 6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */, + 6C69518E1F75A7DC00F68F91 /* SFAnalyticsSQLiteStore.h */, + 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */, ); path = Analytics; sourceTree = ""; @@ -13657,6 +14562,18 @@ path = SQLite; sourceTree = ""; }; + 4727FBB81F9918590003AE36 /* secdxctests */ = { + isa = PBXGroup; + children = ( + 4727FBB91F9918590003AE36 /* KeychainCryptoTests.m */, + 4727FBBB1F9918590003AE36 /* Info.plist */, + 477A1FE1203763A500ACD81D /* KeychainAPITests.m */, + 477A1FEB2037A0E000ACD81D /* KeychainXCTest.h */, + 477A1FEC2037A0E000ACD81D /* KeychainXCTest.m */, + ); + path = secdxctests; + sourceTree = ""; + }; 47702B1F1E5F409700B29577 /* seckeychainnetworkextensionsystemdaemontest */ = { isa = PBXGroup; children = ( @@ -13684,6 +14601,25 @@ path = SecurityUnitTests; sourceTree = ""; }; + 47D1837D1FB1183D00CFCD89 /* SecDbKeychainV7-protobufs */ = { + isa = PBXGroup; + children = ( + 47922D4E1FAA7D5C0008F7E0 /* SecDbKeychainSerializedItemV7.proto */, + 47922D501FAA7DF60008F7E0 /* SecDbKeychainSerializedItemV7.h */, + 47922D511FAA7DF70008F7E0 /* SecDbKeychainSerializedItemV7.m */, + 47922D171FAA65120008F7E0 /* SecDbKeychainAKSSerializedWrappedKey.proto */, + 47922D371FAA7C040008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h */, + 47922D361FAA7C030008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m */, + 47922D201FAA75FF0008F7E0 /* SecDbKeychainSerializedMetadata.proto */, + 47922D3B1FAA7C100008F7E0 /* SecDbKeychainSerializedMetadata.h */, + 47922D3A1FAA7C0F0008F7E0 /* SecDbKeychainSerializedMetadata.m */, + 47922D2C1FAA77970008F7E0 /* SecDbKeychainSerializedSecretData.proto */, + 47922D3E1FAA7C1A0008F7E0 /* SecDbKeychainSerializedSecretData.h */, + 47922D3F1FAA7C1B0008F7E0 /* SecDbKeychainSerializedSecretData.m */, + ); + path = "SecDbKeychainV7-protobufs"; + sourceTree = ""; + }; 4814D86C1CAA064F002FFC36 /* os_log */ = { isa = PBXGroup; children = ( @@ -13698,9 +14634,12 @@ isa = PBXGroup; children = ( 53C0E1F1177FAC2C00F8A018 /* CloudKeychain.strings */, + D4C263C81F952E64001317EA /* SecDebugErrorMessages.strings */, + D4C263CC1F952F6C001317EA /* SecErrorMessages.strings */, BE4AC9B818B8273600B84964 /* SharedWebCredentials.strings */, 4C198F1F0ACDB4BF00AAB142 /* OID.strings */, 4C198F1D0ACDB4BF00AAB142 /* Certificate.strings */, + D479F6DF1F980F8F00388D28 /* Trust.strings */, ); name = strings; path = ../../../resources; @@ -13715,6 +14654,7 @@ DCE4E8A01D7F352600AFB96E /* authd */, DCE4E85A1D7A583100AFB96E /* trustd */, DC5AC1FF1D83650C00CF422C /* securityd */, + 6C69517B1F758E1000F68F91 /* supd */, DC0BC4E51D8B6AA600070CB0 /* applications */, DC5AC2011D83663C00CF422C /* tests */, EB2CA5311D2C30CD00AB770F /* xcconfig */, @@ -13725,6 +14665,8 @@ 4C4CE9120AF81F0E0056B01D /* README */, 4CAB97FD1114CC5300EFB38D /* README.keychain */, 4C4CE9070AF81ED80056B01D /* TODO */, + 0CE98BAD1FA93AA900CF1D54 /* CKKSTests-Info.plist */, + 0C85E0041FB38BB7000343A7 /* OTTests-Info.plist */, ); sourceTree = ""; }; @@ -13741,7 +14683,6 @@ 4C711D7613AFCD0900FE865D /* SecurityDevTests.app */, E7B01BF2166594AB000485F1 /* SyncDevTest2.app */, 52D82BDE16A621F70078DFE5 /* CloudKeychainProxy.bundle */, - 728B56A116D59979008FA3AB /* OTAPKIAssetTool */, 4C52D0B416EFC61E0079966E /* CircleJoinRequested */, 5346480117331E1200FE9172 /* KeychainSyncAccountNotification.bundle */, 0C0BDB2F175685B000BC1A7E /* secdtests */, @@ -13761,7 +14702,6 @@ EBCF73FC1CE45F9C00BED7CA /* secitemfunctionality */, 0C2BCBB91D06401F00ED7A2F /* dtlsEchoClient */, 0C2BCBCE1D0648D100ED7A2F /* dtlsEchoServer */, - DC1785051D77873100B50D50 /* Security.framework */, DC1789041D77980500B50D50 /* Security.framework */, DC58C4231D77BDEA003C25A4 /* csparser.bundle */, DC610A341D78F129002223DE /* secdtests */, @@ -13838,7 +14778,6 @@ DCD06A511D8CE281007602F1 /* libcodehost.a */, DCD06A741D8CE2D5007602F1 /* gkunpack */, DCD06AB01D8E0D53007602F1 /* libsecurity_utilities.a */, - DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */, DC3A4B581D91E9FB00E46D4A /* com.apple.CodeSigningHelper.xpc */, DC71D9DF1D95BA6C0065FB93 /* libASN1.a */, EBF374721DC055580065D840 /* security-sysdiagnose */, @@ -13869,6 +14808,14 @@ BED208DD1EDF950E00753952 /* manifeststresstest */, 47C51B841EEA657D0032D9E5 /* SecurityUnitTests.xctest */, EB2D54AA1F02A45E00E46890 /* secatomicfile */, + 4727FBB71F9918580003AE36 /* secdxctests_ios.xctest */, + 0C85E0031FB38BB6000343A7 /* OTTests.xctest */, + 6C9AA79E1F7C1D8F00D08296 /* supdctl */, + 6CAA8D201F842FB3007B6E03 /* securityuploadd */, + 6C4605B81F882B9B001421B6 /* KeychainAnalyticsTests.xctest */, + 0C8BBF081FCB446400580909 /* otctl */, + 478D429C1FD72A8100CAB645 /* secdxctests_mac.xctest */, + EB49B2AE202D877F003F34A0 /* secdmockaks.xctest */, ); name = Products; sourceTree = ""; @@ -13978,6 +14925,8 @@ 4C4296300BB0A68200491999 /* SecTrustSettings.h */, 4C12828C0BB4957D00985BB0 /* SecTrustSettingsPriv.h */, 4C64E00B0B8FBBF3009B306C /* Security.h */, + EB5E3BC62003C66300F1631B /* SecSignpost.h */, + D46246A21F9AE49E00D63882 /* oids.h */, ); name = Security; sourceTree = SOURCE_ROOT; @@ -14002,6 +14951,7 @@ E78A9AD91D34959200006B5B /* NSFileHandle+Formatting.m */, 4C4CB7100DDA44900026B660 /* entitlements.plist */, E7104A0B169E171900DB0045 /* security_tool_commands.c */, + D453C47F1FFD857400DE349B /* security_tool_commands.h */, E7FEFB80169E26E200E18152 /* sub_commands.h */, ); name = "Security2Tool macOS"; @@ -14087,8 +15037,8 @@ 6C34464E1E2534D200F9522B /* AWD */, EBB407AF1EBA433A00A541A5 /* CKKSPowerCollection.h */, EBB407B01EBA433A00A541A5 /* CKKSPowerCollection.m */, - 479108B51EE879F9008CEFA0 /* CKKSAnalyticsLogger.h */, - 479108B61EE879F9008CEFA0 /* CKKSAnalyticsLogger.m */, + 479108B51EE879F9008CEFA0 /* CKKSAnalytics.h */, + 479108B61EE879F9008CEFA0 /* CKKSAnalytics.m */, ); name = Analytics; sourceTree = ""; @@ -14112,6 +15062,51 @@ name = AWD; sourceTree = ""; }; + 6C69517B1F758E1000F68F91 /* supd */ = { + isa = PBXGroup; + children = ( + 6C758CAF1F8826100075BD78 /* Tests */, + 6C69517C1F758E1000F68F91 /* supdProtocol.h */, + 6C69517D1F758E1000F68F91 /* supd.h */, + 6C69517E1F758E1000F68F91 /* supd.m */, + 6C6951801F758E1000F68F91 /* main.m */, + 6C6951821F758E1000F68F91 /* Info.plist */, + 6C1260FA1F7D631D001B2EEC /* securityuploadd-ios.plist */, + 6C1260F21F7D5F25001B2EEC /* securityuploadd-osx.plist */, + 6C5B10211F9164F5009B091E /* securityuploadd.8 */, + 6CDB600E1FA92C1700410924 /* securityuploadd-Entitlements.plist */, + ); + path = supd; + sourceTree = ""; + }; + 6C758CAF1F8826100075BD78 /* Tests */ = { + isa = PBXGroup; + children = ( + 6C1A29FC1F882788002312D8 /* SFAnalyticsTests.m */, + 6C758CB01F8826100075BD78 /* SupdTests.m */, + 6C758CB21F8826100075BD78 /* Info.plist */, + ); + path = Tests; + sourceTree = ""; + }; + 6C7BAFFD2006B4D4004D1B6B /* Clients */ = { + isa = PBXGroup; + children = ( + 6C7BB0042006B4EF004D1B6B /* SOSAnalytics.h */, + 6C7BB0032006B4EE004D1B6B /* SOSAnalytics.m */, + ); + path = Clients; + sourceTree = ""; + }; + 6C9AA79F1F7C1D9000D08296 /* supdctl */ = { + isa = PBXGroup; + children = ( + 6C9AA7A01F7C1D9000D08296 /* main.m */, + 6C5B101B1F91613E009B091E /* supdctl-Entitlements.plist */, + ); + path = supdctl; + sourceTree = ""; + }; 6CB5F4771E402D6D00DBF3F0 /* testrunner */ = { isa = PBXGroup; children = ( @@ -14170,27 +15165,6 @@ name = "Supporting Files"; sourceTree = ""; }; - 728B56A316D59979008FA3AB /* OTAPKIAssetTool */ = { - isa = PBXGroup; - children = ( - 72CD2BBB16D59AE30064EEE1 /* OTAServiceApp.m */, - 72CD2BBC16D59AE30064EEE1 /* OTAServiceApp.h */, - 72CD2BBD16D59AE30064EEE1 /* OTAServicemain.m */, - 728B56A416D59979008FA3AB /* Supporting Files */, - ); - path = OTAPKIAssetTool; - sourceTree = ""; - }; - 728B56A416D59979008FA3AB /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 5DDD0BDD16D6740E00D6C0D6 /* com.apple.OTAPKIAssetTool.plist */, - 5DDD0BDE16D6740E00D6C0D6 /* OTAPKIAssetTool-entitlements.plist */, - 22C002A31AC9D33100B3469E /* OTAPKIAssetTool.xcconfig */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; 7908507E0CA87CF00083CC4D /* ipc */ = { isa = PBXGroup; children = ( @@ -14257,6 +15231,35 @@ name = "Supporting Files"; sourceTree = ""; }; + BE34059B1FD71BA700933DAC /* Protocol Buffers */ = { + isa = PBXGroup; + children = ( + BE3405A11FD71CC800933DAC /* OTBottle.proto */, + BE3405A51FD720C900933DAC /* OTBottleContents.proto */, + BEB0B0CE1FFC37E3007E6A83 /* OTPrivateKey.proto */, + BEE4B1861FFD57D800777D39 /* OTAuthenticatedCiphertext.proto */, + BE3405A21FD71CDE00933DAC /* derived source */, + ); + name = "Protocol Buffers"; + path = ot/proto; + sourceTree = ""; + }; + BE3405A21FD71CDE00933DAC /* derived source */ = { + isa = PBXGroup; + children = ( + BE3405A41FD71DA600933DAC /* OTBottle.h */, + BE3405A31FD71DA400933DAC /* OTBottle.m */, + BE3405A61FD7210200933DAC /* OTBottleContents.h */, + BE3405A71FD7210300933DAC /* OTBottleContents.m */, + BEB0B0D51FFC3D33007E6A83 /* OTPrivateKey.h */, + BEB0B0D41FFC3D32007E6A83 /* OTPrivateKey.m */, + BEE4B18E1FFD5F9000777D39 /* OTAuthenticatedCiphertext.h */, + BEE4B18F1FFD5F9100777D39 /* OTAuthenticatedCiphertext.m */, + ); + name = "derived source"; + path = source; + sourceTree = ""; + }; BED208E31EDF95BB00753952 /* manifeststresstest */ = { isa = PBXGroup; children = ( @@ -14416,12 +15419,12 @@ F621D0801ED6EA4C000EA569 /* authorizationdump */, DC58C4391D77BEA1003C25A4 /* csparser */, 5E10992719A5E55800A60E2B /* ISACLProtectedItems */, - 728B56A316D59979008FA3AB /* OTAPKIAssetTool */, DC5AC1FE1D8364BA00CF422C /* SecurityTool */, DCC78EA21D80860C00865A7C /* SharedWebCredentialAgent */, BE197F2719116FD100BA91D1 /* SharedWebCredentialViewService */, DC0BC5361D8B6ABE00070CB0 /* XPCKeychainSandboxCheck */, DC0BC56E1D8B6E6400070CB0 /* XPCTimeStampingService */, + 6C9AA79F1F7C1D9000D08296 /* supdctl */, ); name = applications; sourceTree = ""; @@ -14560,8 +15563,6 @@ DC0BC6131D8B755200070CB0 /* ckutilities.c */, DC0BC6141D8B755200070CB0 /* ckutilities.h */, DC0BC6151D8B755200070CB0 /* Crypt.h */, - DC0BC6161D8B755200070CB0 /* CryptKitSA.h */, - DC0BC6171D8B755200070CB0 /* CryptKit.h */, DC0BC6181D8B755200070CB0 /* CryptKitAsn1.cpp */, DC0BC6191D8B755200070CB0 /* CryptKitAsn1.h */, DC0BC61A1D8B755200070CB0 /* CryptKitDER.cpp */, @@ -15333,8 +16334,6 @@ DCC78E451D8085FC00865A7C /* SecCTKKeyPriv.h */, DCC78E381D8085FC00865A7C /* SecCertificate.c */, 4CEF4CA70C5551FE00062475 /* SecCertificateInternal.h */, - DCC78E3B1D8085FC00865A7C /* SecCertificatePath.c */, - 4CF41D0A0BBB4022005F3248 /* SecCertificatePath.h */, DCC78E3E1D8085FC00865A7C /* SecCertificateRequest.c */, DCC78E461D8085FC00865A7C /* SecDH.c */, 7940D4110C3ACF9000FDB5D8 /* SecDH.h */, @@ -15387,6 +16386,8 @@ DCC78E7A1D8085FC00865A7C /* SecPasswordGenerate.c */, CDDE9BC31729AB910013B0E8 /* SecPasswordGenerate.h */, DCC78E7E1D8085FC00865A7C /* SecPolicy.c */, + D43DDE581F638061009742A5 /* SecPolicy.list */, + D43DDE511F620F09009742A5 /* SecPolicyChecks.list */, DCC78E811D8085FC00865A7C /* SecPolicyCerts.h */, 4CFBF5F10D5A92E100969BBE /* SecPolicyInternal.h */, DCC78E7F1D8085FC00865A7C /* SecPolicyLeafCallbacks.c */, @@ -15411,6 +16412,7 @@ EB6928BF1D9C9C5900062A18 /* SecRecoveryKey.m */, DCC78E9A1D8085FC00865A7C /* SecuritydXPC.c */, DCC78E9B1D8085FC00865A7C /* SecuritydXPC.h */, + D462469C1F9AE45900D63882 /* oids.c */, DCC78E2A1D8085FC00865A7C /* p12import.c */, 79EF5B720D3D6AFE009F5270 /* p12import.h */, DCC78E2C1D8085FC00865A7C /* p12pbegen.c */, @@ -15419,6 +16421,7 @@ 8E02FA691107BE460043545E /* pbkdf2.h */, DCC78E9C1D8085FC00865A7C /* vmdh.c */, 4C7391770B01745000C4CBFA /* vmdh.h */, + 47A05B101FDB5A8B00D0816E /* SFKeychainControl.h */, ); name = src; sourceTree = ""; @@ -15578,6 +16581,7 @@ DC1789A81D77A06800B50D50 /* Resources */, DC1789A41D779E3B00B50D50 /* dummy.cpp */, DC24B5801DA3286D00330B48 /* Security.order */, + DCB332361F467CC200178C30 /* macos_tapi_hacks.h */, ); name = "Security.framework macOS"; sourceTree = ""; @@ -15586,6 +16590,7 @@ isa = PBXGroup; children = ( DC178A311D77A1F500B50D50 /* FDEPrefs.plist */, + D4C263C51F8FF2A9001317EA /* generateErrStrings.pl */, DC178A321D77A1F500B50D50 /* SecDebugErrorMessages.strings */, DC178A331D77A1F500B50D50 /* SecErrorMessages.strings */, DC178A351D77A1F500B50D50 /* framework.sb */, @@ -15643,14 +16648,17 @@ DC3502B61E0208BE00BC0587 /* Tests (Local) */ = { isa = PBXGroup; children = ( - DCB5022C1FDA155D008F8E4F /* AutoreleaseTest.c */, - DCB502321FDA155E008F8E4F /* AutoreleaseTest.h */, + DAEE05551FAD3FC500DF27F3 /* AutoreleaseTest.c */, + DAEE055B1FAD3FC600DF27F3 /* AutoreleaseTest.h */, 471024D91E79CB6D00844C09 /* CKKSTests.h */, DC3502B71E0208BE00BC0587 /* CKKSTests.m */, + 0CA4EBF1202B8D1C002B1D96 /* CloudKitKeychainSyncingTestsBase.h */, + 0CA4EBF2202B8D1D002B1D96 /* CloudKitKeychainSyncingTestsBase.m */, DC6593D21ED8DBCE00C19462 /* CKKSTests+API.h */, DC15F79B1E68EAD5003B9A40 /* CKKSTests+API.m */, DC6593C91ED8DA9200C19462 /* CKKSTests+CurrentPointerAPI.m */, DC9A2C5E1EB3F556008FAC27 /* CKKSTests+Coalesce.m */, + DCFABF8D20081E2F001128B5 /* CKKSDeviceStateUploadTests.m */, DCAD9B481F8D95F200C5E2AE /* CloudKitKeychainSyncingFixupTests.m */, DCBF2F7C1F90084D00ED0CA4 /* CKKSTLKSharingTests.m */, DC08D1CB1E64FCC5006237DA /* CKKSSOSTests.m */, @@ -15731,6 +16739,8 @@ DC52EA981D80CC2A00B0A59C /* SecurityTool.c */, DC52EA991D80CC2A00B0A59C /* SecurityTool.h */, DC52EA9A1D80CC2A00B0A59C /* tool_errors.h */, + 473337821FDB29A200E19F30 /* KeychainCheck.h */, + 473337831FDB29A200E19F30 /* KeychainCheck.m */, ); name = "SecurityTool iOS"; path = OSX/sec/SecurityTool; @@ -15763,48 +16773,15 @@ DCD067621D8CDE9B007602F1 /* codesigning */, DCD06AA81D8E0D3D007602F1 /* security_utilities */, E7450BB216D42BD4009C07B8 /* Headers */, - DC59E9AB1D91C9CE001BDDF5 /* DER */, DC8834001D8A217200CE0ACA /* ASN1 */, DC0BCC371D8C689C00070CB0 /* utilities */, DCC0800D1CFF7903005C35C8 /* CSSMOID.exp-in */, 4CB7405F0A47498100D641BB /* Security.exp-in */, + EBD8AD632004B45500588BBA /* SecurityCustomSignposts.plist */, ); name = "Security.framework (Shared)"; sourceTree = ""; }; - DC59E9AB1D91C9CE001BDDF5 /* DER */ = { - isa = PBXGroup; - children = ( - DC59E9FD1D91CA0A001BDDF5 /* libDER */, - ); - name = DER; - sourceTree = ""; - }; - DC59E9FD1D91CA0A001BDDF5 /* libDER */ = { - isa = PBXGroup; - children = ( - DC3832C01DB6E69800385F63 /* module.modulemap */, - DC59E9ED1D91CA0A001BDDF5 /* DER_Keys.c */, - DC59E9EE1D91CA0A001BDDF5 /* DER_Keys.h */, - DC59E9EF1D91CA0A001BDDF5 /* asn1Types.h */, - DC59E9F01D91CA0A001BDDF5 /* DER_CertCrl.c */, - DC59E9F11D91CA0A001BDDF5 /* DER_CertCrl.h */, - DC59E9F21D91CA0A001BDDF5 /* DER_Decode.c */, - DC59E9F31D91CA0A001BDDF5 /* DER_Decode.h */, - DC59E9F41D91CA0A001BDDF5 /* DER_Encode.c */, - DC59E9F51D91CA0A001BDDF5 /* DER_Encode.h */, - DC59E9F61D91CA0A001BDDF5 /* libDER_config.h */, - DC59E9F71D91CA0A001BDDF5 /* libDER.h */, - DC59E9F81D91CA0A001BDDF5 /* DER_Digest.h */, - DC59E9F91D91CA0A001BDDF5 /* DER_Digest.c */, - DC59E9FA1D91CA0A001BDDF5 /* oids.c */, - DC1785421D778A7400B50D50 /* oids.h */, - DC59E9FC1D91CA0A001BDDF5 /* oidsPriv.h */, - ); - name = libDER; - path = OSX/libsecurity_keychain/libDER/libDER; - sourceTree = ""; - }; DC5ABD281D832D4C00CF422C /* SecurityTool macOS */ = { isa = PBXGroup; children = ( @@ -16239,6 +17216,8 @@ EB9C1DAA1BDFD0FE00F89272 /* RegressionTests */, 4CE5A55609C7970A00D27A3F /* sslViewer */, 0C2BCBA41D063F7D00ED7A2F /* dtlsEcho */, + 4727FBB81F9918590003AE36 /* secdxctests */, + EB49B2AF202D8780003F34A0 /* secdmockaks */, ); name = tests; sourceTree = ""; @@ -16406,6 +17385,10 @@ DC6D2C941DD3B20400BE372D /* keychain */ = { isa = PBXGroup; children = ( + 0C7CEA391FE9CE3900125C79 /* behavior */, + 0C8BBEF61FCB402900580909 /* otctl */, + 0C8BBE831FC9DA1700580909 /* Octagon Trust */, + 0CF0E2DD1F8EE37C00BD18E4 /* Signin Metrics */, EB27FF051E402C3C00EC9E3A /* ckksctl */, 6C34464D1E2534C200F9522B /* Analytics */, BEF88C451EAFFFED00357577 /* TrustedPeers */, @@ -16515,6 +17498,8 @@ 6CC7F5B31E9F99EE0014AE63 /* RateLimiter.m */, DC9C95B21F79CFD1000D19E5 /* CKKSControl.h */, DC9C95B31F79CFD1000D19E5 /* CKKSControl.m */, + DA6AA1641FE88AFA004565B0 /* CKKSControlServer.h */, + DA6AA15E1FE88AF9004565B0 /* CKKSControlServer.m */, ); name = "CloudKit Syncing"; path = ckks; @@ -16557,6 +17542,8 @@ DCA4D2191E569FFE0056214F /* Helpers */ = { isa = PBXGroup; children = ( + EB4E0CD41FF36A1900CDCACC /* CKKSReachabilityTracker.h */, + EB4E0CD51FF36A1900CDCACC /* CKKSReachabilityTracker.m */, DC207EB61ED4EAB600D46873 /* CKKSLockStateTracker.h */, DC207EB71ED4EAB600D46873 /* CKKSLockStateTracker.m */, DCCD88E61E42622200F5AA71 /* CKKSGroupOperation.h */, @@ -17169,6 +18156,7 @@ 7281E08E1DFD0D810021E1B7 /* secd-210-keyinterest.m */, 522B28081E64B48E002B5638 /* secd-230-keybagtable.m */, DCFAEDD11D9998DD005187E4 /* secd-668-ghosts.m */, + 0C5F4FD71F952FEA00AF1616 /* secd-700-sftm.m */, DCC78C791D8085D800865A7C /* SOSAccountTesting.h */, DCC78C7A1D8085D800865A7C /* SecdTestKeychainUtilities.c */, DCC78C7B1D8085D800865A7C /* SecdTestKeychainUtilities.h */, @@ -17191,7 +18179,7 @@ DCC78C811D8085D800865A7C /* entitlements.plist */, DCC78C8E1D8085D800865A7C /* SecDbItem.c */, DCC78C8F1D8085D800865A7C /* SecDbItem.h */, - DCC78C901D8085D800865A7C /* SecDbKeychainItem.c */, + DCC78C901D8085D800865A7C /* SecDbKeychainItem.m */, DCC78C911D8085D800865A7C /* SecDbKeychainItem.h */, DCC78C921D8085D800865A7C /* SecDbQuery.c */, DCC78C931D8085D800865A7C /* SecDbQuery.h */, @@ -17220,6 +18208,11 @@ EBC15B1B1DB4306C00126882 /* com.apple.secd.sb */, 526965CB1E6E283100627F9D /* AsymKeybagBackup.h */, 526965CC1E6E283100627F9D /* AsymKeybagBackup.m */, + 470ACEF21F58C3A600D1D5BD /* SecDbKeychainItemV7.h */, + 470ACEF31F58C3A600D1D5BD /* SecDbKeychainItemV7.m */, + 47D1837D1FB1183D00CFCD89 /* SecDbKeychainV7-protobufs */, + 473337771FDAFBCC00E19F30 /* SFKeychainControlManager.h */, + 473337781FDAFBCC00E19F30 /* SFKeychainControlManager.m */, ); name = "securityd iOS"; path = OSX/sec/securityd; @@ -17444,6 +18437,7 @@ DCC78D891D8085F200865A7C /* SOSCloudCircle.m */, DCC78D8A1D8085F200865A7C /* SOSCloudCircle.h */, DCC78D8B1D8085F200865A7C /* SOSCloudCircleInternal.h */, + DCB332371F46804000178C30 /* SOSSysdiagnose.h */, DCC78D8C1D8085F200865A7C /* SOSSysdiagnose.m */, DCC78D8D1D8085F200865A7C /* SOSInternal.m */, DCC78D8E1D8085F200865A7C /* SOSInternal.h */, @@ -17451,6 +18445,8 @@ DCC78D901D8085F200865A7C /* SOSPlatform.h */, EBEEEE351EA31A8300E15F5C /* SOSControlHelper.h */, EBEEEE361EA31A8300E15F5C /* SOSControlHelper.m */, + DAB27ADA1FA29EB700DEBBDE /* SOSControlServer.h */, + DAB27AE01FA29EB800DEBBDE /* SOSControlServer.m */, ); path = SecureObjectSync; sourceTree = ""; @@ -17621,9 +18617,9 @@ DCC78DD81D8085FC00865A7C /* si-60-cms.c */, DCC78DD91D8085FC00865A7C /* si-61-pkcs12.c */, D48F029B1EA1671B00ACC3C9 /* si-61-pkcs12.h */, - DCC78DDA1D8085FC00865A7C /* si-62-csr.c */, + DCC78DDA1D8085FC00865A7C /* si-62-csr.m */, DCC78DDD1D8085FC00865A7C /* si-63-scep */, - DCC78DDE1D8085FC00865A7C /* si-63-scep.c */, + DCC78DDE1D8085FC00865A7C /* si-63-scep.m */, DCC78DDF1D8085FC00865A7C /* si-63-scep.h */, DCC78DE61D8085FC00865A7C /* si-64-ossl-cms */, DCC78DE71D8085FC00865A7C /* si-64-ossl-cms.c */, @@ -17652,7 +18648,8 @@ DCC78E081D8085FC00865A7C /* si-85-sectrust-ssl-policy.h */, DCC78E091D8085FC00865A7C /* si-87-sectrust-name-constraints.m */, DCC78E0A1D8085FC00865A7C /* si-87-sectrust-name-constraints.h */, - DCC78E0B1D8085FC00865A7C /* si-89-cms-hash-agility.c */, + BEB9E9E51FFF193D00676593 /* si-88-sectrust-valid.m */, + DCC78E0B1D8085FC00865A7C /* si-89-cms-hash-agility.m */, DCC78E0C1D8085FC00865A7C /* si-89-cms-hash-agility.h */, DCC78E0D1D8085FC00865A7C /* si-90-emcs.m */, DCC78E0E1D8085FC00865A7C /* si-95-cms-basic.c */, @@ -17705,6 +18702,7 @@ DCC78E231D8085FC00865A7C /* scep.c */, DCC78E241D8085FC00865A7C /* SecurityCommands.h */, DCC78E251D8085FC00865A7C /* show_certificates.c */, + D453C38A1FEC669300DE349B /* trust_update.m */, DCC78E261D8085FC00865A7C /* spc.c */, ); name = Security/Tool; @@ -17723,6 +18721,7 @@ 79BDD3940D60D5F9000D84D3 /* libCMS.xcodeproj */, DCC78E321D8085FC00865A7C /* SecAccessControlExports.exp-in */, DCC78E4E1D8085FC00865A7C /* SecExports.exp-in */, + DCD7EE9B1F4F51D9007D9804 /* ios_tapi_hacks.h */, ); name = "Security.framework iOS"; path = OSX/sec/Security; @@ -17747,7 +18746,6 @@ children = ( DC1787441D7790A500B50D50 /* CSCommonPriv.h */, DC1787451D7790A500B50D50 /* SecAssessment.h */, - DC1787461D7790A500B50D50 /* SecCodeHostLib.h */, DC1787471D7790A500B50D50 /* SecCodePriv.h */, DC1787481D7790A500B50D50 /* SecCodeSigner.h */, DC17874B1D7790A500B50D50 /* SecRequirementPriv.h */, @@ -17755,7 +18753,6 @@ DC1785811D778B7F00B50D50 /* CodeSigning.h */, DC1785821D778B7F00B50D50 /* CSCommon.h */, DC1785831D778B7F00B50D50 /* SecCode.h */, - DC1785841D778B8000B50D50 /* SecCodeHost.h */, DC1785851D778B8000B50D50 /* SecRequirement.h */, DC1785861D778B8000B50D50 /* SecStaticCode.h */, DCD068141D8CDF7E007602F1 /* lib */, @@ -18228,7 +19225,6 @@ DCD06B3C1D8E0D7D007602F1 /* lib */ = { isa = PBXGroup; children = ( - DCD06AB11D8E0D7D007602F1 /* debugging.h */, DCD06AB21D8E0D7D007602F1 /* FileLockTransaction.cpp */, DCD06AB31D8E0D7D007602F1 /* FileLockTransaction.h */, DCD06AB41D8E0D7D007602F1 /* CSPDLTransaction.cpp */, @@ -18432,7 +19428,7 @@ D43DBED61E99D17100C04AEA /* asynchttp.h */, D43DBED71E99D17100C04AEA /* nameconstraints.c */, D43DBED81E99D17100C04AEA /* nameconstraints.h */, - D43DBED91E99D17100C04AEA /* OTATrustUtilities.c */, + D43DBED91E99D17100C04AEA /* OTATrustUtilities.m */, D43DBEDA1E99D17100C04AEA /* OTATrustUtilities.h */, D43DBEDB1E99D17100C04AEA /* personalization.c */, D43DBEDC1E99D17100C04AEA /* personalization.h */, @@ -18462,7 +19458,7 @@ D43761651EB2996C00954447 /* SecRevocationNetworking.m */, D43DBEF31E99D17300C04AEA /* SecRevocationServer.c */, D43DBEF41E99D17300C04AEA /* SecRevocationServer.h */, - D43DBEF51E99D17300C04AEA /* SecTrustLoggingServer.c */, + D43DBEF51E99D17300C04AEA /* SecTrustLoggingServer.m */, D43DBEF61E99D17300C04AEA /* SecTrustLoggingServer.h */, D43DBEF71E99D17300C04AEA /* SecTrustServer.c */, D43DBEF81E99D17300C04AEA /* SecTrustServer.h */, @@ -19276,6 +20272,8 @@ D4EC94FA1CEA482D0083E753 /* si-20-sectrust-policies-data */, 0C0C88771CCEC5BD00617D1B /* si-82-sectrust-ct-data */, DCE4E72E1D7A436300AFB96E /* si-82-sectrust-ct-logs.plist */, + D4C6C5C71FB2AD3F007EA57E /* si-87-sectrust-name-constraints */, + BEB9EA2E1FFF1AF600676593 /* si-88-sectrust-valid-data */, 4C50ACFB1410671D00EE92DE /* DigiNotar */, 79679E241462028800CF997F /* DigicertMalaysia */, E710C74B1331946500F85568 /* Supporting Files */, @@ -19415,6 +20413,42 @@ E7FCBE401314471B000DE34E /* Frameworks */ = { isa = PBXGroup; children = ( + 5A94C6D4203CC2590066E391 /* AuthKit.framework */, + 5A94C6D1203CC1C60066E391 /* AOSAccountsLite.framework */, + 477A1F4C20320E4900ACD81D /* Accounts.framework */, + EB49B2DE202DF286003F34A0 /* CoreFollowUpUI.framework */, + EB49B2DC202DF251003F34A0 /* libbsm.tbd */, + EB49B2CE202DF111003F34A0 /* CoreFollowUp.framework */, + D4119E72202BDF2B0048587B /* libz.tbd */, + 472339681FD7156700CB6A72 /* CoreCDP.framework */, + 472339611FD7155C00CB6A72 /* libprequelite.dylib */, + 47D1838B1FB3827700CFCD89 /* OCMock.framework */, + 4727FBE81F9921D00003AE36 /* libACM.a */, + 4727FBE61F9921890003AE36 /* ApplePushService.framework */, + 4727FBE41F99217A0003AE36 /* SharedWebCredentials.framework */, + 4727FBE21F9921660003AE36 /* MobileKeyBag.framework */, + 4727FBE01F99212F0003AE36 /* IOKit.framework */, + 4727FBDE1F99211D0003AE36 /* libaks.a */, + 4727FBDC1F9920F10003AE36 /* libaks_acl.a */, + 4727FBDA1F9920CB0003AE36 /* WirelessDiagnostics.framework */, + 4727FBD81F9920BB0003AE36 /* SystemConfiguration.framework */, + 4727FBD41F9920510003AE36 /* ProtocolBuffer.framework */, + 4727FBD21F9920290003AE36 /* CloudKit.framework */, + 4727FBD01F991F990003AE36 /* libMobileGestalt.dylib */, + 4727FBCF1F991F820003AE36 /* SecurityFoundation.framework */, + 4727FBCC1F991F660003AE36 /* libsqlite3.dylib */, + 4727FBCA1F991F510003AE36 /* Security.framework */, + 4727FBC41F991C460003AE36 /* Foundation.framework */, + D4C6C5CE1FB3B44C007EA57E /* libarchive.2.dylib */, + D4C6C5CB1FB3B3CC007EA57E /* libarchive.tbd */, + 6CB96BB41F966E0C00E11457 /* libsqlite3.tbd */, + 6CFDC4561F907E1D00646DBB /* libprequelite.tbd */, + D46246911F9AE2E400D63882 /* libDER.a */, + D46246A91F9AE6C900D63882 /* libDER.a */, + D46246AF1F9AE73F00D63882 /* libDER.a */, + D46246C31F9AEA5200D63882 /* libDER.a */, + D46246CE1F9AEAE300D63882 /* libDER.a */, + 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */, F682C1CE1F4486F600F1B029 /* libctkloginhelper.a */, 5EAFA4CD1EF16059002DC188 /* LocalAuthentication.framework */, D41D36701EB14D87007FA978 /* libDiagnosticMessagesClient.tbd */, @@ -19484,7 +20518,6 @@ E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */, E7FCBE411314471B000DE34E /* UIKit.framework */, E75E498C1C8F76680001A34F /* libASN1.a */, - E75E498A1C8F76360001A34F /* libDER.a */, DC1789121D7798B300B50D50 /* libDiagnosticMessagesClient.dylib */, DC610A3C1D78F25C002223DE /* libDiagnosticMessagesClient.dylib */, DC1789141D77997F00B50D50 /* libOpenScriptingUtil.dylib */, @@ -19587,6 +20620,20 @@ name = secitemstresstest; sourceTree = ""; }; + EB49B2AF202D8780003F34A0 /* secdmockaks */ = { + isa = PBXGroup; + children = ( + 72D1E5F3202FE43C003A38C5 /* secdmock_db_version_10_5.h */, + EB49B2B0202D8780003F34A0 /* secdmockaks.m */, + EB6667BE204CD65E000B404F /* testPlistDER.m */, + EB49B303202FB8DE003F34A0 /* mockaks.h */, + EB49B2E4202DFE7F003F34A0 /* mockaks.m */, + EB49B2B2202D8780003F34A0 /* Info.plist */, + ); + name = secdmockaks; + path = tests/secdmockaks; + sourceTree = ""; + }; EB80211C1D3D9044008540C4 /* Modules */ = { isa = PBXGroup; children = ( @@ -19685,7 +20732,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 225394D31E3083C600D3CD9B /* SecCodeHost.h in Headers */, 225394D41E3083D000D3CD9B /* CodeSigning.h in Headers */, 225394D51E3083DA00D3CD9B /* CSCommon.h in Headers */, 225394D61E3083E300D3CD9B /* SecCode.h in Headers */, @@ -19694,6 +20740,7 @@ 2296B0E61E32EF08000D1EA7 /* requirement.h in Headers */, 2296B0EC1E32EF10000D1EA7 /* cs.h in Headers */, 225394DB1E30864B00D3CD9B /* CSCommonPriv.h in Headers */, + DC926F071F33F7C20012A315 /* SecCodeHost.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -19706,13 +20753,17 @@ 4C32C1250A4976BF002891BD /* SecCertificate.h in Headers */, 4C32C1260A4976BF002891BD /* SecTrust.h in Headers */, 4CF0484C0A5D988F00268236 /* SecItem.h in Headers */, + 6CE3654F1FA100F10012F6AB /* SFAnalyticsDefines.h in Headers */, 4CF048800A5F016300268236 /* SecItemPriv.h in Headers */, 4C999BA60AB5F0BB0010451D /* NtlmGenerator.h in Headers */, 4C999BA80AB5F0BB0010451D /* ntlmBlobPriv.h in Headers */, + EB5E3BCC2003C67A00F1631B /* SecSignpost.h in Headers */, 4C7608B30AC34A8100980096 /* SecCertificatePriv.h in Headers */, + EB10A3E520356E2000E84270 /* OTConstants.h in Headers */, 4CEF4CA80C5551FE00062475 /* SecCertificateInternal.h in Headers */, BE061FE11899ECEE00C739F6 /* SecSharedCredential.h in Headers */, 443381EE18A3D83A00215606 /* SecAccessControlPriv.h in Headers */, + 6CC952491FB4CB2D0051A823 /* SFAnalytics+Internal.h in Headers */, DC3C73541D837B1900F6A832 /* SOSCloudCircle.h in Headers */, 524492941AFD6D480043695A /* der_plist.h in Headers */, DC3C73531D837AF800F6A832 /* SOSPeerInfo.h in Headers */, @@ -19721,12 +20772,15 @@ 4C7072860AC9EA4F007CC205 /* SecKey.h in Headers */, 476541651F339F6300413F65 /* SecdWatchdog.h in Headers */, 4C7072D40AC9ED5A007CC205 /* SecKeyPriv.h in Headers */, + DCD7EE981F4F4DE9007D9804 /* SecBase64.h in Headers */, 4C7073CA0ACB2BAD007CC205 /* SecRSAKey.h in Headers */, EB6928C51D9C9C6E00062A18 /* SecRecoveryKey.h in Headers */, 4C0B906E0ACCBD240077CD03 /* SecFramework.h in Headers */, 4C7391790B01745000C4CBFA /* vmdh.h in Headers */, + 6CDB5FFB1FA78D2C00410924 /* SFAnalyticsMultiSampler.h in Headers */, 4C64E01C0B8FBC71009B306C /* SecIdentity.h in Headers */, 4C64E01D0B8FBC7E009B306C /* Security.h in Headers */, + 0C8BBF211FCB4F1800580909 /* OTControlProtocol.h in Headers */, E7676DB619411DF300498DD4 /* SecServerEncryptionSupport.h in Headers */, F964772C1E5832540019E4EB /* SecCodePriv.h in Headers */, 4C4296320BB0A68200491999 /* SecTrustSettings.h in Headers */, @@ -19740,7 +20794,6 @@ 4C1B442D0BB9CAF900461B82 /* SecTrustStore.h in Headers */, DC3C7AB81D838C6F00F6A832 /* oidsalg.h in Headers */, B61F67561F1FCFCA00E2FDBB /* SecPaddingConfigurationsPriv.h in Headers */, - 4CF41D0C0BBB4022005F3248 /* SecCertificatePath.h in Headers */, 4C2F81D50BF121D2003C4F77 /* SecRandom.h in Headers */, ACBAF6EE1E941AE00007BA2F /* transform_regressions.h in Headers */, 7940D4130C3ACF9000FDB5D8 /* SecDH.h in Headers */, @@ -19751,36 +20804,42 @@ 4CE7EA791AEAF39C0067F5BD /* SecItemBackup.h in Headers */, 222F23A01DAC1603007ACB90 /* SecTaskPriv.h in Headers */, DC3C7AB51D838C1300F6A832 /* SecAsn1Templates.h in Headers */, + 6CE365511FA100FE0012F6AB /* SFAnalyticsSampler.h in Headers */, 79EF5B6E0D3D6A31009F5270 /* SecImportExport.h in Headers */, 4723C9CA1F152ECE0082882F /* SFSQLiteStatement.h in Headers */, 4CCE0ADA0D41797400DDBB21 /* SecIdentityPriv.h in Headers */, - 4723C9DC1F1540CE0082882F /* SFAnalyticsLogger.h in Headers */, 4CCE0ADE0D4179E500DDBB21 /* SecBasePriv.h in Headers */, - 4CFBF6100D5A951100969BBE /* SecPolicyInternal.h in Headers */, - DC3C7AB91D838C8D00F6A832 /* oids.h in Headers */, + DCD7EE991F4F4E03007D9804 /* ocspTemplates.h in Headers */, 4C87F3A80D611C26000E7104 /* SecTrustPriv.h in Headers */, 79BDD3C20D60DB84000D84D3 /* SecCMS.h in Headers */, DC2C5F4B1F0D935200FEBDA7 /* CKKSControlProtocol.h in Headers */, 107226D30D91DB32003CF14F /* SecTask.h in Headers */, 4C7CE5700DC7DC6600AE53FC /* SecEntitlements.h in Headers */, + 6CE365551FA101730012F6AB /* SFAnalyticsSQLiteStore.h in Headers */, 791766DE0DD0162C00F3B974 /* SecCertificateRequest.h in Headers */, 4C7416040F1D71A2008E0E4D /* SecSCEP.h in Headers */, DC3C72E21D8374D600F6A832 /* SecureTransportPriv.h in Headers */, 4AF7FFFD15AFB73800B9D400 /* SecOTR.h in Headers */, DC3C7AB21D838B6D00F6A832 /* SecureTransport.h in Headers */, + 6CBF65391FA147E500A68667 /* SFAnalyticsActivityTracker.h in Headers */, 4AF7FFFE15AFB73800B9D400 /* SecOTRDHKey.h in Headers */, 4AF7FFFF15AFB73800B9D400 /* SecOTRErrors.h in Headers */, - 4AF7000015AFB73800B9D400 /* SecOTRIdentityPriv.h in Headers */, + 6C73F48F2006B910003D5D63 /* SOSAnalytics.h in Headers */, + DCD7EE9A1F4F5156007D9804 /* oidsocsp.h in Headers */, + BE2AD2B31FDA07EF00739F96 /* OTBottledPeerRecord.h in Headers */, 4AF7000115AFB73800B9D400 /* SecOTRMath.h in Headers */, 4AF7000315AFB73800B9D400 /* SecOTRPacketData.h in Headers */, DC3C7AB31D838BC300F6A832 /* CipherSuite.h in Headers */, 4AF7000415AFB73800B9D400 /* SecOTRPackets.h in Headers */, + 6C8CE6C11FA248DA0032ADF0 /* SFAnalyticsActivityTracker+Internal.h in Headers */, DC3C7ABA1D838C9F00F6A832 /* sslTypes.h in Headers */, + 6CE3654B1FA100D00012F6AB /* SFAnalytics.h in Headers */, 4AF7000515AFB73800B9D400 /* SecOTRSession.h in Headers */, D487B9821DFA28DB000410A1 /* SecInternalReleasePriv.h in Headers */, 4AF7000615AFB73800B9D400 /* SecOTRSessionPriv.h in Headers */, EB69AB301BF4348000913AF1 /* SecEMCSPriv.h in Headers */, D47F514C1C3B812500A7CEFE /* SecCFAllocator.h in Headers */, + BEB0B0DB1FFC45C2007E6A83 /* OTPrivateKey+SF.h in Headers */, 8E02FA6B1107BE460043545E /* pbkdf2.h in Headers */, 8ED6F6CA110904E300D2B368 /* SecPBKDF.h in Headers */, 7901791812D51F7200CA4D44 /* SecCmsBase.h in Headers */, @@ -19792,14 +20851,18 @@ 22A23B3D1E3AAC9800C41830 /* SecStaticCode.h in Headers */, 724340BA1ED3FEC800F8F566 /* SecSMIME.h in Headers */, 22A23B3E1E3AAC9800C41830 /* SecRequirement.h in Headers */, - 22A23B3F1E3AAC9800C41830 /* SecCodeHost.h in Headers */, DC9C95BE1F79DC5F000D19E5 /* CKKSControl.h in Headers */, + 0CBFEACC200FCD33009A60E9 /* SFTransactionMetric.h in Headers */, DC3C7AB61D838C2D00F6A832 /* SecAsn1Types.h in Headers */, DC3C73551D837B2C00F6A832 /* SOSPeerInfoPriv.h in Headers */, + D46246A31F9AE59E00D63882 /* oids.h in Headers */, + DCD7EEA41F4F58D7007D9804 /* SecLogging.h in Headers */, + 47A05B161FDB5D9E00D0816E /* SFKeychainControl.h in Headers */, 7901791912D51F7200CA4D44 /* SecCmsContentInfo.h in Headers */, 7901791A12D51F7200CA4D44 /* SecCmsDecoder.h in Headers */, 7901791B12D51F7200CA4D44 /* SecCmsDigestContext.h in Headers */, 7901791C12D51F7200CA4D44 /* SecCmsEncoder.h in Headers */, + 0C8BBF201FCB4F1800580909 /* OTControl.h in Headers */, 7901791D12D51F7200CA4D44 /* SecCmsEnvelopedData.h in Headers */, 7901791E12D51F7200CA4D44 /* SecCmsMessage.h in Headers */, 7901791F12D51F7200CA4D44 /* SecCmsRecipientInfo.h in Headers */, @@ -19909,7 +20972,6 @@ DC0BC6721D8B755200070CB0 /* ellipticMeasure.h in Headers */, DC0BC6711D8B755200070CB0 /* elliptic.h in Headers */, DC0BC66E1D8B755200070CB0 /* ECDSA_Profile.h in Headers */, - DC0BC6651D8B755200070CB0 /* CryptKit.h in Headers */, DC0BC69B1D8B755200070CB0 /* platform.h in Headers */, DC0BC6581D8B755200070CB0 /* ckconfig.h in Headers */, DC0BC6831D8B755200070CB0 /* feeFEED.h in Headers */, @@ -19924,7 +20986,6 @@ DC0BC6741D8B755200070CB0 /* ellipticProj.h in Headers */, DC0BC6521D8B755200070CB0 /* byteRep.h in Headers */, DC0BC6851D8B755200070CB0 /* feeFEEDExp.h in Headers */, - DC0BC6641D8B755200070CB0 /* CryptKitSA.h in Headers */, DC0BC6571D8B755200070CB0 /* CipherFileTypes.h in Headers */, DC0BC6691D8B755200070CB0 /* CryptKitDER.h in Headers */, DC0BC65C1D8B755200070CB0 /* ckMD5.h in Headers */, @@ -20261,19 +21322,22 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - DC1785021D77873100B50D50 /* Headers */ = { + DC1789011D77980500B50D50 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + D46246A81F9AE64000D63882 /* oids.h in Headers */, DC1785251D7789AF00B50D50 /* AuthSession.h in Headers */, DC1785211D7789AF00B50D50 /* Authorization.h in Headers */, DC1785221D7789AF00B50D50 /* AuthorizationDB.h in Headers */, DC1785231D7789AF00B50D50 /* AuthorizationPlugin.h in Headers */, DC17875F1D7790E500B50D50 /* AuthorizationPriv.h in Headers */, DC1785241D7789AF00B50D50 /* AuthorizationTags.h in Headers */, + EB5E3BCD2003C67B00F1631B /* SecSignpost.h in Headers */, DC1787601D7790E500B50D50 /* AuthorizationTagsPriv.h in Headers */, DC1785901D778B9D00B50D50 /* CMSDecoder.h in Headers */, DC1785911D778B9D00B50D50 /* CMSEncoder.h in Headers */, + EB10A3FC2035789B00E84270 /* OTConstants.h in Headers */, DC1787591D7790B600B50D50 /* CMSPrivate.h in Headers */, DC1785881D778B8000B50D50 /* CSCommon.h in Headers */, DC17874E1D7790A500B50D50 /* CSCommonPriv.h in Headers */, @@ -20289,7 +21353,9 @@ DC17851A1D77895A00B50D50 /* SecAsn1Types.h in Headers */, DC17874F1D7790A500B50D50 /* SecAssessment.h in Headers */, DC1785931D778BEE00B50D50 /* SecBase.h in Headers */, + DC2671071F3E8A0900816EED /* SecECKey.h in Headers */, DC17877C1D77919500B50D50 /* SecBasePriv.h in Headers */, + 0C8BBF231FCB4F1800580909 /* OTControlProtocol.h in Headers */, DC1787741D77915500B50D50 /* SecBreadcrumb.h in Headers */, DC1787761D77916600B50D50 /* SecCFAllocator.h in Headers */, DC1787111D778FA900B50D50 /* SecCMS.h in Headers */, @@ -20311,13 +21377,13 @@ DC17871C1D778FAA00B50D50 /* SecCmsSignedData.h in Headers */, DC17871D1D778FAA00B50D50 /* SecCmsSignerInfo.h in Headers */, DC1785891D778B8000B50D50 /* SecCode.h in Headers */, - DC17858A1D778B8000B50D50 /* SecCodeHost.h in Headers */, - DC1787501D7790A500B50D50 /* SecCodeHostLib.h in Headers */, DC1787511D7790A500B50D50 /* SecCodePriv.h in Headers */, DC1787521D7790A500B50D50 /* SecCodeSigner.h in Headers */, DC1785301D778A0100B50D50 /* SecCustomTransform.h in Headers */, + 0CBFEACD200FCD33009A60E9 /* SFTransactionMetric.h in Headers */, DC1787771D77916A00B50D50 /* SecDH.h in Headers */, DC1785311D778A0100B50D50 /* SecDecodeTransform.h in Headers */, + 6CE365561FA101740012F6AB /* SFAnalyticsSQLiteStore.h in Headers */, DC1785321D778A0100B50D50 /* SecDigestTransform.h in Headers */, DC1785331D778A0100B50D50 /* SecEncodeTransform.h in Headers */, DC1785341D778A0100B50D50 /* SecEncryptTransform.h in Headers */, @@ -20333,9 +21399,11 @@ DC1787781D77917100B50D50 /* SecItemBackup.h in Headers */, DC17877F1D7791A800B50D50 /* SecItemPriv.h in Headers */, DC17859D1D778C8000B50D50 /* SecKey.h in Headers */, + 6CC952481FB4CB2C0051A823 /* SFAnalytics+Internal.h in Headers */, DC1787801D7791AD00B50D50 /* SecKeyPriv.h in Headers */, DC1785521D778ACD00B50D50 /* SecKeychain.h in Headers */, DC1785531D778ACD00B50D50 /* SecKeychainItem.h in Headers */, + 0C8BBF221FCB4F1800580909 /* OTControl.h in Headers */, DC1787391D77903700B50D50 /* SecKeychainItemExtendedAttributes.h in Headers */, DC17873A1D77903700B50D50 /* SecKeychainItemPriv.h in Headers */, DC17873B1D77903700B50D50 /* SecKeychainPriv.h in Headers */, @@ -20354,6 +21422,7 @@ DC17873E1D77903700B50D50 /* SecRandomP.h in Headers */, DC1785351D778A0100B50D50 /* SecReadTransform.h in Headers */, DC17873F1D77903700B50D50 /* SecRecoveryPassword.h in Headers */, + 6CE3654C1FA100D10012F6AB /* SFAnalytics.h in Headers */, DC17858B1D778B8000B50D50 /* SecRequirement.h in Headers */, DC1787551D7790A500B50D50 /* SecRequirementPriv.h in Headers */, DC17871E1D778FAA00B50D50 /* SecSMIME.h in Headers */, @@ -20368,6 +21437,7 @@ DC1786F41D778EF800B50D50 /* SecTranslocate.h in Headers */, DC1785A01D778C9400B50D50 /* SecTrust.h in Headers */, DC1787841D7791C900B50D50 /* SecTrustPriv.h in Headers */, + 6CDB5FFC1FA78D2D00410924 /* SFAnalyticsMultiSampler.h in Headers */, DC1785A11D778C9A00B50D50 /* SecTrustSettings.h in Headers */, DC1787851D7791CE00B50D50 /* SecTrustSettingsPriv.h in Headers */, DC1785561D778ACD00B50D50 /* SecTrustedApplication.h in Headers */, @@ -20380,6 +21450,7 @@ DC1787411D77903700B50D50 /* TrustSettingsSchema.h in Headers */, D487B9881DFA2902000410A1 /* SecInternalReleasePriv.h in Headers */, DC1787721D77911D00B50D50 /* X509Templates.h in Headers */, + DC926F081F33F7D30012A315 /* SecCodeHost.h in Headers */, DC17876A1D77911D00B50D50 /* asn1Templates.h in Headers */, DC17876B1D77911D00B50D50 /* certExtensionTemplates.h in Headers */, DC1785971D778C0800B50D50 /* certextensions.h in Headers */, @@ -20387,13 +21458,16 @@ DC17876C1D77911D00B50D50 /* csrTemplates.h in Headers */, DC17856C1D778B4A00B50D50 /* cssm.h in Headers */, DC17856D1D778B4A00B50D50 /* cssmaci.h in Headers */, + 6CBF65401FA1480C00A68667 /* SFAnalyticsActivityTracker.h in Headers */, DC17856E1D778B4A00B50D50 /* cssmapi.h in Headers */, DC1785991D778C5300B50D50 /* cssmapple.h in Headers */, DC1787431D77906C00B50D50 /* cssmapplePriv.h in Headers */, DC17856F1D778B4A00B50D50 /* cssmcli.h in Headers */, DC1785701D778B4A00B50D50 /* cssmconfig.h in Headers */, DC1785711D778B4A00B50D50 /* cssmcspi.h in Headers */, + 6C73F4902006B911003D5D63 /* SOSAnalytics.h in Headers */, DC1785721D778B4A00B50D50 /* cssmdli.h in Headers */, + DC337B1F1EA04E2100B3A1F0 /* SecBase64.h in Headers */, DC1785731D778B4A00B50D50 /* cssmerr.h in Headers */, DC1785741D778B4A00B50D50 /* cssmkrapi.h in Headers */, DC1785751D778B4A00B50D50 /* cssmkrspi.h in Headers */, @@ -20403,14 +21477,15 @@ DC17877B1D77918C00B50D50 /* der_plist.h in Headers */, DC1785791D778B4A00B50D50 /* eisl.h in Headers */, DC17857A1D778B4A00B50D50 /* emmspi.h in Headers */, + 6C8CE6C21FA248DB0032ADF0 /* SFAnalyticsActivityTracker+Internal.h in Headers */, DC17857B1D778B4A00B50D50 /* emmtype.h in Headers */, DC17876D1D77911D00B50D50 /* keyTemplates.h in Headers */, DC17853D1D778A3100B50D50 /* mds.h in Headers */, DC17853C1D778A3100B50D50 /* mds_schema.h in Headers */, DC1787231D778FC900B50D50 /* mdspriv.h in Headers */, + DC2671001F3E766E00816EED /* SecOTRSession.h in Headers */, DC17876E1D77911D00B50D50 /* nameTemplates.h in Headers */, DC17876F1D77911D00B50D50 /* ocspTemplates.h in Headers */, - DC1785431D778A7400B50D50 /* oids.h in Headers */, DC1785161D77895A00B50D50 /* oidsalg.h in Headers */, DC1785171D77895A00B50D50 /* oidsattr.h in Headers */, DCCBFA391DBAE445001DD54D /* SecInternal.h in Headers */, @@ -20422,23 +21497,18 @@ DC1787711D77911D00B50D50 /* secasn1t.h in Headers */, DC1786FC1D778F3D00B50D50 /* sslTypes.h in Headers */, DC17871F1D778FAA00B50D50 /* tsaSupport.h in Headers */, - DC1787201D778FAA00B50D50 /* tsaSupportPriv.h in Headers */, - DC1787211D778FAA00B50D50 /* tsaTemplates.h in Headers */, DC17857F1D778B4A00B50D50 /* x509defs.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DC1789011D77980500B50D50 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( + DCB3323B1F4681AE00178C30 /* SecOTR.h in Headers */, 4723C9CB1F152ECF0082882F /* SFSQLiteStatement.h in Headers */, + 6CE365501FA100F20012F6AB /* SFAnalyticsDefines.h in Headers */, + 6CE365521FA100FF0012F6AB /* SFAnalyticsSampler.h in Headers */, 4723C9C31F152EB60082882F /* SFObjCType.h in Headers */, + DCB3323C1F46833E00178C30 /* SecLogging.h in Headers */, DC9C95BD1F79DC5A000D19E5 /* CKKSControl.h in Headers */, DC3C73561D837B9B00F6A832 /* SOSPeerInfoPriv.h in Headers */, EB6928C61D9C9C6F00062A18 /* SecRecoveryKey.h in Headers */, - 4723C9DD1F1540CE0082882F /* SFAnalyticsLogger.h in Headers */, 4723C9C71F152EC10082882F /* SFSQLite.h in Headers */, + 47A05B171FDB5D9F00D0816E /* SFKeychainControl.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -20446,19 +21516,23 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 47922D431FAA7C260008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h in Headers */, DCFE1C351F17ECE5007640C8 /* CKKSCondition.h in Headers */, 6C3446461E25346C00F9522B /* CKKSRateLimiter.h in Headers */, DC2C5F5E1F0EB97E00FEBDA7 /* CKKSNotifier.h in Headers */, DC5BB4FF1E0C98320010F836 /* CKKSOutgoingQueueOperation.h in Headers */, DC222C651E034D1F00B09171 /* SOSChangeTracker.h in Headers */, + 47922D551FAA7E070008F7E0 /* SecDbKeychainSerializedItemV7.h in Headers */, + 0C770EC21FCF7C9800B5F0E2 /* OTCloudStore.h in Headers */, DC14478B1F5764C600236DB4 /* CKKSResultOperation.h in Headers */, DCFE1C521F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.h in Headers */, DCBDB3BC1E57CA7A00B61300 /* CKKSViewManager.h in Headers */, DC762A9F1E57A86A00B03A2C /* CKKSRecordHolder.h in Headers */, DC1DA65F1E4554620094CE7F /* CKKSScanLocalItemsOperation.h in Headers */, DC222C661E034D1F00B09171 /* SOSEngine.h in Headers */, + 0C8BBF1E1FCB4F0400580909 /* OTControl.h in Headers */, DCB5D93C1E4A9A3400BE22AB /* CKKSSynchronizeOperation.h in Headers */, - 479108B81EE879F9008CEFA0 /* CKKSAnalyticsLogger.h in Headers */, + 479108B81EE879F9008CEFA0 /* CKKSAnalytics.h in Headers */, DC222C671E034D1F00B09171 /* SecDbKeychainItem.h in Headers */, DC222C681E034D1F00B09171 /* SecDbQuery.h in Headers */, DCEA5D561E2826DB0089CF55 /* CKKSSIV.h in Headers */, @@ -20466,13 +21540,16 @@ DC222C6A1E034D1F00B09171 /* CKKSZoneStateEntry.h in Headers */, DC94BCCB1F10448600E07CEB /* CloudKitCategories.h in Headers */, DCFE1C281F17E455007640C8 /* CKKSDeviceStateEntry.h in Headers */, + BEE4B1931FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.h in Headers */, DCFB12C61E95A4C000510F5F /* CKKSCKAccountStateTracker.h in Headers */, DC222C6B1E034D1F00B09171 /* SecItemDataSource.h in Headers */, DC7341F41F8447AB00AB9BDF /* CKKSTLKShare.h in Headers */, DC18F7701E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.h in Headers */, DC222C6C1E034D1F00B09171 /* CKKSIncomingQueueEntry.h in Headers */, + 47922D471FAA7C350008F7E0 /* SecDbKeychainSerializedMetadata.h in Headers */, DC9082C71EA027DC00D0C1C5 /* CKKSZoneChangeFetcher.h in Headers */, DCA4D2161E5684220056214F /* CKKSReencryptOutgoingItemsOperation.h in Headers */, + BEE4B1991FFDAFE600777D39 /* SFPublicKey+SPKI.h in Headers */, DC222C6D1E034D1F00B09171 /* SecItemDb.h in Headers */, DC222C6E1E034D1F00B09171 /* SecItemSchema.h in Headers */, DCAD9B451F8D939C00C5E2AE /* CKKSFixups.h in Headers */, @@ -20486,13 +21563,18 @@ DCCD88E91E42622200F5AA71 /* CKKSGroupOperation.h in Headers */, DC15F7671E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.h in Headers */, DCD6C4B31EC5302500414FEE /* CKKSNearFutureScheduler.h in Headers */, + 0C8BBF251FCB4FE800580909 /* OTManager.h in Headers */, DCBF2F861F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.h in Headers */, DCE278E91ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.h in Headers */, + 0C8BBF1F1FCB4F0400580909 /* OTControlProtocol.h in Headers */, DCD662F61E329B6800188186 /* CKKSNewTLKOperation.h in Headers */, DC1447971F5766D200236DB4 /* NSOperationCategories.h in Headers */, DC4DB1511E24692100CD6769 /* CKKSKey.h in Headers */, DCE278DE1ED789EF0083B485 /* CKKSCurrentItemPointer.h in Headers */, + DA6AA1681FE88AFB004565B0 /* CKKSControlServer.h in Headers */, DC222C731E034D1F00B09171 /* CKKSItem.h in Headers */, + 4733377A1FDAFBCC00E19F30 /* SFKeychainControlManager.h in Headers */, + 47922D4B1FAA7C440008F7E0 /* SecDbKeychainSerializedSecretData.h in Headers */, DC7A17EE1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -20501,19 +21583,23 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 47922D421FAA7C240008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h in Headers */, DCFE1C341F17ECE5007640C8 /* CKKSCondition.h in Headers */, DC1DA65E1E4554620094CE7F /* CKKSScanLocalItemsOperation.h in Headers */, DC2C5F5D1F0EB97E00FEBDA7 /* CKKSNotifier.h in Headers */, DCCD88E81E42622200F5AA71 /* CKKSGroupOperation.h in Headers */, 6CC1859E1E24E8EB009657D8 /* CKKSRateLimiter.h in Headers */, + 47922D541FAA7E060008F7E0 /* SecDbKeychainSerializedItemV7.h in Headers */, + 0C770EBC1FCF7C9800B5F0E2 /* OTCloudStore.h in Headers */, DC14478A1F5764C600236DB4 /* CKKSResultOperation.h in Headers */, DCFE1C511F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.h in Headers */, DCBDB3BB1E57CA7A00B61300 /* CKKSViewManager.h in Headers */, DC762A9E1E57A86A00B03A2C /* CKKSRecordHolder.h in Headers */, DC5BB4FE1E0C98320010F836 /* CKKSOutgoingQueueOperation.h in Headers */, DCB5D93B1E4A9A3400BE22AB /* CKKSSynchronizeOperation.h in Headers */, + 0C8BBF1C1FCB4F0300580909 /* OTControl.h in Headers */, DC52E7E81D80BE8700B0A59C /* SOSChangeTracker.h in Headers */, - 479108B71EE879F9008CEFA0 /* CKKSAnalyticsLogger.h in Headers */, + 479108B71EE879F9008CEFA0 /* CKKSAnalytics.h in Headers */, DC52E7E51D80BE7400B0A59C /* SOSEngine.h in Headers */, DC52E7E41D80BE6E00B0A59C /* SecDbKeychainItem.h in Headers */, DC7A17ED1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.h in Headers */, @@ -20521,13 +21607,16 @@ DC378B2D1DEF9DF000A3DAFA /* CKKSMirrorEntry.h in Headers */, DC94BCCA1F10448600E07CEB /* CloudKitCategories.h in Headers */, DCFE1C271F17E455007640C8 /* CKKSDeviceStateEntry.h in Headers */, + BEE4B1921FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.h in Headers */, DCFB12C51E95A4C000510F5F /* CKKSCKAccountStateTracker.h in Headers */, DC378B381DEFADB500A3DAFA /* CKKSZoneStateEntry.h in Headers */, DC7341F31F8447AB00AB9BDF /* CKKSTLKShare.h in Headers */, DC52E7E71D80BE8100B0A59C /* SecItemDataSource.h in Headers */, DC18F76F1E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.h in Headers */, + 47922D461FAA7C340008F7E0 /* SecDbKeychainSerializedMetadata.h in Headers */, DC9082C61EA027DB00D0C1C5 /* CKKSZoneChangeFetcher.h in Headers */, DCA4D2151E5684220056214F /* CKKSReencryptOutgoingItemsOperation.h in Headers */, + BEE4B1981FFDAFE600777D39 /* SFPublicKey+SPKI.h in Headers */, DC378B3C1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.h in Headers */, DC52E7E61D80BE7B00B0A59C /* SecItemDb.h in Headers */, DCAD9B441F8D939C00C5E2AE /* CKKSFixups.h in Headers */, @@ -20541,13 +21630,18 @@ DC6D2C931DD2836500BE372D /* CKKSOutgoingQueueEntry.h in Headers */, DC15F7661E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.h in Headers */, DCD6C4B21EC5302500414FEE /* CKKSNearFutureScheduler.h in Headers */, + 0C8BBF241FCB4FE700580909 /* OTManager.h in Headers */, DCBF2F851F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.h in Headers */, DCE278E81ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.h in Headers */, + 0C8BBF1D1FCB4F0300580909 /* OTControlProtocol.h in Headers */, DCEA5D851E2F14810089CF55 /* CKKSAPSReceiver.h in Headers */, DC1447961F5766D200236DB4 /* NSOperationCategories.h in Headers */, DC4DB1501E24692100CD6769 /* CKKSKey.h in Headers */, DCE278DD1ED789EF0083B485 /* CKKSCurrentItemPointer.h in Headers */, + DA6AA1671FE88AFB004565B0 /* CKKSControlServer.h in Headers */, DCEA5D551E2826DB0089CF55 /* CKKSSIV.h in Headers */, + 473337791FDAFBCC00E19F30 /* SFKeychainControlManager.h in Headers */, + 47922D4A1FAA7C430008F7E0 /* SecDbKeychainSerializedSecretData.h in Headers */, DCDCCB8F1DF7B8D4006E840E /* CKKSItem.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -20556,6 +21650,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + DCB3325A1F478C4100178C30 /* SOSUserKeygen.h in Headers */, DC52E9071D80C3B300B0A59C /* SOSARCDefines.h in Headers */, 0C48990B1E0E0FF300C6CF70 /* SOSTransportCircleCK.h in Headers */, DC52E9101D80C3EF00B0A59C /* SOSAccountLog.h in Headers */, @@ -20603,6 +21698,9 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + DCB332381F46804600178C30 /* SOSSysdiagnose.h in Headers */, + DCE5DC101EA802DA006308A6 /* secToolFileIO.h in Headers */, + DCE5DC111EA80348006308A6 /* accountCirclesViewsPrint.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -20663,13 +21761,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DC59E9AD1D91C9DC001BDDF5 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( + 47A05B181FDB5DBC00D0816E /* SFKeychainControl.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -21033,7 +22125,6 @@ buildActionMask = 2147483647; files = ( DCEDE3961D80B12600C3826E /* SecTrustInternal.h in Headers */, - DCEDE3951D80B12000C3826E /* secToolFileIO.h in Headers */, DCEDE3941D80B11800C3826E /* SecPasswordGenerate.h in Headers */, DCEDE3931D80B11200C3826E /* SecOTR.h in Headers */, DCEDE3921D80B10E00C3826E /* SecOTRDHKey.h in Headers */, @@ -21046,7 +22137,6 @@ DCC0937E1D80B0A700F984E4 /* SecOTRPacketData.h in Headers */, DCC0937D1D80B09E00F984E4 /* SecOTRPackets.h in Headers */, DCC0937C1D80B09200F984E4 /* SecSignatureVerificationSupport.h in Headers */, - 48C2F93C1E4BD00F0093D70C /* accountCirclesViewsPrint.h in Headers */, DCC0937B1D80B07B00F984E4 /* SecOTRSession.h in Headers */, DCC0937A1D80B07200F984E4 /* SecOTRSessionPriv.h in Headers */, DCC093791D80B02100F984E4 /* SecOnOSX.h in Headers */, @@ -21123,7 +22213,6 @@ DCD068591D8CDF7E007602F1 /* kerneldiskrep.h in Headers */, DCD0685F1D8CDF7E007602F1 /* diskimagerep.h in Headers */, DCD069001D8CDFFE007602F1 /* CharInputBuffer.hpp in Headers */, - DCD068691D8CDF7E007602F1 /* SecCodeHostLib.h in Headers */, DCD068F61D8CDFFE007602F1 /* ANTLRUtil.hpp in Headers */, DCD069161D8CDFFF007602F1 /* SemanticException.hpp in Headers */, DC1002D81D8E1A670025549C /* SecTask.h in Headers */, @@ -21212,7 +22301,6 @@ DCD06B821D8E0D7D007602F1 /* utilities.h in Headers */, DCD06B521D8E0D7D007602F1 /* devrandom.h in Headers */, DCD06B751D8E0D7D007602F1 /* threading.h in Headers */, - DCD06B3D1D8E0D7D007602F1 /* debugging.h in Headers */, DCD06B611D8E0D7D007602F1 /* logging.h in Headers */, DCD06B471D8E0D7D007602F1 /* alloc.h in Headers */, DCD06B731D8E0D7D007602F1 /* superblob.h in Headers */, @@ -21223,6 +22311,7 @@ DCD06B951D8E0D7D007602F1 /* vproc++.h in Headers */, DCD06BAA1D8E0D7D007602F1 /* cfmunge.h in Headers */, DCD06B6A1D8E0D7D007602F1 /* seccfobject.h in Headers */, + DC2670F21F3E6EC500816EED /* debugging.h in Headers */, DCD06B411D8E0D7D007602F1 /* CSPDLTransaction.h in Headers */, DCD06B4D1D8E0D7D007602F1 /* daemon.h in Headers */, DCD06BAC1D8E0D7D007602F1 /* cfutilities.h in Headers */, @@ -21273,11 +22362,11 @@ files = ( DCD8A15A1E09EE0F00E4FA0A /* SOSAccountTransaction.h in Headers */, 0CE760561E1316E900B4381E /* SOSAccountTrustClassic+Retirement.h in Headers */, + DC2670FC1F3E72C400816EED /* SOSCircleDer.h in Headers */, 0CE760541E13155100B4381E /* SOSAccountTrustClassic+Circle.h in Headers */, DCD8A15C1E09EE0F00E4FA0A /* SOSBackupSliceKeyBag.h in Headers */, DCD8A15D1E09EE0F00E4FA0A /* SOSCircle.h in Headers */, 0C4899271E0F399B00C6CF70 /* SOSAccountTrustOctagon.h in Headers */, - DCD8A15E1E09EE0F00E4FA0A /* SOSCircleDer.h in Headers */, DCD8A15F1E09EE0F00E4FA0A /* SOSCirclePriv.h in Headers */, DCD8A1601E09EE0F00E4FA0A /* SOSCircleRings.h in Headers */, DCD8A1611E09EE0F00E4FA0A /* SOSCircleV2.h in Headers */, @@ -21308,7 +22397,6 @@ DCD8A1861E09EE0F00E4FA0A /* SOSRingPeerInfoUtils.h in Headers */, 0CE760521E1314F700B4381E /* SOSAccountTrustClassic+Identity.h in Headers */, DCD8A1871E09EE0F00E4FA0A /* SOSRingTypes.h in Headers */, - DCD8A1881E09EE0F00E4FA0A /* SOSAccountPriv.h in Headers */, DCD8A1DF1E09F76000E4FA0A /* SOSPeerInfoCollections.h in Headers */, DCD8A1891E09EE0F00E4FA0A /* SOSRingUtils.h in Headers */, DCD8A18A1E09EE0F00E4FA0A /* SOSRingV0.h in Headers */, @@ -21317,7 +22405,6 @@ DCD8A1901E09EE0F00E4FA0A /* SOSAccountTrust.h in Headers */, DCD8A1DE1E09F74700E4FA0A /* SOSPeerInfoV2.h in Headers */, DCD8A1931E09EE0F00E4FA0A /* SOSTypes.h in Headers */, - DCD8A1941E09EE0F00E4FA0A /* SOSUserKeygen.h in Headers */, DCD8A1951E09EE0F00E4FA0A /* SOSViews.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -21719,7 +22806,6 @@ DC00ABD11D821F1A00513D74 /* PBXTargetDependency */, DC00ABD31D821F1D00513D74 /* PBXTargetDependency */, DCD8A1EF1E09F8BC00E4FA0A /* PBXTargetDependency */, - DC59EA901D91CDC6001BDDF5 /* PBXTargetDependency */, DC65E75A1D8CB48900152EF0 /* PBXTargetDependency */, DC59E9A91D91C7CC001BDDF5 /* PBXTargetDependency */, DC65E75C1D8CB49200152EF0 /* PBXTargetDependency */, @@ -21766,6 +22852,47 @@ productReference = 0C2BCBCE1D0648D100ED7A2F /* dtlsEchoServer */; productType = "com.apple.product-type.tool"; }; + 0C85DFD11FB38BB6000343A7 /* OTTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0C85E0001FB38BB6000343A7 /* Build configuration list for PBXNativeTarget "OTTests" */; + buildPhases = ( + 0C85DFE21FB38BB6000343A7 /* Sources */, + 0C85DFE51FB38BB6000343A7 /* Frameworks */, + 0C85DFFD1FB38BB6000343A7 /* Embed OCMock */, + 0C85DFFF1FB38BB6000343A7 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + 0C85DFD41FB38BB6000343A7 /* PBXTargetDependency */, + 0C85DFD81FB38BB6000343A7 /* PBXTargetDependency */, + 0C85DFDA1FB38BB6000343A7 /* PBXTargetDependency */, + 0C85DFDC1FB38BB6000343A7 /* PBXTargetDependency */, + 0C85DFDE1FB38BB6000343A7 /* PBXTargetDependency */, + 0C85DFE01FB38BB6000343A7 /* PBXTargetDependency */, + ); + name = OTTests; + productName = CKKSTests; + productReference = 0C85E0031FB38BB6000343A7 /* OTTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 0C8BBEFD1FCB446400580909 /* otctl */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0C8BBF051FCB446400580909 /* Build configuration list for PBXNativeTarget "otctl" */; + buildPhases = ( + 0C8BBEFE1FCB446400580909 /* Sources */, + 0C8BBF021FCB446400580909 /* Frameworks */, + 0C8BBF041FCB446400580909 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = otctl; + productName = ckksctl; + productReference = 0C8BBF081FCB446400580909 /* otctl */; + productType = "com.apple.product-type.tool"; + }; 225394AC1E3080A600D3CD9B /* security_codesigning_ios */ = { isa = PBXNativeTarget; buildConfigurationList = 225394B11E3080A600D3CD9B /* Build configuration list for PBXNativeTarget "security_codesigning_ios" */; @@ -21818,6 +22945,27 @@ productReference = 470415CF1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */; productType = "com.apple.product-type.tool"; }; + 4727FBB61F9918580003AE36 /* secdxctests_ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4727FBC31F9918590003AE36 /* Build configuration list for PBXNativeTarget "secdxctests_ios" */; + buildPhases = ( + 4727FBB31F9918580003AE36 /* Sources */, + 4727FBB41F9918580003AE36 /* Frameworks */, + 4727FBB51F9918580003AE36 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 47DE88D91FA7ADBB00DD3254 /* PBXTargetDependency */, + 47DE88D71FA7ADAC00DD3254 /* PBXTargetDependency */, + 47DE88D51FA7AD7000DD3254 /* PBXTargetDependency */, + 47DE88CE1FA7AD6200DD3254 /* PBXTargetDependency */, + ); + name = secdxctests_ios; + productName = secdxctests; + productReference = 4727FBB71F9918580003AE36 /* secdxctests_ios.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 47702B1D1E5F409700B29577 /* seckeychainnetworkextensionsystemdaemontest */ = { isa = PBXNativeTarget; buildConfigurationList = 47702B221E5F409700B29577 /* Build configuration list for PBXNativeTarget "seckeychainnetworkextensionsystemdaemontest" */; @@ -21852,6 +23000,30 @@ productReference = 47702B2E1E5F492C00B29577 /* seckeychainnetworkextensionunauthorizedaccesstest */; productType = "com.apple.product-type.tool"; }; + 478D426C1FD72A8100CAB645 /* secdxctests_mac */ = { + isa = PBXNativeTarget; + buildConfigurationList = 478D42991FD72A8100CAB645 /* Build configuration list for PBXNativeTarget "secdxctests_mac" */; + buildPhases = ( + 478D42751FD72A8100CAB645 /* Sources */, + 478D427D1FD72A8100CAB645 /* Frameworks */, + 478D42981FD72A8100CAB645 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + DC34CD3620326C3B00302481 /* PBXTargetDependency */, + DC34CD3420326C3100302481 /* PBXTargetDependency */, + DC34CD2D20326C2C00302481 /* PBXTargetDependency */, + 478D426D1FD72A8100CAB645 /* PBXTargetDependency */, + 478D426F1FD72A8100CAB645 /* PBXTargetDependency */, + 478D42711FD72A8100CAB645 /* PBXTargetDependency */, + 478D42731FD72A8100CAB645 /* PBXTargetDependency */, + ); + name = secdxctests_mac; + productName = secdxctests; + productReference = 478D429C1FD72A8100CAB645 /* secdxctests_mac.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 47C51B831EEA657D0032D9E5 /* SecurityUnitTests */ = { isa = PBXNativeTarget; buildConfigurationList = 47C51B931EEA657D0032D9E5 /* Build configuration list for PBXNativeTarget "SecurityUnitTests" */; @@ -21876,6 +23048,7 @@ buildPhases = ( 4C32C0AA0A4975F6002891BD /* Headers */, E73288DD1AED7215008CE839 /* Copy SecureObjectSync Headers */, + D4C263C41F8FEAA8001317EA /* Run Script Generate Error Strings */, 4C32C0AB0A4975F6002891BD /* Resources */, 4C32C0AC0A4975F6002891BD /* Sources */, 4C32C0AD0A4975F6002891BD /* Frameworks */, @@ -21886,7 +23059,6 @@ ); dependencies = ( DC59E9A61D91C710001BDDF5 /* PBXTargetDependency */, - DC59EA761D91CC5E001BDDF5 /* PBXTargetDependency */, DCD22D7D1D8CCA18001C9B81 /* PBXTargetDependency */, DCD22D7B1D8CCA07001C9B81 /* PBXTargetDependency */, DCD8A19C1E09EEA200E4FA0A /* PBXTargetDependency */, @@ -21934,7 +23106,6 @@ buildRules = ( ); dependencies = ( - DC59EA841D91CD2C001BDDF5 /* PBXTargetDependency */, DC00ABAA1D821DE600513D74 /* PBXTargetDependency */, DC00ABAC1D821DE700513D74 /* PBXTargetDependency */, DCD8A1FB1E09F99700E4FA0A /* PBXTargetDependency */, @@ -22075,7 +23246,6 @@ dependencies = ( D40B6A861E2B5F7600CD6EE5 /* PBXTargetDependency */, DC89998B1E410DBF00E6E604 /* PBXTargetDependency */, - DC59EA8D1D91CDB9001BDDF5 /* PBXTargetDependency */, DC65E7561D8CB47600152EF0 /* PBXTargetDependency */, DC00ABC91D821F0200513D74 /* PBXTargetDependency */, DCD8A1E61E09F81300E4FA0A /* PBXTargetDependency */, @@ -22087,6 +23257,23 @@ productReference = 5EBE247A1B00CCAE0007DB0E /* secacltests */; productType = "com.apple.product-type.tool"; }; + 6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6C4605B51F882B9B001421B6 /* Build configuration list for PBXNativeTarget "KeychainAnalyticsTests" */; + buildPhases = ( + 6C46057A1F882B9B001421B6 /* Sources */, + 6C46059B1F882B9B001421B6 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 6C9A49B21FAB647D00239D58 /* PBXTargetDependency */, + ); + name = KeychainAnalyticsTests; + productName = CKKSTests; + productReference = 6C4605B81F882B9B001421B6 /* KeychainAnalyticsTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 6C98082C1E788AEB00E70590 /* CKKSCloudKitTests_mac */ = { isa = PBXNativeTarget; buildConfigurationList = 6C98085E1E788AEB00E70590 /* Build configuration list for PBXNativeTarget "CKKSCloudKitTests_mac" */; @@ -22098,7 +23285,6 @@ buildRules = ( ); dependencies = ( - 6C98082D1E788AEB00E70590 /* PBXTargetDependency */, 6C98082F1E788AEB00E70590 /* PBXTargetDependency */, 6C9808311E788AEB00E70590 /* PBXTargetDependency */, 6C9808351E788AEB00E70590 /* PBXTargetDependency */, @@ -22124,7 +23310,6 @@ ); dependencies = ( 6C9808A41E788CB100E70590 /* PBXTargetDependency */, - 6C9808691E788AFD00E70590 /* PBXTargetDependency */, 6C98086B1E788AFD00E70590 /* PBXTargetDependency */, 6C98086D1E788AFD00E70590 /* PBXTargetDependency */, 6C9808711E788AFD00E70590 /* PBXTargetDependency */, @@ -22137,6 +23322,41 @@ productReference = 6C98089D1E788AFD00E70590 /* CKKSCloudKitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 6C9AA79D1F7C1D8F00D08296 /* supdctl */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6C9AA7A21F7C1D9000D08296 /* Build configuration list for PBXNativeTarget "supdctl" */; + buildPhases = ( + 6C9AA79A1F7C1D8F00D08296 /* Sources */, + 6C9AA79B1F7C1D8F00D08296 /* Frameworks */, + 6C9AA79C1F7C1D8F00D08296 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = supdctl; + productName = supdctl; + productReference = 6C9AA79E1F7C1D8F00D08296 /* supdctl */; + productType = "com.apple.product-type.tool"; + }; + 6CAA8D1F1F842FB3007B6E03 /* securityuploadd */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6CAA8D241F842FB4007B6E03 /* Build configuration list for PBXNativeTarget "securityuploadd" */; + buildPhases = ( + 6CAA8D1C1F842FB3007B6E03 /* Sources */, + 6CAA8D1D1F842FB3007B6E03 /* Frameworks */, + 6CAA8D1E1F842FB3007B6E03 /* Copy Manpage */, + 6CAA8D361F84317F007B6E03 /* Install launchd plist */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = securityuploadd; + productName = supd; + productReference = 6CAA8D201F842FB3007B6E03 /* securityuploadd */; + productType = "com.apple.product-type.tool"; + }; 6CCDF7831E3C25FA003F2555 /* KeychainEntitledTestRunner */ = { isa = PBXNativeTarget; buildConfigurationList = 6CCDF7881E3C25FB003F2555 /* Build configuration list for PBXNativeTarget "KeychainEntitledTestRunner" */; @@ -22189,23 +23409,6 @@ productReference = 6CF4A0E01E4549F200ECD7B5 /* KeychainEntitledTestApp.app */; productType = "com.apple.product-type.application"; }; - 728B56A016D59979008FA3AB /* OTAPKIAssetTool */ = { - isa = PBXNativeTarget; - buildConfigurationList = 728B56AB16D59979008FA3AB /* Build configuration list for PBXNativeTarget "OTAPKIAssetTool" */; - buildPhases = ( - 728B569D16D59979008FA3AB /* Sources */, - 728B569E16D59979008FA3AB /* Frameworks */, - 22C002A21AC9D2D100B3469E /* ShellScript */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = OTAPKIAssetTool; - productName = OTAPKIAssetTool; - productReference = 728B56A116D59979008FA3AB /* OTAPKIAssetTool */; - productType = "com.apple.product-type.tool"; - }; 790851B50CA9859F0083CC4D /* securityd_ios */ = { isa = PBXNativeTarget; buildConfigurationList = 790851C90CA985C10083CC4D /* Build configuration list for PBXNativeTarget "securityd_ios" */; @@ -22218,7 +23421,6 @@ buildRules = ( ); dependencies = ( - DC59EA7D1D91CCAA001BDDF5 /* PBXTargetDependency */, DC65E7291D8CB2F400152EF0 /* PBXTargetDependency */, D40B6A7F1E2B5F3D00CD6EE5 /* PBXTargetDependency */, DC52E84B1D80BF1100B0A59C /* PBXTargetDependency */, @@ -22385,7 +23587,6 @@ dependencies = ( D41257E81E941AD200781F23 /* PBXTargetDependency */, D41257E61E941ACC00781F23 /* PBXTargetDependency */, - D41257E41E941A8400781F23 /* PBXTargetDependency */, ); name = trustd_ios; productName = trustd_ios; @@ -22841,31 +24042,14 @@ productReference = DC0BCD481D8C694700070CB0 /* libutilitiesRegressions.a */; productType = "com.apple.product-type.library.static"; }; - DC1785041D77873100B50D50 /* copyHeadersToSystem */ = { - isa = PBXNativeTarget; - buildConfigurationList = DC17850A1D77873200B50D50 /* Build configuration list for PBXNativeTarget "copyHeadersToSystem" */; - buildPhases = ( - DC1785021D77873100B50D50 /* Headers */, - DC1785031D77873100B50D50 /* Resources */, - DC17886F1D77934100B50D50 /* Copy SecurityObjectSync Headers */, - DC1788D81D7793C000B50D50 /* Unifdef RC_HIDE_J79/J80 */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = copyHeadersToSystem; - productName = copyHeadersToSystem; - productReference = DC1785051D77873100B50D50 /* Security.framework */; - productType = "com.apple.product-type.framework"; - }; DC1789031D77980500B50D50 /* Security_osx */ = { isa = PBXNativeTarget; buildConfigurationList = DC17890D1D77980500B50D50 /* Build configuration list for PBXNativeTarget "Security_osx" */; buildPhases = ( + DC1789011D77980500B50D50 /* Headers */, + DCF7F5D11F69AC28001042E9 /* Copy SecureObjectSync Headers */, DC1788FF1D77980500B50D50 /* Sources */, DC1789001D77980500B50D50 /* Frameworks */, - DC1789011D77980500B50D50 /* Headers */, DC1789A71D779E7E00B50D50 /* Run Script Generate Strings */, DC1789021D77980500B50D50 /* Resources */, DC1789E81D77A0E700B50D50 /* CopyFiles */, @@ -22876,10 +24060,8 @@ ); dependencies = ( DCD8A1FE1E09FA1800E4FA0A /* PBXTargetDependency */, - DC0B62961D90B6DB00D43BCB /* PBXTargetDependency */, DCC5BF381D937329008D1E84 /* PBXTargetDependency */, DC1789791D779C6700B50D50 /* PBXTargetDependency */, - DC59EA791D91CC78001BDDF5 /* PBXTargetDependency */, DC0BCDB71D8C6AD100070CB0 /* PBXTargetDependency */, DCB340191D8A248C0054D16E /* PBXTargetDependency */, DCD66DC31D82056C00DB1393 /* PBXTargetDependency */, @@ -22928,7 +24110,6 @@ DC222C381E034D1F00B09171 /* Sources */, DC222C631E034D1F00B09171 /* Frameworks */, DC222C641E034D1F00B09171 /* Headers */, - 6C0B0C481E2537E2007F95E5 /* CopyFiles */, ); buildRules = ( DC9FD3221F85877000C8AAC8 /* PBXBuildRule */, @@ -22953,7 +24134,6 @@ buildRules = ( ); dependencies = ( - DC3502C71E020D5600BC0587 /* PBXTargetDependency */, DC3502C41E020D4D00BC0587 /* PBXTargetDependency */, DC3502CE1E020E2200BC0587 /* PBXTargetDependency */, DC0984F71E1DB6D400140ADC /* PBXTargetDependency */, @@ -23228,24 +24408,6 @@ productReference = DC58C4231D77BDEA003C25A4 /* csparser.bundle */; productType = "com.apple.product-type.bundle"; }; - DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */ = { - isa = PBXNativeTarget; - buildConfigurationList = DC59E9E91D91C9DC001BDDF5 /* Build configuration list for PBXNativeTarget "DER_not_installed" */; - buildPhases = ( - DC71DA011D95BD670065FB93 /* Why is this here? */, - DC59E9AD1D91C9DC001BDDF5 /* Headers */, - DC59E9D01D91C9DC001BDDF5 /* Sources */, - DC59E9E81D91C9DC001BDDF5 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = DER_not_installed; - productName = libsecurityd_client_macos; - productReference = DC59E9EC1D91C9DC001BDDF5 /* libDER_not_installed.a */; - productType = "com.apple.product-type.library.static"; - }; DC5ABDC41D832DAB00CF422C /* securitytool_macos */ = { isa = PBXNativeTarget; buildConfigurationList = DC5ABDC91D832DAB00CF422C /* Build configuration list for PBXNativeTarget "securitytool_macos" */; @@ -23301,7 +24463,6 @@ dependencies = ( DC0BB4441ED4D74A0035F886 /* PBXTargetDependency */, DC65E7601D8CB4A300152EF0 /* PBXTargetDependency */, - DC59EA931D91CDD6001BDDF5 /* PBXTargetDependency */, DC65E7621D8CB4AA00152EF0 /* PBXTargetDependency */, DC00ABE21D821F6000513D74 /* PBXTargetDependency */, DC00ABE01D821F5C00513D74 /* PBXTargetDependency */, @@ -23309,6 +24470,7 @@ D40B6A921E2B678D00CD6EE5 /* PBXTargetDependency */, DC00ABE41D821F6200513D74 /* PBXTargetDependency */, DCD22D671D8CC387001C9B81 /* PBXTargetDependency */, + DCB332471F47857D00178C30 /* PBXTargetDependency */, DC65E7641D8CB4B100152EF0 /* PBXTargetDependency */, DCD22D691D8CC3A6001C9B81 /* PBXTargetDependency */, ); @@ -23502,7 +24664,6 @@ buildRules = ( ); dependencies = ( - DC59EA991D91CE8C001BDDF5 /* PBXTargetDependency */, ); name = security_keychain; productName = libsecurityd_client_macos; @@ -23730,7 +24891,7 @@ ); dependencies = ( DC65E7541D8CB46100152EF0 /* PBXTargetDependency */, - DC59EA8A1D91CD89001BDDF5 /* PBXTargetDependency */, + DC2671101F3E933700816EED /* PBXTargetDependency */, DC52EE631D80D7D900B0A59C /* PBXTargetDependency */, DCB345B31D8A361F0054D16E /* PBXTargetDependency */, DC63CAFA1D91A16700C03317 /* PBXTargetDependency */, @@ -23754,7 +24915,6 @@ buildRules = ( ); dependencies = ( - DC59EA961D91CDEE001BDDF5 /* PBXTargetDependency */, DC65E7661D8CB4C200152EF0 /* PBXTargetDependency */, DC65E7681D8CB4CB00152EF0 /* PBXTargetDependency */, DCE4E7D81D7A4B3500AFB96E /* PBXTargetDependency */, @@ -23780,7 +24940,6 @@ ); dependencies = ( DCD8A2071E09FB1F00E4FA0A /* PBXTargetDependency */, - DC71DA091D95BEE00065FB93 /* PBXTargetDependency */, DC71DA031D95BDEA0065FB93 /* PBXTargetDependency */, DC00AB721D821C4600513D74 /* PBXTargetDependency */, DC00AB741D821C4800513D74 /* PBXTargetDependency */, @@ -23808,7 +24967,6 @@ ); dependencies = ( D40B6A811E2B5F4700CD6EE5 /* PBXTargetDependency */, - DC71DA0B1D95BEF60065FB93 /* PBXTargetDependency */, DC71DA051D95BDF90065FB93 /* PBXTargetDependency */, DC65E72C1D8CB31200152EF0 /* PBXTargetDependency */, ); @@ -24012,7 +25170,6 @@ buildRules = ( ); dependencies = ( - DC59EA871D91CD76001BDDF5 /* PBXTargetDependency */, DC00ABBB1D821E9B00513D74 /* PBXTargetDependency */, DC00ABBD1D821E9F00513D74 /* PBXTargetDependency */, DCD8A1F51E09F91F00E4FA0A /* PBXTargetDependency */, @@ -24086,7 +25243,6 @@ DC00AB9E1D821DBB00513D74 /* PBXTargetDependency */, DCD8A1F81E09F97300E4FA0A /* PBXTargetDependency */, DC65E7401D8CB3CD00152EF0 /* PBXTargetDependency */, - DC59EA811D91CD16001BDDF5 /* PBXTargetDependency */, DC65E7421D8CB3D400152EF0 /* PBXTargetDependency */, ); name = KeychainCircleTests; @@ -24143,7 +25299,6 @@ EBFBC2B41E76586700A34469 /* PBXTargetDependency */, EBFBC2B61E76587800A34469 /* PBXTargetDependency */, EB108F1F1E6CE4D2003B0456 /* PBXTargetDependency */, - EBFBC2B81E76588200A34469 /* PBXTargetDependency */, EBFBC2BA1E76588A00A34469 /* PBXTargetDependency */, ); name = KCPairingTests; @@ -24217,6 +25372,23 @@ productReference = EB433A281CC3243600A7EACE /* secitemstresstest */; productType = "com.apple.product-type.tool"; }; + EB49B2AD202D877F003F34A0 /* secdmockaks */ = { + isa = PBXNativeTarget; + buildConfigurationList = EB49B2BA202D8780003F34A0 /* Build configuration list for PBXNativeTarget "secdmockaks" */; + buildPhases = ( + EB49B2AA202D877F003F34A0 /* Sources */, + EB49B2AB202D877F003F34A0 /* Frameworks */, + EB49B30E202FF484003F34A0 /* Embedded OCMock */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = secdmockaks; + productName = secdmockaks; + productReference = EB49B2AE202D877F003F34A0 /* secdmockaks.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; EB9C1D791BDFD0E000F89272 /* secbackupntest */ = { isa = PBXNativeTarget; buildConfigurationList = EB9C1DA91BDFD0E100F89272 /* Build configuration list for PBXNativeTarget "secbackupntest" */; @@ -24293,6 +25465,7 @@ buildRules = ( ); dependencies = ( + DCE5DC171EA804E5006308A6 /* PBXTargetDependency */, 0C10C93C1DD548BD000602A8 /* PBXTargetDependency */, 0C10C93A1DD548B6000602A8 /* PBXTargetDependency */, ); @@ -24350,6 +25523,10 @@ CreatedOnToolsVersion = 9.0; ProvisioningStyle = Automatic; }; + 4727FBB61F9918580003AE36 = { + CreatedOnToolsVersion = 9.1; + ProvisioningStyle = Automatic; + }; 47702B1D1E5F409700B29577 = { CreatedOnToolsVersion = 9.0; ProvisioningStyle = Automatic; @@ -24358,6 +25535,9 @@ CreatedOnToolsVersion = 9.0; ProvisioningStyle = Automatic; }; + 478D426C1FD72A8100CAB645 = { + ProvisioningStyle = Automatic; + }; 47C51B831EEA657D0032D9E5 = { CreatedOnToolsVersion = 9.0; }; @@ -24370,6 +25550,14 @@ 6C9808681E788AFD00E70590 = { TestTargetID = 6CF4A0DF1E4549F200ECD7B5; }; + 6C9AA79D1F7C1D8F00D08296 = { + CreatedOnToolsVersion = 9.0; + ProvisioningStyle = Automatic; + }; + 6CAA8D1F1F842FB3007B6E03 = { + CreatedOnToolsVersion = 9.0; + ProvisioningStyle = Automatic; + }; 6CCDF7831E3C25FA003F2555 = { CreatedOnToolsVersion = 8.3; ProvisioningStyle = Automatic; @@ -24423,10 +25611,6 @@ CreatedOnToolsVersion = 8.0; ProvisioningStyle = Automatic; }; - DC1785041D77873100B50D50 = { - CreatedOnToolsVersion = 8.0; - ProvisioningStyle = Automatic; - }; DC1789031D77980500B50D50 = { CreatedOnToolsVersion = 8.0; ProvisioningStyle = Automatic; @@ -24545,6 +25729,10 @@ CreatedOnToolsVersion = 8.3; ProvisioningStyle = Automatic; }; + EB49B2AD202D877F003F34A0 = { + CreatedOnToolsVersion = 9.3; + ProvisioningStyle = Automatic; + }; EB6A6FA81B90F83A0045DC68 = { CreatedOnToolsVersion = 7.0; }; @@ -24629,7 +25817,6 @@ DC8E04991D7F6D9C006D80EB /* ====== Frameworks ======== */, 4C32C0AE0A4975F6002891BD /* Security_ios */, DC1789031D77980500B50D50 /* Security_osx */, - DC1785041D77873100B50D50 /* copyHeadersToSystem */, E7D847C41C6BE9710025BB44 /* KeychainCircle */, BEF88C271EAFFC3F00357577 /* TrustedPeers */, DC8E04911D7F6CED006D80EB /* ======= Daemons ========= */, @@ -24637,6 +25824,7 @@ DCE4E7F51D7A4DA800AFB96E /* secd */, 790851B50CA9859F0083CC4D /* securityd_ios */, DC5AC04F1D8352D900CF422C /* securityd_macos */, + 6CAA8D1F1F842FB3007B6E03 /* securityuploadd */, D41257CE1E9410A300781F23 /* trustd_ios */, DCE4E82D1D7A57AE00AFB96E /* trustd_macos */, 52D82BDD16A621F70078DFE5 /* CloudKeychainProxy */, @@ -24672,7 +25860,6 @@ 225394AC1E3080A600D3CD9B /* security_codesigning_ios */, DC8834011D8A218F00CE0ACA /* ASN1_not_installed */, DC71D99F1D95BA6C0065FB93 /* ASN1 */, - DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */, DCF782BA1D88B44300E694BB /* ==== macOS Libraries ====== */, DCF7830A1D88B4DE00E694BB /* security_apple_csp */, DCF785021D88B95500E694BB /* security_apple_cspdl */, @@ -24713,8 +25900,10 @@ 4C52D0B316EFC61E0079966E /* CircleJoinRequested */, F93C49021AB8FCE00047E01A /* ckcdiagnose.sh */, EBF374711DC055580065D840 /* security-sysdiagnose */, + 6C9AA79D1F7C1D8F00D08296 /* supdctl */, EB27FF101E402CD300EC9E3A /* ckksctl */, F621D0271ED6DCE7000EA569 /* authorizationdump */, + 0C8BBEFD1FCB446400580909 /* otctl */, DC8E04A11D7F6DFC006D80EB /* ======= Apps ========== */, DCE4E9101D7F3D5300AFB96E /* Keychain Circle Notification */, DCE4E8DC1D7F39DB00AFB96E /* Cloud Keychain Utility */, @@ -24727,6 +25916,7 @@ E710C7411331946400F85568 /* SecurityTests */, DCE4E7311D7A43B500AFB96E /* SecurityTestsOSX */, DC3502B41E0208BE00BC0587 /* CKKSTests */, + 0C85DFD11FB38BB6000343A7 /* OTTests */, DC610AAD1D7910C3002223DE /* gk_reset_check_macos */, DC610A551D78F9D2002223DE /* codesign_tests_macos */, DC610A461D78F48F002223DE /* SecTaskTest_macos */, @@ -24758,6 +25948,7 @@ 6CF4A0B31E45488B00ECD7B5 /* KeychainEntitledTestApp_mac */, 6CF4A0DF1E4549F200ECD7B5 /* KeychainEntitledTestApp_ios */, 6CCDF7831E3C25FA003F2555 /* KeychainEntitledTestRunner */, + 6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */, DC5AC1351D835D9700CF422C /* ===== Source Gen ===== */, DC008B451D90CE53004002A3 /* securityd_macos_mig */, DC6BC26C1D90CFEF00DD57B3 /* securityd_macos_startup */, @@ -24770,7 +25961,6 @@ DCD0675B1D8CDD6D007602F1 /* codesigning_SystemPolicy */, DC8E04AD1D7F6E76006D80EB /* ======= misc ========= */, E7B01BBD166594AB000485F1 /* SyncDevTest2 */, - 728B56A016D59979008FA3AB /* OTAPKIAssetTool */, 5E10992419A5E55800A60E2B /* ISACLProtectedItems */, 5346480017331E1100FE9172 /* KeychainSyncAccountNotification */, DA30D6751DF8C8FB00EC6B43 /* KeychainSyncAccountUpdater */, @@ -24796,6 +25986,9 @@ 05EF68B519491512007958C3 /* Security_frameworks */, F667EC561E96E9B100203D5C /* authdtest */, 47C51B831EEA657D0032D9E5 /* SecurityUnitTests */, + 4727FBB61F9918580003AE36 /* secdxctests_ios */, + 478D426C1FD72A8100CAB645 /* secdxctests_mac */, + EB49B2AD202D877F003F34A0 /* secdmockaks */, ); }; /* End PBXProject section */ @@ -24888,6 +26081,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4727FBB51F9918580003AE36 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 478D42981FD72A8100CAB645 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 47C51B821EEA657D0032D9E5 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -24899,13 +26106,20 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + D4C263CF1F953019001317EA /* SecDebugErrorMessages.strings in Resources */, + D4C263CE1F95300F001317EA /* SecErrorMessages.strings in Resources */, + BEB9EA2F1FFF1AF700676593 /* si-88-sectrust-valid-data in Resources */, + 47922D4F1FAA7D5C0008F7E0 /* SecDbKeychainSerializedItemV7.proto in Resources */, 53C0E1FF177FB48A00F8A018 /* CloudKeychain.strings in Resources */, BE4AC9BA18B8273600B84964 /* SharedWebCredentials.strings in Resources */, DCEE1E861D93427400DC0EB7 /* com.apple.securityd.plist in Resources */, + 47922D211FAA76000008F7E0 /* SecDbKeychainSerializedMetadata.proto in Resources */, EB433A2E1CC325E900A7EACE /* secitemstresstest.entitlements in Resources */, - 475F37201EE8F23900248FB5 /* SFAnalyticsLogging.plist in Resources */, + 47922D2D1FAA77970008F7E0 /* SecDbKeychainSerializedSecretData.proto in Resources */, + 475F37201EE8F23900248FB5 /* SFAnalytics.plist in Resources */, 4C198F220ACDB4BF00AAB142 /* Certificate.strings in Resources */, 4C198F230ACDB4BF00AAB142 /* OID.strings in Resources */, + D479F6E21F980FAB00388D28 /* Trust.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -24919,6 +26133,8 @@ D4AA64861E97273D00D317ED /* si-18-certificate-parse in Resources */, D4EC94FB1CEA482D0083E753 /* si-20-sectrust-policies-data in Resources */, 0C0C88781CCEC5C400617D1B /* si-82-sectrust-ct-data in Resources */, + D4C6C5CA1FB2AD7A007EA57E /* si-87-sectrust-name-constraints in Resources */, + BEA74217202525DC00EC7993 /* si-88-sectrust-valid-data in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -25015,13 +26231,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - DC1785031D77873100B50D50 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; DC1789021D77980500B50D50 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -25046,7 +26255,7 @@ DC178A2F1D77A1E700B50D50 /* sd_cspdl_common.mdsinfo in Resources */, DC178A291D77A1E700B50D50 /* dl_primary.mdsinfo in Resources */, DC178A261D77A1E700B50D50 /* cspdl_csp_primary.mdsinfo in Resources */, - 475F37211EE8F23900248FB5 /* SFAnalyticsLogging.plist in Resources */, + 475F37211EE8F23900248FB5 /* SFAnalytics.plist in Resources */, DC178A221D77A1E700B50D50 /* csp_common.mdsinfo in Resources */, DC178A431D77A1F600B50D50 /* SecDebugErrorMessages.strings in Resources */, DC178A481D77A1F600B50D50 /* TimeStampingPrefs.plist in Resources */, @@ -25080,6 +26289,8 @@ DCE4E76F1D7A43B500AFB96E /* si-20-sectrust-policies-data in Resources */, DCE4E7701D7A43B500AFB96E /* si-82-sectrust-ct-data in Resources */, DCE4E7B41D7A43DC00AFB96E /* si-82-sectrust-ct-logs.plist in Resources */, + D4C6C5C81FB2AD5E007EA57E /* si-87-sectrust-name-constraints in Resources */, + BEB9EA301FFF1B0800676593 /* si-88-sectrust-valid-data in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -25131,6 +26342,8 @@ D4AA64871E97274900D317ED /* si-18-certificate-parse in Resources */, D4EC94FE1CEA48760083E753 /* si-20-sectrust-policies-data in Resources */, 0C0C88791CCEC5C500617D1B /* si-82-sectrust-ct-data in Resources */, + D4C6C5C91FB2AD6D007EA57E /* si-87-sectrust-name-constraints in Resources */, + BEA74211202525CD00EC7993 /* si-88-sectrust-valid-data in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -25165,7 +26378,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 22C002A21AC9D2D100B3469E /* ShellScript */ = { + 0C85DFFF1FB38BB6000343A7 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 8; files = ( @@ -25176,8 +26389,7 @@ ); runOnlyForDeploymentPostprocessing = 1; shellPath = /bin/sh; - shellScript = "if [ -n \"${OTAPKIASSETTOOL_LAUNCHD_PLIST}\" ]; then\n mkdir -p \"$LAUNCHD_PLIST_INSTALL_DIR\"\n plutil -convert binary1 -o \"$LAUNCHD_PLIST_INSTALL_DIR/com.apple.OTAPKIAssetTool.plist\" \"$OTAPKIASSETTOOL_LAUNCHD_PLIST\"\nfi"; - showEnvVarsInLog = 0; + shellScript = "#Disable until this places a plist in this directory\n#chown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; }; 5EE098DE1CD21661009FCA27 /* Unifdef RC_HIDE_J79/J80 */ = { isa = PBXShellScriptBuildPhase; @@ -25194,6 +26406,20 @@ shellScript = "if [ -d $DSTROOT ]; then\n RC_HIDE_J79_VAL=0\n RC_HIDE_J80_VAL=0\n SEC_HDRS_PATH=\"System/Library/Frameworks/Security.framework/Headers\"\n\n if [ ! -z $RC_HIDE_J79 ]; then\n RC_HIDE_J79_VAL=1\n fi\n\n if [ ! -z $RC_HIDE_J80 ]; then\n RC_HIDE_J80_VAL=1\n fi\n\n if [ -a $DSTROOT/$SEC_HDRS_PATH/SecAccessControl.h ]; then\n unifdef -B -DRC_HIDE_J79=$RC_HIDE_J79_VAL -DRC_HIDE_J80=$RC_HIDE_J80_VAL -o $DSTROOT/$SEC_HDRS_PATH/SecAccessControl.h $DSTROOT/$SEC_HDRS_PATH/SecAccessControl.h\n if [$? eq 2]; then\n exit 2\n fi\n fi\n\n if [ -a $DSTROOT/$SEC_HDRS_PATH/SecItem.h ]; then\n unifdef -B -DRC_HIDE_J79=$RC_HIDE_J79_VAL -DRC_HIDE_J80=$RC_HIDE_J80_VAL -o $DSTROOT/$SEC_HDRS_PATH/SecItem.h $DSTROOT/$SEC_HDRS_PATH/SecItem.h\n if [$? eq 2]; then\n exit 2\n fi\n fi\n\n exit 0\nfi"; showEnvVarsInLog = 0; }; + 6CAA8D361F84317F007B6E03 /* Install launchd plist */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputPaths = ( + ); + name = "Install launchd plist"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "mkdir -p \"$LAUNCHD_PLIST_LOCATION\"\nplutil -convert binary1 -o \"$LAUNCHD_PLIST_LOCATION/com.apple.securityuploadd.plist\" \"$LAUNCHD_PLIST\""; + }; 6CB5F4761E402D0000DBF3F0 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 8; @@ -25241,6 +26467,25 @@ shellPath = /bin/sh; shellScript = "PLIST_FILE_NAME=com.apple.security.cloudkeychainproxy3\nFILE_TO_COPY=${PROJECT_DIR}/KVSKeychainSyncingProxy/${PLIST_FILE_NAME}.ios.plist\n\nif [ ${PLATFORM_NAME} = \"macosx\" ]\nthen\nFILE_TO_COPY=${PROJECT_DIR}/KVSKeychainSyncingProxy/${PLIST_FILE_NAME}.osx.plist\nfi\n\ncp ${FILE_TO_COPY} ${INSTALL_ROOT}/${INSTALL_DAEMON_AGENT_DIR}/${PLIST_FILE_NAME}.plist"; }; + D4C263C41F8FEAA8001317EA /* Run Script Generate Error Strings */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecBase.h", + "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecureTransport.h", + "${BUILT_PRODUCTS_DIR}/Security.framework/PrivateHeaders/CSCommon.h", + ); + name = "Run Script Generate Error Strings"; + outputPaths = ( + "${BUILT_PRODUCTS_DIR}/derived_src/SecDebugErrorMessages.strings", + "${BUILT_PRODUCTS_DIR}/derived_src/English.lproj/SecErrorMessages.strings", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "set -x\n\nDERIVED_SRC=${BUILT_PRODUCTS_DIR}/derived_src\nmkdir -p ${DERIVED_SRC}\n\n# make error message string files\n\nGENDEBUGSTRS[0]=YES; ERRORSTRINGS[0]=${DERIVED_SRC}/SecDebugErrorMessages.strings\nGENDEBUGSTRS[1]=NO ; ERRORSTRINGS[1]=${DERIVED_SRC}/English.lproj/SecErrorMessages.strings\n\nmkdir -p ${DERIVED_SRC}/English.lproj\n\nfor ((ix=0;ix<2;ix++)) ; do\nperl OSX/lib/generateErrStrings.pl \\\n${GENDEBUGSTRS[ix]} \\\n${DERIVED_SRC} \\\n${ERRORSTRINGS[ix]} \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecureTransport.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecBase.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/PrivateHeaders/CSCommon.h\ndone\n"; + }; DC008B581D90CE70004002A3 /* securityd mig */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -25275,21 +26520,6 @@ shellPath = /bin/sh; shellScript = "name=checkpw\n\nmkdir -p \"${DSTROOT}/private/etc/pam.d/\"\ncp \"${PROJECT_DIR}/OSX/libsecurity_checkpw/checkpw.pam\" \"${DSTROOT}/private/etc/pam.d/${name}\""; }; - DC1788D81D7793C000B50D50 /* Unifdef RC_HIDE_J79/J80 */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Unifdef RC_HIDE_J79/J80"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "if [ -d $DSTROOT ]; then\nRC_HIDE_J79_VAL=0\nRC_HIDE_J80_VAL=0\nSEC_HDRS_PATH=\"System/Library/Frameworks/Security.framework/Headers\"\n\nif [ ! -z $RC_HIDE_J79 ]; then\nRC_HIDE_J79_VAL=1\nfi\n\nif [ ! -z $RC_HIDE_J80 ]; then\nRC_HIDE_J80_VAL=1\nfi\n\nif [ -a $DSTROOT/$SEC_HDRS_PATH/SecAccessControl.h ]; then\nunifdef -B -DRC_HIDE_J79=$RC_HIDE_J79_VAL -DRC_HIDE_J80=$RC_HIDE_J80_VAL -o $DSTROOT/$SEC_HDRS_PATH/SecAccessControl.h $DSTROOT/$SEC_HDRS_PATH/SecAccessControl.h\nif [$? eq 2]; then\nexit 2\nfi\nfi\n\nif [ -a $DSTROOT/$SEC_HDRS_PATH/SecItem.h ]; then\nunifdef -B -DRC_HIDE_J79=$RC_HIDE_J79_VAL -DRC_HIDE_J80=$RC_HIDE_J80_VAL -o $DSTROOT/$SEC_HDRS_PATH/SecItem.h $DSTROOT/$SEC_HDRS_PATH/SecItem.h\nif [$? eq 2]; then\nexit 2\nfi\nfi\n\nexit 0\nfi"; - showEnvVarsInLog = 0; - }; DC1789A71D779E7E00B50D50 /* Run Script Generate Strings */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -25300,12 +26530,10 @@ "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/AuthSession.h", "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecureTransport.h", "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecBase.h", - "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmerr.h", "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmapple.h", "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/CSCommon.h", - "${BUILT_PRODUCTS_DIR}/Security.framework/PrivateHeaders/AuthorizationPriv.h", "${PROJECT_DIR}/libsecurity_keychain/lib/MacOSErrorStrings.h", - "${BUILT_PRODUCTS_DIR}/Security.framework/PrivateHeaders/SecureTransportPriv.h", + "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmerr.h", ); name = "Run Script Generate Strings"; outputPaths = ( @@ -25314,7 +26542,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "set -x\n\nDERIVED_SRC=${BUILT_PRODUCTS_DIR}/derived_src\nmkdir -p ${DERIVED_SRC}\n\n# make error message string files\n\nGENDEBUGSTRS[0]=YES; ERRORSTRINGS[0]=${DERIVED_SRC}/SecDebugErrorMessages.strings\nGENDEBUGSTRS[1]=NO ; ERRORSTRINGS[1]=${DERIVED_SRC}/en.lproj/SecErrorMessages.strings\n\nmkdir -p ${DERIVED_SRC}/en.lproj\n\nfor ((ix=0;ix<2;ix++)) ; do\nperl OSX/lib/generateErrStrings.pl \\\n${GENDEBUGSTRS[ix]} \\\n${DERIVED_SRC} \\\n${ERRORSTRINGS[ix]} \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/Authorization.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/AuthSession.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecureTransport.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecBase.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmerr.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmapple.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/CSCommon.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/PrivateHeaders/AuthorizationPriv.h \\\n${PROJECT_DIR}/OSX/libsecurity_keychain/lib/MacOSErrorStrings.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/PrivateHeaders/SecureTransportPriv.h\ndone\n"; + shellScript = "set -x\n\nDERIVED_SRC=${BUILT_PRODUCTS_DIR}/derived_src\nmkdir -p ${DERIVED_SRC}\n\n# make error message string files\n\nGENDEBUGSTRS[0]=YES; ERRORSTRINGS[0]=${DERIVED_SRC}/SecDebugErrorMessages.strings\nGENDEBUGSTRS[1]=NO ; ERRORSTRINGS[1]=${DERIVED_SRC}/en.lproj/SecErrorMessages.strings\n\nmkdir -p ${DERIVED_SRC}/en.lproj\n\nfor ((ix=0;ix<2;ix++)) ; do\nperl OSX/lib/generateErrStrings.pl \\\n${GENDEBUGSTRS[ix]} \\\n${DERIVED_SRC} \\\n${ERRORSTRINGS[ix]} \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/Authorization.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/AuthSession.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecureTransport.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecBase.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmerr.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmapple.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/CSCommon.h \\\n${PROJECT_DIR}/OSX/libsecurity_keychain/lib/MacOSErrorStrings.h\ndone\n"; }; DC178B481D77A51600B50D50 /* Make XPC server symlink */ = { isa = PBXShellScriptBuildPhase; @@ -25458,22 +26686,6 @@ shellScript = "# The build system requires that we don't install these headers and .as in multiple phases.\n# This target will not install anything, so feel free to depend on it whenever you use it.\n\n# If you make changes to this target, please make them to ASN1 as well."; showEnvVarsInLog = 0; }; - DC71DA011D95BD670065FB93 /* Why is this here? */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; - files = ( - ); - inputPaths = ( - "$(SRCROOT)/OSX/libsecurity_keychain/libDER/libDER/libDER.h", - ); - name = "Why is this here?"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "# The build system requires that we don't install these headers and .as in multiple phases.\n# This target will not install anything, so feel free to depend on it whenever you use it.\n\n# If you make changes to this target, please make them to DER as well."; - showEnvVarsInLog = 0; - }; DC82FFE61D90D3F60085674B /* security_utilities DTrace */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -25679,6 +26891,57 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 0C85DFE21FB38BB6000343A7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0CB9754F2023A8F5008D6B48 /* CloudKitMockXCTest.m in Sources */, + 0CB9754E2023A8DD008D6B48 /* CloudKitKeychainSyncingMockXCTest.m in Sources */, + 0C0DA5D01FE1F1F3003BD3BB /* CKKSControlProtocol.m in Sources */, + 0CBDF64D1FFC951200433E0D /* OTBottledPeerTLK.m in Sources */, + 0C16371C1FD116B300210823 /* MockCloudKit.m in Sources */, + 0C8A034F1FDF60070042E8BE /* OTBottledPeerTests.m in Sources */, + 0C52C1FF20003BCA003F0733 /* OTTestsBase.m in Sources */, + 0C1637211FD12F1500210823 /* OTCloudStoreTests.m in Sources */, + 0CAEC9D81FD740CF00D1F2CA /* OTContextTests.m in Sources */, + 0C0DA5CF1FE1F1C5003BD3BB /* OTControlProtocol.m in Sources */, + 0C8A03461FDF42BA0042E8BE /* OTEscrowKeyTests.m in Sources */, + 0C8A034D1FDF4CCE0042E8BE /* OTLocalStoreTests.m in Sources */, + DCDB296C1FD8820400B5D242 /* SFAnalytics.m in Sources */, + 6C73F48D2006B83E003D5D63 /* SOSAnalytics.m in Sources */, + 0C46A57B2035019800F17112 /* OTLockStateNetworkingTests.m in Sources */, + DCDB296E1FD8821400B5D242 /* SFAnalyticsActivityTracker.m in Sources */, + DCDB29701FD8821800B5D242 /* SFAnalyticsMultiSampler.m in Sources */, + DCDB29741FD8822200B5D242 /* SFAnalyticsSQLiteStore.m in Sources */, + 0C46A5712034C6BA00F17112 /* OTControl.m in Sources */, + DCDB29721FD8821D00B5D242 /* SFAnalyticsSampler.m in Sources */, + DCDB297E1FD8849D00B5D242 /* SFObjCType.m in Sources */, + 0CC0445B1FFC4150004A5B63 /* CKKSControl.m in Sources */, + DCDB297C1FD8848A00B5D242 /* SFSQLite.m in Sources */, + 0CA4EBF4202B8DBE002B1D96 /* CloudKitKeychainSyncingTestsBase.m in Sources */, + DCDB297D1FD8849A00B5D242 /* SFSQLiteStatement.m in Sources */, + DCDB297B1FD8847100B5D242 /* SecTask.c in Sources */, + 0C1637291FD2066A00210823 /* SecdWatchdog.m in Sources */, + DCDB29791FD8844C00B5D242 /* client.c in Sources */, + DCDB297A1FD8845600B5D242 /* client_endpoint.m in Sources */, + 0CB975512023B199008D6B48 /* OTRampingTests.m in Sources */, + 0C16372B1FD2067F00210823 /* server_endpoint.m in Sources */, + 0C16372D1FD2069300210823 /* server_entitlement_helpers.c in Sources */, + 0C1637301FD206BC00210823 /* server_security_helpers.c in Sources */, + 0C1637271FD2065400210823 /* spi.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 0C8BBEFE1FCB446400580909 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0C8BBF1B1FCB4EC500580909 /* OTControlProtocol.m in Sources */, + 0C8BBF091FCB447600580909 /* otctl.m in Sources */, + 0C8BBEFF1FCB446400580909 /* SecArgParse.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 225394AD1E3080A600D3CD9B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -25686,7 +26949,6 @@ 220179EB1E3BF1F100EFB6F3 /* detachedrep.cpp in Sources */, 220179EA1E3BF16000EFB6F3 /* slcrep.cpp in Sources */, 220179E31E3BEB7100EFB6F3 /* dirscanner.cpp in Sources */, - 225394B71E3081F900D3CD9B /* cskernel.cpp in Sources */, 225394B81E30820900D3CD9B /* Code.cpp in Sources */, 225394B91E30821400D3CD9B /* bundlediskrep.cpp in Sources */, 225394BA1E30821E00D3CD9B /* cdbuilder.cpp in Sources */, @@ -25700,9 +26962,9 @@ 225394C11E30827600D3CD9B /* filediskrep.cpp in Sources */, 225394C21E30827E00D3CD9B /* kerneldiskrep.cpp in Sources */, 225394C31E30828800D3CD9B /* StaticCode.cpp in Sources */, - 225394C41E30829300D3CD9B /* reqparser.cpp in Sources */, 225394C51E3082A100D3CD9B /* requirement.cpp in Sources */, 225394C61E3082AB00D3CD9B /* Requirements.cpp in Sources */, + DCD7EE851F4E47D2007D9804 /* reqparser.cpp in Sources */, 225394C71E3082B600D3CD9B /* reqdumper.cpp in Sources */, 225394C81E3082BE00D3CD9B /* reqinterp.cpp in Sources */, 225394C91E3082C900D3CD9B /* reqmaker.cpp in Sources */, @@ -25734,6 +26996,22 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4727FBB31F9918580003AE36 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 47DE88DA1FA7B07400DD3254 /* server_xpc.m in Sources */, + 4727FBEF1F9924FB0003AE36 /* server_security_helpers.c in Sources */, + 4727FBEE1F9924DA0003AE36 /* server_entitlement_helpers.c in Sources */, + 477A1FED2037A0E000ACD81D /* KeychainXCTest.m in Sources */, + 4727FBEB1F99227F0003AE36 /* spi.c in Sources */, + 4727FBEC1F99235B0003AE36 /* SecdWatchdog.m in Sources */, + 4727FBBA1F9918590003AE36 /* KeychainCryptoTests.m in Sources */, + 477A1FE4203763A500ACD81D /* KeychainAPITests.m in Sources */, + 4727FBED1F99249A0003AE36 /* server_endpoint.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 47702B1A1E5F409700B29577 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -25750,6 +27028,22 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 478D42751FD72A8100CAB645 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 478D42761FD72A8100CAB645 /* server_xpc.m in Sources */, + 478D42771FD72A8100CAB645 /* server_security_helpers.c in Sources */, + 478D42781FD72A8100CAB645 /* server_entitlement_helpers.c in Sources */, + 477A1FEE2037A0E000ACD81D /* KeychainXCTest.m in Sources */, + 478D42791FD72A8100CAB645 /* spi.c in Sources */, + 478D427A1FD72A8100CAB645 /* SecdWatchdog.m in Sources */, + 478D427B1FD72A8100CAB645 /* KeychainCryptoTests.m in Sources */, + 477A1FE5203763A500ACD81D /* KeychainAPITests.m in Sources */, + 478D427C1FD72A8100CAB645 /* server_endpoint.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 47C51B801EEA657D0032D9E5 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -25762,21 +27056,32 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 6CAA8CFF1F83E800007B6E03 /* SFSQLite.m in Sources */, + 6CDB5FF61FA78D1B00410924 /* SFAnalyticsMultiSampler.m in Sources */, + D46246A61F9AE61000D63882 /* oids.c in Sources */, + 0CBFEACB200FCD2D009A60E9 /* SFTransactionMetric.m in Sources */, + 0CBD55B31FE883F200A8CE21 /* SFBehavior.m in Sources */, 220179E91E3BF03200EFB6F3 /* dummy.cpp in Sources */, + DC926F091F33FA8D0012A315 /* CKKSControlProtocol.m in Sources */, 4723C9CC1F152ED30082882F /* SFSQLiteStatement.m in Sources */, - DC9C95C11F79DD4B000D19E5 /* CKKSControlProtocol.m in Sources */, DCA85B931E8D97E400BA7241 /* client.c in Sources */, + 6CBF653A1FA147E500A68667 /* SFAnalyticsActivityTracker.m in Sources */, DC9C95BF1F79DC88000D19E5 /* CKKSControl.m in Sources */, + 0C8BBF131FCB4AFA00580909 /* OTControlProtocol.m in Sources */, + EB10A3E620356E2000E84270 /* OTConstants.m in Sources */, 18F7F67914D77F4400F88A12 /* NtlmGenerator.c in Sources */, 0CD8CB051ECA50780076F37F /* SOSPeerOTRTimer.m in Sources */, DCA85B981E8D980A00BA7241 /* client_endpoint.m in Sources */, + 6CE3654E1FA100E50012F6AB /* SFAnalytics.m in Sources */, 18F7F67A14D77F4400F88A12 /* ntlmBlobPriv.c in Sources */, - 4723C9E01F1540CE0082882F /* SFAnalyticsLogger.m in Sources */, - 4723C9C81F152ECA0082882F /* SFSQLite.m in Sources */, + 6CAA8CFC1F83E7EA007B6E03 /* SFObjCType.m in Sources */, E7B00700170B581D00B27966 /* Security.exp-in in Sources */, - 4723C9C41F152EBB0082882F /* SFObjCType.m in Sources */, + 0C8BBF121FCB4AAB00580909 /* OTControl.m in Sources */, EB48C1A51E573EE400EC5E57 /* whoami.m in Sources */, B61F67571F1FCFCB00E2FDBB /* SecPaddingConfigurations.c in Sources */, + 6CE365531FA101080012F6AB /* SFAnalyticsSampler.m in Sources */, + 6C73F48A2006B839003D5D63 /* SOSAnalytics.m in Sources */, + 6CE365571FA1017D0012F6AB /* SFAnalyticsSQLiteStore.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -25885,24 +27190,47 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 6C46057A1F882B9B001421B6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6CB96BB21F966DA400E11457 /* SFSQLite.m in Sources */, + 6CB96BB31F966DA400E11457 /* SFSQLiteStatement.m in Sources */, + 6CBF65421FA2255800A68667 /* SFAnalyticsActivityTracker.m in Sources */, + 6CDF8DF21F9649AB00140B54 /* SFAnalyticsSampler.m in Sources */, + 6CDF8DF41F9649C000140B54 /* SFAnalytics.m in Sources */, + 6C4605BC1F882DB6001421B6 /* SFAnalyticsTests.m in Sources */, + 6C13AE471F8E9F5F00F047E3 /* supd.m in Sources */, + 6C4605BD1F882DC3001421B6 /* SupdTests.m in Sources */, + 6CDB5FFA1FA78D2500410924 /* SFAnalyticsMultiSampler.m in Sources */, + 6CB96BAC1F966D6500E11457 /* main.m in Sources */, + 6CB96BB61F966E4300E11457 /* SFObjCType.m in Sources */, + 6CDF8DF31F9649C000140B54 /* SFAnalyticsSQLiteStore.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 6C98083D1E788AEB00E70590 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 6CBF65431FA2257100A68667 /* SFAnalyticsActivityTracker.m in Sources */, + 6CAA8CF71F83E79E007B6E03 /* SFSQLite.m in Sources */, 476541A41F33EDED00413F65 /* SecdWatchdog.m in Sources */, - 47B011A71F17D8980030B49F /* SFAnalyticsLogger.m in Sources */, - 47B011981F17D78D0030B49F /* SFSQLite.m in Sources */, 47B011991F17D78D0030B49F /* SFSQLiteStatement.m in Sources */, - 47B011971F17D7810030B49F /* SFObjCType.m in Sources */, DC2D438F1F0EEC2A0005D382 /* MockCloudKit.m in Sources */, + 6CDF8DEF1F96495600140B54 /* SFAnalyticsSampler.m in Sources */, DCB515E21ED3D134001F1152 /* SecTask.c in Sources */, DCB515E11ED3D11A001F1152 /* client.c in Sources */, 6C9808A61E788CD200E70590 /* CKKSCloudKitTests.m in Sources */, 6C98083E1E788AEB00E70590 /* spi.c in Sources */, DC2353301ECA658900D7C1BE /* server_security_helpers.c in Sources */, + 6CAA8CF01F83E65E007B6E03 /* SFObjCType.m in Sources */, + 6CAA8D131F83ECD4007B6E03 /* SFAnalytics.m in Sources */, DC2353321ECA659000D7C1BE /* server_xpc.m in Sources */, + 6CDB5FF91FA78D2400410924 /* SFAnalyticsMultiSampler.m in Sources */, DC5F35B11EE0F28B00900966 /* server_entitlement_helpers.c in Sources */, DC2353291ECA658300D7C1BE /* server_endpoint.m in Sources */, + 6CAA8CF91F83E7AA007B6E03 /* SFAnalyticsSQLiteStore.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -25910,21 +27238,43 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 6CAA8CF61F83E79D007B6E03 /* SFSQLite.m in Sources */, + 6CDB5FF81FA78D2300410924 /* SFAnalyticsMultiSampler.m in Sources */, 476541A51F33EE1E00413F65 /* SecdWatchdog.m in Sources */, - 47B011AD1F17D8A00030B49F /* SFAnalyticsLogger.m in Sources */, - 47B0119B1F17D7F10030B49F /* SFSQLite.m in Sources */, - 47B0119C1F17D7F10030B49F /* SFSQLiteStatement.m in Sources */, - 47B0119A1F17D7E80030B49F /* SFObjCType.m in Sources */, DC2D43951F0EEC300005D382 /* MockCloudKit.m in Sources */, + 6CAA8CF81F83E7A9007B6E03 /* SFAnalyticsSQLiteStore.m in Sources */, 6C9808A51E788CD100E70590 /* CKKSCloudKitTests.m in Sources */, + 6CBF65441FA2257200A68667 /* SFAnalyticsActivityTracker.m in Sources */, DCB515E31ED3D135001F1152 /* SecTask.c in Sources */, + 6CAA8CEF1F83E65D007B6E03 /* SFObjCType.m in Sources */, DCB515E01ED3D111001F1152 /* client.c in Sources */, DCB515E41ED3D15A001F1152 /* client_endpoint.m in Sources */, + 6CAA8D141F83ECD5007B6E03 /* SFAnalytics.m in Sources */, 6C98087A1E788AFD00E70590 /* spi.c in Sources */, + 6CAA8D0D1F83EC57007B6E03 /* SFSQLiteStatement.m in Sources */, DC5F35B21EE0F28C00900966 /* server_entitlement_helpers.c in Sources */, DC2353311ECA658B00D7C1BE /* server_security_helpers.c in Sources */, DC2353331ECA659000D7C1BE /* server_xpc.m in Sources */, DC23532F1ECA658400D7C1BE /* server_endpoint.m in Sources */, + 6CDF8DF01F96495700140B54 /* SFAnalyticsSampler.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6C9AA79A1F7C1D8F00D08296 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6C9AA7A51F7C6F7F00D08296 /* SecArgParse.c in Sources */, + 6C9AA7A11F7C1D9000D08296 /* main.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6CAA8D1C1F842FB3007B6E03 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6CAA8D351F84306C007B6E03 /* main.m in Sources */, + 6CAA8D271F843002007B6E03 /* supd.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -25956,15 +27306,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 728B569D16D59979008FA3AB /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 72CD2BBE16D59AE30064EEE1 /* OTAServiceApp.m in Sources */, - 72CD2BBF16D59AE30064EEE1 /* OTAServicemain.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 790851B30CA9859F0083CC4D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -26094,7 +27435,7 @@ files = ( D43DBEFB1E99D1CA00C04AEA /* asynchttp.c in Sources */, D43DBEFC1E99D1CA00C04AEA /* nameconstraints.c in Sources */, - D43DBEFD1E99D1CA00C04AEA /* OTATrustUtilities.c in Sources */, + D43DBEFD1E99D1CA00C04AEA /* OTATrustUtilities.m in Sources */, D43DBEFE1E99D1CA00C04AEA /* personalization.c in Sources */, D43DBEFF1E99D1CA00C04AEA /* policytree.c in Sources */, D43DBF001E99D1CA00C04AEA /* SecCAIssuerCache.c in Sources */, @@ -26109,7 +27450,7 @@ D43DBF081E99D1CA00C04AEA /* SecPolicyServer.c in Sources */, D43DBF091E99D1CA00C04AEA /* SecRevocationDb.c in Sources */, D43DBF0A1E99D1CA00C04AEA /* SecRevocationServer.c in Sources */, - D43DBF0B1E99D1CA00C04AEA /* SecTrustLoggingServer.c in Sources */, + D43DBF0B1E99D1CA00C04AEA /* SecTrustLoggingServer.m in Sources */, D43DBF0C1E99D1CA00C04AEA /* SecTrustServer.c in Sources */, D43DBF0D1E99D1CA00C04AEA /* SecTrustStoreServer.c in Sources */, D40B6A9B1E2B690E00CD6EE5 /* SecuritydXPC.c in Sources */, @@ -26529,18 +27870,29 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4723C9C91F152ECA0082882F /* SFSQLite.m in Sources */, + 0CBD55B91FE883F300A8CE21 /* SFBehavior.m in Sources */, + D46246A71F9AE62000D63882 /* oids.c in Sources */, DCA85B991E8D980B00BA7241 /* client_endpoint.m in Sources */, + DC926F0A1F33FA8E0012A315 /* CKKSControlProtocol.m in Sources */, + 6CE365541FA101090012F6AB /* SFAnalyticsSampler.m in Sources */, + 6CE365581FA1017E0012F6AB /* SFAnalyticsSQLiteStore.m in Sources */, + 6CDB5FF51FA78D1A00410924 /* SFAnalyticsMultiSampler.m in Sources */, DCA85B941E8D97E400BA7241 /* client.c in Sources */, DCDF0A4F1D81D76F007AF174 /* Security.exp-in in Sources */, + 0CBFEACA200FCD2D009A60E9 /* SFTransactionMetric.m in Sources */, DC1789A51D779E3B00B50D50 /* dummy.cpp in Sources */, - 4723C9C51F152EBC0082882F /* SFObjCType.m in Sources */, + 0C8BBF111FCB4AAA00580909 /* OTControl.m in Sources */, 4723C9CD1F152ED40082882F /* SFSQLiteStatement.m in Sources */, + EB10A3E920356E7A00E84270 /* OTConstants.m in Sources */, + 6CAA8CFE1F83E800007B6E03 /* SFSQLite.m in Sources */, DC9C95C01F79DC89000D19E5 /* CKKSControl.m in Sources */, - 4723C9E11F1540CE0082882F /* SFAnalyticsLogger.m in Sources */, + 0C8BBF141FCB4AFB00580909 /* OTControlProtocol.m in Sources */, B61577E81F20151C004A3930 /* SecPaddingConfigurations.c in Sources */, + 6C73F48B2006B83A003D5D63 /* SOSAnalytics.m in Sources */, + 6CE3654D1FA100E50012F6AB /* SFAnalytics.m in Sources */, + 6CAA8CFD1F83E7EB007B6E03 /* SFObjCType.m in Sources */, DC1789A21D779DF400B50D50 /* SecBreadcrumb.c in Sources */, - DC9C95C21F79DD4D000D19E5 /* CKKSControlProtocol.m in Sources */, + 6CBF65411FA1481100A68667 /* SFAnalyticsActivityTracker.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -26548,18 +27900,27 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + BEE4B18D1FFD588000777D39 /* OTAuthenticatedCiphertext.proto in Sources */, + BEB0B0D81FFC3DD3007E6A83 /* OTPrivateKey.proto in Sources */, + BE3405AE1FD725EC00933DAC /* OTBottle.proto in Sources */, + BE3405AF1FD725F000933DAC /* OTBottleContents.proto in Sources */, DC9FD3231F8587A500C8AAC8 /* CKKSSerializedKey.proto in Sources */, DC222C3A1E034D1F00B09171 /* CKKSItemEncrypter.m in Sources */, DC7A17F01E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.m in Sources */, DCEA5D581E2826DB0089CF55 /* CKKSSIV.m in Sources */, EBB407B41EBA46B300A541A5 /* CKKSPowerCollection.m in Sources */, DCB5D93E1E4A9A3400BE22AB /* CKKSSynchronizeOperation.m in Sources */, + 0CD9E8011FE05B6600F66C38 /* OTContextRecord.m in Sources */, + BEB0B0DE1FFC45D8007E6A83 /* OTPrivateKey+SF.m in Sources */, DC222C3B1E034D1F00B09171 /* SOSChangeTracker.c in Sources */, DC222C3D1E034D1F00B09171 /* SOSEngine.c in Sources */, 6C8CC3B31E2F913D009025C5 /* AWDKeychainCKKSRateLimiterAggregatedScores.m in Sources */, DC222C401E034D1F00B09171 /* SecDbItem.c in Sources */, DCCD88EB1E42622200F5AA71 /* CKKSGroupOperation.m in Sources */, - DC222C411E034D1F00B09171 /* SecDbKeychainItem.c in Sources */, + DC222C411E034D1F00B09171 /* SecDbKeychainItem.m in Sources */, + 0C8BBEAA1FC9DBC000580909 /* OTLocalStore.m in Sources */, + 4733377C1FDAFBCC00E19F30 /* SFKeychainControlManager.m in Sources */, + 0CE1BCCF1FCE11690017230E /* OTBottledPeerSigned.m in Sources */, DC222C421E034D1F00B09171 /* SecDbQuery.c in Sources */, 6C3446471E25346C00F9522B /* CKKSRateLimiter.m in Sources */, DCA4D2001E552DD50056214F /* CKKSCurrentKeyPointer.m in Sources */, @@ -26568,8 +27929,12 @@ DCE278E01ED789EF0083B485 /* CKKSCurrentItemPointer.m in Sources */, DC222C441E034D1F00B09171 /* SecItemDataSource.c in Sources */, DC3D748F1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.m in Sources */, + 0C8BBF161FCB4B1C00580909 /* OTManager.m in Sources */, + 0C8BBEA61FC9DBB200580909 /* OTEscrowKeys.m in Sources */, 526965D31E6E284500627F9D /* AsymKeybagBackup.m in Sources */, + DA6AA1661FE88AFB004565B0 /* CKKSControlServer.m in Sources */, DCFE1C541F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.m in Sources */, + 47922D491FAA7C3D0008F7E0 /* SecDbKeychainSerializedMetadata.m in Sources */, DCD6C4B51EC5302500414FEE /* CKKSNearFutureScheduler.m in Sources */, 6C588D811EAA20AC00D7E322 /* RateLimiter.m in Sources */, DC94BCCD1F10448600E07CEB /* CloudKitCategories.m in Sources */, @@ -26582,47 +27947,65 @@ DCEA5D881E2F14810089CF55 /* CKKSAPSReceiver.m in Sources */, DC2C5F611F0EB97E00FEBDA7 /* CKKSNotifier.m in Sources */, DC222C481E034D1F00B09171 /* SecItemServer.c in Sources */, - DC9C95B71F79CFD1000D19E5 /* CKKSControl.m in Sources */, DC18F7721E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.m in Sources */, DC222C491E034D1F00B09171 /* SecKeybagSupport.c in Sources */, + 471A03F21F72E35C000A8904 /* SecDbKeychainItemV7.m in Sources */, + 0C8BBF181FCB4E5000580909 /* OTControlProtocol.m in Sources */, + EB4E0CDC1FF36A9700CDCACC /* CKKSReachabilityTracker.m in Sources */, DC1DA6691E4555D80094CE7F /* CKKSScanLocalItemsOperation.m in Sources */, 6C8CC3B41E2F913D009025C5 /* AWDKeychainCKKSRateLimiterOverload.m in Sources */, + 0C8BBEA21FC9DBAA00580909 /* OTContext.m in Sources */, DC222C4A1E034D1F00B09171 /* SecLogSettingsServer.m in Sources */, DC14478D1F5764C600236DB4 /* CKKSResultOperation.m in Sources */, 479DA1781EBBA8D30065C98F /* CKKSManifest.m in Sources */, DCD662F81E329B6800188186 /* CKKSNewTLKOperation.m in Sources */, + DC124DCE20059BA900BE8DAC /* OctagonControlServer.m in Sources */, DC222C4D1E034D1F00B09171 /* CKKSOutgoingQueueEntry.m in Sources */, DCBF2F881F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.m in Sources */, + EB10A3E720356E6500E84270 /* OTConstants.m in Sources */, + 0C5CFB392019610000913B9C /* OTRamping.m in Sources */, DC222C4E1E034D1F00B09171 /* CKKS.m in Sources */, DC762AA11E57A86A00B03A2C /* CKKSRecordHolder.m in Sources */, DC222C501E034D1F00B09171 /* SecOTRRemote.m in Sources */, - 479108BA1EE879F9008CEFA0 /* CKKSAnalyticsLogger.m in Sources */, + 47922D451FAA7C2E0008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */, + 479108BA1EE879F9008CEFA0 /* CKKSAnalytics.m in Sources */, + 479108BA1EE879F9008CEFA0 /* CKKSAnalytics.m in Sources */, DC1447991F5766D200236DB4 /* NSOperationCategories.m in Sources */, DC222C511E034D1F00B09171 /* CKKSItem.m in Sources */, DCBDB3BE1E57CA7A00B61300 /* CKKSViewManager.m in Sources */, DCFE1C2A1F17E455007640C8 /* CKKSDeviceStateEntry.m in Sources */, + 0C8BBEA81FC9DBB600580909 /* OTIdentity.m in Sources */, DCAD9B471F8D939C00C5E2AE /* CKKSFixups.m in Sources */, DCA4D2181E5684220056214F /* CKKSReencryptOutgoingItemsOperation.m in Sources */, DCE278EB1ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.m in Sources */, DC222C541E034D1F00B09171 /* CKKSSQLDatabaseObject.m in Sources */, DCEA5D981E3015840089CF55 /* CKKSZone.m in Sources */, + 0CE407AD1FD4769B00F59B31 /* OTCloudStoreState.m in Sources */, DCB837381ED5045100015C07 /* CKKSLockStateTracker.m in Sources */, - DAD3BD021F9830BC00DF29BA /* CKKSControlProtocol.m in Sources */, + 47922D4D1FAA7C4B0008F7E0 /* SecDbKeychainSerializedSecretData.m in Sources */, DC4DB1531E24692100CD6769 /* CKKSKey.m in Sources */, DC9082C51EA0277700D0C1C5 /* CKKSZoneChangeFetcher.m in Sources */, + 0CCCC7CA20261D310024405E /* OT.m in Sources */, + 47922D571FAA7E0E0008F7E0 /* SecDbKeychainSerializedItemV7.m in Sources */, DC222C571E034D1F00B09171 /* SecuritydXPC.c in Sources */, DC7341F61F8447AB00AB9BDF /* CKKSTLKShare.m in Sources */, 6C8CC3B51E2F913D009025C5 /* AWDKeychainCKKSRateLimiterTopWriters.m in Sources */, DCBDB3B81E57C82300B61300 /* CKKSKeychainView.m in Sources */, DC222C5A1E034D1F00B09171 /* iCloudTrace.c in Sources */, DC5BB5011E0C98320010F836 /* CKKSOutgoingQueueOperation.m in Sources */, + 0C8BBEA01FC9DBA400580909 /* OTBottledPeer.m in Sources */, 6C869A7A1F54C37A00957298 /* AWDKeychainSOSKeychainBackupFailed.m in Sources */, 6C869A761F50CAF500957298 /* SOSEnsureBackup.m in Sources */, + BE2AD2BB1FDA080900739F96 /* OTBottledPeerRecord.m in Sources */, + 0C770EC51FCF7E2000B5F0E2 /* OTCloudStore.m in Sources */, 5269658E1E6A154800627F9D /* SecBackupKeybagEntry.m in Sources */, + 0C36B3222007F2570029F7A2 /* OTPreflightInfo.m in Sources */, DC222C5D1E034D1F00B09171 /* CKKSMirrorEntry.m in Sources */, + BEE4B1951FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.m in Sources */, DC54DD101EA7D9E800108E92 /* CKKSManifestLeafRecord.m in Sources */, DCFE1C371F17ECE5007640C8 /* CKKSCondition.m in Sources */, DC222C611E034D1F00B09171 /* swcagent_client.c in Sources */, + BEE4B19B1FFDAFE600777D39 /* SFECPublicKey+SPKI.m in Sources */, DC222C621E034D1F00B09171 /* CKKSZoneStateEntry.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -26632,10 +28015,7 @@ buildActionMask = 2147483647; files = ( 476541A61F33EE2700413F65 /* SecdWatchdog.m in Sources */, - 4771ECD91F17CE5100840998 /* SFAnalyticsLogger.m in Sources */, - 4771ECCE1F17CD2100840998 /* SFObjCType.m in Sources */, - 4771ECCC1F17CD0E00840998 /* SFSQLite.m in Sources */, - DCB502331FDA156B008F8E4F /* AutoreleaseTest.c in Sources */, + 6CAA8CF41F83E799007B6E03 /* SFSQLite.m in Sources */, 4771ECCD1F17CD0E00840998 /* SFSQLiteStatement.m in Sources */, DCD6C4B71EC5319600414FEE /* CKKSNearFutureSchedulerTests.m in Sources */, DC08D1C41E64FA8C006237DA /* CloudKitKeychainSyncingMockXCTest.m in Sources */, @@ -26643,20 +28023,28 @@ 6C588D7F1EAA14AA00D7E322 /* RateLimiterTests.m in Sources */, DC4DB15F1E2590B100CD6769 /* CKKSAESSIVEncryptionTests.m in Sources */, DC3502E71E0214C800BC0587 /* MockCloudKit.m in Sources */, + 6CAA8D151F83ECD9007B6E03 /* SFAnalytics.m in Sources */, DC6593D11ED8DAB900C19462 /* CKKSTests+CurrentPointerAPI.m in Sources */, + 6CBF65451FA2257500A68667 /* SFAnalyticsActivityTracker.m in Sources */, DCA85B9A1E8D981100BA7241 /* client_endpoint.m in Sources */, DCAD9B491F8D95F200C5E2AE /* CloudKitKeychainSyncingFixupTests.m in Sources */, + 0CA4EBF3202B8D9C002B1D96 /* CloudKitKeychainSyncingTestsBase.m in Sources */, DC9A2C5F1EB3F557008FAC27 /* CKKSTests+Coalesce.m in Sources */, DC222C8A1E089BAE00B09171 /* CKKSSQLTests.m in Sources */, DC15F79C1E68EAD5003B9A40 /* CKKSTests+API.m in Sources */, 4723C9D41F1531A30082882F /* CKKSLoggerTests.m in Sources */, + 6C73F48C2006B83D003D5D63 /* SOSAnalytics.m in Sources */, DCBF2F7D1F90084D00ED0CA4 /* CKKSTLKSharingTests.m in Sources */, + DCFABF8E20081E2F001128B5 /* CKKSDeviceStateUploadTests.m in Sources */, DC3502B81E0208BE00BC0587 /* CKKSTests.m in Sources */, 6C3446301E24F6BE00F9522B /* CKKSRateLimiterTests.m in Sources */, DCA85B961E8D980100BA7241 /* client.c in Sources */, + 6CAA8CFA1F83E7AC007B6E03 /* SFAnalyticsSQLiteStore.m in Sources */, DCE7F2091F21726500DDB0F7 /* CKKSAPSReceiverTests.m in Sources */, DC96053F1ECA2D6400AF9BDA /* SecTask.c in Sources */, DC08D1CC1E64FCC5006237DA /* CKKSSOSTests.m in Sources */, + 6CDB5FF71FA78D2100410924 /* SFAnalyticsMultiSampler.m in Sources */, + 6CDF8DF11F96498300140B54 /* SFAnalyticsSampler.m in Sources */, DC222CA81E08A7D900B09171 /* CloudKitMockXCTest.m in Sources */, DC9C75161E4BCE1800F1CA0D /* CKKSOperationTests.m in Sources */, DCB221561E8B08BF001598BC /* server_xpc.m in Sources */, @@ -26664,9 +28052,13 @@ DC4268FE1E820371002B7110 /* server_endpoint.m in Sources */, DCFE1C3D1F17EFB5007640C8 /* CKKSConditionTests.m in Sources */, DCCD33C91E3FE95900AA4AD1 /* spi.c in Sources */, + 6CFDC4551F907D2600646DBB /* SFObjCType.m in Sources */, DC9C95971F748D0B000D19E5 /* CKKSServerValidationRecoveryTests.m in Sources */, DC7341FE1F84642C00AB9BDF /* CKKSTLKSharingEncryptionTests.m in Sources */, DC5F35AC1EE0F27900900966 /* server_entitlement_helpers.c in Sources */, + DAEE055C1FAD3FC700DF27F3 /* AutoreleaseTest.c in Sources */, + DA19DAEF1FCFA420008E82EE /* CKKSControl.m in Sources */, + DA19DAF01FCFA425008E82EE /* CKKSControlProtocol.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -26682,18 +28074,27 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + BEE4B18C1FFD585800777D39 /* OTAuthenticatedCiphertext.proto in Sources */, + BEB0B0D71FFC3D9A007E6A83 /* OTPrivateKey.proto in Sources */, + BE3405AC1FD7258900933DAC /* OTBottle.proto in Sources */, + BE3405AD1FD725A700933DAC /* OTBottleContents.proto in Sources */, DC9FD3361F86A34F00C8AAC8 /* CKKSSerializedKey.proto in Sources */, DC797E1A1DD3F9A400CC9E42 /* CKKSSQLDatabaseObject.m in Sources */, 6CC1859F1E24E8EB009657D8 /* CKKSRateLimiter.m in Sources */, DCFB12C71E95A4C000510F5F /* CKKSCKAccountStateTracker.m in Sources */, EBB407B31EBA46B200A541A5 /* CKKSPowerCollection.m in Sources */, DCCD88EA1E42622200F5AA71 /* CKKSGroupOperation.m in Sources */, + 0CD9E8001FE05B6600F66C38 /* OTContextRecord.m in Sources */, + BEB0B0DD1FFC45D7007E6A83 /* OTPrivateKey+SF.m in Sources */, DC54DD0F1EA7D9E700108E92 /* CKKSManifestLeafRecord.m in Sources */, DCDCCB901DF7B8D4006E840E /* CKKSItem.m in Sources */, DC1ED8C11DD5197E002BDCFA /* CKKSItemEncrypter.m in Sources */, DC6D2C921DD2835A00BE372D /* CKKSOutgoingQueueEntry.m in Sources */, 6C8CC3AD1E2F913C009025C5 /* AWDKeychainCKKSRateLimiterTopWriters.m in Sources */, DC378B3D1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.m in Sources */, + 0C8BBEA91FC9DBBF00580909 /* OTLocalStore.m in Sources */, + 4733377B1FDAFBCC00E19F30 /* SFKeychainControlManager.m in Sources */, + 0CE1BCCE1FCE11680017230E /* OTBottledPeerSigned.m in Sources */, DC5BB4FA1E0C90DE0010F836 /* CKKSIncomingQueueOperation.m in Sources */, DC5BB5001E0C98320010F836 /* CKKSOutgoingQueueOperation.m in Sources */, DC378B391DEFADB500A3DAFA /* CKKSZoneStateEntry.m in Sources */, @@ -26702,8 +28103,12 @@ DC15F7681E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.m in Sources */, DCE278DF1ED789EF0083B485 /* CKKSCurrentItemPointer.m in Sources */, DC3D748E1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.m in Sources */, + 0C8BBF151FCB4B1B00580909 /* OTManager.m in Sources */, + 0C8BBEA51FC9DBB100580909 /* OTEscrowKeys.m in Sources */, DCA4D1FF1E552DD50056214F /* CKKSCurrentKeyPointer.m in Sources */, + DA6AA1651FE88AFB004565B0 /* CKKSControlServer.m in Sources */, DCFE1C531F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.m in Sources */, + 47922D481FAA7C3C0008F7E0 /* SecDbKeychainSerializedMetadata.m in Sources */, DCD6C4B41EC5302500414FEE /* CKKSNearFutureScheduler.m in Sources */, DC378B2F1DEF9E0E00A3DAFA /* CKKSMirrorEntry.m in Sources */, DC94BCCC1F10448600E07CEB /* CloudKitCategories.m in Sources */, @@ -26716,47 +28121,65 @@ DC18F7711E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.m in Sources */, DC2C5F601F0EB97E00FEBDA7 /* CKKSNotifier.m in Sources */, DC52E7CF1D80BCFD00B0A59C /* SOSEngine.c in Sources */, - DC9C95B61F79CFD1000D19E5 /* CKKSControl.m in Sources */, DC4DB1521E24692100CD6769 /* CKKSKey.m in Sources */, DCBDB3BD1E57CA7A00B61300 /* CKKSViewManager.m in Sources */, + 471A03EC1F72E35B000A8904 /* SecDbKeychainItemV7.m in Sources */, + 0C8BBF171FCB4E5000580909 /* OTControlProtocol.m in Sources */, + EB4E0CDB1FF36A9700CDCACC /* CKKSReachabilityTracker.m in Sources */, DC52E7C41D80BCAD00B0A59C /* SecDbItem.c in Sources */, - DC52E7D31D80BD1800B0A59C /* SecDbKeychainItem.c in Sources */, + DC52E7D31D80BD1800B0A59C /* SecDbKeychainItem.m in Sources */, DC52E7CC1D80BCDF00B0A59C /* SecDbQuery.c in Sources */, DC14478C1F5764C600236DB4 /* CKKSResultOperation.m in Sources */, 479DA1721EBBA8D10065C98F /* CKKSManifest.m in Sources */, DC52E7CB1D80BCD800B0A59C /* SecItemBackupServer.c in Sources */, DC52E7CD1D80BCE700B0A59C /* SecItemDataSource.c in Sources */, - DCBF2F871F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.m in Sources */, + DC124DCD20059BA900BE8DAC /* OctagonControlServer.m in Sources */, DC52E7DE1D80BD7F00B0A59C /* SecItemDb.c in Sources */, DC52E7E01D80BD8D00B0A59C /* SecItemSchema.c in Sources */, + EB10A3E820356E6500E84270 /* OTConstants.m in Sources */, + 0C5CFB382019610000913B9C /* OTRamping.m in Sources */, DC52E7D71D80BD2D00B0A59C /* SecItemServer.c in Sources */, - 479108B91EE879F9008CEFA0 /* CKKSAnalyticsLogger.m in Sources */, + 47922D441FAA7C2C0008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */, + 479108B91EE879F9008CEFA0 /* CKKSAnalytics.m in Sources */, + 479108B91EE879F9008CEFA0 /* CKKSAnalytics.m in Sources */, + 0C8BBEE61FCA6E0500580909 /* OTContext.m in Sources */, DC1447981F5766D200236DB4 /* NSOperationCategories.m in Sources */, DCD8A0CF1E09EA1800E4FA0A /* SecKeybagSupport.c in Sources */, DC52E7E11D80BD9300B0A59C /* SecLogSettingsServer.m in Sources */, DCFE1C291F17E455007640C8 /* CKKSDeviceStateEntry.m in Sources */, DCAD9B461F8D939C00C5E2AE /* CKKSFixups.m in Sources */, + 0C8BBEA71FC9DBB500580909 /* OTIdentity.m in Sources */, 6C8CC3AC1E2F913C009025C5 /* AWDKeychainCKKSRateLimiterOverload.m in Sources */, DC52E7DC1D80BD4F00B0A59C /* SecOTRRemote.m in Sources */, DCE278EA1ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.m in Sources */, DCD662F71E329B6800188186 /* CKKSNewTLKOperation.m in Sources */, DCB837321ED5045000015C07 /* CKKSLockStateTracker.m in Sources */, - DAD3BD011F9830BB00DF29BA /* CKKSControlProtocol.m in Sources */, + 0CE407AC1FD4769B00F59B31 /* OTCloudStoreState.m in Sources */, + 47922D4C1FAA7C4A0008F7E0 /* SecDbKeychainSerializedSecretData.m in Sources */, DCBDB3B71E57C82300B61300 /* CKKSKeychainView.m in Sources */, DC52E7D61D80BD2800B0A59C /* SecuritydXPC.c in Sources */, + 47922D561FAA7E0D0008F7E0 /* SecDbKeychainSerializedItemV7.m in Sources */, + 0CCCC7C920261D310024405E /* OT.m in Sources */, DC7A17EF1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.m in Sources */, DC7341F51F8447AB00AB9BDF /* CKKSTLKShare.m in Sources */, + 0C5960811FB369C50095BA29 /* CKKSHealTLKSharesOperation.m in Sources */, DCA4D2171E5684220056214F /* CKKSReencryptOutgoingItemsOperation.m in Sources */, 5269658D1E6A154700627F9D /* SecBackupKeybagEntry.m in Sources */, DC52E7D41D80BD1D00B0A59C /* iCloudTrace.c in Sources */, DCEA5D871E2F14810089CF55 /* CKKSAPSReceiver.m in Sources */, + 0C8BBE9F1FC9DBA400580909 /* OTBottledPeer.m in Sources */, 6C869A791F54C37900957298 /* AWDKeychainSOSKeychainBackupFailed.m in Sources */, 6C869A751F50CAF400957298 /* SOSEnsureBackup.m in Sources */, + BE2AD2BA1FDA080800739F96 /* OTBottledPeerRecord.m in Sources */, + 0C770EC41FCF7E2000B5F0E2 /* OTCloudStore.m in Sources */, DCEA5D571E2826DB0089CF55 /* CKKSSIV.m in Sources */, + 0C36B3212007F2550029F7A2 /* OTPreflightInfo.m in Sources */, 6C8CC3AB1E2F913C009025C5 /* AWDKeychainCKKSRateLimiterAggregatedScores.m in Sources */, + BEE4B1941FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.m in Sources */, DC9082C41EA0277600D0C1C5 /* CKKSZoneChangeFetcher.m in Sources */, DCFE1C361F17ECE5007640C8 /* CKKSCondition.m in Sources */, DCEA5D971E3015830089CF55 /* CKKSZone.m in Sources */, + BEE4B19A1FFDAFE600777D39 /* SFECPublicKey+SPKI.m in Sources */, DC52E7C51D80BCB300B0A59C /* swcagent_client.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -26768,9 +28191,12 @@ 48E617211DBEC6BA0098EAAD /* SOSBackupInformation.m in Sources */, DC52E8F11D80C34000B0A59C /* SOSAccount.m in Sources */, DC52E8F31D80C34000B0A59C /* SOSAccountBackup.m in Sources */, + DCB332591F478C3C00178C30 /* SOSUserKeygen.m in Sources */, DC52E8F41D80C34000B0A59C /* SOSAccountCircles.m in Sources */, 0CD8CB0B1ECA50920076F37F /* SOSPeerOTRTimer.m in Sources */, + DC2670F51F3E711400816EED /* SOSAccountCloudParameters.m in Sources */, DCDCC7E51D9B5526006487E8 /* SOSAccountSync.m in Sources */, + DC2670F81F3E723B00816EED /* SOSAccountDer.m in Sources */, DC52E8F71D80C34000B0A59C /* SOSAccountCredentials.m in Sources */, DC52E8F91D80C34000B0A59C /* SOSAccountFullPeerInfo.m in Sources */, DC52E8FC1D80C34000B0A59C /* SOSAccountLog.m in Sources */, @@ -26782,6 +28208,7 @@ DC52E8FD1D80C34000B0A59C /* SOSAccountUpdate.m in Sources */, DC52E9001D80C34000B0A59C /* SOSAccountViewSync.m in Sources */, DC52E9011D80C34000B0A59C /* SOSBackupEvent.c in Sources */, + DC2670F71F3E721800816EED /* SOSAccountTrustClassic.m in Sources */, 7281E0871DFD01800021E1B7 /* SOSAccountGetSet.m in Sources */, 0C4899121E0E105D00C6CF70 /* SOSTransportCircleCK.m in Sources */, DC52E8DD1D80C31F00B0A59C /* SOSCoder.c in Sources */, @@ -26801,6 +28228,7 @@ 0CAD1E1C1E032ADB00537693 /* SOSCloudCircleServer.m in Sources */, DC52E8CF1D80C2FD00B0A59C /* SOSTransportMessageIDS.m in Sources */, 0CAC5DBF1EB3DA4C00AD884B /* SOSPeerRateLimiter.m in Sources */, + DAB27AE11FA29EE300DEBBDE /* SOSControlServer.m in Sources */, DC52E8D01D80C2FD00B0A59C /* SOSTransportMessageKVS.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -26813,6 +28241,7 @@ DC52EAA11D80CCAC00B0A59C /* SecurityTool.c in Sources */, DC52EAA01D80CCA700B0A59C /* whoami.m in Sources */, DC52EA9F1D80CCA100B0A59C /* digest_calc.c in Sources */, + 473337841FDB29C400E19F30 /* KeychainCheck.m in Sources */, EBEEEE3C1EA31D9600E15F5C /* SOSControlHelper.m in Sources */, DC52EA9E1D80CC9B00B0A59C /* leaks.c in Sources */, EB48C1A61E573EEC00EC5E57 /* sos.m in Sources */, @@ -26826,6 +28255,7 @@ buildActionMask = 2147483647; files = ( DC52EC1E1D80CF6700B0A59C /* verify_cert.c in Sources */, + D453C3901FEC66AE00DE349B /* trust_update.m in Sources */, DC52EC1D1D80CF6200B0A59C /* keychain_util.c in Sources */, DC52EC1C1D80CF5D00B0A59C /* add_internet_password.c in Sources */, DC52EC1B1D80CF5600B0A59C /* codesign.c in Sources */, @@ -26843,15 +28273,16 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + DCD7EE841F4E46F9007D9804 /* accountCirclesViewsPrint.m in Sources */, 0C0CECA41DA45ED700C22FBC /* recovery_key.m in Sources */, DC52EC3B1D80CFE900B0A59C /* syncbackup.m in Sources */, DC52EC3A1D80CFE400B0A59C /* keychain_log.m in Sources */, - 48C2F93B1E4BCFE80093D70C /* accountCirclesViewsPrint.m in Sources */, DC52EC391D80CFDF00B0A59C /* secViewDisplay.c in Sources */, DC52EC381D80CFDB00B0A59C /* secToolFileIO.c in Sources */, DC52EC371D80CFD400B0A59C /* keychain_sync_test.m in Sources */, DC52EC361D80CFD000B0A59C /* keychain_sync.m in Sources */, DC3C7C901D83957F00F6A832 /* NSFileHandle+Formatting.m in Sources */, + DCE5DC0F1EA80256006308A6 /* SOSSysdiagnose.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -26925,7 +28356,7 @@ DC52ECBD1D80D22600B0A59C /* si-42-identity.c in Sources */, DC52ECBE1D80D22600B0A59C /* si-43-persistent.c in Sources */, DC52ECC31D80D22600B0A59C /* si-50-secrandom.c in Sources */, - DC52ECC71D80D22600B0A59C /* si-63-scep.c in Sources */, + DC52ECC71D80D22600B0A59C /* si-63-scep.m in Sources */, DC52ECCD1D80D22600B0A59C /* si-69-keydesc.c in Sources */, DC52ECD01D80D22600B0A59C /* si-72-syncableitems.c in Sources */, DC52ECD11D80D22600B0A59C /* si-73-secpasswordgenerate.c in Sources */, @@ -26934,7 +28365,7 @@ DC52ECD51D80D22600B0A59C /* si-78-query-attrs.c in Sources */, DC52ECD61D80D22600B0A59C /* si-80-empty-data.c in Sources */, DC52ECD91D80D22600B0A59C /* si-82-token-ag.c in Sources */, - DC52ECDD1D80D22600B0A59C /* si-89-cms-hash-agility.c in Sources */, + DC52ECDD1D80D22600B0A59C /* si-89-cms-hash-agility.m in Sources */, DC52ECDE1D80D22600B0A59C /* si-90-emcs.m in Sources */, DC52ECDF1D80D22600B0A59C /* si-95-cms-basic.c in Sources */, DC52EC981D80D1D100B0A59C /* vmdh-40.c in Sources */, @@ -27023,6 +28454,7 @@ 0CAD1E591E1C5CBD00537693 /* secd-52-offering-gencount-reset.m in Sources */, DC52EDDD1D80D5C500B0A59C /* secd-70-engine-corrupt.m in Sources */, DC52EDDE1D80D5C500B0A59C /* secd-70-engine-smash.m in Sources */, + 0C5F4FD81F952FEA00AF1616 /* secd-700-sftm.m in Sources */, 522B280E1E64B4BF002B5638 /* secd-230-keybagtable.m in Sources */, DC52EDDF1D80D5C500B0A59C /* secd-70-otr-remote.m in Sources */, DC52EDE21D80D5C500B0A59C /* secd-74-engine-beer-servers.m in Sources */, @@ -27067,7 +28499,7 @@ DC52EE441D80D71900B0A59C /* si-21-sectrust-asr.c in Sources */, DC52EE451D80D71900B0A59C /* si-22-sectrust-iap.c in Sources */, DC52EE471D80D71900B0A59C /* si-23-sectrust-ocsp.c in Sources */, - D48E4E241E42F0620011B4BA /* si-62-csr.c in Sources */, + D48E4E241E42F0620011B4BA /* si-62-csr.m in Sources */, DC52EE481D80D71900B0A59C /* si-24-sectrust-digicert-malaysia.c in Sources */, DC52EE491D80D71900B0A59C /* si-24-sectrust-diginotar.c in Sources */, DC52EE4A1D80D71900B0A59C /* si-24-sectrust-itms.c in Sources */, @@ -27091,6 +28523,7 @@ DC52EE5A1D80D73800B0A59C /* si-83-seccertificate-sighashalg.c in Sources */, DC52EE5B1D80D73800B0A59C /* si-97-sectrust-path-scoring.m in Sources */, D47E69401E92F75D002C8CF6 /* si-61-pkcs12.c in Sources */, + BEB9E9EC1FFF195C00676593 /* si-88-sectrust-valid.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -27125,19 +28558,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - DC59E9D01D91C9DC001BDDF5 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - DC59EA031D91CA0A001BDDF5 /* DER_Decode.c in Sources */, - DC59EA051D91CA0A001BDDF5 /* DER_Encode.c in Sources */, - DC59E9FE1D91CA0A001BDDF5 /* DER_Keys.c in Sources */, - DC59EA0A1D91CA0A001BDDF5 /* DER_Digest.c in Sources */, - DC59EA0B1D91CA0A001BDDF5 /* oids.c in Sources */, - DC59EA011D91CA0A001BDDF5 /* DER_CertCrl.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; DC5ABDC11D832DAB00CF422C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -27596,7 +29016,6 @@ buildActionMask = 2147483647; files = ( 0CAD1E581E1C5C6C00537693 /* SOSCloudCircle.m in Sources */, - DCC78EE81D808B3500865A7C /* secToolFileIO.c in Sources */, DCC78EE71D808B2F00865A7C /* secViewDisplay.c in Sources */, DCC78EE61D808B2A00865A7C /* SecAccessControl.c in Sources */, DCC78EE51D808B2100865A7C /* SecBase64.c in Sources */, @@ -27605,7 +29024,6 @@ BEEB47D91EA189F5004AA5C6 /* SecTrustStatusCodes.c in Sources */, DCC78EE21D808B0E00865A7C /* SecCTKKey.c in Sources */, DCC78EE11D808B0900865A7C /* SecCertificate.c in Sources */, - DCC78EE01D808B0000865A7C /* SecCertificatePath.c in Sources */, DC4269041E82EDAC002B7110 /* SecItem.m in Sources */, EBEEEE3D1EA31DB000E15F5C /* SOSControlHelper.m in Sources */, DCC78EDF1D808AF800865A7C /* SecCertificateRequest.c in Sources */, @@ -27638,7 +29056,6 @@ DCC78EC51D808A4100865A7C /* SecRSAKey.c in Sources */, DCC78EC41D808A3B00865A7C /* SecSCEP.c in Sources */, DCC78EC31D808A2E00865A7C /* SecServerEncryptionSupport.c in Sources */, - 48C2F93A1E4BCFDC0093D70C /* accountCirclesViewsPrint.m in Sources */, DCC78EC21D808A2800865A7C /* SecSharedCredential.c in Sources */, DCC78EC11D808A2200865A7C /* SecSignatureVerificationSupport.c in Sources */, DCC78EC01D808A1C00865A7C /* SecTrust.c in Sources */, @@ -27826,7 +29243,6 @@ DCD66DBF1D82053E00DB1393 /* SecDigest.c in Sources */, BEEB47DA1EA189F5004AA5C6 /* SecTrustStatusCodes.c in Sources */, DCD66DBE1D82053700DB1393 /* SecBase64.c in Sources */, - DCD66DBD1D82053100DB1393 /* SecCertificatePath.c in Sources */, BE1F74D31F609D460068FA64 /* SecFramework.c in Sources */, DCD66DB61D82050900DB1393 /* SecKey.c in Sources */, DCD66DBC1D82052B00DB1393 /* SecKeyAdaptors.c in Sources */, @@ -27862,12 +29278,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCD8A1DA1E09F54700E4FA0A /* SOSAccountDer.m in Sources */, - DCD8A1E31E09F7E700E4FA0A /* SOSAccountCloudParameters.m in Sources */, DCD8A19D1E09EEC800E4FA0A /* SOSBackupSliceKeyBag.m in Sources */, + DC2670FB1F3E72C000816EED /* SOSCircleDer.c in Sources */, EB75B4961E75A44100E469CC /* SOSPiggyback.m in Sources */, DCD8A1B31E09F12D00E4FA0A /* SOSCircle.c in Sources */, - DCD8A1AC1E09F09200E4FA0A /* SOSCircleDer.c in Sources */, DCD8A1FF1E09FA6100E4FA0A /* secViewDisplay.c in Sources */, DCD8A1B41E09F12D00E4FA0A /* SOSCircleV2.c in Sources */, DCD8A1A01E09EF3500E4FA0A /* SOSCloudKeychainClient.c in Sources */, @@ -27876,7 +29290,6 @@ DCD8A1A91E09F04700E4FA0A /* SOSECWrapUnwrap.c in Sources */, 0C4899251E0F38FA00C6CF70 /* SOSAccountTrustOctagon.m in Sources */, DCD8A1BD1E09F1D600E4FA0A /* SOSFullPeerInfo.m in Sources */, - DCD8A2001E09FA7900E4FA0A /* secToolFileIO.c in Sources */, DCD8A1B51E09F15400E4FA0A /* SOSGenCount.c in Sources */, DCD8A19F1E09EF0F00E4FA0A /* SOSInternal.m in Sources */, EBEEEE3F1EA31E6D00E15F5C /* SOSControlHelper.m in Sources */, @@ -27891,7 +29304,6 @@ 0CE7604E1E12F5BA00B4381E /* SOSAccountTrustClassic+Retirement.m in Sources */, DCD8A1A51E09EFAE00E4FA0A /* SOSPeerInfoV2.m in Sources */, 0CE760481E12F2F300B4381E /* SOSAccountTrustClassic+Expansion.m in Sources */, - 48C2F9391E4BCFDA0093D70C /* accountCirclesViewsPrint.m in Sources */, DCD8A1C21E09F23B00E4FA0A /* SOSRecoveryKeyBag.m in Sources */, DCD8A1B81E09F1BB00E4FA0A /* SOSRingBackup.m in Sources */, DCD8A1B91E09F1BB00E4FA0A /* SOSRingBasic.m in Sources */, @@ -27901,11 +29313,8 @@ DCD8A1BA1E09F1BB00E4FA0A /* SOSRingRecovery.m in Sources */, DCD8A1B01E09F0F400E4FA0A /* SOSRingTypes.m in Sources */, DCD8A1AF1E09F0DC00E4FA0A /* SOSRingUtils.c in Sources */, - 0C48991C1E0F384700C6CF70 /* SOSAccountTrustClassic.m in Sources */, DCD8A1B71E09F19100E4FA0A /* SOSRingV0.m in Sources */, - DCD8A1A31E09EF7800E4FA0A /* SOSSysdiagnose.m in Sources */, DCD8A1C71E09F2B400E4FA0A /* SOSTransport.m in Sources */, - DCD8A1A81E09F03100E4FA0A /* SOSUserKeygen.m in Sources */, DCD8A1511E09EE0F00E4FA0A /* SOSViews.m in Sources */, DCD8A19E1E09EEDA00E4FA0A /* SecRecoveryKey.m in Sources */, 0CE7604A1E12F30200B4381E /* SOSAccountTrustClassic+Circle.m in Sources */, @@ -28322,7 +29731,6 @@ files = ( DC5BCC481E53820200649140 /* SecArgParse.c in Sources */, EB27FF2D1E407FF600EC9E3A /* ckksctl.m in Sources */, - DCF7A8A51F0451AC00CABE89 /* CKKSControlProtocol.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -28350,6 +29758,26 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + EB49B2AA202D877F003F34A0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EB49B2E5202DFEB3003F34A0 /* mockaks.m in Sources */, + EB49B2DB202DF20F003F34A0 /* spi.c in Sources */, + EB49B2D7202DF1F7003F34A0 /* server_endpoint.m in Sources */, + EB49B2D8202DF1F7003F34A0 /* server_xpc.m in Sources */, + EB49B2D9202DF1F7003F34A0 /* server_security_helpers.c in Sources */, + EB49B2E0202DF5D7003F34A0 /* server_entitlement_helpers.c in Sources */, + EB6667C7204CD69F000B404F /* testPlistDER.m in Sources */, + EB49B2D5202DF1D8003F34A0 /* SecTask.c in Sources */, + EB49B2D4202DF1C1003F34A0 /* client.c in Sources */, + EB49B2D3202DF1AC003F34A0 /* SecdWatchdog.m in Sources */, + EB49B2B1202D8780003F34A0 /* secdmockaks.m in Sources */, + EB49B2D1202DF15F003F34A0 /* SFAnalyticsActivityTracker.m in Sources */, + EB49B2D0202DF14D003F34A0 /* SFAnalytics.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; EB9C1D761BDFD0E000F89272 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -28435,6 +29863,46 @@ target = 0C0BDB2E175685B000BC1A7E /* secdtests_ios */; targetProxy = 0C664AB31759270C0092D3D9 /* PBXContainerItemProxy */; }; + 0C78CCE51FCC97E7008B4B24 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 0C8BBEFD1FCB446400580909 /* otctl */; + targetProxy = 0C78CCE41FCC97E7008B4B24 /* PBXContainerItemProxy */; + }; + 0C78CCE71FCC97F1008B4B24 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 0C8BBEFD1FCB446400580909 /* otctl */; + targetProxy = 0C78CCE61FCC97F1008B4B24 /* PBXContainerItemProxy */; + }; + 0C85DFD41FB38BB6000343A7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC222C371E034D1F00B09171 /* libsecurityd_ios_NO_AKS */; + targetProxy = 0C85DFD51FB38BB6000343A7 /* PBXContainerItemProxy */; + }; + 0C85DFD81FB38BB6000343A7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; + targetProxy = 0C85DFD91FB38BB6000343A7 /* PBXContainerItemProxy */; + }; + 0C85DFDA1FB38BB6000343A7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = 0C85DFDB1FB38BB6000343A7 /* PBXContainerItemProxy */; + }; + 0C85DFDC1FB38BB6000343A7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; + targetProxy = 0C85DFDD1FB38BB6000343A7 /* PBXContainerItemProxy */; + }; + 0C85DFDE1FB38BB6000343A7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; + targetProxy = 0C85DFDF1FB38BB6000343A7 /* PBXContainerItemProxy */; + }; + 0C85DFE01FB38BB6000343A7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCC78EA81D8088E200865A7C /* security */; + targetProxy = 0C85DFE11FB38BB6000343A7 /* PBXContainerItemProxy */; + }; 0C99B740131C984900584CF4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 0C6799F912F7C37C00712919 /* dtlsTests */; @@ -28465,11 +29933,51 @@ target = 4381690B1B4EDCBD00C54D58 /* SOSCCAuthPlugin */; targetProxy = 438169E61B4EE4B300C54D58 /* PBXContainerItemProxy */; }; + 478D426D1FD72A8100CAB645 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52EDA61D80D58400B0A59C /* secdRegressions */; + targetProxy = 478D426E1FD72A8100CAB645 /* PBXContainerItemProxy */; + }; + 478D426F1FD72A8100CAB645 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCBD91D8C648C00070CB0 /* regressionBase */; + targetProxy = 478D42701FD72A8100CAB645 /* PBXContainerItemProxy */; + }; + 478D42711FD72A8100CAB645 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; + targetProxy = 478D42721FD72A8100CAB645 /* PBXContainerItemProxy */; + }; + 478D42731FD72A8100CAB645 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCC78EA81D8088E200865A7C /* security */; + targetProxy = 478D42741FD72A8100CAB645 /* PBXContainerItemProxy */; + }; 47C51B8B1EEA657D0032D9E5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC1789031D77980500B50D50 /* Security_osx */; targetProxy = 47C51B8A1EEA657D0032D9E5 /* PBXContainerItemProxy */; }; + 47DE88CE1FA7AD6200DD3254 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCC78EA81D8088E200865A7C /* security */; + targetProxy = 47DE88CD1FA7AD6200DD3254 /* PBXContainerItemProxy */; + }; + 47DE88D51FA7AD7000DD3254 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; + targetProxy = 47DE88D41FA7AD7000DD3254 /* PBXContainerItemProxy */; + }; + 47DE88D71FA7ADAC00DD3254 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCBD91D8C648C00070CB0 /* regressionBase */; + targetProxy = 47DE88D61FA7ADAC00DD3254 /* PBXContainerItemProxy */; + }; + 47DE88D91FA7ADBB00DD3254 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52EDA61D80D58400B0A59C /* secdRegressions */; + targetProxy = 47DE88D81FA7ADBB00DD3254 /* PBXContainerItemProxy */; + }; 4C52D0EE16EFCD720079966E /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4C52D0B316EFC61E0079966E /* CircleJoinRequested */; @@ -28515,11 +30023,6 @@ target = 5346480017331E1100FE9172 /* KeychainSyncAccountNotification */; targetProxy = 5346481A17331ED800FE9172 /* PBXContainerItemProxy */; }; - 5DDD0BEE16D6748900D6C0D6 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 728B56A016D59979008FA3AB /* OTAPKIAssetTool */; - targetProxy = 5DDD0BED16D6748900D6C0D6 /* PBXContainerItemProxy */; - }; 5E10995419A5E80B00A60E2B /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 5E10992419A5E55800A60E2B /* ISACLProtectedItems */; @@ -28540,10 +30043,15 @@ target = 6CCDF7831E3C25FA003F2555 /* KeychainEntitledTestRunner */; targetProxy = 6C24EF521E415132000DE79F /* PBXContainerItemProxy */; }; - 6C98082D1E788AEB00E70590 /* PBXTargetDependency */ = { + 6C7C38811FD88C4700DFFE68 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = 6C98082E1E788AEB00E70590 /* PBXContainerItemProxy */; + target = 6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */; + targetProxy = 6C7C38801FD88C4700DFFE68 /* PBXContainerItemProxy */; + }; + 6C7C38881FD88C5A00DFFE68 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */; + targetProxy = 6C7C38871FD88C5A00DFFE68 /* PBXContainerItemProxy */; }; 6C98082F1E788AEB00E70590 /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -28575,11 +30083,6 @@ target = DC222C371E034D1F00B09171 /* libsecurityd_ios_NO_AKS */; targetProxy = 6C98083C1E788AEB00E70590 /* PBXContainerItemProxy */; }; - 6C9808691E788AFD00E70590 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = 6C98086A1E788AFD00E70590 /* PBXContainerItemProxy */; - }; 6C98086B1E788AFD00E70590 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; @@ -28620,6 +30123,31 @@ target = 6CF4A0DF1E4549F200ECD7B5 /* KeychainEntitledTestApp_ios */; targetProxy = 6C9808A31E788CB100E70590 /* PBXContainerItemProxy */; }; + 6C9A49B21FAB647D00239D58 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = 6C9A49B11FAB647D00239D58 /* PBXContainerItemProxy */; + }; + 6CAA8CE51F82FD08007B6E03 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6C9AA79D1F7C1D8F00D08296 /* supdctl */; + targetProxy = 6CAA8CE41F82FD08007B6E03 /* PBXContainerItemProxy */; + }; + 6CAA8CE91F82FD13007B6E03 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6C9AA79D1F7C1D8F00D08296 /* supdctl */; + targetProxy = 6CAA8CE81F82FD13007B6E03 /* PBXContainerItemProxy */; + }; + 6CAA8D3D1F8431BC007B6E03 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6CAA8D1F1F842FB3007B6E03 /* securityuploadd */; + targetProxy = 6CAA8D3C1F8431BC007B6E03 /* PBXContainerItemProxy */; + }; + 6CAA8D3F1F8431C9007B6E03 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6CAA8D1F1F842FB3007B6E03 /* securityuploadd */; + targetProxy = 6CAA8D3E1F8431C9007B6E03 /* PBXContainerItemProxy */; + }; ACBAF6FE1E941E090007BA2F /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = ACBAF6991E9417F40007BA2F /* security_transform_regressions */; @@ -28715,11 +30243,6 @@ target = D4ADA3181E2B41670031CEA3 /* libtrustd */; targetProxy = D40B6A941E2B67FF00CD6EE5 /* PBXContainerItemProxy */; }; - D41257E41E941A8400781F23 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = D41257E31E941A8400781F23 /* PBXContainerItemProxy */; - }; D41257E61E941ACC00781F23 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC0BCC211D8C684F00070CB0 /* utilities */; @@ -28810,11 +30333,6 @@ target = 52D82BDD16A621F70078DFE5 /* CloudKeychainProxy */; targetProxy = D41AD4511B9788B2008C7270 /* PBXContainerItemProxy */; }; - D41AD45A1B978944008C7270 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 728B56A016D59979008FA3AB /* OTAPKIAssetTool */; - targetProxy = D41AD4591B978944008C7270 /* PBXContainerItemProxy */; - }; D41AD45C1B978A7A008C7270 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 790851B50CA9859F0083CC4D /* securityd_ios */; @@ -28860,11 +30378,6 @@ target = 5EBE24791B00CCAE0007DB0E /* secacltests */; targetProxy = D41AD46D1B978F4C008C7270 /* PBXContainerItemProxy */; }; - D41AD4721B978F76008C7270 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 728B56A016D59979008FA3AB /* OTAPKIAssetTool */; - targetProxy = D41AD4711B978F76008C7270 /* PBXContainerItemProxy */; - }; DA30D6821DF8C93500EC6B43 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DA30D6751DF8C8FB00EC6B43 /* KeychainSyncAccountUpdater */; @@ -29055,11 +30568,6 @@ target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; targetProxy = DC0984FF1E1DB70A00140ADC /* PBXContainerItemProxy */; }; - DC0B62961D90B6DB00D43BCB /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC1785041D77873100B50D50 /* copyHeadersToSystem */; - targetProxy = DC0B62951D90B6DB00D43BCB /* PBXContainerItemProxy */; - }; DC0BB4441ED4D74A0035F886 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DCC78EA81D8088E200865A7C /* security */; @@ -29185,15 +30693,30 @@ target = DC222C371E034D1F00B09171 /* libsecurityd_ios_NO_AKS */; targetProxy = DC222C781E034EE700B09171 /* PBXContainerItemProxy */; }; - DC3502C41E020D4D00BC0587 /* PBXTargetDependency */ = { + DC2671101F3E933700816EED /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; - targetProxy = DC3502C31E020D4D00BC0587 /* PBXContainerItemProxy */; + targetProxy = DC26710F1F3E933700816EED /* PBXContainerItemProxy */; + }; + DC34CD2D20326C2C00302481 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; + targetProxy = DC34CD2C20326C2C00302481 /* PBXContainerItemProxy */; + }; + DC34CD3420326C3100302481 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; + targetProxy = DC34CD3320326C3100302481 /* PBXContainerItemProxy */; + }; + DC34CD3620326C3B00302481 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = DC34CD3520326C3B00302481 /* PBXContainerItemProxy */; }; - DC3502C71E020D5600BC0587 /* PBXTargetDependency */ = { + DC3502C41E020D4D00BC0587 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = DC3502C61E020D5600BC0587 /* PBXContainerItemProxy */; + target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; + targetProxy = DC3502C31E020D4D00BC0587 /* PBXContainerItemProxy */; }; DC3502CE1E020E2200BC0587 /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -29305,66 +30828,6 @@ name = libCMS; targetProxy = DC59E9A81D91C7CC001BDDF5 /* PBXContainerItemProxy */; }; - DC59EA761D91CC5E001BDDF5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = DC59EA751D91CC5E001BDDF5 /* PBXContainerItemProxy */; - }; - DC59EA791D91CC78001BDDF5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = DC59EA781D91CC78001BDDF5 /* PBXContainerItemProxy */; - }; - DC59EA7D1D91CCAA001BDDF5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = DC59EA7C1D91CCAA001BDDF5 /* PBXContainerItemProxy */; - }; - DC59EA811D91CD16001BDDF5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = DC59EA801D91CD16001BDDF5 /* PBXContainerItemProxy */; - }; - DC59EA841D91CD2C001BDDF5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = DC59EA831D91CD2C001BDDF5 /* PBXContainerItemProxy */; - }; - DC59EA871D91CD76001BDDF5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = DC59EA861D91CD76001BDDF5 /* PBXContainerItemProxy */; - }; - DC59EA8A1D91CD89001BDDF5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = DC59EA891D91CD89001BDDF5 /* PBXContainerItemProxy */; - }; - DC59EA8D1D91CDB9001BDDF5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = DC59EA8C1D91CDB9001BDDF5 /* PBXContainerItemProxy */; - }; - DC59EA901D91CDC6001BDDF5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = DC59EA8F1D91CDC6001BDDF5 /* PBXContainerItemProxy */; - }; - DC59EA931D91CDD6001BDDF5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = DC59EA921D91CDD6001BDDF5 /* PBXContainerItemProxy */; - }; - DC59EA961D91CDEE001BDDF5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = DC59EA951D91CDEE001BDDF5 /* PBXContainerItemProxy */; - }; - DC59EA991D91CE8C001BDDF5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = DC59EA981D91CE8C001BDDF5 /* PBXContainerItemProxy */; - }; DC5ABE1C1D832F5E00CF422C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC5ABDC41D832DAB00CF422C /* securitytool_macos */; @@ -29385,11 +30848,6 @@ target = DC5AC04F1D8352D900CF422C /* securityd_macos */; targetProxy = DC5AC12E1D8356DA00CF422C /* PBXContainerItemProxy */; }; - DC5AC1341D835C2300CF422C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC1785041D77873100B50D50 /* copyHeadersToSystem */; - targetProxy = DC5AC1331D835C2300CF422C /* PBXContainerItemProxy */; - }; DC61096B1D78E60C002223DE /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 5EBE24791B00CCAE0007DB0E /* secacltests */; @@ -29675,16 +31133,6 @@ target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; targetProxy = DC71DA061D95BE2F0065FB93 /* PBXContainerItemProxy */; }; - DC71DA091D95BEE00065FB93 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = DC71DA081D95BEE00065FB93 /* PBXContainerItemProxy */; - }; - DC71DA0B1D95BEF60065FB93 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = DC71DA0A1D95BEF60065FB93 /* PBXContainerItemProxy */; - }; DC71DA0D1D95DD670065FB93 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; @@ -29705,6 +31153,11 @@ target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; targetProxy = DC89998A1E410DBF00E6E604 /* PBXContainerItemProxy */; }; + DCB332471F47857D00178C30 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52EC211D80CFB200B0A59C /* SOSCommands */; + targetProxy = DCB332461F47857D00178C30 /* PBXContainerItemProxy */; + }; DCB340191D8A248C0054D16E /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; @@ -29945,6 +31398,16 @@ target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; targetProxy = DCD8A2061E09FB1F00E4FA0A /* PBXContainerItemProxy */; }; + DCDB29761FD8839F00B5D242 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 0C85DFD11FB38BB6000343A7 /* OTTests */; + targetProxy = DCDB29751FD8839F00B5D242 /* PBXContainerItemProxy */; + }; + DCDB29781FD883AB00B5D242 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 0C85DFD11FB38BB6000343A7 /* OTTests */; + targetProxy = DCDB29771FD883AB00B5D242 /* PBXContainerItemProxy */; + }; DCE4E6AA1D7A38E700AFB96E /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DCE4E68A1D7A37FA00AFB96E /* security2tool_macos */; @@ -29995,6 +31458,11 @@ target = DCE4E9101D7F3D5300AFB96E /* Keychain Circle Notification */; targetProxy = DCE4E9721D7F3FC200AFB96E /* PBXContainerItemProxy */; }; + DCE5DC171EA804E5006308A6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52EC211D80CFB200B0A59C /* SOSCommands */; + targetProxy = DCE5DC161EA804E5006308A6 /* PBXContainerItemProxy */; + }; DCF785011D88B80600E694BB /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DCF7830A1D88B4DE00E694BB /* security_apple_csp */; @@ -30325,11 +31793,6 @@ target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; targetProxy = EBFBC2B51E76587800A34469 /* PBXContainerItemProxy */; }; - EBFBC2B81E76588200A34469 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC59E9AC1D91C9DC001BDDF5 /* DER_not_installed */; - targetProxy = EBFBC2B71E76588200A34469 /* PBXContainerItemProxy */; - }; EBFBC2BA1E76588A00A34469 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; @@ -30448,6 +31911,23 @@ name = InfoPlist.strings; sourceTree = ""; }; + D479F6DF1F980F8F00388D28 /* Trust.strings */ = { + isa = PBXVariantGroup; + children = ( + D479F6E01F980F8F00388D28 /* English */, + ); + name = Trust.strings; + sourceTree = ""; + }; + D4C263CC1F952F6C001317EA /* SecErrorMessages.strings */ = { + isa = PBXVariantGroup; + children = ( + D4C263CD1F952F6C001317EA /* SecErrorMessages.strings */, + ); + name = SecErrorMessages.strings; + path = derived_src/en.lproj/; + sourceTree = BUILT_PRODUCTS_DIR; + }; DC0B622D1D909C4600D43BCB /* MainMenu.xib */ = { isa = PBXVariantGroup; children = ( @@ -30603,16 +32083,16 @@ ); GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INSTALL_PATH = /usr/local/bin; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)/usr/lib/system", - ); OTHER_LDFLAGS = ( "-ObjC", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_MOBILEASSET)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=embedded]" = ( "$(inherited)", @@ -30626,6 +32106,9 @@ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-framework", CrashReporterSupport, + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_NAME = secdtests; STRIP_STYLE = debugging; @@ -30647,16 +32130,16 @@ ); GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INSTALL_PATH = /usr/local/bin; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)/usr/lib/system", - ); OTHER_LDFLAGS = ( "-ObjC", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_MOBILEASSET)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=embedded]" = ( "$(inherited)", @@ -30670,6 +32153,8 @@ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-framework", CrashReporterSupport, + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_NAME = secdtests; STRIP_STYLE = debugging; @@ -30750,6 +32235,186 @@ }; name = Release; }; + 0C85E0011FB38BB6000343A7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/../../AppleInternal/Library/Frameworks", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "NO_SERVER=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = "keychain/ot/tests/OTTests-Info.plist"; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=iphonesimulator*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ( + "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "-ObjC", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + ); + "OTHER_LDFLAGS[sdk=iphoneos*]" = ( + "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "-ObjC", + "-framework", + CrashReporterSupport, + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.OTTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + USE_XCTRUNNER = YES; + }; + name = Debug; + }; + 0C85E0021FB38BB6000343A7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/../../AppleInternal/Library/Frameworks", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "NO_SERVER=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = "keychain/ot/tests/OTTests-Info.plist"; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=iphonesimulator*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ( + "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "-ObjC", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + ); + "OTHER_LDFLAGS[sdk=iphoneos*]" = ( + "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "-ObjC", + "-framework", + CrashReporterSupport, + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.OTTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + USE_XCTRUNNER = YES; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 0C8BBF061FCB446400580909 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = "keychain/otctl/otctl-Entitlements.plist"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INSTALL_PATH = /usr/local/bin; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 0C8BBF071FCB446400580909 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = "keychain/otctl/otctl-Entitlements.plist"; + COPY_PHASE_STRIP = NO; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INSTALL_PATH = /usr/local/bin; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; 225394B21E3080A600D3CD9B /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = D47C56AB1DCA831C00E18518 /* lib_ios_x64.xcconfig */; @@ -30780,7 +32445,7 @@ "$(PROJECT_DIR)/OSX/libsecurity_asn1", "$(PROJECT_DIR)/OSX/libsecurity_ssl", "$(PROJECT_DIR)/OSX/regressions", - "$(PROJECT_DIR)/OSX/ibsecurity_keychain/libDER", + "$(SDKROOT)/usr/local/include/security_libDER", "$(DSTROOT)/usr/local/include", "${BUILT_PRODUCTS_DIR}/cstemp/**", ); @@ -30829,7 +32494,7 @@ "$(PROJECT_DIR)/OSX/libsecurity_asn1", "$(PROJECT_DIR)/OSX/libsecurity_ssl", "$(PROJECT_DIR)/OSX/regressions", - "$(PROJECT_DIR)/OSX/ibsecurity_keychain/libDER", + "$(SDKROOT)/usr/local/include/security_libDER", "$(DSTROOT)/usr/local/include", "${BUILT_PRODUCTS_DIR}/cstemp/**", ); @@ -30916,6 +32581,85 @@ }; name = Release; }; + 4727FBBC1F9918590003AE36 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_MODULES = NO; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_STRICT_PROTOTYPES = NO; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = "secdtests/secdtests-entitlements.plist"; + CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = secdxctests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.secdxctests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos.internal; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 4727FBBD1F9918590003AE36 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_MODULES = NO; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_STRICT_PROTOTYPES = NO; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = "secdtests/secdtests-entitlements.plist"; + CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + ENABLE_NS_ASSERTIONS = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = secdxctests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.secdxctests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos.internal; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; 47702B231E5F409700B29577 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -31004,6 +32748,85 @@ }; name = Release; }; + 478D429A1FD72A8100CAB645 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_MODULES = NO; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_STRICT_PROTOTYPES = NO; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = "secdtests/secdtests-entitlements.plist"; + CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = secdxctests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.secdxctests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx.internal; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 478D429B1FD72A8100CAB645 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_MODULES = NO; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_STRICT_PROTOTYPES = NO; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = "secdtests/secdtests-entitlements.plist"; + CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + ENABLE_NS_ASSERTIONS = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = secdxctests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.secdxctests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx.internal; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; 47C51B8C1EEA657D0032D9E5 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -31026,11 +32849,9 @@ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = SecurityUnitTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = com.apple.SecurityUnitTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; }; name = Debug; }; @@ -31056,11 +32877,9 @@ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = SecurityUnitTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = com.apple.SecurityUnitTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; }; name = Release; }; @@ -31091,7 +32910,7 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/OSX/libsecurity_keychain/libDER", + "$(SDKROOT)/usr/local/include/security_libDER", "$(PROJECT_DIR)/OSX/libsecurity_asn1", "$(PROJECT_DIR)/libsecurity_smime", "$(PROJECT_DIR)/OSX/sec/ProjectHeaders", @@ -31139,7 +32958,7 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/OSX/libsecurity_keychain/libDER", + "$(SDKROOT)/usr/local/include/security_libDER", "$(PROJECT_DIR)/OSX/libsecurity_asn1", "$(PROJECT_DIR)/libsecurity_smime", "$(PROJECT_DIR)/OSX/sec/ProjectHeaders", @@ -31208,10 +33027,6 @@ "$(PROJECT_DIR)/OSX/regressions", ); INFOPLIST_FILE = "SecurityTests/SecurityDevTests-Info.plist"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SDKROOT)/usr/lib/system\"", - ); OTHER_LDFLAGS = ( "$(inherited)", "$(OTHER_LDFLAGS_APS)", @@ -31219,6 +33034,10 @@ "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=embedded][arch=*]" = ( "$(inherited)", @@ -31235,6 +33054,10 @@ "$(OTHER_LDFLAGS_CLOUDKIT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.${PRODUCT_NAME:identifier}"; PRODUCT_NAME = SecurityDevTests; @@ -31261,10 +33084,6 @@ "$(PROJECT_DIR)/OSX/regressions", ); INFOPLIST_FILE = "SecurityTests/SecurityDevTests-Info.plist"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SDKROOT)/usr/lib/system\"", - ); OTHER_LDFLAGS = ( "$(inherited)", "$(OTHER_LDFLAGS_APS)", @@ -31272,6 +33091,10 @@ "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=embedded]" = ( "$(inherited)", @@ -31288,6 +33111,10 @@ "$(OTHER_LDFLAGS_CLOUDKIT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.${PRODUCT_NAME:identifier}"; PRODUCT_NAME = SecurityDevTests; @@ -31587,7 +33414,10 @@ "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", ); INSTALL_PATH = /usr/local/bin; - LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/local/lib"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/usr/local/lib", + ); OTHER_LDFLAGS = ( "$(APPLE_AKS_LIBRARY)", "$(OTHER_LDFLAGS_PROTOBUF)", @@ -31597,9 +33427,14 @@ "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "$(OTHER_LDFLAGS_AGGREGATEDICTIONARY)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", ); "OTHER_LDFLAGS[sdk=embedded]" = ( "$(inherited)", @@ -31624,7 +33459,10 @@ "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", ); INSTALL_PATH = /usr/local/bin; - LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/local/lib"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/usr/local/lib", + ); OTHER_LDFLAGS = ( "$(APPLE_AKS_LIBRARY)", "$(OTHER_LDFLAGS_PROTOBUF)", @@ -31634,9 +33472,14 @@ "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "$(OTHER_LDFLAGS_AGGREGATEDICTIONARY)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", ); "OTHER_LDFLAGS[sdk=embedded]" = ( "$(inherited)", @@ -31650,6 +33493,69 @@ }; name = Release; }; + 6C4605B61F882B9B001421B6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/../../AppleInternal/Library/Frameworks", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = "$(SRCROOT)/supd/Tests/Info.plist"; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ( + "-ObjC", + "$(AOSKIT_FRAMEWORK)", + "$(OTHER_LDFLAGS_CRASHREPORTER)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.KeychainAnalyticsTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6C4605B71F882B9B001421B6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/../../AppleInternal/Library/Frameworks", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = "$(SRCROOT)/supd/Tests/Info.plist"; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ( + "-ObjC", + "$(AOSKIT_FRAMEWORK)", + "$(OTHER_LDFLAGS_CRASHREPORTER)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.KeychainAnalyticsTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; 6C98085F1E788AEB00E70590 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -31684,8 +33590,12 @@ "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=iphoneos*]" = ( "$(APPLE_AKS_LIBRARY)", @@ -31696,10 +33606,14 @@ "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-framework", CrashReporterSupport, + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.CKKSCloudKitTests; PRODUCT_NAME = CKKSCloudKitTests; @@ -31741,8 +33655,12 @@ "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=iphoneos*]" = ( "$(APPLE_AKS_LIBRARY)", @@ -31753,10 +33671,14 @@ "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-framework", CrashReporterSupport, + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.CKKSCloudKitTests; PRODUCT_NAME = CKKSCloudKitTests; @@ -31799,8 +33721,12 @@ "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=iphoneos*]" = ( "$(APPLE_AKS_LIBRARY)", @@ -31811,10 +33737,14 @@ "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-framework", CrashReporterSupport, + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.CKKSCloudKitTests; PRODUCT_NAME = CKKSCloudKitTests; @@ -31856,8 +33786,12 @@ "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=iphoneos*]" = ( "$(APPLE_AKS_LIBRARY)", @@ -31868,10 +33802,14 @@ "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-framework", CrashReporterSupport, + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.CKKSCloudKitTests; PRODUCT_NAME = CKKSCloudKitTests; @@ -31880,6 +33818,142 @@ }; name = Release; }; + 6C9AA7A31F7C1D9000D08296 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/supdctl/supdctl-Entitlements.plist"; + CODE_SIGN_STYLE = Automatic; + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INSTALL_PATH = /usr/local/bin; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6C9AA7A41F7C1D9000D08296 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/supdctl/supdctl-Entitlements.plist"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + ENABLE_NS_ASSERTIONS = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INSTALL_PATH = /usr/local/bin; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 6CAA8D251F842FB4007B6E03 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/supd/securityuploadd-Entitlements.plist"; + CODE_SIGN_STYLE = Automatic; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INSTALL_PATH = /usr/libexec; + "LAUNCHD_PLIST[sdk=iphoneos*]" = "$(SRCROOT)/supd/securityuploadd-ios.plist"; + "LAUNCHD_PLIST[sdk=iphonesimulator*]" = "$(SRCROOT)/supd/securityuploadd-ios.plist"; + "LAUNCHD_PLIST[sdk=macosx*]" = "$(SRCROOT)/supd/securityuploadd-osx.plist"; + "LAUNCHD_PLIST_LOCATION[sdk=iphoneos*]" = "$(DSTROOT)/System/Library/LaunchDaemons"; + "LAUNCHD_PLIST_LOCATION[sdk=iphonesimulator*]" = "$(DSTROOT)/System/Library/LaunchDaemons"; + "LAUNCHD_PLIST_LOCATION[sdk=macosx*]" = "$(DSTROOT)/System/Library/LaunchAgents"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ( + "$(AOSKIT_FRAMEWORK)", + "$(OTHER_LDFLAGS_CRASHREPORTER)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 6CAA8D261F842FB4007B6E03 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = "$(SRCROOT)/supd/securityuploadd-Entitlements.plist"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + ENABLE_NS_ASSERTIONS = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INSTALL_PATH = /usr/libexec; + "LAUNCHD_PLIST[sdk=iphoneos*]" = "$(SRCROOT)/supd/securityuploadd-ios.plist"; + "LAUNCHD_PLIST[sdk=iphonesimulator*]" = "$(SRCROOT)/supd/securityuploadd-ios.plist"; + "LAUNCHD_PLIST[sdk=macosx*]" = "$(SRCROOT)/supd/securityuploadd-osx.plist"; + "LAUNCHD_PLIST_LOCATION[sdk=iphoneos*]" = "$(DSTROOT)/System/Library/LaunchDaemons"; + "LAUNCHD_PLIST_LOCATION[sdk=iphonesimulator*]" = "$(DSTROOT)/System/Library/LaunchDaemons"; + "LAUNCHD_PLIST_LOCATION[sdk=macosx*]" = "$(DSTROOT)/System/Library/LaunchAgents"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ( + "$(AOSKIT_FRAMEWORK)", + "$(OTHER_LDFLAGS_CRASHREPORTER)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; 6CCDF7891E3C25FB003F2555 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -31903,10 +33977,8 @@ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INSTALL_PATH = /AppleInternal/CoreOS/tests/Security; LD_RUNPATH_SEARCH_PATHS = "/Developer/Library/Frameworks /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx.internal; }; name = Debug; }; @@ -31933,10 +34005,8 @@ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INSTALL_PATH = /AppleInternal/CoreOS/tests/Security; LD_RUNPATH_SEARCH_PATHS = "/Developer/Library/Frameworks /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx.internal; }; name = Release; }; @@ -31961,7 +34031,6 @@ INFOPLIST_FILE = KeychainEntitledTestApp_mac/Info.plist; INSTALL_PATH = /AppleInternal/CoreOS/tests/Security; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = YES; OTHER_CODE_SIGN_FLAGS = "--deep"; PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.KeychainEntitledTestApp-mac"; @@ -31990,7 +34059,6 @@ INFOPLIST_FILE = KeychainEntitledTestApp_mac/Info.plist; INSTALL_PATH = /AppleInternal/CoreOS/tests/Security; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; OTHER_CODE_SIGN_FLAGS = "--deep"; PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.KeychainEntitledTestApp-mac"; @@ -32054,76 +34122,6 @@ }; name = Release; }; - 728B56AC16D59979008FA3AB /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 22C002A31AC9D33100B3469E /* OTAPKIAssetTool.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_ENTITLEMENTS = "$(PROJECT_DIR)/OTAPKIAssetTool/OTAPKIAssetTool-entitlements.plist"; - CODE_SIGN_IDENTITY = "-"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - INSTALL_PATH = /usr/libexec; - ONLY_ACTIVE_ARCH = YES; - OTHER_LDFLAGS = ""; - "OTHER_LDFLAGS[sdk=embedded]" = ( - "-framework", - BackgroundTaskAgent, - ); - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos.internal; - "SKIP_INSTALL[sdk=embeddedsimulator*]" = YES; - }; - name = Debug; - }; - 728B56AD16D59979008FA3AB /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 22C002A31AC9D33100B3469E /* OTAPKIAssetTool.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_ENTITLEMENTS = "$(PROJECT_DIR)/OTAPKIAssetTool/OTAPKIAssetTool-entitlements.plist"; - CODE_SIGN_IDENTITY = "-"; - ENABLE_NS_ASSERTIONS = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; - INSTALL_PATH = /usr/libexec; - OTHER_LDFLAGS = ""; - "OTHER_LDFLAGS[sdk=embedded]" = ( - "-framework", - BackgroundTaskAgent, - ); - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos.internal; - "SKIP_INSTALL[sdk=embeddedsimulator*]" = YES; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; 7913B20D0D172B3900601FE9 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -32188,6 +34186,10 @@ INFOPLIST_FILE = "Security-Info.plist"; INSTALLHDRS_SCRIPT_PHASE = YES; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/usr/local/lib/security_libDER", + ); MODULEMAP_FILE = Modules/Security.iOS.modulemap; OTHER_LDFLAGS = ( "-laks", @@ -32195,9 +34197,11 @@ "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", ); "OTHER_LDFLAGS[sdk=*simulator*]" = "-Wl,-upward_framework,Foundation"; + OTHER_TAPI_FLAGS = "-I$(PROJECT_DIR)/header_symlinks/iOS/ -extra-private-header $(PROJECT_DIR)/OSX/sec/Security/ios_tapi_hacks.h $(OTHER_TAPI_FLAGS_SECURITY_FRAMEWORK) $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = "com.apple.${EXECUTABLE_NAME}"; PRODUCT_NAME = Security; STRIP_STYLE = debugging; + SUPPORTS_TEXT_BASED_API = YES; Sim_Name = ""; "Sim_Name[sdk=embeddedsimulator*][arch=*]" = _sim; }; @@ -32216,6 +34220,10 @@ INFOPLIST_FILE = "Security-Info.plist"; INSTALLHDRS_SCRIPT_PHASE = YES; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/usr/local/lib/security_libDER", + ); MODULEMAP_FILE = Modules/Security.iOS.modulemap; OTHER_LDFLAGS = ( "-laks", @@ -32223,9 +34231,11 @@ "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", ); "OTHER_LDFLAGS[sdk=*simulator*]" = "-Wl,-upward_framework,Foundation"; + OTHER_TAPI_FLAGS = "-I$(PROJECT_DIR)/header_symlinks/iOS/ -extra-private-header $(PROJECT_DIR)/OSX/sec/Security/ios_tapi_hacks.h $(OTHER_TAPI_FLAGS_SECURITY_FRAMEWORK) $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = "com.apple.${EXECUTABLE_NAME}"; PRODUCT_NAME = Security; STRIP_STYLE = debugging; + SUPPORTS_TEXT_BASED_API = YES; Sim_Name = ""; "Sim_Name[sdk=embeddedsimulator*][arch=*]" = _sim; }; @@ -32245,9 +34255,13 @@ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=embedded][arch=*]" = ( "-lsqlite3", @@ -32264,7 +34278,11 @@ "$(OTHER_LDFLAGS_CLOUDKIT)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_NAME = security; STRIP_STYLE = debugging; @@ -32292,9 +34310,13 @@ "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=embeddedsimulator*][arch=*]" = ( "-lsqlite3", @@ -32304,7 +34326,11 @@ "$(OTHER_LDFLAGS_CLOUDKIT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_NAME = security; STRIP_STYLE = debugging; @@ -32359,12 +34385,17 @@ GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; INSTALL_PATH = /usr/libexec; LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/local/lib"; + OTHER_CODE_SIGN_FLAGS = "$(OTHER_CODE_SIGN_FLAGS_LIBRARY_VALIDATION)"; OTHER_LDFLAGS = ( "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=embedded][arch=*]" = ( "$(OTHER_LDFLAGS)", @@ -32378,9 +34409,14 @@ "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "-framework", CrashReporterSupport, + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=iphonesimulator*]" = ( "$(inherited)", @@ -32414,12 +34450,17 @@ GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; INSTALL_PATH = /usr/libexec; LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/local/lib"; + OTHER_CODE_SIGN_FLAGS = "$(OTHER_CODE_SIGN_FLAGS_LIBRARY_VALIDATION)"; OTHER_LDFLAGS = ( "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=embedded][arch=*]" = ( "$(OTHER_LDFLAGS)", @@ -32434,8 +34475,13 @@ "$(OTHER_LDFLAGS_CLOUDKIT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_PREQUELITE)", "-framework", CrashReporterSupport, + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=iphonesimulator*]" = ( "$(inherited)", @@ -32533,8 +34579,10 @@ "SECURITY_FRAMEWORK_RESOURCES_DIR[sdk=macosx*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/A/Resources"; STRIP_INSTALLED_PRODUCT = NO; SUPPORTED_PLATFORMS = "iphonesimulator iphoneos watchos macosx appletvos appletvsimulator watchsimulator"; + SUPPORTS_TEXT_BASED_API = YES; Sim_Name = ""; "Sim_Name[sdk=embeddedsimulator*][arch=*]" = _sim; + TAPI_VERIFY_MODE = ErrorsAndWarnings; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -32564,7 +34612,7 @@ CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = YES; + COPY_PHASE_STRIP = NO; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -32604,8 +34652,10 @@ SECURITY_FRAMEWORK_RESOURCES_DIR = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/"; "SECURITY_FRAMEWORK_RESOURCES_DIR[sdk=macosx*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/A/Resources"; SUPPORTED_PLATFORMS = "iphonesimulator iphoneos watchos macosx appletvos appletvsimulator watchsimulator"; + SUPPORTS_TEXT_BASED_API = YES; Sim_Name = ""; "Sim_Name[sdk=embeddedsimulator*][arch=*]" = _sim; + TAPI_VERIFY_MODE = ErrorsAndWarnings; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; @@ -33005,7 +35055,10 @@ "$(inherited)", ); INSTALL_PATH = /usr/libexec; - LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/local/lib"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/usr/local/lib", + ); MTL_ENABLE_DEBUG_INFO = YES; OTHER_LDFLAGS = "$(OTHER_LDFLAGS_MOBILEASSET)"; "OTHER_LDFLAGS[sdk=embedded]" = ( @@ -33028,7 +35081,10 @@ "$(inherited)", ); INSTALL_PATH = /usr/libexec; - LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/local/lib"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/usr/local/lib", + ); MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = "$(OTHER_LDFLAGS_MOBILEASSET)"; "OTHER_LDFLAGS[sdk=embedded]" = ( @@ -33937,6 +35993,7 @@ MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + STRIP_INSTALLED_PRODUCT = NO; WARNING_CFLAGS = ( "$(inherited)", "-Wno-unused-function", @@ -33970,6 +36027,7 @@ MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + STRIP_INSTALLED_PRODUCT = NO; WARNING_CFLAGS = ( "$(inherited)", "-Wno-unused-function", @@ -34037,100 +36095,6 @@ }; name = Release; }; - DC17850B1D77873200B50D50 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = ""; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - FRAMEWORK_VERSION = A; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MTL_ENABLE_DEBUG_INFO = YES; - PRODUCT_NAME = Security; - SDKROOT = macosx.internal; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - DC17850C1D77873200B50D50 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = ""; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - FRAMEWORK_VERSION = A; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_NAME = Security; - SDKROOT = macosx.internal; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; DC17890E1D77980500B50D50 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = DC178BB11D77A5F500B50D50 /* security_framework_macos.xcconfig */; @@ -34160,6 +36124,9 @@ "-Wl,-upward_framework,Foundation", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", ); + SUPPORTS_TEXT_BASED_API = YES; + TAPI_VERIFY_MODE = ErrorsAndWarnings; + VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; }; @@ -34192,6 +36159,9 @@ "-Wl,-upward_framework,Foundation", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", ); + SUPPORTS_TEXT_BASED_API = YES; + TAPI_VERIFY_MODE = ErrorsAndWarnings; + VERSIONING_SYSTEM = "apple-generic"; }; name = Release; }; @@ -34291,9 +36261,12 @@ "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-ObjC", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=iphoneos*]" = ( "$(APPLE_AKS_LIBRARY)", @@ -34304,11 +36277,14 @@ "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-ObjC", "-framework", CrashReporterSupport, + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.CKKSTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -34351,9 +36327,12 @@ "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-ObjC", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=iphoneos*]" = ( "$(APPLE_AKS_LIBRARY)", @@ -34364,11 +36343,14 @@ "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-ObjC", "-framework", CrashReporterSupport, + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.CKKSTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -35096,42 +37078,6 @@ }; name = Release; }; - DC59E9EA1D91C9DC001BDDF5 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D47C56FB1DCA8F4900E18518 /* all_arches.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GENERATE_TEXT_BASED_STUBS = NO; - INLINE_PRIVATE_FRAMEWORKS = NO; - MTL_ENABLE_DEBUG_INFO = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_libDER/libDER; - SKIP_INSTALL = YES; - SUPPORTS_TEXT_BASED_API = NO; - }; - name = Debug; - }; - DC59E9EB1D91C9DC001BDDF5 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D47C56FB1DCA8F4900E18518 /* all_arches.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GENERATE_TEXT_BASED_STUBS = NO; - INLINE_PRIVATE_FRAMEWORKS = NO; - MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_NAME = "$(TARGET_NAME)"; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_libDER/libDER; - SKIP_INSTALL = YES; - SUPPORTS_TEXT_BASED_API = NO; - }; - name = Release; - }; DC5ABDCA1D832DAB00CF422C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -35380,14 +37326,11 @@ ); GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INSTALL_PATH = /usr/local/bin; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)/usr/lib/system", - ); OTHER_LDFLAGS = ( "$(APPLE_AKS_LIBRARY)", "-ObjC", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_IMCORE)", ); "OTHER_LDFLAGS[sdk=embedded]" = ( "-lACM", @@ -35414,14 +37357,11 @@ ); GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INSTALL_PATH = /usr/local/bin; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(SDKROOT)/usr/lib/system", - ); OTHER_LDFLAGS = ( "$(APPLE_AKS_LIBRARY)", "-ObjC", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_IMCORE)", ); "OTHER_LDFLAGS[sdk=embedded]" = ( "-lACM", @@ -36723,6 +38663,7 @@ GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; MTL_ENABLE_DEBUG_INFO = YES; + SUPPORTS_TEXT_BASED_API = NO; }; name = Debug; }; @@ -36746,6 +38687,7 @@ GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; MTL_ENABLE_DEBUG_INFO = NO; + SUPPORTS_TEXT_BASED_API = NO; }; name = Release; }; @@ -37277,6 +39219,9 @@ "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_NAME = security2; SUPPORTED_PLATFORMS = macosx; @@ -37293,6 +39238,9 @@ "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_NAME = security2; SUPPORTED_PLATFORMS = macosx; @@ -37310,10 +39258,6 @@ INFOPLIST_FILE = OSX/SecurityTestsOSX/Info.plist; INSTALL_PATH = /AppleInternal/CoreOS/tests/Security/; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SDKROOT)/usr/lib/system\"", - ); OTHER_LDFLAGS = ""; "OTHER_LDFLAGS[sdk=embedded]" = ( "$(inherited)", @@ -37341,10 +39285,6 @@ INFOPLIST_FILE = OSX/SecurityTestsOSX/Info.plist; INSTALL_PATH = /AppleInternal/CoreOS/tests/Security/; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SDKROOT)/usr/lib/system\"", - ); OTHER_LDFLAGS = ""; "OTHER_LDFLAGS[sdk=embedded]" = ( "$(inherited)", @@ -37463,10 +39403,12 @@ INFOPLIST_FILE = "OSX/sec/securityd/Info-macOS.plist"; INSTALL_PATH = /usr/libexec; MTL_ENABLE_DEBUG_INFO = YES; + OTHER_CODE_SIGN_FLAGS = "$(OTHER_CODE_SIGN_FLAGS_LIBRARY_VALIDATION)"; OTHER_LDFLAGS = ( "$(APPLE_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "-ObjC", + "$(OTHER_LDFLAGS_IMCORE)", ); PRODUCT_NAME = "$(TARGET_NAME)"; USE_HEADERMAP = NO; @@ -37517,10 +39459,12 @@ INFOPLIST_FILE = "OSX/sec/securityd/Info-macOS.plist"; INSTALL_PATH = /usr/libexec; MTL_ENABLE_DEBUG_INFO = NO; + OTHER_CODE_SIGN_FLAGS = "$(OTHER_CODE_SIGN_FLAGS_LIBRARY_VALIDATION)"; OTHER_LDFLAGS = ( "$(APPLE_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "-ObjC", + "$(OTHER_LDFLAGS_IMCORE)", ); PRODUCT_NAME = "$(TARGET_NAME)"; USE_HEADERMAP = NO; @@ -38214,16 +40158,16 @@ INFOPLIST_FILE = "SecurityTests/SecurityTests-Info.plist"; INSTALL_PATH = /AppleInternal/Applications; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SDKROOT)/usr/lib/system\"", - ); OTHER_LDFLAGS = ( "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=embedded]" = ( "$(inherited)", @@ -38238,10 +40182,14 @@ "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "-framework", CrashReporterSupport, + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.${PRODUCT_NAME:identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -38267,16 +40215,16 @@ INFOPLIST_FILE = "SecurityTests/SecurityTests-Info.plist"; INSTALL_PATH = /AppleInternal/Applications; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SDKROOT)/usr/lib/system\"", - ); OTHER_LDFLAGS = ( "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=embedded]" = ( "$(inherited)", @@ -38291,10 +40239,14 @@ "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "-framework", CrashReporterSupport, + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", ); PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.${PRODUCT_NAME:identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -38394,7 +40346,7 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/OSX/libsecurity_keychain/libDER", + "$(SDKROOT)/usr/local/include/security_libDER", "$(PROJECT_DIR)/OSX/libsecurity_asn1", "$(PROJECT_DIR)/libsecurity_smime", "$(PROJECT_DIR)/OSX/sec", @@ -38410,10 +40362,6 @@ ); INFOPLIST_FILE = "Keychain/Keychain-Info.plist"; INSTALL_PATH = /AppleInternal/Applications; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SDKROOT)/usr/lib/system\"", - ); ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = "$(inherited)"; "OTHER_LDFLAGS[sdk=embedded][arch=*]" = ( @@ -38443,7 +40391,7 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/OSX/libsecurity_keychain/libDER", + "$(SDKROOT)/usr/local/include/security_libDER", "$(PROJECT_DIR)/OSX/libsecurity_asn1", "$(PROJECT_DIR)/libsecurity_smime", "$(PROJECT_DIR)/OSX/sec", @@ -38459,10 +40407,6 @@ ); INFOPLIST_FILE = "Keychain/Keychain-Info.plist"; INSTALL_PATH = /AppleInternal/Applications; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SDKROOT)/usr/lib/system\"", - ); OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; OTHER_LDFLAGS = "$(inherited)"; "OTHER_LDFLAGS[sdk=embedded]" = ( @@ -38533,6 +40477,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.KeychainCircle.KeychainCircle; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_TEXT_BASED_API = YES; + TAPI_VERIFY_MODE = ErrorsOnly; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -38575,6 +40520,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.KeychainCircle.KeychainCircle; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_TEXT_BASED_API = YES; + TAPI_VERIFY_MODE = ErrorsOnly; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -38944,6 +40890,7 @@ MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx.internal; + SUPPORTS_TEXT_BASED_API = NO; }; name = Debug; }; @@ -38969,6 +40916,7 @@ MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx.internal; + SUPPORTS_TEXT_BASED_API = NO; }; name = Release; }; @@ -39492,6 +41440,104 @@ }; name = Release; }; + EB49B2B3202D8780003F34A0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = tests/secdmockaks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.Security.secdmockaks; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + EB49B2B4202D8780003F34A0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + ENABLE_NS_ASSERTIONS = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = tests/secdmockaks/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.Security.secdmockaks; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; EB6A6FAA1B90F83A0045DC68 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -40300,6 +42346,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 0C85E0001FB38BB6000343A7 /* Build configuration list for PBXNativeTarget "OTTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 0C85E0011FB38BB6000343A7 /* Debug */, + 0C85E0021FB38BB6000343A7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 0C8BBF051FCB446400580909 /* Build configuration list for PBXNativeTarget "otctl" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 0C8BBF061FCB446400580909 /* Debug */, + 0C8BBF071FCB446400580909 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 225394B11E3080A600D3CD9B /* Build configuration list for PBXNativeTarget "security_codesigning_ios" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -40327,6 +42391,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 4727FBC31F9918590003AE36 /* Build configuration list for PBXNativeTarget "secdxctests_ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4727FBBC1F9918590003AE36 /* Debug */, + 4727FBBD1F9918590003AE36 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 47702B221E5F409700B29577 /* Build configuration list for PBXNativeTarget "seckeychainnetworkextensionsystemdaemontest" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -40345,6 +42418,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 478D42991FD72A8100CAB645 /* Build configuration list for PBXNativeTarget "secdxctests_mac" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 478D429A1FD72A8100CAB645 /* Debug */, + 478D429B1FD72A8100CAB645 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 47C51B931EEA657D0032D9E5 /* Build configuration list for PBXNativeTarget "SecurityUnitTests" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -40480,6 +42562,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 6C4605B51F882B9B001421B6 /* Build configuration list for PBXNativeTarget "KeychainAnalyticsTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6C4605B61F882B9B001421B6 /* Debug */, + 6C4605B71F882B9B001421B6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 6C98085E1E788AEB00E70590 /* Build configuration list for PBXNativeTarget "CKKSCloudKitTests_mac" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -40498,6 +42589,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 6C9AA7A21F7C1D9000D08296 /* Build configuration list for PBXNativeTarget "supdctl" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6C9AA7A31F7C1D9000D08296 /* Debug */, + 6C9AA7A41F7C1D9000D08296 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6CAA8D241F842FB4007B6E03 /* Build configuration list for PBXNativeTarget "securityuploadd" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6CAA8D251F842FB4007B6E03 /* Debug */, + 6CAA8D261F842FB4007B6E03 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 6CCDF7881E3C25FB003F2555 /* Build configuration list for PBXNativeTarget "KeychainEntitledTestRunner" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -40525,15 +42634,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 728B56AB16D59979008FA3AB /* Build configuration list for PBXNativeTarget "OTAPKIAssetTool" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 728B56AC16D59979008FA3AB /* Debug */, - 728B56AD16D59979008FA3AB /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 790851C90CA985C10083CC4D /* Build configuration list for PBXNativeTarget "securityd_ios" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -40885,15 +42985,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - DC17850A1D77873200B50D50 /* Build configuration list for PBXNativeTarget "copyHeadersToSystem" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - DC17850B1D77873200B50D50 /* Debug */, - DC17850C1D77873200B50D50 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; DC17890D1D77980500B50D50 /* Build configuration list for PBXNativeTarget "Security_osx" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -41056,15 +43147,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - DC59E9E91D91C9DC001BDDF5 /* Build configuration list for PBXNativeTarget "DER_not_installed" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - DC59E9EA1D91C9DC001BDDF5 /* Debug */, - DC59E9EB1D91C9DC001BDDF5 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; DC5ABDC91D832DAB00CF422C /* Build configuration list for PBXNativeTarget "securitytool_macos" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -41776,6 +43858,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + EB49B2BA202D8780003F34A0 /* Build configuration list for PBXNativeTarget "secdmockaks" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EB49B2B3202D8780003F34A0 /* Debug */, + EB49B2B4202D8780003F34A0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; EB6A6FA91B90F83A0045DC68 /* Build configuration list for PBXAggregateTarget "phase1_ios" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Security.xcodeproj/xcshareddata/xcschemes/CKKSTests.xcscheme b/Security.xcodeproj/xcshareddata/xcschemes/CKKSTests.xcscheme index 5bfe9cf0..822094ed 100644 --- a/Security.xcodeproj/xcshareddata/xcschemes/CKKSTests.xcscheme +++ b/Security.xcodeproj/xcshareddata/xcschemes/CKKSTests.xcscheme @@ -5,12 +5,27 @@ + + + + + + @@ -56,6 +57,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/Security.xcodeproj/xcshareddata/xcschemes/ios - Debug.xcscheme b/Security.xcodeproj/xcshareddata/xcschemes/ios - Debug.xcscheme index f6881673..87b2f010 100644 --- a/Security.xcodeproj/xcshareddata/xcschemes/ios - Debug.xcscheme +++ b/Security.xcodeproj/xcshareddata/xcschemes/ios - Debug.xcscheme @@ -40,7 +40,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + + + - - @@ -292,14 +306,6 @@ argument = "si_29_sectrust_sha1_deprecation" isEnabled = "NO"> - - - - @@ -428,10 +434,6 @@ argument = "si_80_empty_data" isEnabled = "NO"> - - @@ -456,6 +458,10 @@ argument = "si_87_sectrust_name_constraints" isEnabled = "NO"> + + @@ -480,42 +486,6 @@ argument = "sc_25_soskeygen" isEnabled = "NO"> - - - - - - - - - - - - - - - - - - diff --git a/Security.xcodeproj/xcshareddata/xcschemes/ios - Release.xcscheme b/Security.xcodeproj/xcshareddata/xcschemes/ios - Release.xcscheme index 470baeb2..502d6def 100644 --- a/Security.xcodeproj/xcshareddata/xcschemes/ios - Release.xcscheme +++ b/Security.xcodeproj/xcshareddata/xcschemes/ios - Release.xcscheme @@ -40,6 +40,7 @@ buildConfiguration = "Release" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" shouldUseLaunchSchemeArgsEnv = "YES"> + + diff --git a/Security.xcodeproj/xcshareddata/xcschemes/ios - secdtests.xcscheme b/Security.xcodeproj/xcshareddata/xcschemes/ios - secdtests.xcscheme index cea3092e..92c639d2 100644 --- a/Security.xcodeproj/xcshareddata/xcschemes/ios - secdtests.xcscheme +++ b/Security.xcodeproj/xcshareddata/xcschemes/ios - secdtests.xcscheme @@ -26,9 +26,18 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + @@ -191,7 +203,7 @@ + isEnabled = "NO"> + + @@ -336,30 +352,10 @@ - - - - - - - - + + + + + + + + + + + + + + diff --git a/Security.xcodeproj/xcshareddata/xcschemes/osx - sectests.xcscheme b/Security.xcodeproj/xcshareddata/xcschemes/osx - sectests.xcscheme index fc4ced8e..0dbd5337 100644 --- a/Security.xcodeproj/xcshareddata/xcschemes/osx - sectests.xcscheme +++ b/Security.xcodeproj/xcshareddata/xcschemes/osx - sectests.xcscheme @@ -40,6 +40,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" shouldUseLaunchSchemeArgsEnv = "YES"> @@ -59,6 +60,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/Security/Security.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Security/Security.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..94b2795e --- /dev/null +++ b/Security/Security.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,4 @@ + + + diff --git a/SecurityTests/SecurityTests-Entitlements.plist b/SecurityTests/SecurityTests-Entitlements.plist index eec208ed..dc5def77 100644 --- a/SecurityTests/SecurityTests-Entitlements.plist +++ b/SecurityTests/SecurityTests-Entitlements.plist @@ -28,6 +28,8 @@ com.apple.security.regressions com.apple.private.uninstall.deletion + com.apple.private.security.delete.all + keychain-access-groups com.apple.security.regressions @@ -38,12 +40,6 @@ 123456.test.group2 com.apple.bluetooth - com.apple.private.ubiquity-kvstore-access - - com.apple.securityd - - com.apple.developer.ubiquity-kvstore-identifier - com.apple.security.cloudkeychainproxy3 com.apple.developer.shared-web-credentials localhost diff --git a/SecurityTests/si-87-sectrust-name-constraints/TestCertificates b/SecurityTests/si-87-sectrust-name-constraints/TestCertificates new file mode 100644 index 00000000..8a2fbfa5 Binary files /dev/null and b/SecurityTests/si-87-sectrust-name-constraints/TestCertificates differ diff --git a/SecurityTests/si-87-sectrust-name-constraints/expects.plist b/SecurityTests/si-87-sectrust-name-constraints/expects.plist new file mode 100644 index 00000000..e0cee796 --- /dev/null +++ b/SecurityTests/si-87-sectrust-name-constraints/expects.plist @@ -0,0 +1,92437 @@ + + + + + expects + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 4 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 5 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 6 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 7 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 8 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 9 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 10 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 11 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 12 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 13 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 14 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 15 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 16 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 17 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 18 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 19 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 20 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 21 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 22 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 23 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 24 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 25 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 26 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 27 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 28 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 29 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 30 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 31 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 32 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 33 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 34 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 35 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 36 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 37 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 38 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 39 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 40 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 41 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 42 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 43 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 44 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 45 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 46 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 47 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 48 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 49 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 50 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 51 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 52 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 53 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 54 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 55 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 56 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 57 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 58 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 59 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 60 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 61 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 62 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 63 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 64 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 65 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 66 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 67 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 68 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 69 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 70 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 71 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 72 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 73 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 74 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 75 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 76 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 77 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 78 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 79 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 80 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 81 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 82 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 83 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 84 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 85 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 86 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 87 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 88 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 89 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 90 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 91 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 92 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 93 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 94 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 95 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 96 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 97 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 98 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 99 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 100 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 101 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 102 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 103 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 104 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 105 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 106 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 107 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 108 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 109 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 110 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 111 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 112 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 113 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 114 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 115 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 116 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 117 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 118 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 119 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 120 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 121 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 122 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 123 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 124 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 125 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 126 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 127 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 128 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 129 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 130 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 131 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 132 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 133 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 134 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 135 + ip + + descriptions + + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 136 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 137 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 138 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 139 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 140 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 141 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 142 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 143 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 144 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 145 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 146 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 147 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 148 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 149 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 150 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 151 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 152 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 153 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 154 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 155 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 156 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 157 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 158 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 159 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 160 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 161 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 162 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 163 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 164 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 165 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 166 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 167 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 168 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 169 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 170 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 171 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 172 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 173 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 174 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 175 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 176 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 177 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 178 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 179 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 180 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 181 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 182 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 183 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 184 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 185 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 186 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 187 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 188 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 189 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 190 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 191 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 192 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 193 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 194 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 195 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 196 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 197 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 198 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 199 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 200 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 201 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 202 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 203 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 204 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 205 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 206 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 207 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 208 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 209 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 210 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 211 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 212 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 213 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 214 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 215 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 216 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 217 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 218 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 219 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 220 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 221 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 222 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 223 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 224 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 225 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 226 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 227 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 228 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 229 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 230 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 231 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 232 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 233 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 234 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 235 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 236 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 237 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 238 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 239 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 240 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 241 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 242 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 243 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 244 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 245 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 246 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 247 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 248 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 249 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 250 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 251 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 252 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 253 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 254 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 255 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 256 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 257 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 258 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 259 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 260 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 261 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 262 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 263 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 264 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 265 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 266 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 267 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 268 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 269 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 270 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 271 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 272 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 273 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 274 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 275 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 276 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 277 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 278 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 279 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 280 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 281 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 282 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 283 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 284 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 285 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 286 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 287 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 288 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 289 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 290 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 291 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 292 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 293 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 294 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 295 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 296 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 297 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 298 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 299 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 300 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 301 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 302 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 303 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 304 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 305 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 306 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 307 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 308 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 309 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 310 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 311 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 312 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 313 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 314 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 315 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 316 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 317 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 318 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 319 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 320 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 321 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 322 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 323 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 324 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 325 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 326 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 327 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 328 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 329 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 330 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 331 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 332 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 333 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 334 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 335 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 336 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 337 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 338 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 339 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 340 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 341 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 342 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 343 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 344 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 345 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 346 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 347 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 348 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 349 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 350 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 351 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 352 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 353 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 354 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 355 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 356 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 357 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 358 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 359 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 360 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 361 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 362 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 363 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 364 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 365 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 366 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 367 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 368 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 369 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 370 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 371 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 372 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 373 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 374 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 375 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 376 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 377 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 378 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 379 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 380 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 381 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 382 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 383 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 384 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 385 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 386 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 387 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 388 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 389 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 390 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 391 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 392 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 393 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 394 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 395 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 396 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 397 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 398 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 399 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 400 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 401 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 402 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 403 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 404 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 405 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 406 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 407 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 408 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 409 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 410 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 411 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 412 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 413 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 414 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 415 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 416 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 417 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 418 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 419 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 420 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 421 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 422 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 423 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 424 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 425 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 426 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 427 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 428 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 429 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 430 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 431 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 432 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 433 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 434 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 435 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 436 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 437 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 438 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 439 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 440 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 441 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 442 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 443 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 444 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 445 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 446 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 447 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 448 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 449 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 450 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 451 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 452 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 453 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 454 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 455 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 456 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 457 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 458 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 459 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 460 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 461 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 462 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 463 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 464 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 465 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 466 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 467 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 468 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 469 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 470 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 471 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 472 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 473 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 474 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 475 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 476 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 477 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 478 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 479 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 480 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 481 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 482 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 483 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 484 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 485 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 486 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 487 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 488 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 489 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 490 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 491 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 492 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 493 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 494 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 495 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 496 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 497 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 498 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 499 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 500 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 501 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 502 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 503 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 504 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 505 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 506 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 507 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 508 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 509 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 510 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 511 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 512 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 513 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 514 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 515 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 516 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 517 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 518 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 519 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 520 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 521 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 522 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 523 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 524 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 525 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 526 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 527 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 528 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 529 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 530 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 531 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 532 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 533 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 534 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 535 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 536 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 537 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 538 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 539 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 540 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 541 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 542 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 543 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 544 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 545 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 546 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 547 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 548 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 549 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 550 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 551 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 552 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 553 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 554 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 555 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 556 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 557 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 558 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 559 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 560 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 561 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 562 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 563 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 564 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 565 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 566 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 567 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 568 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 569 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 570 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 571 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 572 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 573 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 574 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 575 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 576 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 577 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 578 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 579 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 580 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 581 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 582 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 583 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 584 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 585 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 586 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 587 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 588 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 589 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 590 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 591 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 592 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 593 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 594 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 595 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 596 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 597 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 598 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 599 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 600 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 601 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 602 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 603 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 604 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 605 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 606 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 607 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 608 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 609 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 610 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 611 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 612 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 613 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 614 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 615 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 616 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 617 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 618 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 619 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 620 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 621 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 622 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 623 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 624 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 625 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 626 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 627 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 628 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 629 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 630 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 631 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 632 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 633 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 634 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 635 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 636 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 637 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 638 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 639 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 640 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 641 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 642 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 643 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 644 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 645 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 646 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 647 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 648 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 649 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 650 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 651 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 652 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 653 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 654 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 655 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 656 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 657 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 658 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 659 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 660 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 661 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 662 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 663 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 664 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 665 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 666 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 667 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 668 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 669 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 670 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 671 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 672 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 673 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 674 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 675 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 676 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 677 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 678 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 679 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 680 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 681 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 682 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 683 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 684 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 685 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 686 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 687 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 688 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 689 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 690 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 691 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 692 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 693 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 694 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 695 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 696 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 697 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 698 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 699 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 700 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 701 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 702 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 703 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 704 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 705 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 706 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 707 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 708 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 709 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 710 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 711 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 712 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 713 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 714 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 715 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 716 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 717 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 718 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 719 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 720 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 721 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 722 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 723 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 724 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 725 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 726 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 727 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 728 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 729 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + + expect + WEAK-OK + + id + 730 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 731 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + + expect + WEAK-OK + + id + 732 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + + expect + WEAK-OK + + id + 733 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 734 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + + expect + WEAK-OK + + id + 735 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + + expect + WEAK-OK + + id + 736 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 737 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + + expect + WEAK-OK + + id + 738 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + + expect + WEAK-OK + + id + 739 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 740 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + + expect + WEAK-OK + + id + 741 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + + expect + WEAK-OK + + id + 742 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 743 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + + expect + WEAK-OK + + id + 744 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + + expect + WEAK-OK + + id + 745 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 746 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + + expect + WEAK-OK + + id + 747 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 748 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 749 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 750 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 751 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 752 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 753 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 754 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 755 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 756 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 757 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 758 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 759 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 760 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 761 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 762 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 763 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 764 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 765 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 766 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 767 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 768 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 769 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 770 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 771 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 772 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 773 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 774 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 775 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 776 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 777 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 778 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 779 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 780 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 781 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 782 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 783 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 784 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 785 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 786 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 787 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 788 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 789 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 790 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 791 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 792 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 793 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 794 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 795 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 796 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 797 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 798 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 799 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 800 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 801 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 802 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 803 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 804 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 805 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 806 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 807 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 808 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 809 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 810 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 811 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 812 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 813 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 814 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 815 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 816 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 817 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 818 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 819 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 820 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 821 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 822 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 823 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 824 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 825 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 826 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 827 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 828 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 829 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 830 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 831 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 832 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 833 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 834 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 835 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 836 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 837 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 838 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 839 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 840 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 841 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 842 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 843 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 844 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 845 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 846 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 847 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 848 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 849 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 850 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 851 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 852 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 853 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 854 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 855 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 856 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 857 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 858 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 859 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 860 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 861 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 862 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 863 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 864 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 865 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 866 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 867 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 868 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 869 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 870 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 871 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 872 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 873 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 874 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 875 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 876 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 877 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 878 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 879 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 880 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 881 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 882 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 883 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 884 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 885 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 886 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 887 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 888 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 889 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 890 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 891 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 892 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 893 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 894 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 895 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 896 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 897 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 898 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 899 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 900 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 901 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 902 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 903 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 904 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 905 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 906 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 907 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 908 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 909 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 910 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 911 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 912 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 913 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 914 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 915 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 916 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 917 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 918 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 919 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 920 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 921 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 922 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 923 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 924 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 925 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 926 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 927 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 928 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 929 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 930 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 931 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 932 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 933 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 934 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 935 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 936 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 937 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 938 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 939 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 940 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 941 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 942 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 943 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 944 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 945 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 946 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 947 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 948 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 949 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 950 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 951 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 952 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 953 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 954 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 955 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 956 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 957 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 958 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 959 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 960 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 961 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 962 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 963 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 964 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 965 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 966 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 967 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 968 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 969 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 970 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 971 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 972 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 973 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 974 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 975 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 976 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 977 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 978 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 979 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 980 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 981 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 982 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 983 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 984 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 985 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 986 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 987 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 988 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 989 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 990 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 991 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 992 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 993 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 994 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 995 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 996 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 997 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 998 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 999 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1000 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1001 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1002 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1003 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1004 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1005 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1006 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1007 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1008 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1009 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1010 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1011 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1012 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1013 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1014 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1015 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1016 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1017 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1018 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1019 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1020 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1021 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1022 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1023 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1024 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1025 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1026 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1027 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1028 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1029 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1030 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1031 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1032 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1033 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1034 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1035 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1036 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1037 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1038 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1039 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1040 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1041 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1042 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1043 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1044 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1045 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1046 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1047 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1048 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1049 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1050 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1051 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1052 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1053 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1054 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1055 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1056 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1057 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1058 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1059 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1060 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1061 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1062 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1063 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1064 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1065 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1066 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1067 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1068 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1069 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1070 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1071 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1072 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1073 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1074 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1075 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1076 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1077 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1078 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1079 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1080 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1081 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1082 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1083 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1084 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1085 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1086 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1087 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1088 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1089 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1090 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1091 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1092 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1093 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1094 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1095 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1096 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1097 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1098 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1099 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1100 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1101 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1102 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1103 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1104 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1105 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1106 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1107 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1108 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1109 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1110 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1111 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1112 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1113 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1114 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1115 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1116 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1117 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1118 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1119 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1120 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1121 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1122 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1123 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1124 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1125 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1126 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1127 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1128 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1129 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1130 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1131 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1132 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1133 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1134 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1135 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1136 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1137 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1138 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1139 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1140 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1141 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1142 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1143 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1144 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1145 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1146 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1147 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1148 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1149 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1150 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1151 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1152 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1153 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1154 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1155 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1156 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1157 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1158 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1159 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1160 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1161 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1162 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1163 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1164 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1165 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1166 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1167 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1168 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1169 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1170 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1171 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1172 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1173 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1174 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1175 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1176 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1177 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1178 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1179 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1180 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1181 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1182 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1183 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1184 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1185 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1186 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1187 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1188 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1189 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1190 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1191 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1192 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1193 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1194 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1195 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1196 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1197 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1198 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1199 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1200 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1201 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1202 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1203 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1204 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1205 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1206 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1207 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1208 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1209 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1210 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1211 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1212 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1213 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1214 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1215 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1216 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1217 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1218 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1219 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1220 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1221 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1222 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1223 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1224 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1225 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1226 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1227 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1228 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1229 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1230 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1231 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1232 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1233 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1234 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1235 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1236 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1237 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1238 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1239 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1240 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1241 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1242 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1243 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1244 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1245 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1246 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1247 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1248 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1249 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1250 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1251 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1252 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1253 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1254 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1255 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1256 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1257 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1258 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1259 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1260 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1261 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1262 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1263 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1264 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1265 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1266 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1267 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1268 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1269 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1270 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1271 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1272 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1273 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1274 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1275 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1276 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1277 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 1278 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1279 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1280 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1281 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1282 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1283 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1284 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1285 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1286 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1287 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1288 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1289 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1290 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1291 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1292 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1293 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1294 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1295 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1296 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1297 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1298 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1299 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1300 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1301 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1302 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1303 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1304 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1305 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1306 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1307 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1308 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1309 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1310 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1311 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1312 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1313 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1314 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1315 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1316 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1317 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1318 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1319 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1320 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1321 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1322 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1323 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1324 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1325 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1326 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1327 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1328 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1329 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1330 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1331 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1332 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1333 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1334 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1335 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1336 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1337 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1338 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1339 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1340 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1341 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1342 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1343 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1344 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1345 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1346 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1347 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1348 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1349 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1350 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1351 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1352 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1353 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1354 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1355 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1356 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1357 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1358 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1359 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1360 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1361 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1362 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1363 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1364 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1365 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1366 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1367 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1368 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1369 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1370 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1371 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1372 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1373 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1374 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1375 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1376 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1377 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1378 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1379 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1380 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1381 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1382 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1383 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1384 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1385 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1386 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1387 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1388 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1389 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1390 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1391 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1392 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1393 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1394 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1395 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1396 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1397 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1398 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1399 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1400 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1401 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1402 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1403 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1404 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1405 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1406 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1407 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1408 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1409 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1410 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1411 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1412 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1413 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1414 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1415 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1416 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1417 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1418 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1419 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1420 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1421 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1422 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1423 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1424 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1425 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1426 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1427 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1428 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1429 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1430 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1431 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1432 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1433 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1434 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1435 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1436 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1437 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1438 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1439 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The DNS name for this certificate only exists in the common name. Some browsers (such as Chrome) have deprecated using the CN entirely and only use names from SAN extensions. + The DNS name for this certificate exists in the common name but not in the Subject Alternate Names extension even though the extension is specified. Most implementations will fail DNS-hostname validation on this certificate. + + expect + WEAK-OK + + id + 1440 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1441 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1442 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1443 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1444 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1445 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1446 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1447 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1448 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1449 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1450 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1451 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1452 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1453 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1454 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1455 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1456 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1457 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1458 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1459 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1460 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1461 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1462 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1463 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1464 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1465 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1466 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1467 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1468 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1469 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1470 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1471 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1472 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1473 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1474 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1475 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1476 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1477 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1478 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1479 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1480 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1481 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1482 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1483 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1484 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1485 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1486 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1487 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1488 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1489 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1490 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1491 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1492 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1493 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1494 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1495 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1496 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1497 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1498 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1499 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1500 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1501 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1502 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1503 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1504 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1505 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1506 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1507 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1508 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1509 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1510 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1511 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1512 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1513 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1514 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1515 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1516 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1517 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1518 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1519 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1520 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1521 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1522 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1523 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1524 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1525 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1526 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1527 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1528 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1529 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1530 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1531 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1532 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1533 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1534 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1535 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1536 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1537 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1538 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1539 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1540 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1541 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1542 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1543 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1544 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1545 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1546 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1547 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1548 + ip + + descriptions + + expect + OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1549 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1550 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1551 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1552 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1553 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1554 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1555 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1556 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1557 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1558 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1559 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1560 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1561 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1562 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1563 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1564 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1565 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1566 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1567 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1568 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1569 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1570 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1571 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1572 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1573 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1574 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1575 + ip + + descriptions + + expect + OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1576 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1577 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1578 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1579 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1580 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1581 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1582 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1583 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1584 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1585 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1586 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1587 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1588 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1589 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1590 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1591 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1592 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1593 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1594 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1595 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1596 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1597 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1598 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1599 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1600 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1601 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1602 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1603 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1604 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1605 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1606 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1607 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1608 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1609 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1610 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1611 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1612 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1613 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1614 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1615 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1616 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1617 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1618 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1619 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1620 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1621 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1622 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1623 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1624 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1625 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1626 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1627 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1628 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1629 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1630 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1631 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1632 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1633 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1634 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1635 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1636 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1637 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1638 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1639 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1640 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1641 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1642 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1643 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1644 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1645 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1646 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1647 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1648 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1649 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1650 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1651 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1652 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1653 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1654 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1655 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1656 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1657 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1658 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1659 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1660 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1661 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1662 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1663 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1664 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1665 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1666 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1667 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1668 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1669 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1670 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1671 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1672 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1673 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1674 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1675 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1676 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1677 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1678 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1679 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1680 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1681 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1682 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1683 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1684 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1685 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1686 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1687 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1688 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1689 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1690 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1691 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1692 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1693 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1694 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1695 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1696 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1697 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1698 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1699 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1700 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1701 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1702 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1703 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1704 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1705 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1706 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1707 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1708 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1709 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1710 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1711 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1712 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1713 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1714 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1715 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1716 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1717 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1718 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1719 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1720 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1721 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1722 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1723 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1724 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1725 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1726 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1727 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1728 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1729 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1730 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1731 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1732 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1733 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1734 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1735 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1736 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1737 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1738 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1739 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1740 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1741 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1742 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1743 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1744 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1745 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1746 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1747 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1748 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1749 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1750 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1751 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1752 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1753 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1754 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1755 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1756 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1757 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1758 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1759 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1760 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1761 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1762 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1763 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1764 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1765 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1766 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1767 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1768 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1769 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1770 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1771 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1772 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1773 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1774 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1775 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1776 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1777 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1778 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1779 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1780 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1781 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1782 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1783 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1784 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1785 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1786 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1787 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1788 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1789 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1790 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1791 + ip + + descriptions + + expect + OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1792 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1793 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1794 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1795 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1796 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1797 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1798 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1799 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1800 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1801 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1802 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1803 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1804 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1805 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1806 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1807 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1808 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1809 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1810 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1811 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1812 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1813 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1814 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1815 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1816 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1817 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1818 + ip + + descriptions + + expect + OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1819 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1820 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1821 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1822 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1823 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1824 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1825 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1826 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1827 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1828 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1829 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1830 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1831 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1832 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1833 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1834 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1835 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1836 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1837 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1838 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1839 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1840 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1841 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1842 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1843 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1844 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1845 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1846 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1847 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1848 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1849 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1850 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1851 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1852 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1853 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1854 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1855 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1856 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1857 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1858 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1859 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1860 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1861 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1862 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1863 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1864 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1865 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1866 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1867 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1868 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1869 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1870 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1871 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 1872 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1873 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1874 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1875 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1876 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1877 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1878 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1879 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1880 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 1881 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1882 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1883 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1884 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1885 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1886 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1887 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1888 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1889 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1890 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1891 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1892 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1893 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1894 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1895 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1896 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1897 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1898 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1899 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1900 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1901 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1902 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1903 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1904 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1905 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1906 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1907 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1908 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1909 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1910 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1911 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1912 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1913 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1914 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1915 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1916 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1917 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1918 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1919 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1920 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1921 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1922 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1923 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1924 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1925 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1926 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1927 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1928 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1929 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1930 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1931 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1932 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1933 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1934 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 1935 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1936 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1937 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1938 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1939 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1940 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1941 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1942 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1943 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 1944 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1945 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1946 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1947 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1948 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1949 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1950 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1951 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1952 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1953 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1954 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1955 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1956 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1957 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1958 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1959 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1960 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1961 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1962 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1963 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1964 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1965 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1966 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1967 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1968 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1969 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1970 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1971 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1972 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1973 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1974 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1975 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1976 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1977 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1978 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1979 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1980 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1981 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1982 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1983 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1984 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1985 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1986 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1987 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1988 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1989 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1990 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1991 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1992 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1993 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1994 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1995 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1996 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1997 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1998 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 1999 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2000 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2001 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2002 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2003 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2004 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2005 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2006 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2007 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2008 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2009 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2010 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2011 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2012 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2013 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2014 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2015 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2016 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2017 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2018 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2019 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2020 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2021 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2022 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2023 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2024 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2025 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2026 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2027 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2028 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2029 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2030 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2031 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2032 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2033 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2034 + ip + + descriptions + + expect + OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2035 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2036 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2037 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2038 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2039 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2040 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2041 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2042 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2043 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2044 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2045 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2046 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2047 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2048 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2049 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2050 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2051 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2052 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2053 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2054 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2055 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2056 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2057 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2058 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2059 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2060 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2061 + ip + + descriptions + + expect + OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2062 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2063 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2064 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2065 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2066 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2067 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2068 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2069 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2070 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2071 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2072 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2073 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2074 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2075 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2076 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2077 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2078 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2079 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2080 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2081 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2082 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2083 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2084 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2085 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2086 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2087 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2088 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2089 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2090 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2091 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2092 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2093 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2094 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2095 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2096 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2097 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2098 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2099 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2100 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2101 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2102 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2103 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2104 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2105 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2106 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2107 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2108 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2109 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2110 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2111 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2112 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2113 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2114 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2115 + ip + + descriptions + + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2116 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2117 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2118 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2119 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2120 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2121 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2122 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2123 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2124 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2125 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2126 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2127 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2128 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2129 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2130 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2131 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2132 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2133 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + The IP is only contained in the CN of this certificate, which isn't permitted by RFC but which many implementations support. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2134 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2135 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2136 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2137 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2138 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2139 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2140 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2141 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2142 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2143 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2144 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2145 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2146 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2147 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2148 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2149 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2150 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2151 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2152 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2153 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2154 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2155 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2156 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2157 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2158 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2159 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2160 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2161 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2162 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2163 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2164 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2165 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2166 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2167 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2168 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2169 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2170 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2171 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2172 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2173 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2174 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2175 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2176 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2177 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2178 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2179 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2180 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2181 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2182 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2183 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2184 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2185 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2186 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2187 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2188 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2189 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2190 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2191 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2192 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2193 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2194 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2195 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2196 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2197 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2198 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2199 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2200 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2201 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2202 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2203 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2204 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2205 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2206 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2207 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2208 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2209 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2210 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2211 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2212 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2213 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2214 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2215 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2216 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2217 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2218 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2219 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2220 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2221 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2222 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2223 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2224 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2225 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2226 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2227 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2228 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2229 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2230 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2231 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2232 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2233 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2234 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2235 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2236 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2237 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2238 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2239 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2240 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2241 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2242 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2243 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2244 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2245 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2246 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2247 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2248 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2249 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2250 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2251 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2252 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2253 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2254 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2255 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2256 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2257 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2258 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2259 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2260 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2261 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2262 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2263 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2264 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2265 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2266 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2267 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2268 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2269 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2270 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2271 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2272 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2273 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2274 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2275 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2276 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2277 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2278 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2279 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2280 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2281 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2282 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2283 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2284 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2285 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2286 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2287 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2288 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2289 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2290 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2291 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2292 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2293 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2294 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2295 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2296 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2297 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2298 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2299 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2300 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2301 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2302 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2303 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2304 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2305 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2306 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2307 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2308 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2309 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2310 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2311 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2312 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2313 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2314 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2315 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2316 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2317 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2318 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2319 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2320 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2321 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2322 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2323 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2324 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2325 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2326 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2327 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2328 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2329 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2330 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2331 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2332 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2333 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2334 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2335 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2336 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2337 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2338 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2339 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2340 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2341 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2342 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2343 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2344 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2345 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2346 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2347 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2348 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2349 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2350 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2351 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2352 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2353 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2354 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2355 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2356 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2357 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2358 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2359 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2360 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2361 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2362 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2363 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2364 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2365 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2366 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2367 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2368 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2369 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2370 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2371 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2372 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2373 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2374 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2375 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2376 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2377 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2378 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2379 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2380 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2381 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2382 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2383 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2384 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2385 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2386 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2387 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2388 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2389 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2390 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2391 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2392 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2393 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2394 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2395 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2396 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2397 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2398 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2399 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2400 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2401 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2402 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2403 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2404 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2405 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2406 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2407 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2408 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2409 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2410 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2411 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2412 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2413 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2414 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2415 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2416 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2417 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2418 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2419 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2420 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2421 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2422 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2423 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2424 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2425 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2426 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2427 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2428 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2429 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2430 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2431 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2432 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2433 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2434 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2435 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2436 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2437 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2438 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2439 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2440 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2441 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2442 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2443 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2444 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2445 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2446 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2447 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2448 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2449 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2450 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2451 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2452 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2453 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2454 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2455 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2456 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2457 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2458 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2459 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2460 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2461 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2462 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2463 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2464 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2465 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2466 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2467 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2468 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2469 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2470 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2471 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2472 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2473 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2474 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2475 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2476 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2477 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2478 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2479 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2480 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2481 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2482 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2483 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2484 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2485 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2486 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2487 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2488 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2489 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2490 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2491 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2492 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2493 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2494 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2495 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2496 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2497 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2498 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2499 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2500 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2501 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + There is a IP name constraint but no IP in the certificate. This isn't an explicit violation, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + id + 2502 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2503 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2504 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2505 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2506 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2507 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2508 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2509 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2510 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2511 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2512 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2513 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2514 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2515 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2516 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2517 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2518 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2519 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2520 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2521 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2522 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2523 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2524 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2525 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2526 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2527 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2528 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2529 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2530 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2531 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2532 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2533 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2534 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2535 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2536 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2537 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2538 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2539 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2540 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2541 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2542 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2543 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2544 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2545 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2546 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2547 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2548 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2549 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2550 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2551 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2552 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2553 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2554 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2555 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2556 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2557 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2558 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2559 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2560 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2561 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2562 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2563 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2564 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2565 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2566 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2567 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2568 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2569 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2570 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2571 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2572 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2573 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2574 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2575 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2576 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2577 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2578 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2579 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2580 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2581 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2582 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2583 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2584 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2585 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2586 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2587 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2588 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2589 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2590 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2591 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2592 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2593 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2594 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2595 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2596 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2597 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2598 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2599 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2600 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 2601 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2602 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2603 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2604 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2605 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2606 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2607 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2608 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2609 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + expect + WEAK-OK + + id + 2610 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2611 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2612 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2613 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2614 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2615 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2616 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2617 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2618 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2619 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2620 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2621 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2622 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2623 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2624 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2625 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2626 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2627 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2628 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2629 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2630 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2631 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2632 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2633 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2634 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2635 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2636 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2637 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2638 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2639 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2640 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2641 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2642 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2643 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2644 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2645 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2646 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2647 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2648 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2649 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2650 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2651 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2652 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2653 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2654 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2655 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2656 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2657 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2658 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2659 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2660 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2661 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2662 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2663 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 2664 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2665 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2666 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2667 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2668 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2669 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2670 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2671 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2672 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 2673 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2674 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2675 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2676 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2677 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2678 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2679 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2680 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2681 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2682 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2683 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2684 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2685 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2686 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2687 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2688 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2689 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2690 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2691 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2692 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2693 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2694 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2695 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2696 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2697 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2698 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2699 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2700 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2701 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2702 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2703 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2704 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2705 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2706 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2707 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2708 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2709 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2710 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2711 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2712 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2713 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2714 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2715 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2716 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2717 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2718 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2719 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2720 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2721 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2722 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2723 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2724 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2725 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2726 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2727 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2728 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2729 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2730 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2731 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2732 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2733 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2734 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2735 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2736 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2737 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2738 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2739 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2740 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2741 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2742 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2743 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2744 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2745 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2746 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2747 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2748 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2749 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2750 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2751 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2752 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2753 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2754 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2755 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2756 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2757 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2758 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2759 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2760 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2761 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2762 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2763 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2764 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2765 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2766 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2767 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2768 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2769 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2770 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2771 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2772 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2773 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2774 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2775 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2776 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2777 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2778 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2779 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2780 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2781 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2782 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2783 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2784 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2785 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2786 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2787 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2788 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2789 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2790 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2791 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2792 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2793 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2794 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2795 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2796 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2797 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2798 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2799 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2800 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2801 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2802 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2803 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2804 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2805 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2806 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2807 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2808 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2809 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2810 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2811 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2812 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2813 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2814 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2815 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2816 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2817 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2818 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2819 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2820 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2821 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2822 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2823 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2824 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2825 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2826 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2827 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2828 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2829 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2830 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2831 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2832 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2833 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2834 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2835 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2836 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2837 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2838 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2839 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2840 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2841 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2842 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2843 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2844 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2845 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2846 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2847 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2848 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2849 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2850 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2851 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2852 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2853 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2854 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2855 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2856 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2857 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2858 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2859 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2860 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2861 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2862 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2863 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2864 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2865 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2866 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2867 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2868 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2869 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2870 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2871 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2872 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2873 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2874 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2875 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2876 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2877 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2878 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2879 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2880 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2881 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2882 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2883 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2884 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2885 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2886 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2887 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2888 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2889 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2890 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2891 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2892 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2893 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2894 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2895 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2896 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2897 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2898 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2899 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2900 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2901 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2902 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2903 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2904 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2905 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2906 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2907 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2908 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2909 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2910 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2911 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2912 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2913 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2914 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2915 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2916 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2917 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2918 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2919 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2920 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2921 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2922 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2923 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2924 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2925 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2926 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2927 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2928 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2929 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2930 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2931 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2932 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2933 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2934 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2935 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2936 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2937 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2938 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2939 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2940 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2941 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2942 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2943 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2944 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2945 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2946 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2947 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2948 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2949 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2950 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2951 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2952 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2953 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2954 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2955 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2956 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2957 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2958 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2959 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2960 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2961 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2962 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2963 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2964 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2965 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2966 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2967 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2968 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2969 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2970 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2971 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2972 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2973 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2974 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2975 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2976 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2977 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2978 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2979 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2980 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2981 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2982 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2983 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2984 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2985 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2986 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2987 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2988 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2989 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2990 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2991 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2992 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2993 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2994 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2995 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2996 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2997 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2998 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 2999 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3000 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3001 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3002 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3003 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3004 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3005 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3006 + ip + + descriptions + + expect + OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3007 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3008 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3009 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3010 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3011 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3012 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3013 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3014 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3015 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3016 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3017 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3018 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3019 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3020 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3021 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3022 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3023 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3024 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3025 + ip + + descriptions + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3026 + ip + + descriptions + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3027 + ip + + descriptions + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3028 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3029 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3030 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3031 + ip + + descriptions + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3032 + ip + + descriptions + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3033 + ip + + descriptions + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3034 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3035 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3036 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3037 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3038 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3039 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3040 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3041 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3042 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3043 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3044 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3045 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3046 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3047 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3048 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3049 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3050 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3051 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + There is a DNS name constraint but no DNS name in the certificate. This is allowed by the RFC, but some implementations will fail to validate the certificate. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3052 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3053 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3054 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3055 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3056 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3057 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3058 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3059 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3060 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3061 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3062 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3063 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3064 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3065 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3066 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3067 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3068 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3069 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3070 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3071 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3072 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3073 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3074 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3075 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3076 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3077 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3078 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3079 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3080 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3081 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3082 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3083 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3084 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3085 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3086 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3087 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3088 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3089 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3090 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3091 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3092 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3093 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3094 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3095 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3096 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3097 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3098 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3099 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3100 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3101 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3102 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3103 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3104 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3105 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3106 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3107 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3108 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3109 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3110 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3111 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3112 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3113 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3114 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3115 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3116 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3117 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3118 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3119 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3120 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3121 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3122 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3123 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3124 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3125 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3126 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3127 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3128 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3129 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3130 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3131 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3132 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3133 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3134 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3135 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3136 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3137 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3138 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3139 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3140 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3141 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3142 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3143 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3144 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3145 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3146 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3147 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3148 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3149 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3150 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3151 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3152 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3153 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3154 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3155 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3156 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3157 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3158 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3159 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 3160 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3161 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 3162 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 3163 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3164 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 3165 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 3166 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3167 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 3168 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 3169 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3170 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 3171 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 3172 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3173 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 3174 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 3175 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3176 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 3177 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3178 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3179 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3180 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3181 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3182 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3183 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3184 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3185 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3186 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3187 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3188 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3189 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3190 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3191 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3192 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3193 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3194 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3195 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3196 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3197 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3198 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3199 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3200 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3201 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3202 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3203 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3204 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3205 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3206 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3207 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3208 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3209 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3210 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3211 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3212 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3213 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3214 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3215 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3216 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3217 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3218 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3219 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3220 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3221 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3222 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3223 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3224 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3225 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3226 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3227 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3228 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3229 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3230 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3231 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3232 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3233 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3234 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3235 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3236 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3237 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3238 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3239 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3240 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 3241 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3242 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 3243 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3244 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3245 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3246 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 3247 + ip + + descriptions + + expect + OK + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3248 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 3249 + ip + + descriptions + + expect + OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 3250 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3251 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 3252 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3253 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3254 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3255 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 3256 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3257 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 3258 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3259 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3260 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3261 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3262 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3263 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3264 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3265 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3266 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3267 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3268 + ip + + descriptions + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3269 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3270 + ip + + descriptions + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3271 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3272 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3273 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3274 + ip + + descriptions + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3275 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3276 + ip + + descriptions + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3277 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3278 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3279 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3280 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3281 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3282 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3283 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3284 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3285 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3286 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3287 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3288 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3289 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3290 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3291 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3292 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3293 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3294 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3295 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3296 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3297 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3298 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3299 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3300 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3301 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3302 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3303 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3304 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3305 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3306 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3307 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3308 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3309 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3310 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3311 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3312 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3313 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3314 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3315 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3316 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3317 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3318 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3319 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3320 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3321 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 3322 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3323 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 3324 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 3325 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3326 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 3327 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 3328 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3329 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + expect + OK + + id + 3330 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 3331 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3332 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 3333 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 3334 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3335 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 3336 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 3337 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3338 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + + dns + + descriptions + + expect + WEAK-OK + + id + 3339 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3340 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3341 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3342 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3343 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3344 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3345 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3346 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3347 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3348 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3349 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3350 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3351 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3352 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3353 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3354 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3355 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3356 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3357 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3358 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3359 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3360 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3361 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3362 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3363 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3364 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3365 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3366 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3367 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3368 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3369 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3370 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3371 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3372 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3373 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3374 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3375 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3376 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3377 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3378 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3379 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3380 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3381 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3382 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3383 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3384 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3385 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3386 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3387 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3388 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3389 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3390 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3391 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3392 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + Althought the IP address is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + id + 3393 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3394 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3395 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3396 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3397 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3398 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3399 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3400 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3401 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + expect + ERROR + + id + 3402 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3403 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3404 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3405 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3406 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3407 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3408 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3409 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3410 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3411 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3412 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3413 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3414 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3415 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3416 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3417 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3418 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3419 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3420 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3421 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3422 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3423 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3424 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3425 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3426 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3427 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3428 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3429 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3430 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3431 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3432 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3433 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3434 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3435 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3436 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3437 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3438 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3439 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3440 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3441 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3442 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3443 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3444 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3445 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3446 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3447 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3448 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3449 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3450 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3451 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3452 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3453 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3454 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3455 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3456 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3457 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3458 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3459 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3460 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3461 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3462 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3463 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3464 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3465 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3466 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3467 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3468 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3469 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3470 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3471 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3472 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3473 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3474 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3475 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3476 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3477 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3478 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3479 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3480 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3481 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3482 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3483 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3484 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3485 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3486 + ip + + descriptions + + expect + OK + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3487 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3488 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3489 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3490 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3491 + ip + + descriptions + + expect + OK + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3492 + ip + + descriptions + + expect + OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3493 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3494 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3495 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3496 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3497 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3498 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3499 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3500 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3501 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3502 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3503 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3504 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3505 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3506 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3507 + ip + + descriptions + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3508 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3509 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3510 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3511 + ip + + descriptions + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3512 + ip + + descriptions + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3513 + ip + + descriptions + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3514 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3515 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3516 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3517 + ip + + descriptions + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3518 + ip + + descriptions + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3519 + ip + + descriptions + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3520 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3521 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3522 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3523 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3524 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3525 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3526 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3527 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3528 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3529 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3530 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3531 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3532 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3533 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3534 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3535 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3536 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3537 + ip + + descriptions + + Although the DNS name is not the subject name in question, it's name constraint violation may still cause this certificate to be rejected. + + expect + WEAK-OK + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3538 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3539 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3540 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3541 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3542 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3543 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3544 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3545 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3546 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3547 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3548 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3549 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3550 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3551 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3552 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3553 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3554 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3555 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3556 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3557 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3558 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3559 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3560 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3561 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3562 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3563 + ip + + descriptions + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3564 + ip + + descriptions + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3565 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3566 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3567 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3568 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3569 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3570 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3571 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3572 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3573 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3574 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3575 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3576 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3577 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3578 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3579 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3580 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3581 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3582 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3583 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3584 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3585 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3586 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3587 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3588 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3589 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3590 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3591 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3592 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3593 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3594 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3595 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3596 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3597 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3598 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3599 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3600 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3601 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3602 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3603 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3604 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3605 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3606 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3607 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3608 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3609 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3610 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3611 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3612 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3613 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3614 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3615 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3616 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3617 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3618 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3619 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3620 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3621 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3622 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3623 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3624 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3625 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3626 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + The IP in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3627 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3628 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3629 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3630 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3631 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3632 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3633 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3634 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3635 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3636 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3637 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3638 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3639 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3640 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3641 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3642 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3643 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3644 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + descriptions + + The IP in the common name violates a name constraint. Because there is a SAN extension, this might be ignored. + Although the common name is an IP, some implementations may apply DNS name constraints against it and thus fail validation. + The IP in the SAN extension violates a name constraint. + The DNS name in the SAN extension violates a name constraint. + + dns + + descriptions + + The DNS hostname used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + id + 3645 + ip + + descriptions + + The IP used as an origin is not listed in the CN or SAN extension. + + expect + ERROR + + + + + diff --git a/SecurityTests/si-87-sectrust-name-constraints/manifest.plist b/SecurityTests/si-87-sectrust-name-constraints/manifest.plist new file mode 100644 index 00000000..b03dd848 --- /dev/null +++ b/SecurityTests/si-87-sectrust-name-constraints/manifest.plist @@ -0,0 +1,77526 @@ + + + + + certManifest + + + id + 1 + nameConstraints + + blacklist + + whitelist + + + sans + + + + id + 2 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + + + id + 3 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + + + id + 4 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + + + id + 5 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + + + id + 6 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + + + id + 7 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + + + id + 8 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + + + id + 9 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + + + id + 10 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + id + 11 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + id + 12 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + id + 13 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + id + 14 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + id + 15 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + id + 16 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + id + 17 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + id + 18 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + id + 19 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + + + id + 20 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + + + id + 21 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + + + id + 22 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + + + id + 23 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + + + id + 24 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + + + id + 25 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + + + id + 26 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + + + id + 27 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + + + id + 28 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + + + id + 29 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + + + id + 30 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + + + id + 31 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + + + id + 32 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + + + id + 33 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + + + id + 34 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + + + id + 35 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + + + id + 36 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + + + id + 37 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + id + 38 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + id + 39 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + id + 40 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + id + 41 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + id + 42 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + id + 43 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + id + 44 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + id + 45 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + id + 46 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + id + 47 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + id + 48 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + id + 49 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + id + 50 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + id + 51 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + id + 52 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + id + 53 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + id + 54 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + id + 55 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + + + id + 56 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + + + id + 57 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + + + id + 58 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + + + id + 59 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + + + id + 60 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + + + id + 61 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + + + id + 62 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + + + id + 63 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + + + id + 64 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + id + 65 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + id + 66 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + id + 67 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + id + 68 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + id + 69 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + id + 70 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + id + 71 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + id + 72 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + id + 73 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + id + 74 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + id + 75 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + id + 76 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + id + 77 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + id + 78 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + id + 79 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + id + 80 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + id + 81 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + id + 82 + nameConstraints + + blacklist + + whitelist + + + sans + + 52.20.118.238 + + + + id + 83 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + 52.20.118.238 + + + + id + 84 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + 52.20.118.238 + + + + id + 85 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + 52.20.118.238 + + + + id + 86 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + 52.20.118.238 + + + + id + 87 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + 52.20.118.238 + + + + id + 88 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + 52.20.118.238 + + + + id + 89 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + 52.20.118.238 + + + + id + 90 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + 52.20.118.238 + + + + id + 91 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + id + 92 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + id + 93 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + id + 94 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + id + 95 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + id + 96 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + id + 97 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + id + 98 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + id + 99 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + id + 100 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + id + 101 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + id + 102 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + id + 103 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + id + 104 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + id + 105 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + id + 106 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + id + 107 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + id + 108 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + id + 109 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 110 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 111 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 112 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 113 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 114 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 115 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 116 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 117 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 118 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 119 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 120 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 121 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 122 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 123 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 124 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 125 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 126 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 127 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 128 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 129 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 130 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 131 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 132 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 133 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 134 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 135 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + id + 136 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 137 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 138 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 139 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 140 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 141 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 142 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 143 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 144 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 145 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 146 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 147 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 148 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 149 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 150 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 151 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 152 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 153 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 154 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 155 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 156 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 157 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 158 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 159 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 160 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 161 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 162 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + id + 163 + nameConstraints + + blacklist + + whitelist + + + sans + + 172.16.0.1 + + + + id + 164 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + 172.16.0.1 + + + + id + 165 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + 172.16.0.1 + + + + id + 166 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + 172.16.0.1 + + + + id + 167 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + 172.16.0.1 + + + + id + 168 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + 172.16.0.1 + + + + id + 169 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + 172.16.0.1 + + + + id + 170 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + 172.16.0.1 + + + + id + 171 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + 172.16.0.1 + + + + id + 172 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + id + 173 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + id + 174 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + id + 175 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + id + 176 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + id + 177 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + id + 178 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + id + 179 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + id + 180 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + id + 181 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + id + 182 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + id + 183 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + id + 184 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + id + 185 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + id + 186 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + id + 187 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + id + 188 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + id + 189 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + id + 190 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 191 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 192 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 193 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 194 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 195 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 196 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 197 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 198 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 199 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 200 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 201 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 202 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 203 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 204 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 205 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 206 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 207 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 208 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 209 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 210 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 211 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 212 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 213 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 214 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 215 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 216 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + id + 217 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 218 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 219 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 220 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 221 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 222 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 223 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 224 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 225 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 226 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 227 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 228 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 229 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 230 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 231 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 232 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 233 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 234 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 235 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 236 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 237 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 238 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 239 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 240 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 241 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 242 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 243 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + id + 244 + nameConstraints + + blacklist + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + id + 245 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + id + 246 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + id + 247 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + id + 248 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + id + 249 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + id + 250 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + id + 251 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + id + 252 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + id + 253 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + id + 254 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + id + 255 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + id + 256 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + id + 257 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + id + 258 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + id + 259 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + id + 260 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + id + 261 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + id + 262 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + id + 263 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + id + 264 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + id + 265 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + id + 266 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + id + 267 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + id + 268 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + id + 269 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + id + 270 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + id + 271 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 272 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 273 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 274 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 275 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 276 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 277 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 278 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 279 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 280 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 281 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 282 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 283 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 284 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 285 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 286 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 287 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 288 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 289 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 290 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 291 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 292 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 293 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 294 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 295 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 296 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 297 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 298 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 299 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 300 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 301 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 302 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 303 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 304 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 305 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 306 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 307 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 308 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 309 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 310 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 311 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 312 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 313 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 314 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 315 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 316 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 317 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 318 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 319 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 320 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 321 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 322 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 323 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 324 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + id + 325 + nameConstraints + + blacklist + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 326 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 327 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 328 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 329 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 330 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 331 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 332 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 333 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 334 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 335 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 336 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 337 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 338 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 339 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 340 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 341 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 342 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 343 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 344 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 345 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 346 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 347 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 348 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 349 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 350 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 351 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 352 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 353 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 354 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 355 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 356 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 357 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 358 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 359 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 360 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 361 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 362 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 363 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 364 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 365 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 366 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 367 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 368 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 369 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 370 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 371 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 372 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 373 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 374 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 375 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 376 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 377 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 378 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 379 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 380 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 381 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 382 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 383 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 384 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 385 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 386 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 387 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 388 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 389 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 390 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 391 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 392 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 393 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 394 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 395 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 396 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 397 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 398 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 399 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 400 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 401 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 402 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 403 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 404 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 405 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + id + 406 + nameConstraints + + blacklist + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 407 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 408 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 409 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 410 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 411 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 412 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 413 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 414 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 415 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 416 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 417 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 418 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 419 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 420 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 421 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 422 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 423 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 424 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 425 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 426 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 427 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 428 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 429 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 430 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 431 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 432 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 433 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 434 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 435 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 436 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 437 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 438 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 439 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 440 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 441 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 442 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 443 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 444 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 445 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 446 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 447 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 448 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 449 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 450 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 451 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 452 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 453 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 454 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 455 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 456 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 457 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 458 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 459 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 460 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 461 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 462 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 463 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 464 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 465 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 466 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 467 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 468 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 469 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 470 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 471 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 472 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 473 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 474 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 475 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 476 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 477 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 478 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 479 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 480 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 481 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 482 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 483 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 484 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 485 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 486 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + id + 487 + nameConstraints + + blacklist + + whitelist + + + sans + + bad.example.com + + + + id + 488 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + bad.example.com + + + + id + 489 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + bad.example.com + + + + id + 490 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + + + + id + 491 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + + + + id + 492 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + + + + id + 493 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + + + + id + 494 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + + + + id + 495 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + + + + id + 496 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + id + 497 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + id + 498 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + id + 499 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + id + 500 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + id + 501 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + id + 502 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + id + 503 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + id + 504 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + id + 505 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + bad.example.com + + + + id + 506 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + bad.example.com + + + + id + 507 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + bad.example.com + + + + id + 508 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + + + + id + 509 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + + + + id + 510 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + + + + id + 511 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + + + + id + 512 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + + + + id + 513 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + + + + id + 514 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 515 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 516 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 517 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 518 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 519 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 520 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 521 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 522 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 523 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 524 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 525 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 526 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 527 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 528 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 529 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 530 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 531 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 532 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 533 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 534 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 535 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 536 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 537 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 538 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 539 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 540 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + id + 541 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 542 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 543 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 544 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 545 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 546 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 547 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 548 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 549 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 550 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 551 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 552 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 553 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 554 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 555 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 556 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 557 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 558 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 559 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 560 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 561 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 562 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 563 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 564 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 565 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 566 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 567 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + id + 568 + nameConstraints + + blacklist + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 569 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 570 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 571 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 572 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 573 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 574 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 575 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 576 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 577 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 578 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 579 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 580 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 581 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 582 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 583 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 584 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 585 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 586 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 587 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 588 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 589 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 590 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 591 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 592 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 593 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 594 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 595 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 596 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 597 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 598 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 599 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 600 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 601 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 602 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 603 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 604 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 605 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 606 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 607 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 608 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 609 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 610 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 611 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 612 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 613 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 614 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 615 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 616 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 617 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 618 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 619 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 620 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 621 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 622 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 623 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 624 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 625 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 626 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 627 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 628 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 629 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 630 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 631 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 632 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 633 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 634 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 635 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 636 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 637 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 638 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 639 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 640 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 641 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 642 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 643 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 644 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 645 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 646 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 647 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 648 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + id + 649 + nameConstraints + + blacklist + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 650 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 651 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 652 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 653 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 654 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 655 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 656 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 657 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 658 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 659 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 660 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 661 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 662 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 663 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 664 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 665 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 666 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 667 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 668 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 669 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 670 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 671 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 672 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 673 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 674 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 675 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 676 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 677 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 678 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 679 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 680 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 681 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 682 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 683 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 684 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 685 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 686 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 687 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 688 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 689 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 690 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 691 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 692 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 693 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 694 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 695 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 696 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 697 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 698 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 699 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 700 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 701 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 702 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 703 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 704 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 705 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 706 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 707 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 708 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 709 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 710 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 711 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 712 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 713 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 714 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 715 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 716 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 717 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 718 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 719 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 720 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 721 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 722 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 723 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 724 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 725 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 726 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 727 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 728 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + id + 729 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 730 + nameConstraints + + blacklist + + whitelist + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 731 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 732 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 733 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 734 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 735 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 736 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 737 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 738 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 739 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 740 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 741 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 742 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 743 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 744 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 745 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 746 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 747 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 748 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 749 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 750 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 751 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 752 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 753 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 754 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 755 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 756 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 757 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 758 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 759 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 760 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 761 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 762 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 763 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 764 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 765 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 766 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 767 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 768 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 769 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 770 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 771 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 772 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 773 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 774 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 775 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 776 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 777 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 778 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 779 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 780 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 781 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 782 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 783 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 784 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 785 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 786 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 787 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 788 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 789 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 790 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 791 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 792 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 793 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 794 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 795 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 796 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 797 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 798 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 799 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 800 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 801 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 802 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 803 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 804 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 805 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 806 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 807 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 808 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 809 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 810 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + test.nameconstraints.bettertls.com + id + 811 + nameConstraints + + blacklist + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 812 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 813 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 814 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 815 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 816 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 817 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 818 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 819 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 820 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 821 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 822 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 823 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 824 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 825 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 826 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 827 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 828 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 829 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 830 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 831 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 832 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 833 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 834 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 835 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 836 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 837 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 838 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 839 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 840 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 841 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 842 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 843 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 844 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 845 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 846 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 847 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 848 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 849 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 850 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 851 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 852 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 853 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 854 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 855 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 856 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 857 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 858 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 859 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 860 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 861 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 862 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 863 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 864 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 865 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 866 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 867 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 868 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 869 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 870 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 871 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 872 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 873 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 874 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 875 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 876 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 877 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 878 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 879 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 880 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 881 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 882 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 883 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 884 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 885 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 886 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 887 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 888 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 889 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 890 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 891 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 892 + nameConstraints + + blacklist + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 893 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 894 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 895 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 896 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 897 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 898 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 899 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 900 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 901 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 902 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 903 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 904 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 905 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 906 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 907 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 908 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 909 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 910 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 911 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 912 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 913 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 914 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 915 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 916 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 917 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 918 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 919 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 920 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 921 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 922 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 923 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 924 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 925 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 926 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 927 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 928 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 929 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 930 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 931 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 932 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 933 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 934 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 935 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 936 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 937 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 938 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 939 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 940 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 941 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 942 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 943 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 944 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 945 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 946 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 947 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 948 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 949 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 950 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 951 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 952 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 953 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 954 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 955 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 956 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 957 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 958 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 959 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 960 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 961 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 962 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 963 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 964 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 965 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 966 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 967 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 968 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 969 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 970 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 971 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 972 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 973 + nameConstraints + + blacklist + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 974 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 975 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 976 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 977 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 978 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 979 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 980 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 981 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 982 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 983 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 984 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 985 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 986 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 987 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 988 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 989 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 990 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 991 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 992 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 993 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 994 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 995 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 996 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 997 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 998 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 999 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1000 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1001 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1002 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1003 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1004 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1005 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1006 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1007 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1008 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1009 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1010 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1011 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1012 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1013 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1014 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1015 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1016 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1017 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1018 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1019 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1020 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1021 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1022 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1023 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1024 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1025 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1026 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1027 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1028 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1029 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1030 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1031 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1032 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1033 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1034 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1035 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1036 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1037 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1038 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1039 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1040 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1041 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1042 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1043 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1044 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1045 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1046 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1047 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1048 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1049 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1050 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1051 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1052 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1053 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1054 + nameConstraints + + blacklist + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1055 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1056 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1057 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1058 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1059 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1060 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1061 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1062 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1063 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1064 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1065 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1066 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1067 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1068 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1069 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1070 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1071 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1072 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1073 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1074 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1075 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1076 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1077 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1078 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1079 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1080 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1081 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1082 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1083 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1084 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1085 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1086 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1087 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1088 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1089 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1090 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1091 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1092 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1093 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1094 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1095 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1096 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1097 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1098 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1099 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1100 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1101 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1102 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1103 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1104 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1105 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1106 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1107 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1108 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1109 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1110 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1111 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1112 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1113 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1114 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1115 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1116 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1117 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1118 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1119 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1120 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1121 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1122 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1123 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1124 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1125 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1126 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1127 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1128 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1129 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1130 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1131 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1132 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1133 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1134 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1135 + nameConstraints + + blacklist + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1136 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1137 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1138 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1139 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1140 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1141 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1142 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1143 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1144 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1145 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1146 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1147 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1148 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1149 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1150 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1151 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1152 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1153 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1154 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1155 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1156 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1157 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1158 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1159 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1160 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1161 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1162 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1163 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1164 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1165 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1166 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1167 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1168 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1169 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1170 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1171 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1172 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1173 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1174 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1175 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1176 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1177 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1178 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1179 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1180 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1181 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1182 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1183 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1184 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1185 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1186 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1187 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1188 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1189 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1190 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1191 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1192 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1193 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1194 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1195 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1196 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1197 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1198 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1199 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1200 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1201 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1202 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1203 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1204 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1205 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1206 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1207 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1208 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1209 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1210 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1211 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1212 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1213 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1214 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1215 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1216 + nameConstraints + + blacklist + + whitelist + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1217 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1218 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1219 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1220 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1221 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1222 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1223 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1224 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1225 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1226 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1227 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1228 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1229 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1230 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1231 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1232 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1233 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1234 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1235 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1236 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1237 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1238 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1239 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1240 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1241 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1242 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1243 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1244 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1245 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1246 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1247 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1248 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1249 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1250 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1251 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1252 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1253 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1254 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1255 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1256 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1257 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1258 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1259 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1260 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1261 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1262 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1263 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1264 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1265 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1266 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1267 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1268 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1269 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1270 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1271 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1272 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1273 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1274 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1275 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1276 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1277 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1278 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1279 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1280 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1281 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1282 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1283 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1284 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1285 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1286 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1287 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1288 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1289 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1290 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1291 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1292 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1293 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1294 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1295 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1296 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + test.nameconstraints.bettertls.com + id + 1297 + nameConstraints + + blacklist + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1298 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1299 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1300 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1301 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1302 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1303 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1304 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1305 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1306 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1307 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1308 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1309 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1310 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1311 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1312 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1313 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1314 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1315 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1316 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1317 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1318 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1319 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1320 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1321 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1322 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1323 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1324 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1325 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1326 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1327 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1328 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1329 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1330 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1331 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1332 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1333 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1334 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1335 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1336 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1337 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1338 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1339 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1340 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1341 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1342 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1343 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1344 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1345 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1346 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1347 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1348 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1349 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1350 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1351 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1352 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1353 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1354 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1355 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1356 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1357 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1358 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1359 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1360 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1361 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1362 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1363 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1364 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1365 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1366 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1367 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1368 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1369 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1370 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1371 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1372 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1373 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1374 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1375 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1376 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1377 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + test.nameconstraints.bettertls.com + id + 1378 + nameConstraints + + blacklist + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1379 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1380 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1381 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1382 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1383 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1384 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1385 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1386 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1387 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1388 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1389 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1390 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1391 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1392 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1393 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1394 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1395 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1396 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1397 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1398 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1399 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1400 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1401 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1402 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1403 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1404 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1405 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1406 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1407 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1408 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1409 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1410 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1411 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1412 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1413 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1414 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1415 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1416 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1417 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1418 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1419 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1420 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1421 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1422 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1423 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1424 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1425 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1426 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1427 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1428 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1429 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1430 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1431 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1432 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1433 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1434 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1435 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1436 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1437 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1438 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1439 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1440 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1441 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1442 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1443 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1444 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1445 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1446 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1447 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1448 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1449 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1450 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1451 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1452 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1453 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1454 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1455 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1456 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1457 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + test.nameconstraints.bettertls.com + id + 1458 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1459 + nameConstraints + + blacklist + + whitelist + + + sans + + + + commonName + 52.20.118.238 + id + 1460 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + + + commonName + 52.20.118.238 + id + 1461 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + + + commonName + 52.20.118.238 + id + 1462 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + + + commonName + 52.20.118.238 + id + 1463 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + + + commonName + 52.20.118.238 + id + 1464 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + + + commonName + 52.20.118.238 + id + 1465 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + + + commonName + 52.20.118.238 + id + 1466 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + + + commonName + 52.20.118.238 + id + 1467 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + + + commonName + 52.20.118.238 + id + 1468 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + 52.20.118.238 + id + 1469 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + 52.20.118.238 + id + 1470 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + 52.20.118.238 + id + 1471 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + 52.20.118.238 + id + 1472 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + 52.20.118.238 + id + 1473 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + 52.20.118.238 + id + 1474 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + 52.20.118.238 + id + 1475 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + 52.20.118.238 + id + 1476 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + 52.20.118.238 + id + 1477 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + + + commonName + 52.20.118.238 + id + 1478 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + + + commonName + 52.20.118.238 + id + 1479 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + + + commonName + 52.20.118.238 + id + 1480 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + + + commonName + 52.20.118.238 + id + 1481 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + + + commonName + 52.20.118.238 + id + 1482 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + + + commonName + 52.20.118.238 + id + 1483 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + + + commonName + 52.20.118.238 + id + 1484 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + + + commonName + 52.20.118.238 + id + 1485 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + + + commonName + 52.20.118.238 + id + 1486 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1487 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1488 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1489 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1490 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1491 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1492 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1493 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1494 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1495 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1496 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1497 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1498 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1499 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1500 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1501 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1502 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1503 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1504 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1505 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1506 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1507 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1508 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1509 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1510 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1511 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1512 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + 52.20.118.238 + id + 1513 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1514 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1515 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1516 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1517 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1518 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1519 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1520 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1521 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1522 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1523 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1524 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1525 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1526 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1527 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1528 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1529 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1530 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1531 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1532 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1533 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1534 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1535 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1536 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1537 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1538 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1539 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + 52.20.118.238 + id + 1540 + nameConstraints + + blacklist + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1541 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1542 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1543 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1544 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1545 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1546 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1547 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1548 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1549 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1550 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1551 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1552 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1553 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1554 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1555 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1556 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1557 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1558 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1559 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1560 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1561 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1562 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1563 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1564 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1565 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1566 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1567 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1568 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1569 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1570 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1571 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1572 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1573 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1574 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1575 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1576 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1577 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1578 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1579 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1580 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1581 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1582 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1583 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1584 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1585 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1586 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1587 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1588 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1589 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1590 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1591 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1592 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1593 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1594 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1595 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1596 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1597 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1598 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1599 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1600 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1601 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1602 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1603 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1604 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1605 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1606 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1607 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1608 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1609 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1610 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1611 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1612 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1613 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1614 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1615 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1616 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1617 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1618 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1619 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1620 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1621 + nameConstraints + + blacklist + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1622 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1623 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1624 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1625 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1626 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1627 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1628 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1629 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1630 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1631 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1632 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1633 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1634 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1635 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1636 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1637 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1638 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1639 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1640 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1641 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1642 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1643 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1644 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1645 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1646 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1647 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1648 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1649 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1650 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1651 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1652 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1653 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1654 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1655 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1656 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1657 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1658 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1659 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1660 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1661 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1662 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1663 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1664 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1665 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1666 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1667 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1668 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1669 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1670 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1671 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1672 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1673 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1674 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1675 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1676 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1677 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1678 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1679 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1680 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1681 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1682 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1683 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1684 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1685 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1686 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1687 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1688 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1689 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1690 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1691 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1692 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1693 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1694 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1695 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1696 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1697 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1698 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1699 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1700 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1701 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1702 + nameConstraints + + blacklist + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1703 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1704 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1705 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1706 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1707 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1708 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1709 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1710 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1711 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1712 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1713 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1714 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1715 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1716 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1717 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1718 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1719 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1720 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1721 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1722 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1723 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1724 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1725 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1726 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1727 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1728 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1729 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1730 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1731 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1732 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1733 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1734 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1735 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1736 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1737 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1738 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1739 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1740 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1741 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1742 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1743 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1744 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1745 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1746 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1747 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1748 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1749 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1750 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1751 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1752 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1753 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1754 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1755 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1756 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1757 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1758 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1759 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1760 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1761 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1762 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1763 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1764 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1765 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1766 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1767 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1768 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1769 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1770 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1771 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1772 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1773 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1774 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1775 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1776 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1777 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1778 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1779 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1780 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1781 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1782 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 52.20.118.238 + id + 1783 + nameConstraints + + blacklist + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1784 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1785 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1786 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1787 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1788 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1789 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1790 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1791 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1792 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1793 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1794 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1795 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1796 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1797 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1798 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1799 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1800 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1801 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1802 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1803 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1804 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1805 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1806 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1807 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1808 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1809 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1810 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1811 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1812 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1813 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1814 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1815 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1816 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1817 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1818 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1819 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1820 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1821 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1822 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1823 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1824 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1825 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1826 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1827 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1828 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1829 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1830 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1831 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1832 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1833 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1834 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1835 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1836 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1837 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1838 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1839 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1840 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1841 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1842 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1843 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1844 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1845 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1846 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1847 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1848 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1849 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1850 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1851 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1852 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1853 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1854 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1855 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1856 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1857 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1858 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1859 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1860 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1861 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1862 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1863 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 1864 + nameConstraints + + blacklist + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1865 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1866 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1867 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1868 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1869 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1870 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1871 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1872 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1873 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1874 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1875 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1876 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1877 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1878 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1879 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1880 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1881 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1882 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1883 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1884 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1885 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1886 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1887 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1888 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1889 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1890 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1891 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1892 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1893 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1894 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1895 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1896 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1897 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1898 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1899 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1900 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1901 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1902 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1903 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1904 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1905 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1906 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1907 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1908 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1909 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1910 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1911 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1912 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1913 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1914 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1915 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1916 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1917 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1918 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1919 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1920 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1921 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1922 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1923 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1924 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1925 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1926 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1927 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1928 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1929 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1930 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1931 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1932 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1933 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1934 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1935 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1936 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1937 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1938 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1939 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1940 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1941 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1942 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1943 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1944 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 1945 + nameConstraints + + blacklist + + whitelist + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1946 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1947 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1948 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1949 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1950 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1951 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1952 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1953 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1954 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1955 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1956 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1957 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1958 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1959 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1960 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1961 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1962 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1963 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1964 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1965 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1966 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1967 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1968 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1969 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1970 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1971 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1972 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1973 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1974 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1975 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1976 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1977 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1978 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1979 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1980 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1981 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1982 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1983 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1984 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1985 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1986 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1987 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1988 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1989 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1990 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1991 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1992 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1993 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1994 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1995 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1996 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1997 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1998 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 1999 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2000 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2001 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2002 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2003 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2004 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2005 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2006 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2007 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2008 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2009 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2010 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2011 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2012 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2013 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2014 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2015 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2016 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2017 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2018 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2019 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2020 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2021 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2022 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2023 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2024 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2025 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 52.20.118.238 + id + 2026 + nameConstraints + + blacklist + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2027 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2028 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2029 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2030 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2031 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2032 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2033 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2034 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2035 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2036 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2037 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2038 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2039 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2040 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2041 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2042 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2043 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2044 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2045 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2046 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2047 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2048 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2049 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2050 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2051 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2052 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2053 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2054 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2055 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2056 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2057 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2058 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2059 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2060 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2061 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2062 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2063 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2064 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2065 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2066 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2067 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2068 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2069 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2070 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2071 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2072 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2073 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2074 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2075 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2076 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2077 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2078 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2079 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2080 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2081 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2082 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2083 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2084 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2085 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2086 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2087 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2088 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2089 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2090 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2091 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2092 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2093 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2094 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2095 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2096 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2097 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2098 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2099 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2100 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2101 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2102 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2103 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2104 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2105 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2106 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 52.20.118.238 + id + 2107 + nameConstraints + + blacklist + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2108 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2109 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2110 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2111 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2112 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2113 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2114 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2115 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2116 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2117 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2118 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2119 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2120 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2121 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2122 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2123 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2124 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2125 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2126 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2127 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2128 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2129 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2130 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2131 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2132 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2133 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2134 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2135 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2136 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2137 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2138 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2139 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2140 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2141 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2142 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2143 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2144 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2145 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2146 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2147 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2148 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2149 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2150 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2151 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2152 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2153 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2154 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2155 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2156 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2157 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2158 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2159 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2160 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2161 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2162 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2163 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2164 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2165 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2166 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2167 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2168 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2169 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2170 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2171 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2172 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2173 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2174 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2175 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2176 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2177 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2178 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2179 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2180 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2181 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2182 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2183 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2184 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2185 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2186 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 52.20.118.238 + id + 2187 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2188 + nameConstraints + + blacklist + + whitelist + + + sans + + + + commonName + bad.example.com + id + 2189 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + + + commonName + bad.example.com + id + 2190 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + + + commonName + bad.example.com + id + 2191 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + + + commonName + bad.example.com + id + 2192 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + + + commonName + bad.example.com + id + 2193 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + + + commonName + bad.example.com + id + 2194 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + + + commonName + bad.example.com + id + 2195 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + + + commonName + bad.example.com + id + 2196 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + + + commonName + bad.example.com + id + 2197 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + bad.example.com + id + 2198 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + bad.example.com + id + 2199 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + bad.example.com + id + 2200 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + bad.example.com + id + 2201 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + bad.example.com + id + 2202 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + bad.example.com + id + 2203 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + bad.example.com + id + 2204 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + bad.example.com + id + 2205 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + bad.example.com + id + 2206 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + + + commonName + bad.example.com + id + 2207 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + + + commonName + bad.example.com + id + 2208 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + + + commonName + bad.example.com + id + 2209 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + + + commonName + bad.example.com + id + 2210 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + + + commonName + bad.example.com + id + 2211 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + + + commonName + bad.example.com + id + 2212 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + + + commonName + bad.example.com + id + 2213 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + + + commonName + bad.example.com + id + 2214 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + + + commonName + bad.example.com + id + 2215 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2216 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2217 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2218 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2219 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2220 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2221 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2222 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2223 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2224 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2225 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2226 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2227 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2228 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2229 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2230 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2231 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2232 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2233 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2234 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2235 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2236 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2237 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2238 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2239 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2240 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2241 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + bad.example.com + id + 2242 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2243 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2244 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2245 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2246 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2247 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2248 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2249 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2250 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2251 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2252 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2253 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2254 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2255 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2256 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2257 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2258 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2259 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2260 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2261 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2262 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2263 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2264 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2265 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2266 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2267 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2268 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + bad.example.com + id + 2269 + nameConstraints + + blacklist + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2270 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2271 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2272 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2273 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2274 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2275 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2276 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2277 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2278 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2279 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2280 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2281 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2282 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2283 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2284 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2285 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2286 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2287 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2288 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2289 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2290 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2291 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2292 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2293 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2294 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2295 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2296 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2297 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2298 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2299 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2300 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2301 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2302 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2303 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2304 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2305 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2306 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2307 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2308 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2309 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2310 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2311 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2312 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2313 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2314 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2315 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2316 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2317 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2318 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2319 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2320 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2321 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2322 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2323 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2324 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2325 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2326 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2327 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2328 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2329 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2330 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2331 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2332 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2333 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2334 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2335 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2336 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2337 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2338 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2339 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2340 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2341 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2342 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2343 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2344 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2345 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2346 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2347 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2348 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2349 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + bad.example.com + id + 2350 + nameConstraints + + blacklist + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2351 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2352 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2353 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2354 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2355 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2356 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2357 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2358 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2359 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2360 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2361 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2362 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2363 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2364 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2365 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2366 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2367 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2368 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2369 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2370 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2371 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2372 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2373 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2374 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2375 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2376 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2377 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2378 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2379 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2380 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2381 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2382 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2383 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2384 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2385 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2386 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2387 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2388 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2389 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2390 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2391 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2392 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2393 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2394 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2395 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2396 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2397 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2398 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2399 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2400 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2401 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2402 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2403 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2404 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2405 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2406 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2407 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2408 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2409 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2410 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2411 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2412 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2413 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2414 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2415 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2416 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2417 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2418 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2419 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2420 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2421 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2422 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2423 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2424 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2425 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2426 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2427 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2428 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2429 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2430 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + bad.example.com + id + 2431 + nameConstraints + + blacklist + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2432 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2433 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2434 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2435 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2436 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2437 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2438 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2439 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2440 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2441 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2442 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2443 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2444 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2445 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2446 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2447 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2448 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2449 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2450 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2451 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2452 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2453 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2454 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2455 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2456 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2457 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2458 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2459 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2460 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2461 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2462 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2463 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2464 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2465 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2466 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2467 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2468 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2469 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2470 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2471 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2472 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2473 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2474 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2475 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2476 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2477 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2478 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2479 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2480 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2481 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2482 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2483 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2484 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2485 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2486 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2487 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2488 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2489 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2490 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2491 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2492 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2493 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2494 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2495 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2496 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2497 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2498 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2499 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2500 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2501 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2502 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2503 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2504 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2505 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2506 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2507 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2508 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2509 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2510 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2511 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + bad.example.com + id + 2512 + nameConstraints + + blacklist + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2513 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2514 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2515 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2516 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2517 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2518 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2519 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2520 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2521 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2522 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2523 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2524 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2525 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2526 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2527 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2528 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2529 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2530 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2531 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2532 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2533 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2534 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2535 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2536 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2537 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2538 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2539 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2540 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2541 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2542 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2543 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2544 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2545 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2546 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2547 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2548 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2549 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2550 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2551 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2552 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2553 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2554 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2555 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2556 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2557 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2558 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2559 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2560 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2561 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2562 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2563 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2564 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2565 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2566 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2567 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2568 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2569 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2570 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2571 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2572 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2573 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2574 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2575 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2576 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2577 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2578 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2579 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2580 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2581 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2582 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2583 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2584 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2585 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2586 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2587 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2588 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2589 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2590 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2591 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2592 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2593 + nameConstraints + + blacklist + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2594 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2595 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2596 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2597 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2598 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2599 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2600 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2601 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2602 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2603 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2604 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2605 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2606 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2607 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2608 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2609 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2610 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2611 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2612 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2613 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2614 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2615 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2616 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2617 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2618 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2619 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2620 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2621 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2622 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2623 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2624 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2625 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2626 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2627 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2628 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2629 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2630 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2631 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2632 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2633 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2634 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2635 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2636 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2637 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2638 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2639 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2640 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2641 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2642 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2643 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2644 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2645 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2646 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2647 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2648 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2649 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2650 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2651 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2652 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2653 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2654 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2655 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2656 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2657 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2658 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2659 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2660 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2661 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2662 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2663 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2664 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2665 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2666 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2667 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2668 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2669 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2670 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2671 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2672 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2673 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2674 + nameConstraints + + blacklist + + whitelist + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2675 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2676 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2677 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2678 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2679 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2680 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2681 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2682 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2683 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2684 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2685 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2686 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2687 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2688 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2689 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2690 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2691 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2692 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2693 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2694 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2695 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2696 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2697 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2698 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2699 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2700 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2701 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2702 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2703 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2704 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2705 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2706 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2707 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2708 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2709 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2710 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2711 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2712 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2713 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2714 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2715 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2716 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2717 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2718 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2719 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2720 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2721 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2722 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2723 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2724 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2725 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2726 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2727 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2728 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2729 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2730 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2731 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2732 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2733 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2734 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2735 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2736 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2737 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2738 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2739 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2740 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2741 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2742 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2743 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2744 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2745 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2746 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2747 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2748 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2749 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2750 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2751 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2752 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2753 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2754 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + bad.example.com + id + 2755 + nameConstraints + + blacklist + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2756 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2757 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2758 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2759 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2760 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2761 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2762 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2763 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2764 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2765 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2766 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2767 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2768 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2769 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2770 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2771 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2772 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2773 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2774 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2775 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2776 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2777 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2778 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2779 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2780 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2781 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2782 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2783 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2784 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2785 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2786 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2787 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2788 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2789 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2790 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2791 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2792 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2793 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2794 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2795 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2796 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2797 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2798 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2799 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2800 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2801 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2802 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2803 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2804 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2805 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2806 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2807 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2808 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2809 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2810 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2811 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2812 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2813 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2814 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2815 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2816 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2817 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2818 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2819 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2820 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2821 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2822 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2823 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2824 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2825 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2826 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2827 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2828 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2829 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2830 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2831 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2832 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2833 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2834 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2835 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + bad.example.com + id + 2836 + nameConstraints + + blacklist + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2837 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2838 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2839 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2840 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2841 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2842 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2843 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2844 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2845 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2846 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2847 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2848 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2849 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2850 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2851 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2852 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2853 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2854 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2855 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2856 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2857 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2858 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2859 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2860 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2861 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2862 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2863 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2864 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2865 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2866 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2867 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2868 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2869 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2870 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2871 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2872 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2873 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2874 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2875 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2876 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2877 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2878 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2879 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2880 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2881 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2882 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2883 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2884 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2885 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2886 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2887 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2888 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2889 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2890 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2891 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2892 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2893 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2894 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2895 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2896 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2897 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2898 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2899 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2900 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2901 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2902 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2903 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2904 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2905 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2906 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2907 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2908 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2909 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2910 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2911 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2912 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2913 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2914 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2915 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + bad.example.com + id + 2916 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 2917 + nameConstraints + + blacklist + + whitelist + + + sans + + + + commonName + 172.16.0.1 + id + 2918 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + + + commonName + 172.16.0.1 + id + 2919 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + + + commonName + 172.16.0.1 + id + 2920 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + + + commonName + 172.16.0.1 + id + 2921 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + + + commonName + 172.16.0.1 + id + 2922 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + + + commonName + 172.16.0.1 + id + 2923 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + + + commonName + 172.16.0.1 + id + 2924 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + + + commonName + 172.16.0.1 + id + 2925 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + + + commonName + 172.16.0.1 + id + 2926 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + 172.16.0.1 + id + 2927 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + 172.16.0.1 + id + 2928 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + 172.16.0.1 + id + 2929 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + 172.16.0.1 + id + 2930 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + 172.16.0.1 + id + 2931 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + 172.16.0.1 + id + 2932 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + 172.16.0.1 + id + 2933 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + 172.16.0.1 + id + 2934 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + + + commonName + 172.16.0.1 + id + 2935 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + + + commonName + 172.16.0.1 + id + 2936 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + + + commonName + 172.16.0.1 + id + 2937 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + + + commonName + 172.16.0.1 + id + 2938 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + + + commonName + 172.16.0.1 + id + 2939 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + + + commonName + 172.16.0.1 + id + 2940 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + + + commonName + 172.16.0.1 + id + 2941 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + + + commonName + 172.16.0.1 + id + 2942 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + + + commonName + 172.16.0.1 + id + 2943 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + + + commonName + 172.16.0.1 + id + 2944 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2945 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2946 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2947 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2948 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2949 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2950 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2951 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2952 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2953 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2954 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2955 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2956 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2957 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2958 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2959 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2960 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2961 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2962 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2963 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2964 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2965 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2966 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2967 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2968 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2969 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2970 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + + + commonName + 172.16.0.1 + id + 2971 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2972 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2973 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2974 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2975 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2976 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2977 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2978 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2979 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2980 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2981 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2982 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2983 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2984 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2985 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2986 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2987 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2988 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2989 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2990 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2991 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2992 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2993 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2994 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2995 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2996 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2997 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + + + commonName + 172.16.0.1 + id + 2998 + nameConstraints + + blacklist + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 2999 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3000 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3001 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3002 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3003 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3004 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3005 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3006 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3007 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3008 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3009 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3010 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3011 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3012 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3013 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3014 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3015 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3016 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3017 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3018 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3019 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3020 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3021 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3022 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3023 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3024 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3025 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3026 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3027 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3028 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3029 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3030 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3031 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3032 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3033 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3034 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3035 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3036 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3037 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3038 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3039 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3040 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3041 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3042 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3043 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3044 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3045 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3046 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3047 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3048 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3049 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3050 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3051 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3052 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3053 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3054 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3055 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3056 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3057 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3058 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3059 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3060 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3061 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3062 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3063 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3064 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3065 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3066 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3067 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3068 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3069 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3070 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3071 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3072 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3073 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3074 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3075 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3076 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3077 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3078 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3079 + nameConstraints + + blacklist + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3080 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3081 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3082 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3083 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3084 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3085 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3086 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3087 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3088 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3089 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3090 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3091 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3092 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3093 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3094 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3095 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3096 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3097 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3098 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3099 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3100 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3101 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3102 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3103 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3104 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3105 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3106 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3107 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3108 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3109 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3110 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3111 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3112 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3113 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3114 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3115 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3116 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3117 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3118 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3119 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3120 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3121 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3122 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3123 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3124 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3125 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3126 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3127 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3128 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3129 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3130 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3131 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3132 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3133 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3134 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3135 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3136 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3137 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3138 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3139 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3140 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3141 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3142 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3143 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3144 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3145 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3146 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3147 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3148 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3149 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3150 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3151 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3152 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3153 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3154 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3155 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3156 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3157 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3158 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3159 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3160 + nameConstraints + + blacklist + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3161 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3162 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3163 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3164 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3165 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3166 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3167 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3168 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3169 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3170 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3171 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3172 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3173 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3174 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3175 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3176 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3177 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3178 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3179 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3180 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3181 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3182 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3183 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3184 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3185 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3186 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3187 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3188 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3189 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3190 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3191 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3192 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3193 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3194 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3195 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3196 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3197 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3198 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3199 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3200 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3201 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3202 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3203 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3204 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3205 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3206 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3207 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3208 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3209 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3210 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3211 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3212 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3213 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3214 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3215 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3216 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3217 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3218 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3219 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3220 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3221 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3222 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3223 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3224 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3225 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3226 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3227 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3228 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3229 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3230 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3231 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3232 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3233 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3234 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3235 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3236 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3237 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3238 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3239 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3240 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + + + + commonName + 172.16.0.1 + id + 3241 + nameConstraints + + blacklist + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3242 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3243 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3244 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3245 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3246 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3247 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3248 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3249 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3250 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3251 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3252 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3253 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3254 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3255 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3256 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3257 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3258 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3259 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3260 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3261 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3262 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3263 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3264 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3265 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3266 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3267 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3268 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3269 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3270 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3271 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3272 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3273 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3274 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3275 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3276 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3277 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3278 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3279 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3280 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3281 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3282 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3283 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3284 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3285 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3286 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3287 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3288 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3289 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3290 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3291 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3292 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3293 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3294 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3295 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3296 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3297 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3298 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3299 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3300 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3301 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3302 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3303 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3304 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3305 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3306 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3307 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3308 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3309 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3310 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3311 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3312 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3313 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3314 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3315 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3316 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3317 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3318 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3319 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3320 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3321 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3322 + nameConstraints + + blacklist + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3323 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3324 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3325 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3326 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3327 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3328 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3329 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3330 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3331 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3332 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3333 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3334 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3335 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3336 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3337 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3338 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3339 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3340 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3341 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3342 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3343 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3344 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3345 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3346 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3347 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3348 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3349 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3350 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3351 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3352 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3353 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3354 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3355 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3356 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3357 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3358 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3359 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3360 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3361 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3362 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3363 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3364 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3365 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3366 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3367 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3368 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3369 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3370 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3371 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3372 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3373 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3374 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3375 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3376 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3377 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3378 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3379 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3380 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3381 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3382 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3383 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3384 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3385 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3386 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3387 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3388 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3389 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3390 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3391 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3392 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3393 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3394 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3395 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3396 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3397 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3398 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3399 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3400 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3401 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3402 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + test.nameconstraints.bettertls.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3403 + nameConstraints + + blacklist + + whitelist + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3404 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3405 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3406 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3407 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3408 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3409 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3410 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3411 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3412 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3413 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3414 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3415 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3416 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3417 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3418 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3419 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3420 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3421 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3422 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3423 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3424 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3425 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3426 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3427 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3428 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3429 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3430 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3431 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3432 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3433 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3434 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3435 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3436 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3437 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3438 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3439 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3440 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3441 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3442 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3443 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3444 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3445 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3446 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3447 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3448 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3449 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3450 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3451 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3452 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3453 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3454 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3455 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3456 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3457 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3458 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3459 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3460 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3461 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3462 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3463 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3464 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3465 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3466 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3467 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3468 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3469 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3470 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3471 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3472 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3473 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3474 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3475 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3476 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3477 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3478 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3479 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3480 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3481 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3482 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3483 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + + + + commonName + 172.16.0.1 + id + 3484 + nameConstraints + + blacklist + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3485 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3486 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3487 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3488 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3489 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3490 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3491 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3492 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3493 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3494 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3495 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3496 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3497 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3498 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3499 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3500 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3501 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3502 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3503 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3504 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3505 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3506 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3507 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3508 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3509 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3510 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3511 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3512 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3513 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3514 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3515 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3516 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3517 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3518 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3519 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3520 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3521 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3522 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3523 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3524 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3525 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3526 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3527 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3528 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3529 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3530 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3531 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3532 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3533 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3534 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3535 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3536 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3537 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3538 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3539 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3540 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3541 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3542 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3543 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3544 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3545 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3546 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3547 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3548 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3549 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3550 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3551 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3552 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3553 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3554 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3555 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3556 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3557 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3558 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3559 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3560 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3561 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3562 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3563 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3564 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 52.20.118.238 + + + + commonName + 172.16.0.1 + id + 3565 + nameConstraints + + blacklist + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3566 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3567 + nameConstraints + + blacklist + + example.net + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3568 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3569 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3570 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3571 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3572 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3573 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3574 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3575 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3576 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3577 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3578 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3579 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3580 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3581 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3582 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3583 + nameConstraints + + blacklist + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3584 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3585 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3586 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3587 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3588 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3589 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3590 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3591 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3592 + nameConstraints + + blacklist + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3593 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3594 + nameConstraints + + blacklist + + example.net + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3595 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3596 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3597 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3598 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3599 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3600 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3601 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3602 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3603 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3604 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3605 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3606 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3607 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3608 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3609 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3610 + nameConstraints + + blacklist + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3611 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3612 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3613 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3614 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3615 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3616 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3617 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3618 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 52.0.0.0/11 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3619 + nameConstraints + + blacklist + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3620 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3621 + nameConstraints + + blacklist + + example.net + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3622 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3623 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3624 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3625 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3626 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3627 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3628 + nameConstraints + + blacklist + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3629 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3630 + nameConstraints + + blacklist + + example.net + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3631 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3632 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3633 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3634 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3635 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3636 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3637 + nameConstraints + + blacklist + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3638 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3639 + nameConstraints + + blacklist + + example.net + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3640 + nameConstraints + + blacklist + + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3641 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3642 + nameConstraints + + blacklist + + example.net + 52.0.0.0/11 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3643 + nameConstraints + + blacklist + + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3644 + nameConstraints + + blacklist + + nameconstraints.bettertls.com + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + commonName + 172.16.0.1 + id + 3645 + nameConstraints + + blacklist + + example.net + 192.168.0.0/16 + + whitelist + + example.net + 192.168.0.0/16 + + + sans + + bad.example.com + 172.16.0.1 + + + + + diff --git a/SecurityTests/si-87-sectrust-name-constraints/root.cer b/SecurityTests/si-87-sectrust-name-constraints/root.cer new file mode 100644 index 00000000..a835f760 Binary files /dev/null and b/SecurityTests/si-87-sectrust-name-constraints/root.cer differ diff --git a/SecurityTests/si-88-sectrust-valid-data/ca-na.pem b/SecurityTests/si-88-sectrust-valid-data/ca-na.pem new file mode 100644 index 00000000..d46c67fe --- /dev/null +++ b/SecurityTests/si-88-sectrust-valid-data/ca-na.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIERzCCAy+gAwIBAgIFAKY7r7cwDQYJKoZIhvcNAQELBQAwgYcxHjAcBgNVBAMM +FVZhbGlkIFRlc3QgQ0EgUm9vdCBWMjEiMCAGA1UECwwZVmFsaWQgUHJvamVjdCBU +ZXN0IENBcyBWMjETMBEGA1UECgwKQXBwbGUgSW5jLjESMBAGA1UEBwwJQ3VwZXJ0 +aW5vMQswCQYDVQQIDAJDQTELMAkGA1UEBhMCVVMwIBcNMTcxMDIwMjE0MDE2WhgP +MjExNzA5MjYyMTQwMTZaMIGVMSwwKgYDVQQDDCNDQSBzZXJpYWwgaW52YWxpZCBu +b3RhZnRlciBjb21wbGV0ZTEiMCAGA1UECwwZVmFsaWQgUHJvamVjdCBUZXN0IENB +cyBWMjETMBEGA1UECgwKQXBwbGUgSW5jLjESMBAGA1UEBwwJQ3VwZXJ0aW5vMQsw +CQYDVQQIDAJDQTELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDkxy6tXDpG9zmdAXGJwaqOUlLq9VPeadcYdwjWCkKIpQnxEMzHc8DW +IAqNYt4rTQz8DQn/mKbrKNdYOIzUP86GZBrNK4h+q5j/ylUT3qN6ceLE5jA48KXb +thCgqA5rLP0aciE2X36Uky3qKQb5UO+ZVwPR4Y29jkjQxojdUJaxeUVFaTtOZIBr +NKLFXVoSfox/TfCn+hgbPr+/ViQHsATOCE9ZGM9WIVQnRbcWVyM4hfuzPhF6+qiW +6iyIylAsHzffybyRC2i6MPo/K8wirRtVj2h5f6ikhK6dIMC8RUpkChBiFNgJjsJi +TEzMOqc/r+fL1KzTgnVUAzi1MNjiZ+cvAgMBAAGjgacwgaQwDgYDVR0PAQH/BAQD +AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFPTVk6vvBlWrMKsRTO0x +hnexYR/NMB8GA1UdIwQYMBaAFLpW2Fdmvfxb4hDyObOvsnLtVQ8cMD4GA1UdHwQ3 +MDUwM6AxoC+GLWh0dHA6Ly92YWxpZHRlc3QuYXBwbGUuZ2VvZmZrLm5ldC92Mi1y +b290LmNybDANBgkqhkiG9w0BAQsFAAOCAQEAjlfvw/ykCfoStR83J1gaVCiZLskf +mMbjlgVWVuKuWj0CCP7663pVvyaqktWlLKwmvkJyKUEcInPTJfCEFGXoJ2tgAdgZ +H+UBePMQ08JtOHN8dPWJ00+jejF9zaRtOw4bxzADwSxYgKPg5dkWjpQTUwTqFOTG +LFJvtZNB/XQ2QdpLMR0K4Rc1CFaA676OA34ivOtkjHUeK1CPOPLWR87D4WXV6Xu9 +YblTnXa3xaqCa6m6NWNCliClhKgaKWEZbDpcRaZgjCX/VXx2KVue/qIqs8xuZmZj +WXAwlx6zDXBx83xzy6yoN8qQzyLAuWBwU1dF5DndmXl6rkvr2j9ahRNfjQ== +-----END CERTIFICATE----- diff --git a/SecurityTests/si-88-sectrust-valid-data/ca-nb.pem b/SecurityTests/si-88-sectrust-valid-data/ca-nb.pem new file mode 100644 index 00000000..91d3ec8d --- /dev/null +++ b/SecurityTests/si-88-sectrust-valid-data/ca-nb.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIERzCCAy+gAwIBAgIEKKebDjANBgkqhkiG9w0BAQsFADCBhzEeMBwGA1UEAwwV +VmFsaWQgVGVzdCBDQSBSb290IFYyMSIwIAYDVQQLDBlWYWxpZCBQcm9qZWN0IFRl +c3QgQ0FzIFYyMRMwEQYDVQQKDApBcHBsZSBJbmMuMRIwEAYDVQQHDAlDdXBlcnRp +bm8xCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzAgFw0xNzEwMjAyMTQwMTJaGA8y +MTE3MDkyNjIxNDAxMlowgZYxLTArBgNVBAMMJENBIHNlcmlhbCBpbnZhbGlkIG5v +dGJlZm9yZSBjb21wbGV0ZTEiMCAGA1UECwwZVmFsaWQgUHJvamVjdCBUZXN0IENB +cyBWMjETMBEGA1UECgwKQXBwbGUgSW5jLjESMBAGA1UEBwwJQ3VwZXJ0aW5vMQsw +CQYDVQQIDAJDQTELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDNgpIIellp1m7XZHv56/mogUhJQUoNNKoDw76PT7ksL3tK5TT4KjZr +GFqZTk4jEUX4or7VpgJA2AC8EHjkk2gZb43q/KjNUS0/UxQKEnDBzhyW44YPSLyI +H7nxI+rwz+JP7TOsj4bKzlppc3GIF7P3uUaGHpil3pXdOE0EQjIfqM1IkZNqG41I +O5YaE+d8zH2Us/ZhCLXtNigggN5OScH7p7nPAhL+Od8fyXakxV/DG83pCraYf6zW +jxDWkrq73UGiLsn0v+SElOV2GCuFNSAW1yyICJRGek3YUYBS/t4C6+Qz6k3nGVyn +z/Hy2x6kZYEr4aIVhhNEL/CjOO4ZdWgtAgMBAAGjgacwgaQwDgYDVR0PAQH/BAQD +AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFIUqPu9o57ZUK0WCC0GI +w912c0PBMB8GA1UdIwQYMBaAFLpW2Fdmvfxb4hDyObOvsnLtVQ8cMD4GA1UdHwQ3 +MDUwM6AxoC+GLWh0dHA6Ly92YWxpZHRlc3QuYXBwbGUuZ2VvZmZrLm5ldC92Mi1y +b290LmNybDANBgkqhkiG9w0BAQsFAAOCAQEAF09VSr2PcItAMeZ27daa94q5249P +TQnL9HhaF6P0lGl6QtzlaIjQTxX5fBxdwLP49rxNXDMmCjFP5Aplb19WVjRzTLBg +J9x3EwyETfrrtpnf353OLZW0kHeu1zuUXB+74ihuuCgp/rRMxYQCdrpt0OGplKPR +P7XTa7XgN9LbtLpg9K91hFT595yOIT3PfrF0ODI0Mm6g44IRI66wYITTo3D7QR5k +RTh6fazpokORC85DpiDnWJWgHsRe9mXJ0bgbqQ2WN767G8IwfMLaTYfkXRTqP/HQ +F0esukkYyFua8tRy6Q7lgvyjETAQRYqKY3rD1leOE//045OqwW5jDtQP5Q== +-----END CERTIFICATE----- diff --git a/SecurityTests/si-88-sectrust-valid-data/leaf-na-ok1.pem b/SecurityTests/si-88-sectrust-valid-data/leaf-na-ok1.pem new file mode 100644 index 00000000..e4811f96 --- /dev/null +++ b/SecurityTests/si-88-sectrust-valid-data/leaf-na-ok1.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEjDCCA3SgAwIBAgIEENMx9jANBgkqhkiG9w0BAQsFADCBlTEsMCoGA1UEAwwj +Q0Egc2VyaWFsIGludmFsaWQgbm90YWZ0ZXIgY29tcGxldGUxIjAgBgNVBAsMGVZh +bGlkIFByb2plY3QgVGVzdCBDQXMgVjIxEzARBgNVBAoMCkFwcGxlIEluYy4xEjAQ +BgNVBAcMCUN1cGVydGlubzELMAkGA1UECAwCQ0ExCzAJBgNVBAYTAlVTMCAXDTE3 +MTAyMDIxNDAyNFoYDzIxMTcwOTI2MjE0MDI0WjCBmzEyMDAGA1UEAwwpTGVhZiBz +ZXJpYWwgaW52YWxpZCBub3RhZnRlciBjb21wbGV0ZSBvazExIjAgBgNVBAsMGVZh +bGlkIFByb2plY3QgVGVzdCBDQXMgVjIxEzARBgNVBAoMCkFwcGxlIEluYy4xEjAQ +BgNVBAcMCUN1cGVydGlubzELMAkGA1UECAwCQ0ExCzAJBgNVBAYTAlVTMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4vFPQInu9kkPArjiI5KwJdQJRigL +7m90BgpOmTKnKUwN/QcaT2DqV7/bllniEGsiiV0xE1c1CWiddj0gb+Pg4N2bFU3a +YRrpL1NSh2CQ4mLf+ghWr0E/ZG15TqMv9mx7bA13U2RPpNBq0a7wOGQ7H0htjp9h +Lt+Ymt26COyEV59sXNKTuMby4pzUonDTQaiuk3zPWwuASqT+FY1xvOLhnXu280Pa +9TedtKqSfzd2QhCggqyvTdlPmufcb6vglJJfWg0Kmid+yWybxNrtUexxHAOZVLR1 +D6x9edlAfn7Yjna9wv0wxUv9Ky3Jb6Op3PYqqW6MWtDzuQtSGeH3qgZsfwIDAQAB +o4HZMIHWMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaA +FPTVk6vvBlWrMKsRTO0xhnexYR/NMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly92 +YWxpZHRlc3QuYXBwbGUuZ2VvZmZrLm5ldC92Mi1zZXJpYWwtaW52YWxpZC1ub3Rh +ZnRlci1jb21wbGV0ZS5jcmwwOQYIKwYBBQUHAQEELTArMCkGCCsGAQUFBzABhh1o +dHRwOi8va25vd24tYW5zd2VyLW9jc3Avb2NzcDANBgkqhkiG9w0BAQsFAAOCAQEA +eePooJ+q7jsKxadWLj2G1M6idyUxmIEd2KXJaO84KU1KumwW/92v10YWn055cwVR ++xI7+wk0XffXUguprB7ORA6AxlLc4DgGXextPB7CQRxbNgEMz0Ru+w7ZO5gEM9YD +R/2SjcEk+TUt8DJiFudcBg7Z8YlopVGw2gRTqXgYO8PNtDyV2ecdDpBcbfakAMZT +KRe8BV9YilZPsxz2risXlVzKm1GmqxyAg28k6tkc1m/7XaoKL4iTj2mlr/nZC33l +xzI5SMcLAjqQjFneVI2P0Tl+zKwGB3B8NZTGA3tL3iq3ehHJ/Ah8db3qQB9ZjXz7 +2DQhwSzki31z9LIjnkEWOw== +-----END CERTIFICATE----- diff --git a/SecurityTests/si-88-sectrust-valid-data/leaf-na-ok2.pem b/SecurityTests/si-88-sectrust-valid-data/leaf-na-ok2.pem new file mode 100644 index 00000000..1b5d4da4 --- /dev/null +++ b/SecurityTests/si-88-sectrust-valid-data/leaf-na-ok2.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEjTCCA3WgAwIBAgIFAMtrvtEwDQYJKoZIhvcNAQELBQAwgZUxLDAqBgNVBAMM +I0NBIHNlcmlhbCBpbnZhbGlkIG5vdGFmdGVyIGNvbXBsZXRlMSIwIAYDVQQLDBlW +YWxpZCBQcm9qZWN0IFRlc3QgQ0FzIFYyMRMwEQYDVQQKDApBcHBsZSBJbmMuMRIw +EAYDVQQHDAlDdXBlcnRpbm8xCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzAgFw0x +NzEwMjYxOTAwNTdaGA8yMTE3MTAwMjE5MDA1N1owgZsxMjAwBgNVBAMMKUxlYWYg +c2VyaWFsIGludmFsaWQgbm90YWZ0ZXIgY29tcGxldGUgb2syMSIwIAYDVQQLDBlW +YWxpZCBQcm9qZWN0IFRlc3QgQ0FzIFYyMRMwEQYDVQQKDApBcHBsZSBJbmMuMRIw +EAYDVQQHDAlDdXBlcnRpbm8xCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMsk/Ztsh+g2mYotKMygQYYrRBAT +GPKcuNNSoz2snnn0FlW8O+Z8Pvq19bZHpBalzHIGHOuHn5k4hw3V71rC12v8/+5d +gZ1ztkpgzHSK8vjXvqu/cJGBWisiQq/iZCXBImhMYvv8awCVv9LDo4NMq9e+i6ZX +RewiZKHC5oiqUK0kSi5Emi4BX6T3GFmB/d/uNJymR3LSk5lQHAwXimhBKTy2DOk0 +VFZCrRHxWbPfX+Fu5xFiBnodGKabBlorrauJ5vNdultiEpVjoRjhnOejk10+D9lD +epG3zpe6c1SG5NJNxF2rxkQeZooOjFGS2ahJrOff5Tarm/AV0+pb2rimDEcCAwEA +AaOB2TCB1jAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAW +gBT01ZOr7wZVqzCrEUztMYZ3sWEfzTBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8v +dmFsaWR0ZXN0LmFwcGxlLmdlb2Zmay5uZXQvdjItc2VyaWFsLWludmFsaWQtbm90 +YWZ0ZXItY29tcGxldGUuY3JsMDkGCCsGAQUFBwEBBC0wKzApBggrBgEFBQcwAYYd +aHR0cDovL2tub3duLWFuc3dlci1vY3NwL29jc3AwDQYJKoZIhvcNAQELBQADggEB +AF8bFBX5VEiECFrq+MuBXT8qdQTPQ/fsJZunm8bjIYbAA0arpnjs0GrFZBxonjbU +lci09a/NuE3ED4PeONqDqt3O+EYZzJ3VxC1TuReKf3IJdx8EpMNP6ganD7aWG73T +lA/g3jEck05pvpHPLVJzWRYECk3W7JA0JU204H50R5oV32qfO85rDhpxgrzEy/dt +QJhV4ffEtpotnW8bKySpOx2IiXTM1xa3jrIfXhAgISsDiSDTwfxv4CHwiiBs+zYx +KVVpRkOri3YbFGPjWGM4J/Yq9sX8o1rK484GYMxmIB0J2wz8y/ECmqcVt8NCW6B8 +DKmr7chPaDLPpy+OPfqumII= +-----END CERTIFICATE----- diff --git a/SecurityTests/si-88-sectrust-valid-data/leaf-nb-ok1.pem b/SecurityTests/si-88-sectrust-valid-data/leaf-nb-ok1.pem new file mode 100644 index 00000000..9d1dce48 --- /dev/null +++ b/SecurityTests/si-88-sectrust-valid-data/leaf-nb-ok1.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEkDCCA3igAwIBAgIFAMfTmU4wDQYJKoZIhvcNAQELBQAwgZYxLTArBgNVBAMM +JENBIHNlcmlhbCBpbnZhbGlkIG5vdGJlZm9yZSBjb21wbGV0ZTEiMCAGA1UECwwZ +VmFsaWQgUHJvamVjdCBUZXN0IENBcyBWMjETMBEGA1UECgwKQXBwbGUgSW5jLjES +MBAGA1UEBwwJQ3VwZXJ0aW5vMQswCQYDVQQIDAJDQTELMAkGA1UEBhMCVVMwIBcN +MTcxMDIwMjE0MDE3WhgPMjExNzA5MjYyMTQwMTdaMIGcMTMwMQYDVQQDDCpMZWFm +IHNlcmlhbCBpbnZhbGlkIG5vdGJlZm9yZSBjb21wbGV0ZSBvazExIjAgBgNVBAsM +GVZhbGlkIFByb2plY3QgVGVzdCBDQXMgVjIxEzARBgNVBAoMCkFwcGxlIEluYy4x +EjAQBgNVBAcMCUN1cGVydGlubzELMAkGA1UECAwCQ0ExCzAJBgNVBAYTAlVTMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6+qu3MmEt0qlxWHQvKsP3c7v +nkasrhfjvfJDnwfGXXnwjrewexwvquDXVEerJCm+hw4d/DHt2neMvNpk5H5DD0dh +H/3TElzKR6Pu+AG8Q6tFOQi13SSCWuNOs6hPvdWZEo/tab3swZi+grnA43Ye7RV4 +gPn3gLWWJRMu5sYOwWK5jMeeV7E29GO1HBIRHzER1F1ICqge9UWchofu869u+VzZ +OfTj/6jQHe1+o7Jx1nwAgHVJygpu0iT46Ztjox1usAhovleVsiG5fJB7tMcSMwPf +Aq57Ff5tuDyfYE7Ewug9qfwf6refYTpVw4w35u74UUNs3QkwL9fJnr7me1pW3QID +AQABo4HaMIHXMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMB8GA1UdIwQY +MBaAFIUqPu9o57ZUK0WCC0GIw912c0PBMFsGA1UdHwRUMFIwUKBOoEyGSmh0dHA6 +Ly92YWxpZHRlc3QuYXBwbGUuZ2VvZmZrLm5ldC92Mi1zZXJpYWwtaW52YWxpZC1u +b3RiZWZvcmUtY29tcGxldGUuY3JsMDkGCCsGAQUFBwEBBC0wKzApBggrBgEFBQcw +AYYdaHR0cDovL2tub3duLWFuc3dlci1vY3NwL29jc3AwDQYJKoZIhvcNAQELBQAD +ggEBAL23N0zdcJ3KeMwWQupj+cQq6d2rWya7hsI6Bq6AXdFUYAHI1w5OS/eOwNzE +gF/igYncv1215GvMyK/3cboNE+IHcENhvMMj0Jmw62PrQ85Lktna/VGUqKdn+XXi +ah4dpF6ZmooEJhrthszrxuMwLLzmXGBrzVW8FXrYjTgQoKKiRJnjK8TJO+JMZLBq +ylloA9W16QP72Mxtp0Gjrv91aQcD+SvcQQG7HUFOZYDhR1172fzF4eAqp39qAMnK +/aZrphMTJgeJCB8Htwak0GsucIgPojWzMQhYBgNPywpefa5TqGZcNxBE8E/Q0zfB +24/usBYW4OttPMmGN2Xb5JmmpBM= +-----END CERTIFICATE----- diff --git a/SecurityTests/si-88-sectrust-valid-data/leaf-nb-ok2.pem b/SecurityTests/si-88-sectrust-valid-data/leaf-nb-ok2.pem new file mode 100644 index 00000000..55cf74d2 --- /dev/null +++ b/SecurityTests/si-88-sectrust-valid-data/leaf-nb-ok2.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEjzCCA3egAwIBAgIEOw8TPTANBgkqhkiG9w0BAQsFADCBljEtMCsGA1UEAwwk +Q0Egc2VyaWFsIGludmFsaWQgbm90YmVmb3JlIGNvbXBsZXRlMSIwIAYDVQQLDBlW +YWxpZCBQcm9qZWN0IFRlc3QgQ0FzIFYyMRMwEQYDVQQKDApBcHBsZSBJbmMuMRIw +EAYDVQQHDAlDdXBlcnRpbm8xCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzAgFw0x +NzEwMjYxOTAwNTJaGA8yMTE3MTAwMjE5MDA1MlowgZwxMzAxBgNVBAMMKkxlYWYg +c2VyaWFsIGludmFsaWQgbm90YmVmb3JlIGNvbXBsZXRlIG9rMjEiMCAGA1UECwwZ +VmFsaWQgUHJvamVjdCBUZXN0IENBcyBWMjETMBEGA1UECgwKQXBwbGUgSW5jLjES +MBAGA1UEBwwJQ3VwZXJ0aW5vMQswCQYDVQQIDAJDQTELMAkGA1UEBhMCVVMwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJ7duvdnmpBgDto1UFo5u11+ZR +QaBxvbHS/zd4ECjrWrHHNwVc03Sk6/2SRgd8JEPmWZOe/pPO+aGGhP2jVacIg218 +qxoJVyDfodaYaTJINJj+K1ojvpOAvUigOSWCUqCtOMZI9boj8Mzq3KJh0mdiMvKm +Jdzlgs07D57+vJ2G+v2I8LHLg3/obOIr+Vq1LMW+ImZFFdv2YzSzyCbSOuZU/AvZ +Mw4EpystbGo159c+Al2JAqAFknsGGWalDyZ3O4nQtZXVfbz18u5iq+h6ymBP66gG +YlG7lbdrQO+tOmxNTh+5tONB9K9IkdGqLUN5GTC4G78GDbpXeTnzxKn1MSTxAgMB +AAGjgdowgdcwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgw +FoAUhSo+72jntlQrRYILQYjD3XZzQ8EwWwYDVR0fBFQwUjBQoE6gTIZKaHR0cDov +L3ZhbGlkdGVzdC5hcHBsZS5nZW9mZmsubmV0L3YyLXNlcmlhbC1pbnZhbGlkLW5v +dGJlZm9yZS1jb21wbGV0ZS5jcmwwOQYIKwYBBQUHAQEELTArMCkGCCsGAQUFBzAB +hh1odHRwOi8va25vd24tYW5zd2VyLW9jc3Avb2NzcDANBgkqhkiG9w0BAQsFAAOC +AQEAec1pS/Y9HIcN416ZWA4uUIYG2jR9fGW6MGdoam0ev+JSiGa4+1J0Da+3Pe/4 +geTaRB39Y5x1kR8EL+psB4QWlfgOfAUdgfLuV5a/zykdYLOBXFX1OysTGyrGcrcU +qMMsmlpNL98/tpKq0ck8A6TVuOzWFd16YNUu46HVY4QblCU4PHngWbwBr0b6lr7F +L3/70R8u3H4dUQQThge88u8wG3Dy2F84TTvHYvNFwfKT9ADK34sgmpbX/JOwdjq8 +QQ0t0VfK3pgqC9fluug11r9hyIyFlX3DM5JFcnBkyHoJ3ruatgmBgraMVwgXk0T+ +6YWPpa1A1E3nbBPUW54V6F4EGA== +-----END CERTIFICATE----- diff --git a/SecurityTests/si-88-sectrust-valid-data/leaf-nb-revoked1.pem b/SecurityTests/si-88-sectrust-valid-data/leaf-nb-revoked1.pem new file mode 100644 index 00000000..c8b8e1b5 --- /dev/null +++ b/SecurityTests/si-88-sectrust-valid-data/leaf-nb-revoked1.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIElDCCA3ygAwIBAgIERFwMFjANBgkqhkiG9w0BAQsFADCBljEtMCsGA1UEAwwk +Q0Egc2VyaWFsIGludmFsaWQgbm90YmVmb3JlIGNvbXBsZXRlMSIwIAYDVQQLDBlW +YWxpZCBQcm9qZWN0IFRlc3QgQ0FzIFYyMRMwEQYDVQQKDApBcHBsZSBJbmMuMRIw +EAYDVQQHDAlDdXBlcnRpbm8xCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzAgFw0x +NzEwMjAyMTQwMjJaGA8yMTE3MDkyNjIxNDAyMlowgaExODA2BgNVBAMML0xlYWYg +c2VyaWFsIGludmFsaWQgbm90YmVmb3JlIGNvbXBsZXRlIHJldm9rZWQxMSIwIAYD +VQQLDBlWYWxpZCBQcm9qZWN0IFRlc3QgQ0FzIFYyMRMwEQYDVQQKDApBcHBsZSBJ +bmMuMRIwEAYDVQQHDAlDdXBlcnRpbm8xCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJV +UzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALd3UP8l/Cg881QL929s +xh7iyDKhBL0qR5CPwsJ2yIOtUlBgenCj3h/LHliAvcy12764T2pOM9kP+IoKXOqL +Vjw9LaGZ1LeuOZNyRCNDgMO2sPnrW5t0fim3AvaDslFQwuid/QJLOdDUpQsScvP0 +/q35TVGcEYKdIYse9ixAX6ET8yMCMEWOthYtgS93bkSuytR82aQjOCfW3gM9q99n +X4+R5EsEgzKL+Ieg2xTZ1EdnKPgq13zpc62vTNppC4DQBpJl/FL8Zx4iDc85Vx79 +wa+5aWvbzZYiF9Lzt1DiJej8MYc5KbH2mSVNl3dEzwU6cDeV4AbruAS8gWhT3qb/ +5h0CAwEAAaOB2jCB1zAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAfBgNV +HSMEGDAWgBSFKj7vaOe2VCtFggtBiMPddnNDwTBbBgNVHR8EVDBSMFCgTqBMhkpo +dHRwOi8vdmFsaWR0ZXN0LmFwcGxlLmdlb2Zmay5uZXQvdjItc2VyaWFsLWludmFs +aWQtbm90YmVmb3JlLWNvbXBsZXRlLmNybDA5BggrBgEFBQcBAQQtMCswKQYIKwYB +BQUHMAGGHWh0dHA6Ly9rbm93bi1hbnN3ZXItb2NzcC9vY3NwMA0GCSqGSIb3DQEB +CwUAA4IBAQB+6E3CuqL/Wt8lYHK8xgJfeJIFQ7hpPrq0Z6srdix3+SIOO1wabKww +SO2lsR0KeDvkBFDp6D5Zot1EeLvLyXJj235FAlV6ROghNHsDpPK5bzlpxbSTLp6u +LVWhbBxkj7QCBFtEj3EMHkUNmfzCzDgOBVqJzwryU3fU+gP1k0pqdZUuQm3shYud +H7Je351iGIKos6551FxhnZ72lwKML0tO57lsnegy/++0pjuI9amTp+FH51ys/ma6 +8gdhLf854b2c36luYAEXCzN+VAu8RCKxCAVqgtiVlBjv31wFLlKgBLucFAl0u2dv +qQgHRi6jvwNMLbaTbo2PQ/S9H+keg8ao +-----END CERTIFICATE----- diff --git a/SecurityTests/si-88-sectrust-valid-data/root.pem b/SecurityTests/si-88-sectrust-valid-data/root.pem new file mode 100644 index 00000000..1d70778f --- /dev/null +++ b/SecurityTests/si-88-sectrust-valid-data/root.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID1zCCAr+gAwIBAgIJAIwMjVA0KR22MA0GCSqGSIb3DQEBCwUAMIGHMR4wHAYD +VQQDDBVWYWxpZCBUZXN0IENBIFJvb3QgVjIxIjAgBgNVBAsMGVZhbGlkIFByb2pl +Y3QgVGVzdCBDQXMgVjIxEzARBgNVBAoMCkFwcGxlIEluYy4xEjAQBgNVBAcMCUN1 +cGVydGlubzELMAkGA1UECAwCQ0ExCzAJBgNVBAYTAlVTMCAXDTE3MDUwMTIyMzUz +MloYDzIxMTcwNDA3MjIzNTMyWjCBhzEeMBwGA1UEAwwVVmFsaWQgVGVzdCBDQSBS +b290IFYyMSIwIAYDVQQLDBlWYWxpZCBQcm9qZWN0IFRlc3QgQ0FzIFYyMRMwEQYD +VQQKDApBcHBsZSBJbmMuMRIwEAYDVQQHDAlDdXBlcnRpbm8xCzAJBgNVBAgMAkNB +MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMNt +FGCz0wqK9r6nQr/HEcJsipTxDj1nHJ1K1i7B6neibqqZZ76fp769JNFDyDqId3Ak +ncZeU1kxqbEbH7pnp1dVDbPUAa7kqMTnKRyhOW8aHC3BVgoWPyYvIEkzNdL5bTte +mFlKcM7/pCPmI0Mj5Ysv7mooKEsxoMgIbA84Ebwnf2HPsDa5jLq6PgAe0P9xktuh +jB8DKRN8r4eiQSpeB/7vN8i0cseJA4FpAch7voIKReKI1mOAVCkA9q9Yt2VK0Bp/ +dQEG9rKULV4dArju+lXI3YQp51mq1utsESYW7/Tac9g52OzxjxwT1ix62YoS8eE9 +q4FvfZV0IGrAHfRbfN0CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wHQYDVR0OBBYEFLpW2Fdmvfxb4hDyObOvsnLtVQ8cMA0GCSqGSIb3 +DQEBCwUAA4IBAQC2V+JsI5CH1UD04jk1Lxv7MQ4U+f+XXO16bV+AH5iTChOlj5sr +IA6vYhuw+LsAvdxWO9lLbHuA6hjHMoo4rp/uHxcNHILrkuWHG54+4jJ7tZ+8Uh8H +sXcWqcK2n8HkyidFGPcHf3SVXoxnPeogOUpKebbszpg/YFEm8zcODPw+FL/qdado +D6QcVwT4wRFt0B+TMFy0mZFnPHKVY38tZuAyEcR29cA2IyC85E/a59wQYknAx5H+ +TMwJQLkzDdWQTtmDVCxCgRf631c6FXYFHxFAzoXsoqP2rLZnpnjQqafyYPT80Xie +AADZ5+fl7eQQjY5bzI621nHPVBbUmc1tQCqK +-----END CERTIFICATE----- diff --git a/SecurityTests/testmain.c b/SecurityTests/testmain.c index 42f10fd8..6d6e5e8b 100644 --- a/SecurityTests/testmain.c +++ b/SecurityTests/testmain.c @@ -19,12 +19,14 @@ #include #include +#include "keychain/ckks/CKKS.h" int main(int argc, char *argv[]) { //printf("Build date : %s %s\n", __DATE__, __TIME__); //printf("WARNING: If running those tests on a device with a passcode, DONT FORGET TO UNLOCK!!!\n"); + SecCKKSDisable(); #if 0 && NO_SERVER SOSCloudKeychainServerInit(); #endif diff --git a/SecurityTool/authz.c b/SecurityTool/authz.c index 48e73a14..fa88c365 100644 --- a/SecurityTool/authz.c +++ b/SecurityTool/authz.c @@ -254,7 +254,7 @@ authorizationdb(int argc, char * const * argv) break; case '?': default: - return 2; + return SHOW_USAGE_MESSAGE; } } @@ -262,7 +262,7 @@ authorizationdb(int argc, char * const * argv) argv += optind; if (argc == 0) - return 2; // required right parameter(s) + return SHOW_USAGE_MESSAGE; // required right parameter(s) OSStatus status; @@ -301,7 +301,7 @@ authorizationdb(int argc, char * const * argv) CFRelease(shortcut_definition); } else - return 2; // take one optional argument - no more + return SHOW_USAGE_MESSAGE; // take one optional argument - no more } else if (!strcmp("remove", argv[0])) @@ -386,10 +386,10 @@ authorizationdb(int argc, char * const * argv) else if(!strcmp("enable", argv[1])) status = AuthorizationEnableSmartCard(auth_ref, TRUE); else - return 2; // unrecognized parameter + return SHOW_USAGE_MESSAGE; // unrecognized parameter } else - return 2; // required parameter missing + return SHOW_USAGE_MESSAGE; // required parameter missing } else if (!strcmp("merge", argv[0])) { status = 1; @@ -408,7 +408,7 @@ authorizationdb(int argc, char * const * argv) CFMutableDictionaryRef outDict = NULL; if (argc < 2 || argc > 3) - return 2; + return SHOW_USAGE_MESSAGE; if (!strcmp("-", argv[1])) { // Merging from . @@ -492,10 +492,10 @@ bail: CFRelease(outDict); } else - return 2; + return SHOW_USAGE_MESSAGE; } else - return 2; + return SHOW_USAGE_MESSAGE; if (auth_ref) AuthorizationFree(auth_ref, 0); @@ -563,7 +563,7 @@ authorize(int argc, char * const *argv) break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -571,7 +571,7 @@ authorize(int argc, char * const *argv) argv += optind; if (argc == 0) - return 2; // required right parameter(s) + return SHOW_USAGE_MESSAGE; // required right parameter(s) // set up AuthorizationFlags AuthorizationFlags flags = kAuthorizationFlagDefaults | @@ -682,7 +682,7 @@ execute_with_privileges(int argc, char * const *argv) break; case '?': default: - return 2; + return SHOW_USAGE_MESSAGE; } } @@ -690,7 +690,7 @@ execute_with_privileges(int argc, char * const *argv) argv += optind; if (argc == 0) - return 2; // required tool parameter(s) + return SHOW_USAGE_MESSAGE; // required tool parameter(s) OSStatus status; diff --git a/SecurityTool/createFVMaster.c b/SecurityTool/createFVMaster.c index dd623b7d..36671610 100644 --- a/SecurityTool/createFVMaster.c +++ b/SecurityTool/createFVMaster.c @@ -685,11 +685,11 @@ keychain_createMFV(int argc, char * const *argv) // Specify the keysize in bits (default 1024) keySizeInBits = atoi(optarg); if (!(keySizeInBits == SR_KEY_SIZE_IN_BITS || keySizeInBits == SR2_KEY_SIZE_IN_BITS || keySizeInBits == 4096)) - return 2; + return SHOW_USAGE_MESSAGE; break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } /* @@ -704,7 +704,7 @@ keychain_createMFV(int argc, char * const *argv) argv += optind; if (argc > 1) - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; keychainName = (argc == 1)?*argv:_masterKeychainName; if (!keychainName || *keychainName == '\0') diff --git a/SecurityTool/db_commands.cpp b/SecurityTool/db_commands.cpp index 571ed65b..381501f9 100644 --- a/SecurityTool/db_commands.cpp +++ b/SecurityTool/db_commands.cpp @@ -88,7 +88,7 @@ parse_guid(const char *name, CSSM_GUID *guid) else { sec_error("Invalid guid: %s", name); - return 2; + return SHOW_USAGE_MESSAGE; } return 0; @@ -167,7 +167,7 @@ db_create(int argc, char * const *argv) break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } diff --git a/SecurityTool/entitlements.plist b/SecurityTool/entitlements.plist index ac3d1b60..76e6179f 100644 --- a/SecurityTool/entitlements.plist +++ b/SecurityTool/entitlements.plist @@ -19,5 +19,7 @@ application-identifier com.apple.security + com.apple.private.keychain.keychaincontrol + diff --git a/SecurityTool/identity_find.m b/SecurityTool/identity_find.m index 1fe81888..52c20e66 100644 --- a/SecurityTool/identity_find.m +++ b/SecurityTool/identity_find.m @@ -492,7 +492,7 @@ keychain_find_identity(int argc, char * const *argv) else if (!strcmp(optarg, "macappstore")) policyFlags |= 1 << 11; else { - result = 2; /* @@@ Return 2 triggers usage message. */ + result = SHOW_USAGE_MESSAGE; goto cleanup; } } diff --git a/SecurityTool/identity_prefs.c b/SecurityTool/identity_prefs.c index 2d67ab26..c0e21840 100644 --- a/SecurityTool/identity_prefs.c +++ b/SecurityTool/identity_prefs.c @@ -55,7 +55,7 @@ do_set_identity_preference(CFTypeRef keychainOrArray, // must have a service name if (!service) { - return 2; + return SHOW_USAGE_MESSAGE; } // find identity (if specified by name or hash) @@ -97,7 +97,7 @@ do_get_identity_preference(const char *service, { int result = 0; if (!service) { - return 2; + return SHOW_USAGE_MESSAGE; } CFStringRef serviceRef = CFStringCreateWithCString(NULL, service, kCFStringEncodingUTF8); SecCertificateRef certRef = NULL; @@ -228,7 +228,7 @@ set_identity_preference(int argc, char * const *argv) break; case '?': default: - result = 2; /* @@@ Return 2 triggers usage message. */ + result = SHOW_USAGE_MESSAGE; goto cleanup; } } diff --git a/SecurityTool/key_create.c b/SecurityTool/key_create.c index 6b193f4c..e14f64d2 100644 --- a/SecurityTool/key_create.c +++ b/SecurityTool/key_create.c @@ -146,7 +146,7 @@ parse_algorithm(const char *name, CSSM_ALGORITHMS *algorithm) else { sec_error("Invalid algorithm: %s", name); - return 2; + return SHOW_USAGE_MESSAGE; } return 0; @@ -262,7 +262,7 @@ key_create_pair(int argc, char * const *argv) break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -279,7 +279,7 @@ key_create_pair(int argc, char * const *argv) description = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8); } else if (argc != 0) - return 2; + return SHOW_USAGE_MESSAGE; else description = CFStringCreateWithCString(NULL, "", kCFStringEncodingUTF8); @@ -560,7 +560,7 @@ csr_create(int argc, char * const *argv) break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -577,7 +577,7 @@ csr_create(int argc, char * const *argv) description = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8); } else if (argc != 0) - return 2; + return SHOW_USAGE_MESSAGE; else description = CFStringCreateWithCString(NULL, "", kCFStringEncodingUTF8); diff --git a/SecurityTool/keychain_add.c b/SecurityTool/keychain_add.c index bfc65544..71d59496 100644 --- a/SecurityTool/keychain_add.c +++ b/SecurityTool/keychain_add.c @@ -958,11 +958,11 @@ keychain_add_certificates(int argc, char * const *argv) case 'k': keychainName = optarg; if (*keychainName == '\0') - return 2; + return SHOW_USAGE_MESSAGE; break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -970,7 +970,7 @@ keychain_add_certificates(int argc, char * const *argv) argv += optind; if (argc == 0) - return 2; + return SHOW_USAGE_MESSAGE; result = do_add_certificates(keychainName, argc, argv); diff --git a/SecurityTool/keychain_create.c b/SecurityTool/keychain_create.c index 00e8549d..8564f088 100644 --- a/SecurityTool/keychain_create.c +++ b/SecurityTool/keychain_create.c @@ -80,7 +80,7 @@ keychain_create(int argc, char * const *argv) break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } /* diff --git a/SecurityTool/keychain_delete.c b/SecurityTool/keychain_delete.c index 6ef85243..8f139089 100644 --- a/SecurityTool/keychain_delete.c +++ b/SecurityTool/keychain_delete.c @@ -55,7 +55,7 @@ do_delete_certificate(CFTypeRef keychainOrArray, const char *name, const char *h OSStatus result = noErr; SecKeychainItemRef itemToDelete = NULL; if (!name && !hash) { - return 2; + return SHOW_USAGE_MESSAGE; } itemToDelete = find_unique_certificate(keychainOrArray, name, hash); @@ -200,7 +200,7 @@ keychain_delete(int argc, char * const *argv) { case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } diff --git a/SecurityTool/keychain_export.m b/SecurityTool/keychain_export.m index 4164f2cb..188619f0 100644 --- a/SecurityTool/keychain_export.m +++ b/SecurityTool/keychain_export.m @@ -353,7 +353,7 @@ keychain_export(int argc, char * const *argv) itemSpec = IS_All; } else { - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } break; case 'f': @@ -391,7 +391,7 @@ keychain_export(int argc, char * const *argv) externFormat = kSecFormatPEMSequence; } else { - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } break; case 'w': @@ -405,7 +405,7 @@ keychain_export(int argc, char * const *argv) break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -427,7 +427,7 @@ keychain_export(int argc, char * const *argv) break; default: sec_error("Don't know how to wrap in specified format/type"); - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -716,7 +716,7 @@ ctk_export(int argc, char * const *argv) itemSpec = IS_All; } else { - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } break; case 'i': @@ -725,7 +725,7 @@ ctk_export(int argc, char * const *argv) case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } diff --git a/SecurityTool/keychain_find.c b/SecurityTool/keychain_find.c index a6e781a2..c1ac19c6 100644 --- a/SecurityTool/keychain_find.c +++ b/SecurityTool/keychain_find.c @@ -1383,7 +1383,7 @@ int keychain_set_internet_password_partition_list(int argc, char * const *argv) SetKeyToString(query, kSecAttrProtocol, optarg); break; case 's': - SetKeyToString(query, kSecAttrService, optarg); + SetKeyToString(query, kSecAttrServer, optarg); break; case 't': SetKeyToString(query, kSecAttrAuthenticationType, optarg); @@ -1925,7 +1925,7 @@ keychain_dump(int argc, char * const *argv) break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } diff --git a/SecurityTool/keychain_list.c b/SecurityTool/keychain_list.c index 02eac3a9..70284e4b 100644 --- a/SecurityTool/keychain_list.c +++ b/SecurityTool/keychain_list.c @@ -99,7 +99,7 @@ parse_domain(const char *name, SecPreferencesDomain *domain) else { sec_error("Invalid domain: %s", name); - return 2; + return SHOW_USAGE_MESSAGE; } return 0; @@ -188,7 +188,7 @@ keychain_list(int argc, char * const *argv) break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -363,7 +363,7 @@ keychain_default(int argc, char * const *argv) break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -375,7 +375,7 @@ keychain_default(int argc, char * const *argv) if (argc == 1) keychain = (SecKeychainRef)keychain_create_array(argc, argv); else if (argc > 0) - return 2; + return SHOW_USAGE_MESSAGE; if (use_domain) { @@ -399,7 +399,7 @@ keychain_default(int argc, char * const *argv) else { if (argc > 0) - return 2; + return SHOW_USAGE_MESSAGE; if (use_domain) { @@ -467,7 +467,7 @@ keychain_login(int argc, char * const *argv) break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -479,7 +479,7 @@ keychain_login(int argc, char * const *argv) if (argc == 1) keychain = (SecKeychainRef)keychain_create_array(argc, argv); else if (argc > 0) - return 2; + return SHOW_USAGE_MESSAGE; #if 0 if (use_domain) @@ -507,7 +507,7 @@ keychain_login(int argc, char * const *argv) else { if (argc > 0) - return 2; + return SHOW_USAGE_MESSAGE; if (use_domain) { diff --git a/SecurityTool/keychain_lock.c b/SecurityTool/keychain_lock.c index ce1be4df..20a8d549 100644 --- a/SecurityTool/keychain_lock.c +++ b/SecurityTool/keychain_lock.c @@ -89,7 +89,7 @@ keychain_lock(int argc, char * const *argv) break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } argc -= optind; @@ -105,7 +105,7 @@ keychain_lock(int argc, char * const *argv) } } else if (argc != 0) - return 2; + return SHOW_USAGE_MESSAGE; if (lockAll) result = do_lock_all(); diff --git a/SecurityTool/keychain_recode.c b/SecurityTool/keychain_recode.c index ddfba2ab..1de237c1 100644 --- a/SecurityTool/keychain_recode.c +++ b/SecurityTool/keychain_recode.c @@ -117,7 +117,7 @@ keychain_recode(int argc, char * const *argv) { case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } argc -= optind; @@ -141,7 +141,7 @@ keychain_recode(int argc, char * const *argv) } else - return 2; + return SHOW_USAGE_MESSAGE; result = do_recode(keychainName1, keychainName2); diff --git a/SecurityTool/keychain_show_info.c b/SecurityTool/keychain_show_info.c index 0952f051..7c099753 100644 --- a/SecurityTool/keychain_show_info.c +++ b/SecurityTool/keychain_show_info.c @@ -90,7 +90,7 @@ keychain_show_info(int argc, char * const *argv) } } else if (argc != 1) - return 2; + return SHOW_USAGE_MESSAGE; result = do_keychain_show_info(keychainName); diff --git a/SecurityTool/keychain_unlock.c b/SecurityTool/keychain_unlock.c index 1b5b5cab..0bd2c38a 100644 --- a/SecurityTool/keychain_unlock.c +++ b/SecurityTool/keychain_unlock.c @@ -84,7 +84,7 @@ keychain_unlock(int argc, char * const *argv) break; case '?': default: - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -101,7 +101,7 @@ keychain_unlock(int argc, char * const *argv) } } else if (argc != 0) - return 2; + return SHOW_USAGE_MESSAGE; if (!password && use_password) { diff --git a/SecurityTool/mds_install.cpp b/SecurityTool/mds_install.cpp index de4baf11..d2f2d621 100644 --- a/SecurityTool/mds_install.cpp +++ b/SecurityTool/mds_install.cpp @@ -23,6 +23,7 @@ * mds_install.cpp */ +#include "security_tool.h" #include "mds_install.h" #include @@ -31,7 +32,7 @@ mds_install(int argc, char * const *argv) { if(argc != 1) { /* crufty "show usage" return code */ - return 2; + return SHOW_USAGE_MESSAGE; } try { diff --git a/SecurityTool/security.c b/SecurityTool/security.c index 67abc3d3..a267dac1 100644 --- a/SecurityTool/security.c +++ b/SecurityTool/security.c @@ -907,7 +907,7 @@ usage(void) " -v Be more verbose about what's going on.\n" "%s commands are:\n", getprogname(), getprogname()); help(0, NULL); - return 2; + return SHOW_USAGE_MESSAGE; } /* Execute a single command. */ diff --git a/SecurityTool/security_tool.h b/SecurityTool/security_tool.h index 0bc40f9e..eb163cfd 100644 --- a/SecurityTool/security_tool.h +++ b/SecurityTool/security_tool.h @@ -26,6 +26,8 @@ #ifndef _SECURITY_TOOL_H_ #define _SECURITY_TOOL_H_ 1 +#define SHOW_USAGE_MESSAGE 2 + #ifdef __cplusplus extern "C" { #endif diff --git a/SecurityTool/smartcards.m b/SecurityTool/smartcards.m index fb934a18..93b9ed73 100644 --- a/SecurityTool/smartcards.m +++ b/SecurityTool/smartcards.m @@ -5,6 +5,7 @@ #import #import "smartcards.h" +#import "security_tool.h" const CFStringRef kTKSmartCardPreferencesDomain = CFSTR("com.apple.security.smartcard"); const CFStringRef kTKDisabledTokensPreferencesKey = CFSTR("DisabledTokens"); @@ -72,7 +73,7 @@ static int token(int argc, char * const *argv) } } - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } int smartcards(int argc, char * const *argv) { diff --git a/SecurityTool/translocate.c b/SecurityTool/translocate.c index 25364fa1..8625d918 100644 --- a/SecurityTool/translocate.c +++ b/SecurityTool/translocate.c @@ -28,6 +28,7 @@ #include +#include "security_tool.h" #include "translocate.h" static CFURLRef CFURLfromPath(const char * path, Boolean isDir) @@ -91,7 +92,7 @@ int translocate_create(int argc, char * const *argv) if (argc != 2) { - return 2; + return SHOW_USAGE_MESSAGE; } CFURLRef inUrl = CFURLfromPath(argv[1], PathIsDir(argv[1])); @@ -141,7 +142,7 @@ int translocate_policy(int argc, char * const *argv) if (argc != 2) { - return 2; + return SHOW_USAGE_MESSAGE; } CFURLRef inUrl = CFURLfromPath(argv[1], PathIsDir(argv[1])); @@ -178,7 +179,7 @@ int translocate_check(int argc, char * const *argv) if (argc != 2) { - return 2; + return SHOW_USAGE_MESSAGE; } CFURLRef inUrl = CFURLfromPath(argv[1], PathIsDir(argv[1])); @@ -215,7 +216,7 @@ int translocate_original_path(int argc, char * const * argv) if (argc != 2) { - return 2; + return SHOW_USAGE_MESSAGE; } CFURLRef inUrl = CFURLfromPath(argv[1], PathIsDir(argv[1])); diff --git a/SecurityTool/trust_settings_impexp.c b/SecurityTool/trust_settings_impexp.c index c549e2ad..b7b40842 100644 --- a/SecurityTool/trust_settings_impexp.c +++ b/SecurityTool/trust_settings_impexp.c @@ -46,7 +46,7 @@ extern int trust_settings_export(int argc, char * const *argv) unsigned len; if(argc < 2) { - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } optind = 1; @@ -59,12 +59,12 @@ extern int trust_settings_export(int argc, char * const *argv) domain = kSecTrustSettingsDomainSystem; break; default: - return 2; + return SHOW_USAGE_MESSAGE; } } if(optind != (argc - 1)) { /* no args left for settings file */ - return 2; + return SHOW_USAGE_MESSAGE; } settingsFile = argv[optind]; @@ -99,7 +99,7 @@ extern int trust_settings_import(int argc, char * const *argv) int rtn; if(argc < 2) { - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } optind = 1; @@ -109,12 +109,12 @@ extern int trust_settings_import(int argc, char * const *argv) domain = kSecTrustSettingsDomainAdmin; break; default: - return 2; + return SHOW_USAGE_MESSAGE; } } if(optind != (argc - 1)) { /* no args left for settings file */ - return 2; + return SHOW_USAGE_MESSAGE; } settingsFile = argv[optind]; rtn = readFileSizet(settingsFile, &settingsData, &settingsLen); diff --git a/SecurityTool/trusted_cert_add.c b/SecurityTool/trusted_cert_add.c index d2edf884..c2b1d12b 100644 --- a/SecurityTool/trusted_cert_add.c +++ b/SecurityTool/trusted_cert_add.c @@ -135,13 +135,13 @@ static int appendConstraintsToDict( if(policy != NULL) { oid = policyStringToOid(policy); if(oid == NULL) { - return 2; + return SHOW_USAGE_MESSAGE; } /* OID to SecPolicyRef */ SecPolicyRef policyRef = oidToPolicy(oid); if(policyRef == NULL) { - return 2; + return SHOW_USAGE_MESSAGE; } CFDictionaryAddValue(*dict, kSecTrustSettingsPolicy, policyRef); CFRelease(policyRef); @@ -226,7 +226,7 @@ trusted_cert_add(int argc, char * const *argv) int policyNameCount = 0, policyStringCount = 0, allowedErrorCount = 0; if(argc < 2) { - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } optind = 1; @@ -249,7 +249,7 @@ trusted_cert_add(int argc, char * const *argv) resultType = kSecTrustSettingsResultUnspecified; } else { - return 2; + return SHOW_USAGE_MESSAGE; } haveConstraints = 1; break; @@ -258,7 +258,7 @@ trusted_cert_add(int argc, char * const *argv) policyNames[policyNameCount++] = optarg; } else { fprintf(stderr, "Too many policy arguments.\n"); - return 2; + return SHOW_USAGE_MESSAGE; } haveConstraints = 1; break; @@ -271,7 +271,7 @@ trusted_cert_add(int argc, char * const *argv) policyStrings[policyStringCount++] = optarg; } else { fprintf(stderr, "Too many policy string arguments.\n"); - return 2; + return SHOW_USAGE_MESSAGE; } haveConstraints = 1; break; @@ -285,12 +285,12 @@ trusted_cert_add(int argc, char * const *argv) allowErr = (CSSM_RETURN)atoi(optarg); if (!allowErr) { fprintf(stderr, "Invalid value for allowed error.\n"); - return 2; + return SHOW_USAGE_MESSAGE; } allowedErrors[allowedErrorCount++] = allowErr; } else { fprintf(stderr, "Too many \"allowed error\" arguments.\n"); - return 2; + return SHOW_USAGE_MESSAGE; } haveConstraints = 1; break; @@ -312,7 +312,7 @@ trusted_cert_add(int argc, char * const *argv) break; default: case 'h': - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } if(ourRtn) { @@ -551,7 +551,7 @@ trusted_cert_remove(int argc, char * const *argv) break; default: case 'h': - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } @@ -563,12 +563,12 @@ trusted_cert_remove(int argc, char * const *argv) certFile = argv[optind]; break; default: - return 2; + return SHOW_USAGE_MESSAGE; } if(certFile == NULL) { fprintf(stderr, "No cert file specified.\n"); - return 2; + return SHOW_USAGE_MESSAGE; } if(readCertFile(certFile, &certRef)) { diff --git a/SecurityTool/trusted_cert_dump.c b/SecurityTool/trusted_cert_dump.c index 0fd4429d..bee4303d 100644 --- a/SecurityTool/trusted_cert_dump.c +++ b/SecurityTool/trusted_cert_dump.c @@ -23,6 +23,8 @@ * trusted_cert_dump.c */ +#include "security_tool.h" + #include "trusted_cert_dump.h" #include "trusted_cert_utils.h" @@ -218,12 +220,12 @@ trusted_cert_dump(int argc, char * const *argv) break; default: case 'h': - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } if(optind != argc) { - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } ortn = SecTrustSettingsCopyCertificates(domain, &certArray); diff --git a/SecurityTool/user_trust_enable.cpp b/SecurityTool/user_trust_enable.cpp index 338d7752..95eb82f8 100644 --- a/SecurityTool/user_trust_enable.cpp +++ b/SecurityTool/user_trust_enable.cpp @@ -23,6 +23,7 @@ * user_trust_enable.cpp */ +#include "security_tool.h" #include "user_trust_enable.h" #include #include @@ -57,11 +58,11 @@ user_trust_enable(int argc, char * const *argv) break; default: case 'h': - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } } if(optind != argc) { - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } if(op == utoShow) { diff --git a/SecurityTool/verify_cert.c b/SecurityTool/verify_cert.c index ae3c72e5..3e32b2c9 100644 --- a/SecurityTool/verify_cert.c +++ b/SecurityTool/verify_cert.c @@ -36,6 +36,7 @@ #include "trusted_cert_utils.h" #include "verify_cert.h" #include +#include "security_tool.h" /* * Read file as a cert, add to a CFArray, creating the array if necessary @@ -95,7 +96,7 @@ verify_cert(int argc, char * const *argv) CFOptionFlags revOptions = 0; if(argc < 2) { - return 2; /* @@@ Return 2 triggers usage message. */ + return SHOW_USAGE_MESSAGE; } /* permit network cert fetch unless explicitly turned off with '-L' */ actionFlags |= CSSM_TP_ACTION_FETCH_CERT_FROM_NET; diff --git a/base/SecBase.h b/base/SecBase.h index 4154dab2..f8808db6 100644 --- a/base/SecBase.h +++ b/base/SecBase.h @@ -221,6 +221,8 @@ struct SecKeychainAttributeInfo }; typedef struct SecKeychainAttributeInfo SecKeychainAttributeInfo; +#endif // SEC_OS_OSX_INCLUDES + /*! @function SecCopyErrorMessageString @abstract Returns a string describing the specified error result code. @@ -230,9 +232,7 @@ typedef struct SecKeychainAttributeInfo SecKeychainAttributeInfo; */ __nullable CFStringRef SecCopyErrorMessageString(OSStatus status, void * __nullable reserved) - __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA); - -#endif // SEC_OS_OSX_INCLUDES + __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_11_3); #undef SECTYPE @@ -310,11 +310,12 @@ CF_ENUM(OSStatus) { errSecSuccess = 0, /* No error. */ errSecUnimplemented = -4, /* Function or operation not implemented. */ + errSecDiskFull = -34, /* The disk is full. */ errSecDskFull = -34, - errSecIO = -36, /*I/O error (bummers)*/ - errSecOpWr = -49, /*file already open with write permission*/ + errSecIO = -36, /* I/O error. */ + errSecOpWr = -49, /* File already open with write permission. */ errSecParam = -50, /* One or more parameters passed to a function were not valid. */ - errSecWrPerm = -61, /* write permissions error*/ + errSecWrPerm = -61, /* Write permissions error. */ errSecAllocate = -108, /* Failed to allocate memory. */ errSecUserCanceled = -128, /* User canceled the operation. */ errSecBadReq = -909, /* Bad parameter or invalid state for operation. */ @@ -344,7 +345,7 @@ CF_ENUM(OSStatus) errSecInteractionNotAllowed = -25308, /* User interaction is not allowed. */ errSecReadOnlyAttr = -25309, /* The specified attribute could not be modified. */ errSecWrongSecVersion = -25310, /* This keychain was created by a different version of the system software and cannot be opened. */ - errSecKeySizeNotAllowed = -25311, /* This item specifies a key size which is too large. */ + errSecKeySizeNotAllowed = -25311, /* This item specifies a key size which is too large or too small. */ errSecNoStorageModule = -25312, /* A required component (data storage module) could not be loaded. You may need to restart your computer. */ errSecNoCertificateModule = -25313, /* A required component (certificate module) could not be loaded. You may need to restart your computer. */ errSecNoPolicyModule = -25314, /* A required component (policy module) could not be loaded. You may need to restart your computer. */ @@ -385,7 +386,6 @@ CF_ENUM(OSStatus) errSecAppleInvalidKeyEndDate = -67593, /* The specified key has an invalid end date. */ errSecConversionError = -67594, /* A conversion error has occurred. */ errSecAppleSSLv2Rollback = -67595, /* A SSLv2 rollback error has occurred. */ - errSecDiskFull = -34, /* The disk is full. */ errSecQuotaExceeded = -67596, /* The quota was exceeded. */ errSecFileTooBig = -67597, /* The file is too big. */ errSecInvalidDatabaseBlob = -67598, /* The specified database has an invalid blob. */ @@ -447,16 +447,16 @@ CF_ENUM(OSStatus) errSecTrustSettingDeny = -67654, /* The trust setting for this policy was set to Deny. */ errSecInvalidSubjectName = -67655, /* An invalid certificate subject name was encountered. */ errSecUnknownQualifiedCertStatement = -67656, /* An unknown qualified certificate statement was encountered. */ - errSecMobileMeRequestQueued = -67657, /* The MobileMe request will be sent during the next connection. */ - errSecMobileMeRequestRedirected = -67658, /* The MobileMe request was redirected. */ - errSecMobileMeServerError = -67659, /* A MobileMe server error occurred. */ - errSecMobileMeServerNotAvailable = -67660, /* The MobileMe server is not available. */ - errSecMobileMeServerAlreadyExists = -67661, /* The MobileMe server reported that the item already exists. */ - errSecMobileMeServerServiceErr = -67662, /* A MobileMe service error has occurred. */ - errSecMobileMeRequestAlreadyPending = -67663, /* A MobileMe request is already pending. */ - errSecMobileMeNoRequestPending = -67664, /* MobileMe has no request pending. */ - errSecMobileMeCSRVerifyFailure = -67665, /* A MobileMe CSR verification failure has occurred. */ - errSecMobileMeFailedConsistencyCheck = -67666, /* MobileMe has found a failed consistency check. */ + errSecMobileMeRequestQueued = -67657, + errSecMobileMeRequestRedirected = -67658, + errSecMobileMeServerError = -67659, + errSecMobileMeServerNotAvailable = -67660, + errSecMobileMeServerAlreadyExists = -67661, + errSecMobileMeServerServiceErr = -67662, + errSecMobileMeRequestAlreadyPending = -67663, + errSecMobileMeNoRequestPending = -67664, + errSecMobileMeCSRVerifyFailure = -67665, + errSecMobileMeFailedConsistencyCheck = -67666, errSecNotInitialized = -67667, /* A function was called without initializing CSSM. */ errSecInvalidHandleUsage = -67668, /* The CSSM handle does not match with the service type. */ errSecPVCReferentNotFound = -67669, /* A reference to the calling module was not found in the list of authorized callers. */ @@ -633,7 +633,7 @@ CF_ENUM(OSStatus) errSecInvalidStopOnPolicy = -67840, /* The stop-on policy was not valid. */ errSecInvalidTuple = -67841, /* The tuple was not valid. */ errSecMultipleValuesUnsupported = -67842, /* Multiple values are not supported. */ - errSecNotTrusted = -67843, /* The trust policy was not trusted. */ + errSecNotTrusted = -67843, /* The certificate was not trusted. */ errSecNoDefaultAuthority = -67844, /* No default authority was detected. */ errSecRejectedForm = -67845, /* The trust policy had a rejected form. */ errSecRequestLost = -67846, /* The request was lost. */ diff --git a/base/SecBasePriv.h b/base/SecBasePriv.h index 7c07fe28..40e33b3e 100644 --- a/base/SecBasePriv.h +++ b/base/SecBasePriv.h @@ -99,6 +99,7 @@ enum errSecFailedToSendIDSMessage = -25334, /* Failed to send IDS message. */ errSecDeviceIDNoMatch = -25335, /* The provided device ID does not match any device IDs in the ids account. */ errSecPeersNotAvailable = -25336, /* No peers in the circle are available/online. */ + errSecErrorStringNotAvailable= -25337, /* Unable to load error string for error */ }; // Guard for CFNetwork @@ -110,7 +111,17 @@ const char *cssmErrorString(CSSM_RETURN error) #endif OSStatus SecKeychainErrFromOSStatus(OSStatus osStatus) - __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA); + API_AVAILABLE(macos(10.4), ios(NA), bridgeos(NA)); + +/* + * For used when running in root session as a agent/daemon and want to redirect to + * a background user session. This call must be called before any Sec calls are done, + * so very early in main(). + * + * This only apply to MacOS where background session exists. + */ +void _SecSetSecuritydTargetUID(uid_t uid); + __END_DECLS diff --git a/base/SecSignpost.h b/base/SecSignpost.h new file mode 100644 index 00000000..ffbf852c --- /dev/null +++ b/base/SecSignpost.h @@ -0,0 +1,96 @@ +// +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _SECSIGNPOST_H_ +#define _SECSIGNPOST_H_ + + +#include + +#if !TARGET_IPHONE_SIMULATOR +#import +#endif + +/* + If you update this file, please also update SecurityCustomSignposts.plist. + */ + +static unsigned int SecSignpostComponent = 82; + +typedef CF_ENUM(unsigned int, SecSignpostType) { + /* between 0 and SecSignpostImpulse, use every even number + * After SecSignpostImpulse, its free for all for custom impulse points + * Remeber to update SecurityCustomSignposts.plist + */ + SecSignpostRestoreKeychain = 0, + SecSignpostRestoreOpenKeybag = 2, + SecSignpostUnlockKeybag = 4, + SecSignpostBackupKeychain = 6, + SecSignpostBackupOpenKeybag = 8, + SecSignpostUpgradePhase1 = 10, + SecSignpostUpgradePhase2 = 12, + SecSignpostBackupKeychainBackupable = 14, + SecSignpostRestoreKeychainBackupable = 16, + + SecSignpostSecItemAdd = 18, + SecSignpostSecItemUpdate = 20, + SecSignpostSecItemDelete = 22, + SecSignpostSecItemCopyMatching = 24, + + + SecSignpostImpulse = 0x1000, + SecSignpostImpulseBackupClassCount = 0x1001, + SecSignpostImpulseRestoreClassCount = 0x1002, +}; + + +static inline void SecSignpostStart(SecSignpostType type) { +#if !TARGET_IPHONE_SIMULATOR + kdebug_trace(ARIADNEDBG_CODE(SecSignpostComponent, type + 0), 0, 0, 0, 0); +#endif +} + +static inline void SecSignpostStop(SecSignpostType type) { +#if !TARGET_IPHONE_SIMULATOR + kdebug_trace(ARIADNEDBG_CODE(SecSignpostComponent, type + 1), 0, 0, 0, 0); +#endif +} + +static inline void SecSignpostBackupCount(SecSignpostType type, + CFStringRef cls, + CFIndex count, + unsigned filter) { +#if !TARGET_IPHONE_SIMULATOR + if (CFStringGetLength(cls) != 4) + return; + unsigned char ucls[5]; + if (!CFStringGetCString(cls, (char *)ucls, sizeof(ucls), kCFStringEncodingUTF8)) + return; + uint32_t c = (ucls[0] & 0xff) | (ucls[1] << 8) | (ucls[2] << 16) | (ucls[3] << 24); + kdebug_trace(ARIADNEDBG_CODE(SecSignpostComponent, type), c, count, filter, 0); +#endif +} + + +#endif /* _SECSIGNPOST_H_ */ diff --git a/base/SecurityCustomSignposts.plist b/base/SecurityCustomSignposts.plist new file mode 100644 index 00000000..969f9886 --- /dev/null +++ b/base/SecurityCustomSignposts.plist @@ -0,0 +1,207 @@ + + + + + + Name + SecurityProbes + Children + + + Name + RestoreKeychain + Type + Interval + Component + 82 + CodeBegin + 0 + CodeEnd + 1 + + + Name + RestoreOpenKeybag + Type + Interval + Component + 82 + CodeBegin + 2 + CodeEnd + 3 + + + Name + UnlockKeybag + Type + Interval + Component + 82 + CodeBegin + 4 + CodeEnd + 5 + + + Name + BackupKeychain + Type + Interval + Component + 82 + CodeBegin + 6 + CodeEnd + 7 + + + Name + BackupOpenKeybag + Type + Interval + Component + 82 + CodeBegin + 8 + CodeEnd + 9 + + + Name + UpgradePhase1 + Type + Interval + Component + 82 + CodeBegin + 10 + CodeEnd + 11 + + + Name + UpgradePhase2 + Type + Interval + Component + 82 + CodeBegin + 12 + CodeEnd + 13 + + + Name + BackupKeychainBackupable + Type + Interval + Component + 82 + CodeBegin + 14 + CodeEnd + 15 + + + Name + RestoreKeychainBackupable + Type + Interval + Component + 82 + CodeBegin + 16 + CodeEnd + 17 + + + Name + SecItemAdd + Type + Interval + Component + 82 + CodeBegin + 18 + CodeEnd + 19 + + + Name + SecItemUpdate + Type + Interval + Component + 82 + CodeBegin + 20 + CodeEnd + 21 + + + Name + SecItemDelete + Type + Interval + Component + 82 + CodeBegin + 22 + CodeEnd + 23 + + + Name + SecItemCopyMatching + Type + Interval + Component + 82 + CodeBegin + 24 + CodeEnd + 25 + + + Name + BackupClassCount + Type + Impulse + Component + 82 + Code + 0x1001 + ArgValueLabels + + Arg1 + class + Arg2 + count + Arg3 + filter + + + + Name + RestoreClassCount + Type + Impulse + Component + 82 + Code + 0x1002 + ArgValueLabels + + Arg1 + class + Arg2 + count + Arg3 + filter + + + + + + diff --git a/cssm/cssmapple.h b/cssm/cssmapple.h index 9823cd3f..1cead1e6 100644 --- a/cssm/cssmapple.h +++ b/cssm/cssmapple.h @@ -291,77 +291,76 @@ enum }; enum { - CSSMERR_CSSM_NO_USER_INTERACTION = CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_NO_USER_INTERACTION, - CSSMERR_AC_NO_USER_INTERACTION = CSSM_AC_BASE_ERROR + CSSM_ERRCODE_NO_USER_INTERACTION, - CSSMERR_CSP_NO_USER_INTERACTION = CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_NO_USER_INTERACTION, - CSSMERR_CL_NO_USER_INTERACTION = CSSM_CL_BASE_ERROR + CSSM_ERRCODE_NO_USER_INTERACTION, - CSSMERR_DL_NO_USER_INTERACTION = CSSM_DL_BASE_ERROR + CSSM_ERRCODE_NO_USER_INTERACTION, - CSSMERR_TP_NO_USER_INTERACTION = CSSM_TP_BASE_ERROR + CSSM_ERRCODE_NO_USER_INTERACTION, - - CSSMERR_CSSM_USER_CANCELED = CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_USER_CANCELED, - CSSMERR_AC_USER_CANCELED = CSSM_AC_BASE_ERROR + CSSM_ERRCODE_USER_CANCELED, - CSSMERR_CSP_USER_CANCELED = CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_USER_CANCELED, - CSSMERR_CL_USER_CANCELED = CSSM_CL_BASE_ERROR + CSSM_ERRCODE_USER_CANCELED, - CSSMERR_DL_USER_CANCELED = CSSM_DL_BASE_ERROR + CSSM_ERRCODE_USER_CANCELED, - CSSMERR_TP_USER_CANCELED = CSSM_TP_BASE_ERROR + CSSM_ERRCODE_USER_CANCELED, - - CSSMERR_CSSM_SERVICE_NOT_AVAILABLE = CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_SERVICE_NOT_AVAILABLE, - CSSMERR_AC_SERVICE_NOT_AVAILABLE = CSSM_AC_BASE_ERROR + CSSM_ERRCODE_SERVICE_NOT_AVAILABLE, - CSSMERR_CSP_SERVICE_NOT_AVAILABLE = CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_SERVICE_NOT_AVAILABLE, - CSSMERR_CL_SERVICE_NOT_AVAILABLE = CSSM_CL_BASE_ERROR + CSSM_ERRCODE_SERVICE_NOT_AVAILABLE, - CSSMERR_DL_SERVICE_NOT_AVAILABLE = CSSM_DL_BASE_ERROR + CSSM_ERRCODE_SERVICE_NOT_AVAILABLE, - CSSMERR_TP_SERVICE_NOT_AVAILABLE = CSSM_TP_BASE_ERROR + CSSM_ERRCODE_SERVICE_NOT_AVAILABLE, - - CSSMERR_CSSM_INSUFFICIENT_CLIENT_IDENTIFICATION = CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_INSUFFICIENT_CLIENT_IDENTIFICATION, - CSSMERR_AC_INSUFFICIENT_CLIENT_IDENTIFICATION = CSSM_AC_BASE_ERROR + CSSM_ERRCODE_INSUFFICIENT_CLIENT_IDENTIFICATION, - CSSMERR_CSP_INSUFFICIENT_CLIENT_IDENTIFICATION = CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_INSUFFICIENT_CLIENT_IDENTIFICATION, - CSSMERR_CL_INSUFFICIENT_CLIENT_IDENTIFICATION = CSSM_CL_BASE_ERROR + CSSM_ERRCODE_INSUFFICIENT_CLIENT_IDENTIFICATION, - CSSMERR_DL_INSUFFICIENT_CLIENT_IDENTIFICATION = CSSM_DL_BASE_ERROR + CSSM_ERRCODE_INSUFFICIENT_CLIENT_IDENTIFICATION, - CSSMERR_TP_INSUFFICIENT_CLIENT_IDENTIFICATION = CSSM_TP_BASE_ERROR + CSSM_ERRCODE_INSUFFICIENT_CLIENT_IDENTIFICATION, - - CSSMERR_CSSM_DEVICE_RESET = CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_DEVICE_RESET, - CSSMERR_AC_DEVICE_RESET = CSSM_AC_BASE_ERROR + CSSM_ERRCODE_DEVICE_RESET, - CSSMERR_CSP_DEVICE_RESET = CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_DEVICE_RESET, - CSSMERR_CL_DEVICE_RESET = CSSM_CL_BASE_ERROR + CSSM_ERRCODE_DEVICE_RESET, - CSSMERR_DL_DEVICE_RESET = CSSM_DL_BASE_ERROR + CSSM_ERRCODE_DEVICE_RESET, - CSSMERR_TP_DEVICE_RESET = CSSM_TP_BASE_ERROR + CSSM_ERRCODE_DEVICE_RESET, - - CSSMERR_CSSM_DEVICE_FAILED = CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_DEVICE_FAILED, - CSSMERR_AC_DEVICE_FAILED = CSSM_AC_BASE_ERROR + CSSM_ERRCODE_DEVICE_FAILED, - CSSMERR_CSP_DEVICE_FAILED = CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_DEVICE_FAILED, - CSSMERR_CL_DEVICE_FAILED = CSSM_CL_BASE_ERROR + CSSM_ERRCODE_DEVICE_FAILED, - CSSMERR_DL_DEVICE_FAILED = CSSM_DL_BASE_ERROR + CSSM_ERRCODE_DEVICE_FAILED, - CSSMERR_TP_DEVICE_FAILED = CSSM_TP_BASE_ERROR + CSSM_ERRCODE_DEVICE_FAILED, - - CSSMERR_CSSM_IN_DARK_WAKE = CSSM_CSSM_BASE_ERROR + CSSM_ERRCODE_IN_DARK_WAKE, - CSSMERR_AC_IN_DARK_WAKE = CSSM_AC_BASE_ERROR + CSSM_ERRCODE_IN_DARK_WAKE, - CSSMERR_CSP_IN_DARK_WAKE = CSSM_CSP_BASE_ERROR + CSSM_ERRCODE_IN_DARK_WAKE, - CSSMERR_CL_IN_DARK_WAKE = CSSM_CL_BASE_ERROR + CSSM_ERRCODE_IN_DARK_WAKE, - CSSMERR_DL_IN_DARK_WAKE = CSSM_DL_BASE_ERROR + CSSM_ERRCODE_IN_DARK_WAKE, - CSSMERR_TP_IN_DARK_WAKE = CSSM_TP_BASE_ERROR + CSSM_ERRCODE_IN_DARK_WAKE + CSSMERR_CSSM_NO_USER_INTERACTION = -2147417888, + CSSMERR_AC_NO_USER_INTERACTION = -2147405600, + CSSMERR_CSP_NO_USER_INTERACTION = -2147415840, + CSSMERR_CL_NO_USER_INTERACTION = -2147411744, + CSSMERR_DL_NO_USER_INTERACTION = -2147413792, + CSSMERR_TP_NO_USER_INTERACTION = -2147409696, + + CSSMERR_CSSM_USER_CANCELED = -2147417887, + CSSMERR_AC_USER_CANCELED = -2147405599, + CSSMERR_CSP_USER_CANCELED = -2147415839, + CSSMERR_CL_USER_CANCELED = -2147411743, + CSSMERR_DL_USER_CANCELED = -2147413791, + CSSMERR_TP_USER_CANCELED = -2147409695, + + CSSMERR_CSSM_SERVICE_NOT_AVAILABLE = -2147417886, + CSSMERR_AC_SERVICE_NOT_AVAILABLE = -2147405598, + CSSMERR_CSP_SERVICE_NOT_AVAILABLE = -2147415838, + CSSMERR_CL_SERVICE_NOT_AVAILABLE = -2147411742, + CSSMERR_DL_SERVICE_NOT_AVAILABLE = -2147413790, + CSSMERR_TP_SERVICE_NOT_AVAILABLE = -2147409694, + + CSSMERR_CSSM_INSUFFICIENT_CLIENT_IDENTIFICATION = -2147417885, + CSSMERR_AC_INSUFFICIENT_CLIENT_IDENTIFICATION = -2147405597, + CSSMERR_CSP_INSUFFICIENT_CLIENT_IDENTIFICATION = -2147415837, + CSSMERR_CL_INSUFFICIENT_CLIENT_IDENTIFICATION = -2147411741, + CSSMERR_DL_INSUFFICIENT_CLIENT_IDENTIFICATION = -2147413789, + CSSMERR_TP_INSUFFICIENT_CLIENT_IDENTIFICATION = -2147409693, + + CSSMERR_CSSM_DEVICE_RESET = -2147417884, + CSSMERR_AC_DEVICE_RESET = -2147405596, + CSSMERR_CSP_DEVICE_RESET = -2147415836, + CSSMERR_CL_DEVICE_RESET = -2147411740, + CSSMERR_DL_DEVICE_RESET = -2147413788, + CSSMERR_TP_DEVICE_RESET = -2147409692, + + CSSMERR_CSSM_DEVICE_FAILED = -2147417883, + CSSMERR_AC_DEVICE_FAILED = -2147405595, + CSSMERR_CSP_DEVICE_FAILED = -2147415835, + CSSMERR_CL_DEVICE_FAILED = -2147411739, + CSSMERR_DL_DEVICE_FAILED = -2147413787, + CSSMERR_TP_DEVICE_FAILED = -2147409691, + + CSSMERR_CSSM_IN_DARK_WAKE = -2147417882, + CSSMERR_AC_IN_DARK_WAKE = -2147405594, + CSSMERR_CSP_IN_DARK_WAKE = -2147415834, + CSSMERR_CL_IN_DARK_WAKE = -2147411738, + CSSMERR_DL_IN_DARK_WAKE = -2147413786, + CSSMERR_TP_IN_DARK_WAKE = -2147409690, }; /* AppleCSPDL, AppleCSP private error codes. */ enum { - CSSMERR_CSP_APPLE_ADD_APPLICATION_ACL_SUBJECT = CSSM_CSP_PRIVATE_ERROR + 0, - /* - * An attempt was made to use a public key which is incomplete due to - * the lack of algorithm-specific parameters. - */ - CSSMERR_CSP_APPLE_PUBLIC_KEY_INCOMPLETE = CSSM_CSP_PRIVATE_ERROR + 1, + CSSMERR_CSP_APPLE_ADD_APPLICATION_ACL_SUBJECT = -2147415040, + /* An attempt was made to use a public key which is incomplete due to + the lack of algorithm-specific parameters. */ + CSSMERR_CSP_APPLE_PUBLIC_KEY_INCOMPLETE = -2147415039, /* a code signature match failed */ - CSSMERR_CSP_APPLE_SIGNATURE_MISMATCH = CSSM_CSP_PRIVATE_ERROR + 2, + CSSMERR_CSP_APPLE_SIGNATURE_MISMATCH = -2147415038, - /* Key StartDate/EndDate invalid */ - CSSMERR_CSP_APPLE_INVALID_KEY_START_DATE = CSSM_CSP_PRIVATE_ERROR + 3, - CSSMERR_CSP_APPLE_INVALID_KEY_END_DATE = CSSM_CSP_PRIVATE_ERROR + 4, + /* Key start date invalid */ + CSSMERR_CSP_APPLE_INVALID_KEY_START_DATE = -2147415037, + /* Key end date invalid */ + CSSMERR_CSP_APPLE_INVALID_KEY_END_DATE = -2147415036, /* Keychain Syncing error codes */ - CSSMERR_CSPDL_APPLE_DL_CONVERSION_ERROR = CSSM_CSP_PRIVATE_ERROR + 5, + CSSMERR_CSPDL_APPLE_DL_CONVERSION_ERROR = -2147415035, /* SSLv2 padding check: rollback attack detected */ - CSSMERR_CSP_APPLE_SSLv2_ROLLBACK = CSSM_CSP_PRIVATE_ERROR + 6 + CSSMERR_CSP_APPLE_SSLv2_ROLLBACK = -2147415034, }; @@ -420,182 +419,188 @@ enum /* The OpenParameters argument passed to CSSM_DL_DbCreate or CSSM_DL_DbOpen was neither NULL nor a pointer to a valid CSSM_APPLEDL_OPEN_PARAMETERS structure. */ - CSSMERR_APPLEDL_INVALID_OPEN_PARAMETERS = CSSM_DL_PRIVATE_ERROR + 0, + CSSMERR_APPLEDL_INVALID_OPEN_PARAMETERS = -2147412992, /* an operation failed because the disk was full */ - CSSMERR_APPLEDL_DISK_FULL = CSSM_DL_PRIVATE_ERROR + 1, + CSSMERR_APPLEDL_DISK_FULL = -2147412991, /* an operation failed because a disk quota was exceeded */ - CSSMERR_APPLEDL_QUOTA_EXCEEDED = CSSM_DL_PRIVATE_ERROR + 2, + CSSMERR_APPLEDL_QUOTA_EXCEEDED = -2147412990, /* an operation failed because a file was too large */ - CSSMERR_APPLEDL_FILE_TOO_BIG = CSSM_DL_PRIVATE_ERROR + 3, + CSSMERR_APPLEDL_FILE_TOO_BIG = -2147412989, + + /* a keychain database's internal information ("blob") is invalid */ + CSSMERR_APPLEDL_INVALID_DATABASE_BLOB = -2147412988, /* a keychain database's internal information ("blob") is invalid */ - CSSMERR_APPLEDL_INVALID_DATABASE_BLOB = CSSM_DL_PRIVATE_ERROR + 4, - CSSMERR_APPLEDL_INVALID_KEY_BLOB = CSSM_DL_PRIVATE_ERROR + 5, + CSSMERR_APPLEDL_INVALID_KEY_BLOB = -2147412987, + + /* the internal data format version for a database's internal information ("blob") is invalid */ + CSSMERR_APPLEDL_INCOMPATIBLE_DATABASE_BLOB = -2147412986, /* the internal data format version for a database's internal information ("blob") is invalid */ - CSSMERR_APPLEDL_INCOMPATIBLE_DATABASE_BLOB = CSSM_DL_PRIVATE_ERROR + 6, - CSSMERR_APPLEDL_INCOMPATIBLE_KEY_BLOB = CSSM_DL_PRIVATE_ERROR + 7, + CSSMERR_APPLEDL_INCOMPATIBLE_KEY_BLOB = -2147412985, }; /* Apple X509TP private error codes. */ enum { /* Host name mismatch */ - CSSMERR_APPLETP_HOSTNAME_MISMATCH = CSSM_TP_PRIVATE_ERROR + 0, + CSSMERR_APPLETP_HOSTNAME_MISMATCH = -2147408896, /* Non-understood extension with Critical flag true */ - CSSMERR_APPLETP_UNKNOWN_CRITICAL_EXTEN = CSSM_TP_PRIVATE_ERROR + 1, + CSSMERR_APPLETP_UNKNOWN_CRITICAL_EXTEN = -2147408895, /* Basic Constraints extension required per policy, but not present */ - CSSMERR_APPLETP_NO_BASIC_CONSTRAINTS = CSSM_TP_PRIVATE_ERROR + 2, + CSSMERR_APPLETP_NO_BASIC_CONSTRAINTS = -2147408894, /* Invalid BasicConstraints.CA */ - CSSMERR_APPLETP_INVALID_CA = CSSM_TP_PRIVATE_ERROR + 3, + CSSMERR_APPLETP_INVALID_CA = -2147408893, /* Invalid Authority Key ID */ - CSSMERR_APPLETP_INVALID_AUTHORITY_ID = CSSM_TP_PRIVATE_ERROR + 4, + CSSMERR_APPLETP_INVALID_AUTHORITY_ID = -2147408892, /* Invalid Subject Key ID */ - CSSMERR_APPLETP_INVALID_SUBJECT_ID = CSSM_TP_PRIVATE_ERROR + 5, + CSSMERR_APPLETP_INVALID_SUBJECT_ID = -2147408891, /* Invalid Key Usage for policy */ - CSSMERR_APPLETP_INVALID_KEY_USAGE = CSSM_TP_PRIVATE_ERROR + 6, + CSSMERR_APPLETP_INVALID_KEY_USAGE = -2147408890, /* Invalid Extended Key Usage for policy */ - CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE = CSSM_TP_PRIVATE_ERROR + 7, + CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE = -2147408889, /* Invalid Subject/Authority Key ID Linkage */ - CSSMERR_APPLETP_INVALID_ID_LINKAGE = CSSM_TP_PRIVATE_ERROR + 8, + CSSMERR_APPLETP_INVALID_ID_LINKAGE = -2147408888, /* PathLengthConstraint exceeded */ - CSSMERR_APPLETP_PATH_LEN_CONSTRAINT = CSSM_TP_PRIVATE_ERROR + 9, + CSSMERR_APPLETP_PATH_LEN_CONSTRAINT = -2147408887, /* Cert group terminated at a root cert which did not self-verify */ - CSSMERR_APPLETP_INVALID_ROOT = CSSM_TP_PRIVATE_ERROR + 10, - /* CRL expired/not valid yet */ - CSSMERR_APPLETP_CRL_EXPIRED = CSSM_TP_PRIVATE_ERROR + 11, - CSSMERR_APPLETP_CRL_NOT_VALID_YET = CSSM_TP_PRIVATE_ERROR + 12, + CSSMERR_APPLETP_INVALID_ROOT = -2147408886, + /* CRL expired */ + CSSMERR_APPLETP_CRL_EXPIRED = -2147408885, + /* CRL not valid yet */ + CSSMERR_APPLETP_CRL_NOT_VALID_YET = -2147408884, /* Cannot find appropriate CRL */ - CSSMERR_APPLETP_CRL_NOT_FOUND = CSSM_TP_PRIVATE_ERROR + 13, + CSSMERR_APPLETP_CRL_NOT_FOUND = -2147408883, /* specified CRL server down */ - CSSMERR_APPLETP_CRL_SERVER_DOWN = CSSM_TP_PRIVATE_ERROR + 14, + CSSMERR_APPLETP_CRL_SERVER_DOWN = -2147408882, /* illegible CRL distribution point URL */ - CSSMERR_APPLETP_CRL_BAD_URI = CSSM_TP_PRIVATE_ERROR + 15, - /* Unknown critical cert/CRL extension */ - CSSMERR_APPLETP_UNKNOWN_CERT_EXTEN = CSSM_TP_PRIVATE_ERROR + 16, - CSSMERR_APPLETP_UNKNOWN_CRL_EXTEN = CSSM_TP_PRIVATE_ERROR + 17, + CSSMERR_APPLETP_CRL_BAD_URI = -2147408881, + /* Unknown critical cert extension */ + CSSMERR_APPLETP_UNKNOWN_CERT_EXTEN = -2147408880, + /* Unknown critical CRL extension */ + CSSMERR_APPLETP_UNKNOWN_CRL_EXTEN = -2147408879, /* CRL not verifiable to anchor or root */ - CSSMERR_APPLETP_CRL_NOT_TRUSTED = CSSM_TP_PRIVATE_ERROR + 18, + CSSMERR_APPLETP_CRL_NOT_TRUSTED = -2147408878, /* CRL verified to untrusted root */ - CSSMERR_APPLETP_CRL_INVALID_ANCHOR_CERT = CSSM_TP_PRIVATE_ERROR + 19, + CSSMERR_APPLETP_CRL_INVALID_ANCHOR_CERT = -2147408877, /* CRL failed policy verification */ - CSSMERR_APPLETP_CRL_POLICY_FAIL = CSSM_TP_PRIVATE_ERROR + 20, + CSSMERR_APPLETP_CRL_POLICY_FAIL = -2147408876, /* IssuingDistributionPoint extension violation */ - CSSMERR_APPLETP_IDP_FAIL = CSSM_TP_PRIVATE_ERROR + 21, + CSSMERR_APPLETP_IDP_FAIL = -2147408875, /* Cert not found at specified issuerAltName */ - CSSMERR_APPLETP_CERT_NOT_FOUND_FROM_ISSUER = CSSM_TP_PRIVATE_ERROR + 22, + CSSMERR_APPLETP_CERT_NOT_FOUND_FROM_ISSUER = -2147408874, /* Bad cert obtained from specified issuerAltName */ - CSSMERR_APPLETP_BAD_CERT_FROM_ISSUER = CSSM_TP_PRIVATE_ERROR + 23, + CSSMERR_APPLETP_BAD_CERT_FROM_ISSUER = -2147408873, /* S/MIME Email address mismatch */ - CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND = CSSM_TP_PRIVATE_ERROR + 24, + CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND = -2147408872, /* Appropriate S/MIME ExtendedKeyUsage not found */ - CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE = CSSM_TP_PRIVATE_ERROR + 25, + CSSMERR_APPLETP_SMIME_BAD_EXT_KEY_USE = -2147408871, /* S/MIME KeyUsage incompatibility */ - CSSMERR_APPLETP_SMIME_BAD_KEY_USE = CSSM_TP_PRIVATE_ERROR + 26, + CSSMERR_APPLETP_SMIME_BAD_KEY_USE = -2147408870, /* S/MIME, cert with KeyUsage flagged !critical */ - CSSMERR_APPLETP_SMIME_KEYUSAGE_NOT_CRITICAL = CSSM_TP_PRIVATE_ERROR + 27, + CSSMERR_APPLETP_SMIME_KEYUSAGE_NOT_CRITICAL = -2147408869, /* S/MIME, leaf with empty subject name and no email addrs - * in SubjectAltName */ - CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS = CSSM_TP_PRIVATE_ERROR + 28, + in SubjectAltName */ + CSSMERR_APPLETP_SMIME_NO_EMAIL_ADDRS = -2147408868, /* S/MIME, leaf with empty subject name, SubjectAltName - * not critical */ - CSSMERR_APPLETP_SMIME_SUBJ_ALT_NAME_NOT_CRIT = CSSM_TP_PRIVATE_ERROR + 29, + not critical */ + CSSMERR_APPLETP_SMIME_SUBJ_ALT_NAME_NOT_CRIT = -2147408867, /* Appropriate SSL ExtendedKeyUsage not found */ - CSSMERR_APPLETP_SSL_BAD_EXT_KEY_USE = CSSM_TP_PRIVATE_ERROR + 30, + CSSMERR_APPLETP_SSL_BAD_EXT_KEY_USE = -2147408866, /* unparseable OCSP response */ - CSSMERR_APPLETP_OCSP_BAD_RESPONSE = CSSM_TP_PRIVATE_ERROR + 31, + CSSMERR_APPLETP_OCSP_BAD_RESPONSE = -2147408865, /* unparseable OCSP request */ - CSSMERR_APPLETP_OCSP_BAD_REQUEST = CSSM_TP_PRIVATE_ERROR + 32, + CSSMERR_APPLETP_OCSP_BAD_REQUEST = -2147408864, /* OCSP service unavailable */ - CSSMERR_APPLETP_OCSP_UNAVAILABLE = CSSM_TP_PRIVATE_ERROR + 33, + CSSMERR_APPLETP_OCSP_UNAVAILABLE = -2147408863, /* OCSP status: cert unrecognized */ - CSSMERR_APPLETP_OCSP_STATUS_UNRECOGNIZED = CSSM_TP_PRIVATE_ERROR + 34, + CSSMERR_APPLETP_OCSP_STATUS_UNRECOGNIZED = -2147408862, /* revocation check not successful for each cert */ - CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK = CSSM_TP_PRIVATE_ERROR + 35, + CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK = -2147408861, /* general network error */ - CSSMERR_APPLETP_NETWORK_FAILURE = CSSM_TP_PRIVATE_ERROR + 36, + CSSMERR_APPLETP_NETWORK_FAILURE = -2147408860, /* OCSP response not verifiable to anchor or root */ - CSSMERR_APPLETP_OCSP_NOT_TRUSTED = CSSM_TP_PRIVATE_ERROR + 37, + CSSMERR_APPLETP_OCSP_NOT_TRUSTED = -2147408859, /* OCSP response verified to untrusted root */ - CSSMERR_APPLETP_OCSP_INVALID_ANCHOR_CERT = CSSM_TP_PRIVATE_ERROR + 38, + CSSMERR_APPLETP_OCSP_INVALID_ANCHOR_CERT = -2147408858, /* OCSP response signature error */ - CSSMERR_APPLETP_OCSP_SIG_ERROR = CSSM_TP_PRIVATE_ERROR + 39, + CSSMERR_APPLETP_OCSP_SIG_ERROR = -2147408857, /* No signer for OCSP response found */ - CSSMERR_APPLETP_OCSP_NO_SIGNER = CSSM_TP_PRIVATE_ERROR + 40, + CSSMERR_APPLETP_OCSP_NO_SIGNER = -2147408856, /* OCSP responder status: malformed request */ - CSSMERR_APPLETP_OCSP_RESP_MALFORMED_REQ = CSSM_TP_PRIVATE_ERROR + 41, + CSSMERR_APPLETP_OCSP_RESP_MALFORMED_REQ = -2147408855, /* OCSP responder status: internal error */ - CSSMERR_APPLETP_OCSP_RESP_INTERNAL_ERR = CSSM_TP_PRIVATE_ERROR + 42, + CSSMERR_APPLETP_OCSP_RESP_INTERNAL_ERR = -2147408854, /* OCSP responder status: try later */ - CSSMERR_APPLETP_OCSP_RESP_TRY_LATER = CSSM_TP_PRIVATE_ERROR + 43, + CSSMERR_APPLETP_OCSP_RESP_TRY_LATER = -2147408853, /* OCSP responder status: signature required */ - CSSMERR_APPLETP_OCSP_RESP_SIG_REQUIRED = CSSM_TP_PRIVATE_ERROR + 44, + CSSMERR_APPLETP_OCSP_RESP_SIG_REQUIRED = -2147408852, /* OCSP responder status: unauthorized */ - CSSMERR_APPLETP_OCSP_RESP_UNAUTHORIZED = CSSM_TP_PRIVATE_ERROR + 45, + CSSMERR_APPLETP_OCSP_RESP_UNAUTHORIZED = -2147408851, /* OCSP response nonce did not match request */ - CSSMERR_APPLETP_OCSP_NONCE_MISMATCH = CSSM_TP_PRIVATE_ERROR + 46, + CSSMERR_APPLETP_OCSP_NONCE_MISMATCH = -2147408850, /* Illegal cert chain length for Code Signing */ - CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH = CSSM_TP_PRIVATE_ERROR + 47, + CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH = -2147408849, /* Missing Basic Constraints for Code Signing */ - CSSMERR_APPLETP_CS_NO_BASIC_CONSTRAINTS = CSSM_TP_PRIVATE_ERROR + 48, + CSSMERR_APPLETP_CS_NO_BASIC_CONSTRAINTS = -2147408848, /* Bad PathLengthConstraint for Code Signing */ - CSSMERR_APPLETP_CS_BAD_PATH_LENGTH = CSSM_TP_PRIVATE_ERROR + 49, + CSSMERR_APPLETP_CS_BAD_PATH_LENGTH = -2147408847, /* Missing ExtendedKeyUsage for Code Signing */ - CSSMERR_APPLETP_CS_NO_EXTENDED_KEY_USAGE = CSSM_TP_PRIVATE_ERROR + 50, + CSSMERR_APPLETP_CS_NO_EXTENDED_KEY_USAGE = -2147408846, /* Development style Code Signing Cert Detected */ - CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT = CSSM_TP_PRIVATE_ERROR + 51, + CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT = -2147408845, /* Illegal cert chain length for Resource Signing */ - CSSMERR_APPLETP_RS_BAD_CERT_CHAIN_LENGTH = CSSM_TP_PRIVATE_ERROR + 52, + CSSMERR_APPLETP_RS_BAD_CERT_CHAIN_LENGTH = -2147408844, /* Bad extended key usage for Resource Signing */ - CSSMERR_APPLETP_RS_BAD_EXTENDED_KEY_USAGE = CSSM_TP_PRIVATE_ERROR + 53, + CSSMERR_APPLETP_RS_BAD_EXTENDED_KEY_USAGE = -2147408843, /* Trust Setting: deny */ - CSSMERR_APPLETP_TRUST_SETTING_DENY = CSSM_TP_PRIVATE_ERROR + 54, + CSSMERR_APPLETP_TRUST_SETTING_DENY = -2147408842, /* Invalid empty SubjectName */ - CSSMERR_APPLETP_INVALID_EMPTY_SUBJECT = CSSM_TP_PRIVATE_ERROR + 55, + CSSMERR_APPLETP_INVALID_EMPTY_SUBJECT = -2147408841, /* Unknown critical Qualified Cert Statement ID */ - CSSMERR_APPLETP_UNKNOWN_QUAL_CERT_STATEMENT = CSSM_TP_PRIVATE_ERROR + 56, + CSSMERR_APPLETP_UNKNOWN_QUAL_CERT_STATEMENT = -2147408840, /* Missing required extension */ - CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION = CSSM_TP_PRIVATE_ERROR + 57, + CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION = -2147408839, /* Extended key usage not marked critical */ - CSSMERR_APPLETP_EXT_KEYUSAGE_NOT_CRITICAL = CSSM_TP_PRIVATE_ERROR + 58, + CSSMERR_APPLETP_EXT_KEYUSAGE_NOT_CRITICAL = -2147408838, /* Required name or identifier not present */ - CSSMERR_APPLETP_IDENTIFIER_MISSING = CSSM_TP_PRIVATE_ERROR + 59, + CSSMERR_APPLETP_IDENTIFIER_MISSING = -2147408837, /* Certificate authority pinning mismatch */ - CSSMERR_APPLETP_CA_PIN_MISMATCH = CSSM_TP_PRIVATE_ERROR + 60 + CSSMERR_APPLETP_CA_PIN_MISMATCH = -2147408836, }; /* Apple .mac TP private error codes. */ enum { /* cert request queued */ - CSSMERR_APPLE_DOTMAC_REQ_QUEUED = CSSM_TP_PRIVATE_ERROR + 100, + CSSMERR_APPLE_DOTMAC_REQ_QUEUED = -2147408796, /* cert request redirected */ - CSSMERR_APPLE_DOTMAC_REQ_REDIRECT = CSSM_TP_PRIVATE_ERROR + 101, + CSSMERR_APPLE_DOTMAC_REQ_REDIRECT = -2147408795, /* general server-reported error */ - CSSMERR_APPLE_DOTMAC_REQ_SERVER_ERR = CSSM_TP_PRIVATE_ERROR + 102, + CSSMERR_APPLE_DOTMAC_REQ_SERVER_ERR = -2147408794, /* server-reported parameter error */ - CSSMERR_APPLE_DOTMAC_REQ_SERVER_PARAM = CSSM_TP_PRIVATE_ERROR + 103, + CSSMERR_APPLE_DOTMAC_REQ_SERVER_PARAM = -2147408793, /* server-reported authorization error */ - CSSMERR_APPLE_DOTMAC_REQ_SERVER_AUTH = CSSM_TP_PRIVATE_ERROR + 104, + CSSMERR_APPLE_DOTMAC_REQ_SERVER_AUTH = -2147408792, /* server-reported unimplemented */ - CSSMERR_APPLE_DOTMAC_REQ_SERVER_UNIMPL = CSSM_TP_PRIVATE_ERROR + 105, + CSSMERR_APPLE_DOTMAC_REQ_SERVER_UNIMPL = -2147408791, /* server-reported not available */ - CSSMERR_APPLE_DOTMAC_REQ_SERVER_NOT_AVAIL = CSSM_TP_PRIVATE_ERROR + 106, + CSSMERR_APPLE_DOTMAC_REQ_SERVER_NOT_AVAIL = -2147408790, /* server-reported already exists */ - CSSMERR_APPLE_DOTMAC_REQ_SERVER_ALREADY_EXIST = CSSM_TP_PRIVATE_ERROR + 107, + CSSMERR_APPLE_DOTMAC_REQ_SERVER_ALREADY_EXIST = -2147408789, /* server-reported service error */ - CSSMERR_APPLE_DOTMAC_REQ_SERVER_SERVICE_ERROR = CSSM_TP_PRIVATE_ERROR + 108, + CSSMERR_APPLE_DOTMAC_REQ_SERVER_SERVICE_ERROR = -2147408788, /* request already pending for specified user */ - CSSMERR_APPLE_DOTMAC_REQ_IS_PENDING = CSSM_TP_PRIVATE_ERROR + 109, + CSSMERR_APPLE_DOTMAC_REQ_IS_PENDING = -2147408787, /* no request pending for specified user */ - CSSMERR_APPLE_DOTMAC_NO_REQ_PENDING = CSSM_TP_PRIVATE_ERROR + 110, + CSSMERR_APPLE_DOTMAC_NO_REQ_PENDING = -2147408786, /* CSR failed to verify */ - CSSMERR_APPLE_DOTMAC_CSR_VERIFY_FAIL = CSSM_TP_PRIVATE_ERROR + 111, + CSSMERR_APPLE_DOTMAC_CSR_VERIFY_FAIL = -2147408785, /* server reported failed consistency check */ - CSSMERR_APPLE_DOTMAC_FAILED_CONSISTENCY_CHECK = CSSM_TP_PRIVATE_ERROR + 112 + CSSMERR_APPLE_DOTMAC_FAILED_CONSISTENCY_CHECK = -2147408784, }; enum diff --git a/header_symlinks/Security/CSCommon.h b/header_symlinks/Security/CSCommon.h new file mode 120000 index 00000000..161b1306 --- /dev/null +++ b/header_symlinks/Security/CSCommon.h @@ -0,0 +1 @@ +././../OSX/libsecurity_codesigning/lib/CSCommon.h \ No newline at end of file diff --git a/header_symlinks/Security/CSCommonPriv.h b/header_symlinks/Security/CSCommonPriv.h new file mode 120000 index 00000000..e8b33401 --- /dev/null +++ b/header_symlinks/Security/CSCommonPriv.h @@ -0,0 +1 @@ +././../OSX/libsecurity_codesigning/lib/CSCommonPriv.h \ No newline at end of file diff --git a/header_symlinks/Security/CodeSigning.h b/header_symlinks/Security/CodeSigning.h new file mode 120000 index 00000000..ceb8cc49 --- /dev/null +++ b/header_symlinks/Security/CodeSigning.h @@ -0,0 +1 @@ +././../OSX/libsecurity_codesigning/lib/CodeSigning.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCode.h b/header_symlinks/Security/SecCode.h new file mode 120000 index 00000000..fe672eff --- /dev/null +++ b/header_symlinks/Security/SecCode.h @@ -0,0 +1 @@ +././../OSX/libsecurity_codesigning/lib/SecCode.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCodeHost.h b/header_symlinks/Security/SecCodeHost.h new file mode 120000 index 00000000..577c81c2 --- /dev/null +++ b/header_symlinks/Security/SecCodeHost.h @@ -0,0 +1 @@ +././../OSX/libsecurity_codesigning/lib/SecCodeHost.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCodePriv.h b/header_symlinks/Security/SecCodePriv.h new file mode 120000 index 00000000..262fcde4 --- /dev/null +++ b/header_symlinks/Security/SecCodePriv.h @@ -0,0 +1 @@ +././../OSX/libsecurity_codesigning/lib/SecCodePriv.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCodeSigner.h b/header_symlinks/Security/SecCodeSigner.h new file mode 120000 index 00000000..bfbce813 --- /dev/null +++ b/header_symlinks/Security/SecCodeSigner.h @@ -0,0 +1 @@ +././../OSX/libsecurity_codesigning/lib/SecCodeSigner.h \ No newline at end of file diff --git a/header_symlinks/Security/SecRandomP.h b/header_symlinks/Security/SecRandomP.h new file mode 100644 index 00000000..e69de29b diff --git a/header_symlinks/Security/SecRequirement.h b/header_symlinks/Security/SecRequirement.h new file mode 120000 index 00000000..9ff00e02 --- /dev/null +++ b/header_symlinks/Security/SecRequirement.h @@ -0,0 +1 @@ +././../OSX/libsecurity_codesigning/lib/SecRequirement.h \ No newline at end of file diff --git a/header_symlinks/Security/SecRequirementPriv.h b/header_symlinks/Security/SecRequirementPriv.h new file mode 120000 index 00000000..42f5ece1 --- /dev/null +++ b/header_symlinks/Security/SecRequirementPriv.h @@ -0,0 +1 @@ +././../OSX/libsecurity_codesigning/lib/SecRequirementPriv.h \ No newline at end of file diff --git a/header_symlinks/Security/SecSignpost.h b/header_symlinks/Security/SecSignpost.h new file mode 120000 index 00000000..d63913e0 --- /dev/null +++ b/header_symlinks/Security/SecSignpost.h @@ -0,0 +1 @@ +./../base/SecSignpost.h \ No newline at end of file diff --git a/header_symlinks/Security/SecStaticCode.h b/header_symlinks/Security/SecStaticCode.h new file mode 120000 index 00000000..116637f7 --- /dev/null +++ b/header_symlinks/Security/SecStaticCode.h @@ -0,0 +1 @@ +././../OSX/libsecurity_codesigning/lib/SecStaticCode.h \ No newline at end of file diff --git a/header_symlinks/Security/SecStaticCodePriv.h b/header_symlinks/Security/SecStaticCodePriv.h new file mode 120000 index 00000000..1a626c64 --- /dev/null +++ b/header_symlinks/Security/SecStaticCodePriv.h @@ -0,0 +1 @@ +././../OSX/libsecurity_codesigning/lib/SecStaticCodePriv.h \ No newline at end of file diff --git a/header_symlinks/Security/X509Templates.h b/header_symlinks/Security/X509Templates.h new file mode 120000 index 00000000..e0dff012 --- /dev/null +++ b/header_symlinks/Security/X509Templates.h @@ -0,0 +1 @@ +././../OSX/libsecurity_asn1/lib/X509Templates.h \ No newline at end of file diff --git a/header_symlinks/Security/keyTemplates.h b/header_symlinks/Security/keyTemplates.h new file mode 120000 index 00000000..6d9c1652 --- /dev/null +++ b/header_symlinks/Security/keyTemplates.h @@ -0,0 +1 @@ +././../OSX/libsecurity_asn1/lib/keyTemplates.h \ No newline at end of file diff --git a/header_symlinks/Security/nameTemplates.h b/header_symlinks/Security/nameTemplates.h new file mode 120000 index 00000000..9aa683b9 --- /dev/null +++ b/header_symlinks/Security/nameTemplates.h @@ -0,0 +1 @@ +././../OSX/libsecurity_asn1/lib/nameTemplates.h \ No newline at end of file diff --git a/header_symlinks/Security/oids.h b/header_symlinks/Security/oids.h new file mode 120000 index 00000000..d760f054 --- /dev/null +++ b/header_symlinks/Security/oids.h @@ -0,0 +1 @@ +./../trust/oids.h \ No newline at end of file diff --git a/header_symlinks/Security/oidsattr.h b/header_symlinks/Security/oidsattr.h new file mode 120000 index 00000000..6a56c805 --- /dev/null +++ b/header_symlinks/Security/oidsattr.h @@ -0,0 +1 @@ +././../OSX/libsecurity_asn1/lib/oidsattr.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/CSCommon.h b/header_symlinks/iOS/Security/CSCommon.h deleted file mode 120000 index a2c01617..00000000 --- a/header_symlinks/iOS/Security/CSCommon.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_codesigning/lib/CSCommon.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/CSCommonPriv.h b/header_symlinks/iOS/Security/CSCommonPriv.h deleted file mode 120000 index fc11d821..00000000 --- a/header_symlinks/iOS/Security/CSCommonPriv.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_codesigning/lib/CSCommonPriv.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/CodeSigning.h b/header_symlinks/iOS/Security/CodeSigning.h deleted file mode 120000 index 3f02ac7b..00000000 --- a/header_symlinks/iOS/Security/CodeSigning.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_codesigning/lib/CodeSigning.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecCode.h b/header_symlinks/iOS/Security/SecCode.h deleted file mode 120000 index ed9f8f59..00000000 --- a/header_symlinks/iOS/Security/SecCode.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_codesigning/lib/SecCode.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecCodeHost.h b/header_symlinks/iOS/Security/SecCodeHost.h deleted file mode 120000 index 484bbaeb..00000000 --- a/header_symlinks/iOS/Security/SecCodeHost.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_codesigning/lib/SecCodeHost.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecCodePriv.h b/header_symlinks/iOS/Security/SecCodePriv.h deleted file mode 120000 index fedda6e6..00000000 --- a/header_symlinks/iOS/Security/SecCodePriv.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_codesigning/lib/SecCodePriv.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecCodeSigner.h b/header_symlinks/iOS/Security/SecCodeSigner.h deleted file mode 120000 index 3f2e50d6..00000000 --- a/header_symlinks/iOS/Security/SecCodeSigner.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_codesigning/lib/SecCodeSigner.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecRequirement.h b/header_symlinks/iOS/Security/SecRequirement.h deleted file mode 120000 index d1a9c5be..00000000 --- a/header_symlinks/iOS/Security/SecRequirement.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_codesigning/lib/SecRequirement.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecRequirementPriv.h b/header_symlinks/iOS/Security/SecRequirementPriv.h deleted file mode 120000 index dcfaa942..00000000 --- a/header_symlinks/iOS/Security/SecRequirementPriv.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_codesigning/lib/SecRequirementPriv.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecStaticCode.h b/header_symlinks/iOS/Security/SecStaticCode.h deleted file mode 120000 index a3d61d95..00000000 --- a/header_symlinks/iOS/Security/SecStaticCode.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_codesigning/lib/SecStaticCode.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecStaticCodePriv.h b/header_symlinks/iOS/Security/SecStaticCodePriv.h deleted file mode 120000 index 82e25d4a..00000000 --- a/header_symlinks/iOS/Security/SecStaticCodePriv.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_codesigning/lib/SecStaticCodePriv.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/X509Templates.h b/header_symlinks/iOS/Security/X509Templates.h deleted file mode 120000 index 4e02f5b8..00000000 --- a/header_symlinks/iOS/Security/X509Templates.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_asn1/lib/X509Templates.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/keyTemplates.h b/header_symlinks/iOS/Security/keyTemplates.h deleted file mode 120000 index 86bd66db..00000000 --- a/header_symlinks/iOS/Security/keyTemplates.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_asn1/lib/keyTemplates.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/nameTemplates.h b/header_symlinks/iOS/Security/nameTemplates.h deleted file mode 120000 index 1af658bf..00000000 --- a/header_symlinks/iOS/Security/nameTemplates.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_asn1/lib/nameTemplates.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/oidsattr.h b/header_symlinks/iOS/Security/oidsattr.h deleted file mode 120000 index 2c68f9a5..00000000 --- a/header_symlinks/iOS/Security/oidsattr.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_asn1/lib/oidsattr.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/AuthSession.h b/header_symlinks/macOS/Security/AuthSession.h new file mode 120000 index 00000000..5e9f7d35 --- /dev/null +++ b/header_symlinks/macOS/Security/AuthSession.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_authorization/lib/AuthSession.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/Authorization.h b/header_symlinks/macOS/Security/Authorization.h new file mode 120000 index 00000000..de551aa8 --- /dev/null +++ b/header_symlinks/macOS/Security/Authorization.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_authorization/lib/Authorization.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/AuthorizationDB.h b/header_symlinks/macOS/Security/AuthorizationDB.h new file mode 120000 index 00000000..0ae307d7 --- /dev/null +++ b/header_symlinks/macOS/Security/AuthorizationDB.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_authorization/lib/AuthorizationDB.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/AuthorizationPlugin.h b/header_symlinks/macOS/Security/AuthorizationPlugin.h new file mode 120000 index 00000000..35ee221b --- /dev/null +++ b/header_symlinks/macOS/Security/AuthorizationPlugin.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_authorization/lib/AuthorizationPlugin.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/AuthorizationPriv.h b/header_symlinks/macOS/Security/AuthorizationPriv.h new file mode 120000 index 00000000..516588e4 --- /dev/null +++ b/header_symlinks/macOS/Security/AuthorizationPriv.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_authorization/lib/AuthorizationPriv.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/AuthorizationTags.h b/header_symlinks/macOS/Security/AuthorizationTags.h new file mode 120000 index 00000000..97eab30e --- /dev/null +++ b/header_symlinks/macOS/Security/AuthorizationTags.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_authorization/lib/AuthorizationTags.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/AuthorizationTagsPriv.h b/header_symlinks/macOS/Security/AuthorizationTagsPriv.h new file mode 120000 index 00000000..f0ece70a --- /dev/null +++ b/header_symlinks/macOS/Security/AuthorizationTagsPriv.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_authorization/lib/AuthorizationTagsPriv.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/CMSDecoder.h b/header_symlinks/macOS/Security/CMSDecoder.h new file mode 120000 index 00000000..3b5d8995 --- /dev/null +++ b/header_symlinks/macOS/Security/CMSDecoder.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cms/lib/CMSDecoder.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/CMSEncoder.h b/header_symlinks/macOS/Security/CMSEncoder.h new file mode 120000 index 00000000..6be993dc --- /dev/null +++ b/header_symlinks/macOS/Security/CMSEncoder.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cms/lib/CMSEncoder.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/CMSPrivate.h b/header_symlinks/macOS/Security/CMSPrivate.h new file mode 120000 index 00000000..557fb87f --- /dev/null +++ b/header_symlinks/macOS/Security/CMSPrivate.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cms/lib/CMSPrivate.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/CipherSuite.h b/header_symlinks/macOS/Security/CipherSuite.h new file mode 120000 index 00000000..d3f4fef0 --- /dev/null +++ b/header_symlinks/macOS/Security/CipherSuite.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_ssl/lib/CipherSuite.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecACL.h b/header_symlinks/macOS/Security/SecACL.h new file mode 120000 index 00000000..5a8d417d --- /dev/null +++ b/header_symlinks/macOS/Security/SecACL.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecACL.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecASN1Coder.h b/header_symlinks/macOS/Security/SecASN1Coder.h new file mode 120000 index 00000000..1c2f34cf --- /dev/null +++ b/header_symlinks/macOS/Security/SecASN1Coder.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_asn1/lib/SecAsn1Coder.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecASN1Templates.h b/header_symlinks/macOS/Security/SecASN1Templates.h new file mode 120000 index 00000000..79eb8e10 --- /dev/null +++ b/header_symlinks/macOS/Security/SecASN1Templates.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_asn1/lib/SecAsn1Templates.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecAccess.h b/header_symlinks/macOS/Security/SecAccess.h new file mode 120000 index 00000000..0cca8021 --- /dev/null +++ b/header_symlinks/macOS/Security/SecAccess.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecAccess.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecAccessControl.h b/header_symlinks/macOS/Security/SecAccessControl.h new file mode 120000 index 00000000..49bc4ad0 --- /dev/null +++ b/header_symlinks/macOS/Security/SecAccessControl.h @@ -0,0 +1 @@ +./../../keychain/SecAccessControl.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecAccessPriv.h b/header_symlinks/macOS/Security/SecAccessPriv.h new file mode 120000 index 00000000..324d8187 --- /dev/null +++ b/header_symlinks/macOS/Security/SecAccessPriv.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecAccessPriv.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCertificateBundle.h b/header_symlinks/macOS/Security/SecCertificateBundle.h new file mode 120000 index 00000000..b651860d --- /dev/null +++ b/header_symlinks/macOS/Security/SecCertificateBundle.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecCertificateBundle.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCertificateOIDs.h b/header_symlinks/macOS/Security/SecCertificateOIDs.h new file mode 120000 index 00000000..dd3b4e15 --- /dev/null +++ b/header_symlinks/macOS/Security/SecCertificateOIDs.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecCertificateOIDs.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCmsDigestedData.h b/header_symlinks/macOS/Security/SecCmsDigestedData.h new file mode 120000 index 00000000..31c66b51 --- /dev/null +++ b/header_symlinks/macOS/Security/SecCmsDigestedData.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_smime/lib/SecCmsDigestedData.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCmsEncryptedData.h b/header_symlinks/macOS/Security/SecCmsEncryptedData.h new file mode 120000 index 00000000..cc59cb7f --- /dev/null +++ b/header_symlinks/macOS/Security/SecCmsEncryptedData.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_smime/lib/SecCmsEncryptedData.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCustomTransform.h b/header_symlinks/macOS/Security/SecCustomTransform.h new file mode 120000 index 00000000..f79ef46c --- /dev/null +++ b/header_symlinks/macOS/Security/SecCustomTransform.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_transform/lib/SecCustomTransform.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecDecodeTransform.h b/header_symlinks/macOS/Security/SecDecodeTransform.h new file mode 120000 index 00000000..0ba1af07 --- /dev/null +++ b/header_symlinks/macOS/Security/SecDecodeTransform.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_transform/lib/SecDecodeTransform.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecDigestTransform.h b/header_symlinks/macOS/Security/SecDigestTransform.h new file mode 120000 index 00000000..30c69218 --- /dev/null +++ b/header_symlinks/macOS/Security/SecDigestTransform.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_transform/lib/SecDigestTransform.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecEncodeTransform.h b/header_symlinks/macOS/Security/SecEncodeTransform.h new file mode 120000 index 00000000..b9f1330c --- /dev/null +++ b/header_symlinks/macOS/Security/SecEncodeTransform.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_transform/lib/SecEncodeTransform.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecEncryptTransform.h b/header_symlinks/macOS/Security/SecEncryptTransform.h new file mode 120000 index 00000000..ef3a8e71 --- /dev/null +++ b/header_symlinks/macOS/Security/SecEncryptTransform.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_transform/lib/SecEncryptTransform.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecIdentitySearch.h b/header_symlinks/macOS/Security/SecIdentitySearch.h new file mode 120000 index 00000000..1d1c5b82 --- /dev/null +++ b/header_symlinks/macOS/Security/SecIdentitySearch.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecIdentitySearch.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecIdentitySearchPriv.h b/header_symlinks/macOS/Security/SecIdentitySearchPriv.h new file mode 120000 index 00000000..f6e611a7 --- /dev/null +++ b/header_symlinks/macOS/Security/SecIdentitySearchPriv.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecIdentitySearchPriv.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecKeychain.h b/header_symlinks/macOS/Security/SecKeychain.h new file mode 120000 index 00000000..37d88c39 --- /dev/null +++ b/header_symlinks/macOS/Security/SecKeychain.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecKeychain.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecKeychainItem.h b/header_symlinks/macOS/Security/SecKeychainItem.h new file mode 120000 index 00000000..664949a8 --- /dev/null +++ b/header_symlinks/macOS/Security/SecKeychainItem.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecKeychainItem.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecKeychainItemPriv.h b/header_symlinks/macOS/Security/SecKeychainItemPriv.h new file mode 120000 index 00000000..492a149a --- /dev/null +++ b/header_symlinks/macOS/Security/SecKeychainItemPriv.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecKeychainItemPriv.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecKeychainPriv.h b/header_symlinks/macOS/Security/SecKeychainPriv.h new file mode 120000 index 00000000..85953b19 --- /dev/null +++ b/header_symlinks/macOS/Security/SecKeychainPriv.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecKeychainPriv.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecKeychainSearch.h b/header_symlinks/macOS/Security/SecKeychainSearch.h new file mode 120000 index 00000000..c43f34f8 --- /dev/null +++ b/header_symlinks/macOS/Security/SecKeychainSearch.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecKeychainSearch.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecKeychainSearchPriv.h b/header_symlinks/macOS/Security/SecKeychainSearchPriv.h new file mode 120000 index 00000000..6ad6bf6f --- /dev/null +++ b/header_symlinks/macOS/Security/SecKeychainSearchPriv.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecKeychainSearchPriv.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecPolicySearch.h b/header_symlinks/macOS/Security/SecPolicySearch.h new file mode 120000 index 00000000..3b734d12 --- /dev/null +++ b/header_symlinks/macOS/Security/SecPolicySearch.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecPolicySearch.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecReadTransform.h b/header_symlinks/macOS/Security/SecReadTransform.h new file mode 120000 index 00000000..c7e02bc5 --- /dev/null +++ b/header_symlinks/macOS/Security/SecReadTransform.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_transform/lib/SecReadTransform.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecSMIME.h b/header_symlinks/macOS/Security/SecSMIME.h new file mode 120000 index 00000000..35059140 --- /dev/null +++ b/header_symlinks/macOS/Security/SecSMIME.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_smime/lib/SecSMIME.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecSignVerifyTransform.h b/header_symlinks/macOS/Security/SecSignVerifyTransform.h new file mode 120000 index 00000000..c01dcc32 --- /dev/null +++ b/header_symlinks/macOS/Security/SecSignVerifyTransform.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_transform/lib/SecSignVerifyTransform.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecTransform.h b/header_symlinks/macOS/Security/SecTransform.h new file mode 120000 index 00000000..1aa456d0 --- /dev/null +++ b/header_symlinks/macOS/Security/SecTransform.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_transform/lib/SecTransform.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecTransformReadTransform.h b/header_symlinks/macOS/Security/SecTransformReadTransform.h new file mode 120000 index 00000000..d2cbd0a1 --- /dev/null +++ b/header_symlinks/macOS/Security/SecTransformReadTransform.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_transform/lib/SecTransformReadTransform.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecTrustedApplication.h b/header_symlinks/macOS/Security/SecTrustedApplication.h new file mode 120000 index 00000000..c5a12708 --- /dev/null +++ b/header_symlinks/macOS/Security/SecTrustedApplication.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecTrustedApplication.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecTrustedApplicationPriv.h b/header_symlinks/macOS/Security/SecTrustedApplicationPriv.h new file mode 120000 index 00000000..2c315c5a --- /dev/null +++ b/header_symlinks/macOS/Security/SecTrustedApplicationPriv.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecTrustedApplicationPriv.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecureTransport.h b/header_symlinks/macOS/Security/SecureTransport.h new file mode 120000 index 00000000..adb0d587 --- /dev/null +++ b/header_symlinks/macOS/Security/SecureTransport.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_ssl/lib/SecureTransport.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/TrustSettingsSchema.h b/header_symlinks/macOS/Security/TrustSettingsSchema.h new file mode 120000 index 00000000..477e723d --- /dev/null +++ b/header_symlinks/macOS/Security/TrustSettingsSchema.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/TrustSettingsSchema.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/certExtensionTemplates.h b/header_symlinks/macOS/Security/certExtensionTemplates.h new file mode 120000 index 00000000..5910b0cb --- /dev/null +++ b/header_symlinks/macOS/Security/certExtensionTemplates.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_asn1/lib/certExtensionTemplates.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/checkpw.h b/header_symlinks/macOS/Security/checkpw.h new file mode 120000 index 00000000..c9aca420 --- /dev/null +++ b/header_symlinks/macOS/Security/checkpw.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_checkpw/lib/checkpw.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/csrTemplates.h b/header_symlinks/macOS/Security/csrTemplates.h new file mode 120000 index 00000000..01434ee5 --- /dev/null +++ b/header_symlinks/macOS/Security/csrTemplates.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_asn1/lib/csrTemplates.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/cssm.h b/header_symlinks/macOS/Security/cssm.h new file mode 120000 index 00000000..cdec35c9 --- /dev/null +++ b/header_symlinks/macOS/Security/cssm.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/cssm.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/cssmaci.h b/header_symlinks/macOS/Security/cssmaci.h new file mode 120000 index 00000000..ab97d742 --- /dev/null +++ b/header_symlinks/macOS/Security/cssmaci.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/cssmaci.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/cssmapi.h b/header_symlinks/macOS/Security/cssmapi.h new file mode 120000 index 00000000..88d33194 --- /dev/null +++ b/header_symlinks/macOS/Security/cssmapi.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/cssmapi.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/cssmapple.h b/header_symlinks/macOS/Security/cssmapple.h new file mode 120000 index 00000000..246de2d8 --- /dev/null +++ b/header_symlinks/macOS/Security/cssmapple.h @@ -0,0 +1 @@ +./../../cssm/cssmapple.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/cssmapplePriv.h b/header_symlinks/macOS/Security/cssmapplePriv.h new file mode 120000 index 00000000..4bb4e6c5 --- /dev/null +++ b/header_symlinks/macOS/Security/cssmapplePriv.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/cssmapplePriv.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/cssmcli.h b/header_symlinks/macOS/Security/cssmcli.h new file mode 120000 index 00000000..4f69edb9 --- /dev/null +++ b/header_symlinks/macOS/Security/cssmcli.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/cssmcli.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/cssmconfig.h b/header_symlinks/macOS/Security/cssmconfig.h new file mode 120000 index 00000000..006fed21 --- /dev/null +++ b/header_symlinks/macOS/Security/cssmconfig.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/cssmconfig.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/cssmcspi.h b/header_symlinks/macOS/Security/cssmcspi.h new file mode 120000 index 00000000..f1e2c87e --- /dev/null +++ b/header_symlinks/macOS/Security/cssmcspi.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/cssmcspi.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/cssmdli.h b/header_symlinks/macOS/Security/cssmdli.h new file mode 120000 index 00000000..cd9fe8dc --- /dev/null +++ b/header_symlinks/macOS/Security/cssmdli.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/cssmdli.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/cssmerr.h b/header_symlinks/macOS/Security/cssmerr.h new file mode 120000 index 00000000..b450a619 --- /dev/null +++ b/header_symlinks/macOS/Security/cssmerr.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/cssmerr.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/cssmkrapi.h b/header_symlinks/macOS/Security/cssmkrapi.h new file mode 120000 index 00000000..616fca79 --- /dev/null +++ b/header_symlinks/macOS/Security/cssmkrapi.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/cssmkrapi.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/cssmkrspi.h b/header_symlinks/macOS/Security/cssmkrspi.h new file mode 120000 index 00000000..4ed381a3 --- /dev/null +++ b/header_symlinks/macOS/Security/cssmkrspi.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/cssmkrspi.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/cssmspi.h b/header_symlinks/macOS/Security/cssmspi.h new file mode 120000 index 00000000..407debd9 --- /dev/null +++ b/header_symlinks/macOS/Security/cssmspi.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/cssmspi.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/cssmtpi.h b/header_symlinks/macOS/Security/cssmtpi.h new file mode 120000 index 00000000..cb59c36d --- /dev/null +++ b/header_symlinks/macOS/Security/cssmtpi.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/cssmtpi.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/cssmtype.h b/header_symlinks/macOS/Security/cssmtype.h new file mode 120000 index 00000000..67ef1ff8 --- /dev/null +++ b/header_symlinks/macOS/Security/cssmtype.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/cssmtype.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/emmspi.h b/header_symlinks/macOS/Security/emmspi.h new file mode 120000 index 00000000..af3f7c26 --- /dev/null +++ b/header_symlinks/macOS/Security/emmspi.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/emmspi.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/emmtype.h b/header_symlinks/macOS/Security/emmtype.h new file mode 120000 index 00000000..c0779924 --- /dev/null +++ b/header_symlinks/macOS/Security/emmtype.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/emmtype.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/mds.h b/header_symlinks/macOS/Security/mds.h new file mode 120000 index 00000000..9baf55e1 --- /dev/null +++ b/header_symlinks/macOS/Security/mds.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_mds/lib/mds.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/mds_schema.h b/header_symlinks/macOS/Security/mds_schema.h new file mode 120000 index 00000000..5b6dbe0f --- /dev/null +++ b/header_symlinks/macOS/Security/mds_schema.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_mds/lib/mds_schema.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/mdspriv.h b/header_symlinks/macOS/Security/mdspriv.h new file mode 120000 index 00000000..26456831 --- /dev/null +++ b/header_symlinks/macOS/Security/mdspriv.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_mds/lib/mdspriv.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/ocspTemplates.h b/header_symlinks/macOS/Security/ocspTemplates.h new file mode 120000 index 00000000..5cdaef70 --- /dev/null +++ b/header_symlinks/macOS/Security/ocspTemplates.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_asn1/lib/ocspTemplates.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/oids.h b/header_symlinks/macOS/Security/oids.h new file mode 120000 index 00000000..d5320bd2 --- /dev/null +++ b/header_symlinks/macOS/Security/oids.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/libDER/libDER/oids.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/oidsalg.h b/header_symlinks/macOS/Security/oidsalg.h new file mode 120000 index 00000000..019d63f2 --- /dev/null +++ b/header_symlinks/macOS/Security/oidsalg.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_asn1/lib/oidsalg.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/oidscert.h b/header_symlinks/macOS/Security/oidscert.h new file mode 120000 index 00000000..ca96a371 --- /dev/null +++ b/header_symlinks/macOS/Security/oidscert.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/oidscert.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/oidscrl.h b/header_symlinks/macOS/Security/oidscrl.h new file mode 120000 index 00000000..d9c80e98 --- /dev/null +++ b/header_symlinks/macOS/Security/oidscrl.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/oidscrl.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/osKeyTemplates.h b/header_symlinks/macOS/Security/osKeyTemplates.h new file mode 120000 index 00000000..ac9e5316 --- /dev/null +++ b/header_symlinks/macOS/Security/osKeyTemplates.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_asn1/lib/osKeyTemplates.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/secasn1t.h b/header_symlinks/macOS/Security/secasn1t.h new file mode 120000 index 00000000..941f15f3 --- /dev/null +++ b/header_symlinks/macOS/Security/secasn1t.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_asn1/lib/secasn1t.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/tsaTemplates.h b/header_symlinks/macOS/Security/tsaTemplates.h new file mode 120000 index 00000000..f212ae66 --- /dev/null +++ b/header_symlinks/macOS/Security/tsaTemplates.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_smime/lib/tsaTemplates.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/x509defs.h b/header_symlinks/macOS/Security/x509defs.h new file mode 120000 index 00000000..d2bdeb7c --- /dev/null +++ b/header_symlinks/macOS/Security/x509defs.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/x509defs.h \ No newline at end of file diff --git a/keychain/SecAccessControl.h b/keychain/SecAccessControl.h index 98f7fd74..3701baf3 100644 --- a/keychain/SecAccessControl.h +++ b/keychain/SecAccessControl.h @@ -46,18 +46,57 @@ CF_IMPLICIT_BRIDGING_ENABLED CFTypeID SecAccessControlGetTypeID(void) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); +/*! + @typedef SecAccessControlCreateFlags + + @constant kSecAccessControlUserPresence + User presence policy using biometry or Passcode. Biometry does not have to be available or enrolled. Item is still + accessible by Touch ID even if fingers are added or removed. Item is still accessible by Face ID if user is re-enrolled. + + @constant kSecAccessControlBiometryAny + Constraint: Touch ID (any finger) or Face ID. Touch ID or Face ID must be available. With Touch ID + at least one finger must be enrolled. With Face ID user has to be enrolled. Item is still accessible by Touch ID even + if fingers are added or removed. Item is still accessible by Face ID if user is re-enrolled. + + @constant kSecAccessControlTouchIDAny + Deprecated, please use kSecAccessControlBiometryAny instead. + + @constant kSecAccessControlBiometryCurrentSet + Constraint: Touch ID from the set of currently enrolled fingers. Touch ID must be available and at least one finger must + be enrolled. When fingers are added or removed, the item is invalidated. When Face ID is re-enrolled this item is invalidated. + + @constant kSecAccessControlTouchIDCurrentSet + Deprecated, please use kSecAccessControlBiometryCurrentSet instead. + + @constant kSecAccessControlDevicePasscode + Constraint: Device passcode + + @constant kSecAccessControlOr + Constraint logic operation: when using more than one constraint, at least one of them must be satisfied. + + @constant kSecAccessControlAnd + Constraint logic operation: when using more than one constraint, all must be satisfied. + + @constant kSecAccessControlPrivateKeyUsage + Create access control for private key operations (i.e. sign operation) + + @constant kSecAccessControlApplicationPassword + Security: Application provided password for data encryption key generation. This is not a constraint but additional item + encryption mechanism. +*/ typedef CF_OPTIONS(CFOptionFlags, SecAccessControlCreateFlags) { - kSecAccessControlUserPresence = 1 << 0, // User presence policy using biometry or Passcode. Biometry does not have to be available or enrolled. Item is still accessible by Touch ID even if fingers are added or removed. Item is still accessible by Face ID if user is re-enrolled. - kSecAccessControlTouchIDAny CF_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 1, // Constraint: Touch ID (any finger) or Face ID. Touch ID or Face ID must be available. With Touch ID at least one finger must be enrolled. With Face ID user has to be enrolled. Item is still accessible by Touch ID even if fingers are added or removed. Item is still accessible by Face ID if user is re-enrolled. - kSecAccessControlTouchIDCurrentSet CF_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 3, // Constraint: Touch ID from the set of currently enrolled fingers. Touch ID must be available and at least one finger must be enrolled. When fingers are added or removed, the item is invalidated. When Face ID is re-enrolled this item is invalidated. - kSecAccessControlDevicePasscode CF_ENUM_AVAILABLE(10_11, 9_0) = 1u << 4, // Constraint: Device passcode - kSecAccessControlOr CF_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 14, // Constraint logic operation: when using more than one constraint, at least one of them must be satisfied. - kSecAccessControlAnd CF_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 15, // Constraint logic operation: when using more than one constraint, all must be satisfied. - kSecAccessControlPrivateKeyUsage CF_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 30, // Create access control for private key operations (i.e. sign operation) - kSecAccessControlApplicationPassword CF_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 31, // Security: Application provided password for data encryption key generation. This is not a constraint but additional item encryption mechanism. + kSecAccessControlUserPresence = 1u << 0, + kSecAccessControlBiometryAny CF_ENUM_AVAILABLE(10_13_4, 11_3) = 1u << 1, + kSecAccessControlTouchIDAny API_DEPRECATED_WITH_REPLACEMENT("kSecAccessControlBiometryAny", macos(10.12.1, 10.13.4), ios(9.0, 11.3)) = 1u << 1, + kSecAccessControlBiometryCurrentSet CF_ENUM_AVAILABLE(10_13_4, 11_3) = 1u << 3, + kSecAccessControlTouchIDCurrentSet API_DEPRECATED_WITH_REPLACEMENT("kSecAccessControlBiometryCurrentSet", macos(10.12.1, 10.13.4), ios(9.0, 11.3)) = 1u << 3, + kSecAccessControlDevicePasscode CF_ENUM_AVAILABLE(10_11, 9_0) = 1u << 4, + kSecAccessControlOr CF_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 14, + kSecAccessControlAnd CF_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 15, + kSecAccessControlPrivateKeyUsage CF_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 30, + kSecAccessControlApplicationPassword CF_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 31, } __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); - /*! @function SecAccessControlCreateWithFlags @abstract Creates new access control object based on protection type and additional flags. diff --git a/keychain/SecImportExport.h b/keychain/SecImportExport.h index 225ad9af..7badf0ed 100644 --- a/keychain/SecImportExport.h +++ b/keychain/SecImportExport.h @@ -251,7 +251,7 @@ typedef struct OSStatus SecKeychainItemExport( CFTypeRef keychainItemOrArray, SecExternalFormat outputFormat, - SecItemImportExportFlags flags, /* kSecItemPemArmor, etc. */ + SecItemImportExportFlags flags, /* kSecItemPemArmour, etc. */ const SecKeyImportExportParameters * __nullable keyParams, /* optional */ CFDataRef * __nonnull CF_RETURNS_RETAINED exportedData) /* external representation returned here */ DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; @@ -311,10 +311,10 @@ OSStatus SecKeychainItemExport( OSStatus SecItemExport( CFTypeRef secItemOrArray, SecExternalFormat outputFormat, - SecItemImportExportFlags flags, /* kSecItemPemArmor, etc. */ + SecItemImportExportFlags flags, /* kSecItemPemArmour, etc. */ const SecItemImportExportKeyParameters * __nullable keyParams, /* optional */ CFDataRef * __nonnull CF_RETURNS_RETAINED exportedData) /* external representation returned here */ - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); /* * SecKeychainItemImport() * @@ -351,7 +351,7 @@ OSStatus SecItemExport( * be unwise for an application to count on that ability. * * PEM formatting is determined internally via inspection of the incoming - * data, so the kSecItemPemArmuor in the flags field is ignored. + * data, so the kSecItemPemArmour in the flags field is ignored. * * Zero, one, or both of the following occurs upon successful completion * of this function: @@ -510,7 +510,7 @@ OSStatus SecKeychainItemImport( * be unwise for an application to count on that ability. * * PEM formatting is determined internally via inspection of the incoming - * data, so the kSecItemPemArmuor in the flags field is ignored. + * data, so the kSecItemPemArmour in the flags field is ignored. * * Zero, one, or both of the following occurs upon successful completion * of this function: @@ -640,7 +640,7 @@ OSStatus SecItemImport( const SecItemImportExportKeyParameters * __nullable keyParams, /* optional */ SecKeychainRef __nullable importKeychain, /* optional */ CFArrayRef * __nullable CF_RETURNS_RETAINED outItems) /* optional */ - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); #endif /* SEC_OS_OSX */ /*! @@ -651,11 +651,11 @@ OSStatus SecItemImport( @constant kSecImportExportAccess On OSX, specifies an access represented by a SecAccessRef for the initial access (ACL) of a key imported from PKCS#12 format. */ extern const CFStringRef kSecImportExportPassphrase - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecImportExportKeychain - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecImportExportAccess - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); /*! @enum Import/Export item description @@ -674,15 +674,15 @@ extern const CFStringRef kSecImportExportAccess certificates for this item's identity */ extern const CFStringRef kSecImportItemLabel - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecImportItemKeyID - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecImportItemTrust - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecImportItemCertChain - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecImportItemIdentity - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); /*! @function SecPKCS12Import @@ -700,7 +700,7 @@ extern const CFStringRef kSecImportItemIdentity incorrect password was supplied, or data in the container is damaged. */ OSStatus SecPKCS12Import(CFDataRef pkcs12_data, CFDictionaryRef options, CFArrayRef * __nonnull CF_RETURNS_RETAINED items) - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); CF_IMPLICIT_BRIDGING_DISABLED diff --git a/keychain/SecItem.h b/keychain/SecItem.h index f34d6957..1329fa22 100644 --- a/keychain/SecItem.h +++ b/keychain/SecItem.h @@ -51,7 +51,7 @@ CF_IMPLICIT_BRIDGING_ENABLED that contains the item class code. */ extern const CFStringRef kSecClass - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); /*! @enum Class Value Constants @@ -66,15 +66,15 @@ extern const CFStringRef kSecClass @constant kSecClassIdentity Specifies identity items. */ extern const CFStringRef kSecClassInternetPassword - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecClassGenericPassword - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0); + API_AVAILABLE(macos(10.7), ios(2.0)); extern const CFStringRef kSecClassCertificate - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0); + API_AVAILABLE(macos(10.7), ios(2.0)); extern const CFStringRef kSecClassKey - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0); + API_AVAILABLE(macos(10.7), ios(2.0)); extern const CFStringRef kSecClassIdentity - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0); + API_AVAILABLE(macos(10.7), ios(2.0)); /*! @enum Attribute Key Constants @@ -447,113 +447,113 @@ extern const CFStringRef kSecClassIdentity backed by device's Secure Enclave. iOS only. */ extern const CFStringRef kSecAttrAccessible - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0); + API_AVAILABLE(macos(10.9), ios(4.0)); extern const CFStringRef kSecAttrAccess - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecAttrAccessControl - __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); + API_AVAILABLE(macos(10.10), ios(8.0)); extern const CFStringRef kSecAttrAccessGroup - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_3_0); + API_AVAILABLE(macos(10.9), ios(3.0)); extern const CFStringRef kSecAttrSynchronizable - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); + API_AVAILABLE(macos(10.9), ios(7.0)); extern const CFStringRef kSecAttrSynchronizableAny - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); + API_AVAILABLE(macos(10.9), ios(7.0)); extern const CFStringRef kSecAttrCreationDate - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrModificationDate - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrDescription - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrComment - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrCreator - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrType - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrLabel - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrIsInvisible - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrIsNegative - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrAccount - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrService - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrGeneric - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrSecurityDomain - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrServer - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocol - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrAuthenticationType - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrPort - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrPath - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrSubject - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrIssuer - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrSerialNumber - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrSubjectKeyID - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrPublicKeyHash - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrCertificateType - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrCertificateEncoding - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrKeyClass - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrApplicationLabel - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrIsPermanent - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrIsSensitive - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrIsExtractable - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrApplicationTag - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrKeyType - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrPRF - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecAttrSalt - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecAttrRounds - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecAttrKeySizeInBits - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrEffectiveKeySize - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrCanEncrypt - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrCanDecrypt - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrCanDerive - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrCanSign - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrCanVerify - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrCanWrap - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrCanUnwrap - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrSyncViewHint - __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0); + API_AVAILABLE(macos(10.11), ios(9.0)); extern const CFStringRef kSecAttrTokenID - __OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_9_0); + API_AVAILABLE(macos(10.12), ios(9.0)); extern const CFStringRef kSecAttrPersistantReference - __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); + API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); extern const CFStringRef kSecAttrPersistentReference -__OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); + API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)); /*! @enum kSecAttrAccessible Value Constants @@ -604,19 +604,19 @@ __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AV restored to a new device, these items will be missing. */ extern const CFStringRef kSecAttrAccessibleWhenUnlocked - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0); + API_AVAILABLE(macos(10.9), ios(4.0)); extern const CFStringRef kSecAttrAccessibleAfterFirstUnlock - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0); + API_AVAILABLE(macos(10.9), ios(4.0)); extern const CFStringRef kSecAttrAccessibleAlways - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0); + API_AVAILABLE(macos(10.9), ios(4.0)); extern const CFStringRef kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly - __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); + API_AVAILABLE(macos(10.10), ios(8.0)); extern const CFStringRef kSecAttrAccessibleWhenUnlockedThisDeviceOnly - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0); + API_AVAILABLE(macos(10.9), ios(4.0)); extern const CFStringRef kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0); + API_AVAILABLE(macos(10.9), ios(4.0)); extern const CFStringRef kSecAttrAccessibleAlwaysThisDeviceOnly - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0); + API_AVAILABLE(macos(10.9), ios(4.0)); /*! @enum kSecAttrProtocol Value Constants @@ -656,67 +656,67 @@ extern const CFStringRef kSecAttrAccessibleAlwaysThisDeviceOnly @constant kSecAttrProtocolPOP3S. */ extern const CFStringRef kSecAttrProtocolFTP - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolFTPAccount - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolHTTP - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolIRC - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolNNTP - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolPOP3 - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolSMTP - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolSOCKS - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolIMAP - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolLDAP - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolAppleTalk - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolAFP - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolTelnet - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolSSH - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolFTPS - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolHTTPS - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolHTTPProxy - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolHTTPSProxy - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolFTPProxy - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolSMB - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolRTSP - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolRTSPProxy - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolDAAP - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolEPPC - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolIPP - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolNNTPS - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolLDAPS - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolTelnetS - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolIMAPS - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolIRCS - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrProtocolPOP3S - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); /*! @enum kSecAttrAuthenticationType Value Constants @@ -733,21 +733,21 @@ extern const CFStringRef kSecAttrProtocolPOP3S @constant kSecAttrAuthenticationTypeDefault. */ extern const CFStringRef kSecAttrAuthenticationTypeNTLM - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrAuthenticationTypeMSN - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrAuthenticationTypeDPA - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrAuthenticationTypeRPA - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrAuthenticationTypeHTTPBasic - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrAuthenticationTypeHTTPDigest - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrAuthenticationTypeHTMLForm - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecAttrAuthenticationTypeDefault - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); /*! @enum kSecAttrKeyClass Value Constants @@ -759,11 +759,11 @@ extern const CFStringRef kSecAttrAuthenticationTypeDefault @constant kSecAttrKeyClassSymmetric. */ extern const CFStringRef kSecAttrKeyClassPublic - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0); + API_AVAILABLE(macos(10.7), ios(2.0)); extern const CFStringRef kSecAttrKeyClassPrivate - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0); + API_AVAILABLE(macos(10.7), ios(2.0)); extern const CFStringRef kSecAttrKeyClassSymmetric - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0); + API_AVAILABLE(macos(10.7), ios(2.0)); /*! @enum kSecAttrKeyType Value Constants @@ -781,27 +781,27 @@ extern const CFStringRef kSecAttrKeyClassSymmetric @constant kSecAttrKeyTypeECDSA (deprecated; use kSecAttrKeyTypeEC instead.) (OSX only) */ extern const CFStringRef kSecAttrKeyTypeRSA - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0); + API_AVAILABLE(macos(10.7), ios(2.0)); extern const CFStringRef kSecAttrKeyTypeDSA - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecAttrKeyTypeAES - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecAttrKeyTypeDES - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecAttrKeyType3DES - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecAttrKeyTypeRC4 - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecAttrKeyTypeRC2 - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecAttrKeyTypeCAST - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecAttrKeyTypeECDSA - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecAttrKeyTypeEC - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0); + API_AVAILABLE(macos(10.9), ios(4.0)); extern const CFStringRef kSecAttrKeyTypeECSECPrimeRandom - __OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0); + API_AVAILABLE(macos(10.12), ios(10.0)); /* @enum kSecAttrPRF Value Constants @@ -814,15 +814,15 @@ extern const CFStringRef kSecAttrKeyTypeECSECPrimeRandom @constant kSecAttrPRFHmacAlgSHA512 */ extern const CFStringRef kSecAttrPRFHmacAlgSHA1 - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecAttrPRFHmacAlgSHA224 - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecAttrPRFHmacAlgSHA256 - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecAttrPRFHmacAlgSHA384 - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecAttrPRFHmacAlgSHA512 - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); /*! @@ -890,39 +890,39 @@ extern const CFStringRef kSecAttrPRFHmacAlgSHA512 key. */ extern const CFStringRef kSecMatchPolicy - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecMatchItemList - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecMatchSearchList - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecMatchIssuers - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecMatchEmailAddressIfPresent - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecMatchSubjectContains - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecMatchSubjectStartsWith - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecMatchSubjectEndsWith - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecMatchSubjectWholeString - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecMatchCaseInsensitive - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecMatchDiacriticInsensitive - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecMatchWidthInsensitive - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecMatchTrustedOnly - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecMatchValidOnDate - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecMatchLimit - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecMatchLimitOne - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecMatchLimitAll - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); /*! @@ -952,13 +952,13 @@ extern const CFStringRef kSecMatchLimitAll persistent reference to an item (CFDataRef) should be returned. */ extern const CFStringRef kSecReturnData - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecReturnAttributes - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecReturnRef - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecReturnPersistentRef - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); /*! @@ -979,11 +979,11 @@ extern const CFStringRef kSecReturnPersistentRef even a different application) to retrieve the item referenced by it. */ extern const CFStringRef kSecValueData - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecValueRef - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecValuePersistentRef - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); /*! @@ -1021,17 +1021,17 @@ extern const CFStringRef kSecValuePersistentRef keychain operations. */ extern const CFStringRef kSecUseItemList - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); extern const CFStringRef kSecUseKeychain - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecUseOperationPrompt - __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); + API_AVAILABLE(macos(10.10), ios(8.0)); extern const CFStringRef kSecUseNoAuthenticationUI - __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_10, __MAC_10_11, __IPHONE_8_0, __IPHONE_9_0, "Use a kSecUseAuthenticationUI instead."); + API_DEPRECATED("Use kSecUseAuthenticationUI instead.", macos(10.10, 10.11), ios(8.0, 9.0)); extern const CFStringRef kSecUseAuthenticationUI - __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0); + API_AVAILABLE(macos(10.11), ios(9.0)); extern const CFStringRef kSecUseAuthenticationContext - __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0); + API_AVAILABLE(macos(10.11), ios(9.0)); /*! @enum kSecUseAuthenticationUI Value Constants @@ -1049,11 +1049,11 @@ extern const CFStringRef kSecUseAuthenticationContext only with SecItemCopyMatching. */ extern const CFStringRef kSecUseAuthenticationUIAllow - __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0); + API_AVAILABLE(macos(10.11), ios(9.0)); extern const CFStringRef kSecUseAuthenticationUIFail - __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0); + API_AVAILABLE(macos(10.11), ios(9.0)); extern const CFStringRef kSecUseAuthenticationUISkip - __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0); + API_AVAILABLE(macos(10.11), ios(9.0)); /*! @enum kSecAttrTokenID Value Constants @@ -1069,7 +1069,7 @@ extern const CFStringRef kSecUseAuthenticationUISkip possible to import pregenerated keys to kSecAttrTokenIDSecureEnclave token. */ extern const CFStringRef kSecAttrTokenIDSecureEnclave - __OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_9_0); + API_AVAILABLE(macos(10.12), ios(9.0)); /*! @enum kSecAttrAccessGroup Value Constants @@ -1082,7 +1082,7 @@ extern const CFStringRef kSecAttrTokenIDSecureEnclave be able to access items from external tokens. */ extern const CFStringRef kSecAttrAccessGroupToken - __OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0); + API_AVAILABLE(macos(10.12), ios(10.0)); /*! @function SecItemCopyMatching @@ -1147,7 +1147,7 @@ extern const CFStringRef kSecAttrAccessGroupToken of the same type. */ OSStatus SecItemCopyMatching(CFDictionaryRef query, CFTypeRef * __nullable CF_RETURNS_RETAINED result) - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); /*! @function SecItemAdd @@ -1188,7 +1188,7 @@ OSStatus SecItemCopyMatching(CFDictionaryRef query, CFTypeRef * __nullable CF_RE On OSX, the added item is returned. */ OSStatus SecItemAdd(CFDictionaryRef attributes, CFTypeRef * __nullable CF_RETURNS_RETAINED result) - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); /*! @function SecItemUpdate @@ -1207,7 +1207,7 @@ OSStatus SecItemAdd(CFDictionaryRef attributes, CFTypeRef * __nullable CF_RETURN pairs to the query dictionary. */ OSStatus SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate) - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); /*! @function SecItemDelete @@ -1238,7 +1238,7 @@ OSStatus SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate undefined. */ OSStatus SecItemDelete(CFDictionaryRef query) - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_2_0); + API_AVAILABLE(macos(10.6), ios(2.0)); CF_IMPLICIT_BRIDGING_DISABLED CF_ASSUME_NONNULL_END diff --git a/keychain/SecItemPriv.h b/keychain/SecItemPriv.h index fe66f3eb..d827b882 100644 --- a/keychain/SecItemPriv.h +++ b/keychain/SecItemPriv.h @@ -348,14 +348,11 @@ extern const CFStringRef kSecAttrViewHintPCSMailDrop; extern const CFStringRef kSecAttrViewHintPCSiCloudBackup; extern const CFStringRef kSecAttrViewHintPCSNotes; extern const CFStringRef kSecAttrViewHintPCSiMessage; -#if SEC_OS_IPHONE extern const CFStringRef kSecAttrViewHintPCSFeldspar; -#endif /* SEC_OS_IPHONE */ extern const CFStringRef kSecAttrViewHintPCSSharing; extern const CFStringRef kSecAttrViewHintAppleTV; extern const CFStringRef kSecAttrViewHintHomeKit; -extern const CFStringRef kSecAttrViewHintThumper; extern const CFStringRef kSecAttrViewHintContinuityUnlock; extern const CFStringRef kSecAttrViewHintAccessoryPairing; extern const CFStringRef kSecAttrViewHintNanoRegistry; @@ -538,8 +535,11 @@ CFDataRef _SecKeychainCopyBackup(CFDataRef backupKeybag, CFDataRef password); CFDataRef _SecKeychainCopyOTABackup(void); OSStatus _SecKeychainRestoreBackup(CFDataRef backup, CFDataRef backupKeybag, CFDataRef password); +/* + EMCS backups are similar to regular backups but we do not want to unlock the keybag + */ +CFDataRef _SecKeychainCopyEMCSBackup(CFDataRef backupKeybag); -#if SEC_OS_IPHONE bool _SecKeychainWriteBackupToFileDescriptor(CFDataRef backupKeybag, CFDataRef password, int fd, CFErrorRef *error); @@ -548,7 +548,6 @@ _SecKeychainRestoreBackupFromFileDescriptor(int fd, CFDataRef backupKeybag, CFDa CFStringRef _SecKeychainCopyKeybagUUIDFromFileDescriptor(int fd, CFErrorRef *error); -#endif /* SEC_OS_IPHONE */ OSStatus _SecKeychainBackupSyncable(CFDataRef keybag, CFDataRef password, CFDictionaryRef backup_in, CFDictionaryRef *backup_out); OSStatus _SecKeychainRestoreSyncable(CFDataRef keybag, CFDataRef password, CFDictionaryRef backup_in); @@ -569,7 +568,7 @@ bool _SecKeychainRollKeys(bool force, CFErrorRef *error); CFDictionaryRef _SecSecuritydCopyWhoAmI(CFErrorRef *error); XPC_RETURNS_RETAINED xpc_endpoint_t _SecSecuritydCopyCKKSEndpoint(CFErrorRef *error); -XPC_RETURNS_RETAINED xpc_endpoint_t _SecSecuritydCopySOSStatusEndpoint(CFErrorRef *error); +XPC_RETURNS_RETAINED xpc_endpoint_t _SecSecuritydCopyKeychainControlEndpoint(CFErrorRef* error); #if SEC_OS_IPHONE bool _SecSyncBubbleTransfer(CFArrayRef services, uid_t uid, CFErrorRef *error); @@ -628,7 +627,7 @@ SecItemUpdateWithError(CFDictionaryRef inQuery, @function SecItemParentCachePurge @abstract Clear the cache of parent certificates used in SecItemCopyParentCertificates_osx. */ -void SecItemParentCachePurge(); +void SecItemParentCachePurge(void); #endif diff --git a/keychain/SecKeyPriv.h b/keychain/SecKeyPriv.h index b5af4ce9..77bfcb5b 100644 --- a/keychain/SecKeyPriv.h +++ b/keychain/SecKeyPriv.h @@ -38,11 +38,6 @@ #include #include -#if SEC_OS_IOS -#include -#include -#endif - #if SEC_OS_OSX #include #include @@ -270,30 +265,32 @@ SecKeyRef SecKeyCreatePublicFromDER(CFAllocatorRef allocator, /* Create public key from private key */ SecKeyRef SecKeyCreatePublicFromPrivate(SecKeyRef privateKey); +#endif // SEC_OS_IPHONE /* Get Private Key (if present) by publicKey. */ SecKeyRef SecKeyCopyMatchingPrivateKey(SecKeyRef publicKey, CFErrorRef *error); -OSStatus SecKeyGetMatchingPrivateKeyStatus(SecKeyRef publicKey, CFErrorRef *error); +OSStatus SecKeyGetMatchingPrivateKeyStatus(SecKeyRef publicKey, CFErrorRef *error); CFDataRef SecKeyCreatePersistentRefToMatchingPrivateKey(SecKeyRef publicKey, CFErrorRef *error); /* Return an attribute dictionary used to find a private key by public key hash */ CFDictionaryRef CreatePrivateKeyMatchingQuery(SecKeyRef publicKey, bool returnPersistentRef); -/* Return an attribute dictionary used to store this item in a keychain. */ -CFDictionaryRef SecKeyCopyAttributeDictionary(SecKeyRef key); - /* Return a key from an attribute dictionary that was used to store this item - in a keychain. */ + in a keychain. */ SecKeyRef SecKeyCreateFromAttributeDictionary(CFDictionaryRef refAttributes); OSStatus SecKeyDigestAndVerify( - SecKeyRef key, /* Public key */ - const SecAsn1AlgId *algId, /* algorithm oid/params */ - const uint8_t *dataToDigest, /* signature over this data */ - size_t dataToDigestLen,/* length of dataToDigest */ - const uint8_t *sig, /* signature to verify */ - size_t sigLen); /* length of sig */ + SecKeyRef key, /* Public key */ + const SecAsn1AlgId *algId, /* algorithm oid/params */ + const uint8_t *dataToDigest, /* signature over this data */ + size_t dataToDigestLen,/* length of dataToDigest */ + const uint8_t *sig, /* signature to verify */ + size_t sigLen); /* length of sig */ + +#if SEC_OS_IPHONE +/* Return an attribute dictionary used to store this item in a keychain. */ +CFDictionaryRef SecKeyCopyAttributeDictionary(SecKeyRef key); OSStatus SecKeyDigestAndSign( SecKeyRef key, /* Private key */ @@ -389,6 +386,9 @@ typedef enum { size_t SecKeyGetSize(SecKeyRef key, SecKeySize whichSize) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0); +#endif + +#if SEC_OS_IPHONE /*! @function SecKeyLookupPersistentRef @@ -399,6 +399,7 @@ __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0); */ OSStatus SecKeyFindWithPersistentRef(CFDataRef persistentRef, SecKeyRef* lookedUpData) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); +#endif // SEC_OS_IPHONE /*! @function SecKeyCopyPersistentRef @@ -410,6 +411,7 @@ __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); OSStatus SecKeyCopyPersistentRef(SecKeyRef key, CFDataRef* persistentRef) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); +#if SEC_OS_IPHONE /* * diff --git a/keychain/Signin Metrics/SFTransactionMetric.h b/keychain/Signin Metrics/SFTransactionMetric.h new file mode 100644 index 00000000..6fd9876d --- /dev/null +++ b/keychain/Signin Metrics/SFTransactionMetric.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if __OBJC2__ +#ifndef SFTransactionMetric_h +#define SFTransactionMetric_h + +#import + +@interface SFTransactionMetric : NSObject + +/* + abstract: creates a new SFTransactionMetric object + uuid: iCloud sign in transaction UUID + category: name of client subsystem. This will be used as the category name when logging +*/ +- (instancetype)initWithUUID:(NSString *)uuid category:(NSString *)category; + +/* + abstract: log when a particular event occurs ex. piggybacking, restore from backup + eventName: name of the event that occured + arguments: dictionary containing a set of event attributes a subsystem wishes to log. +*/ +- (void)logEvent:(NSString*)eventName eventAttributes:(NSDictionary*)attributes; + +/* + abstract: call to time tasks that take a while (backup, wait for initial sync) + eventName: name of the event that occured + blockToTime: the block of code you wish to have timed +*/ +- (void)timeEvent:(NSString*)eventName blockToTime:(void(^)(void))blockToTime; + +/* + abstract: call to log when a error occurs during sign in + error: error that occured during iCloud Sign in +*/ +- (void)logError:(NSError*)error; + +/* + abstract: call to signal iCloud sign in has finished. + */ +- (void)signInCompleted; + +@end + + +#endif /* SFTransactionMetric_h */ +#endif diff --git a/keychain/Signin Metrics/SFTransactionMetric.m b/keychain/Signin Metrics/SFTransactionMetric.m new file mode 100644 index 00000000..74ee8219 --- /dev/null +++ b/keychain/Signin Metrics/SFTransactionMetric.m @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if __OBJC2__ + +#import "SFTransactionMetric.h" +#import + +@interface SFTransactionMetric () +@property (nonatomic, copy) NSString *uuid; +@property (nonatomic, copy) NSString *category; +@property (nonatomic, strong) os_log_t logObject; + +-(os_log_t) sftmCreateLogCategory:(NSString*) category; +-(os_log_t) sftmObjectForCategory:(NSString*) category; +@end + +static NSMutableDictionary *logObjects; +static const NSString* signInLogSpace = @"com.apple.security.wiiss"; + +@implementation SFTransactionMetric + ++ (BOOL)supportsSecureCoding { + return YES; +} + +-(os_log_t) sftmObjectForCategory:(NSString*) category +{ + return logObjects[category]; +} + +-(os_log_t) sftmCreateLogCategory:(NSString*) category +{ + return os_log_create([signInLogSpace UTF8String], [category UTF8String]); +} + +- (instancetype)initWithUUID:(NSString *)uuid category:(NSString *)category +{ + self = [super init]; + if (self) { + _uuid = uuid; + _category = category; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + logObjects = [NSMutableDictionary dictionary]; + }); + @synchronized(logObjects){ + if(category){ + _logObject = [self sftmObjectForCategory:category]; + + if(!_logObject){ + _logObject = [self sftmCreateLogCategory:category]; + [logObjects setObject:_logObject forKey:category]; + } + } + } + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [coder encodeObject:_uuid forKey:@"UUID"]; + [coder encodeObject:_category forKey:@"category"]; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)decoder +{ + self = [super init]; + if (self) { + _uuid = [decoder decodeObjectOfClass:[NSString class] forKey:@"UUID"]; + _category = [decoder decodeObjectOfClass:[NSString class] forKey:@"category"]; + } + return self; +} + +- (void)logEvent:(NSString*)eventName eventAttributes:(NSDictionary*)attributes +{ + [attributes enumerateKeysAndObjectsUsingBlock:^(NSString* key, id obj, BOOL * stop) { + os_log(self.logObject, "event: %@, %@ : %@", eventName, key, obj); + }]; +} + +- (void)timeEvent:(NSString*)eventName blockToTime:(void(^)(void))blockToTime +{ + NSDate *firstTime = [NSDate date]; + + blockToTime(); + + NSDate *SecondTime = [NSDate date]; + + os_log(self.logObject, "event: %@, Time elapsed: %@", eventName, [[NSString alloc] initWithFormat:@"%f", [SecondTime timeIntervalSinceDate:firstTime]]); +} + +- (void)logError:(NSError*)error +{ + os_log_error(self.logObject, "%@", error); +} + +- (void)signInCompleted +{ + //print final + os_log(self.logObject, "sign in complete for %@", self.uuid); +} + +@end +#endif diff --git a/keychain/analytics/CKKSPowerCollection.h b/keychain/analytics/CKKSPowerCollection.h index 7e7deb2e..aa150f07 100644 --- a/keychain/analytics/CKKSPowerCollection.h +++ b/keychain/analytics/CKKSPowerCollection.h @@ -26,10 +26,31 @@ #if OCTAGON +@protocol CKKSPowerEventType +@end +typedef NSString CKKSPowerEvent; + +extern CKKSPowerEvent* const kCKKSPowerEventOutgoingQueue; +extern CKKSPowerEvent* const kCKKSPowerEventIncommingQueue; +extern CKKSPowerEvent* const kCKKSPowerEventTLKShareProcessing; +extern CKKSPowerEvent* const kCKKSPowerEventScanLocalItems; +extern CKKSPowerEvent* const kCKKSPowerEventFetchAllChanges; + +@protocol OTPowerEventType +@end +typedef NSString OTPowerEvent; + +extern OTPowerEvent* const kOTPowerEventRestore; +extern OTPowerEvent* const kOTPowerEventEnroll; + @class CKKSOutgoingQueueEntry; @interface CKKSPowerCollection : NSOperation ++ (void)CKKSPowerEvent:(CKKSPowerEvent *)operation zone:(NSString *)zone; ++ (void)CKKSPowerEvent:(CKKSPowerEvent *)operation zone:(NSString *)zone count:(NSUInteger)count; ++ (void)OTPowerEvent:(NSString *)operation; + - (void)storedOQE:(CKKSOutgoingQueueEntry *)oqe; - (void)deletedOQE:(CKKSOutgoingQueueEntry *)oqe; diff --git a/keychain/analytics/CKKSPowerCollection.m b/keychain/analytics/CKKSPowerCollection.m index c3bbde44..7442658c 100644 --- a/keychain/analytics/CKKSPowerCollection.m +++ b/keychain/analytics/CKKSPowerCollection.m @@ -27,6 +27,16 @@ #if OCTAGON +CKKSPowerEvent* const kCKKSPowerEventOutgoingQueue = (CKKSPowerEvent*)@"processOutgoingQueue"; +CKKSPowerEvent* const kCKKSPowerEventIncommingQueue = (CKKSPowerEvent*)@"processIncomingQueue"; +CKKSPowerEvent* const kCKKSPowerEventTLKShareProcessing = (CKKSPowerEvent*)@"TLKShareProcessing"; +CKKSPowerEvent* const kCKKSPowerEventScanLocalItems = (CKKSPowerEvent*)@"scanLocalItems"; +CKKSPowerEvent* const kCKKSPowerEventFetchAllChanges = (CKKSPowerEvent*)@"fetchAllChanges"; + +OTPowerEvent* const kOTPowerEventRestore = (OTPowerEvent *)@"restoreBottledPeer"; +OTPowerEvent* const kOTPowerEventEnroll = (OTPowerEvent *)@"enrollBottledPeer"; + + @interface CKKSPowerCollection () @property (strong) NSMutableDictionary *store; @property (strong) NSMutableDictionary *delete; @@ -34,6 +44,30 @@ @implementation CKKSPowerCollection ++ (void)CKKSPowerEvent:(CKKSPowerEvent *)operation zone:(NSString *)zone +{ + SecPLLogRegisteredEvent(@"CKKSSyncing", @{ + @"operation" : operation, + @"zone" : zone + }); +} + ++ (void)CKKSPowerEvent:(CKKSPowerEvent *)operation zone:(NSString *)zone count:(NSUInteger)count +{ + SecPLLogRegisteredEvent(@"CKKSSyncing", @{ + @"operation" : operation, + @"zone" : zone, + @"count" : @(count) + }); +} + ++ (void)OTPowerEvent:(NSString *)operation +{ + SecPLLogRegisteredEvent(@"OctagonTrust", @{ + @"operation" : operation + }); +} + - (instancetype)init { if ((self = [super init]) != nil) { diff --git a/keychain/behavior/SFBehavior.h b/keychain/behavior/SFBehavior.h new file mode 100644 index 00000000..69fc256a --- /dev/null +++ b/keychain/behavior/SFBehavior.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if __OBJC2__ + +#import + +typedef NS_ENUM(uint32_t, SFBehaviorRamping) { + SFBehaviorRampingDisabled = 0, /* must not be enabled */ + SFBehaviorRampingEnabled = 1, /* unconditionally enabled */ + SFBehaviorRampingPromoted = 2, /* should be promoted by application */ + SFBehaviorRampingVisible = 3, /* allowed to enabled */ +}; + +@interface SFBehavior : NSObject + ++ (SFBehavior *)behaviorFamily:(NSString *)family; +- (instancetype)init NS_UNAVAILABLE; + +/* + * Ramping control controlled by CloudKit and configuration + * + * Return the current ramping state, can be called as often as clients want, state is cached + * and fetched in background (returning SFBehaviorRampingDisabled) until server changes the value. + * + * Ramping always go from Disable -> Visiable -> Promoted -> Enabled, can can skip over steps in-between. + * + * The feature can also go from { Visiable, Promoted, Enabled } -> Disabled if the feature is disabled + * + * Passing in force will for fetching the value from the server and bypass all caching, this will + * take its sweet time, so don't block UI on this operation, using force is not recommended. + */ +- (SFBehaviorRamping)ramping:(NSString *)feature force:(bool)force; + +/* + * This feature is assumed to be enabled unless disabled by configuration. + */ +- (bool)featureEnabled:(NSString *)feature; +/* + * This feature is assumed to be disabled unless enabled by configuration. + */ +- (bool)featureDisabled:(NSString *)feature; + +/* + * Fetch configuration values that might be changed from server configuration + */ +- (NSNumber *)configurationNumber:(NSString *)configuration defaultValue:(NSNumber *)defaultValue; +- (NSString *)configurationString:(NSString *)configuration defaultValue:(NSString *)defaultValue; + +@end + +#endif diff --git a/keychain/behavior/SFBehavior.m b/keychain/behavior/SFBehavior.m new file mode 100644 index 00000000..cd46021f --- /dev/null +++ b/keychain/behavior/SFBehavior.m @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import "SFBehavior.h" +#import + +#if __OBJC2__ + +@interface SFBehavior () +@property NSString *family; +@property NSXPCConnection *connection; +- (instancetype)initBehaviorFamily:(NSString *)family connection:(NSXPCConnection *)connection; +@end + +@protocol SFBehaviorProtocol +- (void)ramping:(NSString *)feature family:(NSString*)family complete:(void (^)(SFBehaviorRamping))complete; +- (void)feature:(NSString *)feature family:(NSString*)family defaultValue:(bool)defaultValue complete:(void (^)(bool))complete; + +- (void)configNumber:(NSString *)configuration family:(NSString*)family complete:(void (^)(NSNumber *))complete; +- (void)configString:(NSString *)configuration family:(NSString*)family complete:(void (^)(NSString *))complete; +@end + + +@implementation SFBehavior + ++ (SFBehavior *)behaviorFamily:(NSString *)family +{ + static dispatch_once_t onceToken = 0; + static NSMutableDictionary *behaviors; + static NSXPCConnection *connection = NULL; + dispatch_once(&onceToken, ^{ + behaviors = [NSMutableDictionary dictionary]; + connection = [[NSXPCConnection alloc] initWithMachServiceName:@"com.apple.security.behavior" options:NSXPCConnectionPrivileged]; + + connection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(SFBehaviorProtocol)]; + [connection resume]; + }); + + SFBehavior *behavior = nil; + @synchronized (behaviors) { + behavior = behaviors[family]; + if (behavior == NULL) { + behavior = [[SFBehavior alloc] initBehaviorFamily:family connection:connection]; + behaviors[family] = behavior; + } + } + + return behavior; +} + +- (instancetype)initBehaviorFamily:(NSString *)family connection:(NSXPCConnection *)connection +{ + self = [super init]; + if (self) { + _family = family; + _connection = connection; + } + return self; +} + +- (SFBehaviorRamping)ramping:(NSString *)feature force:(bool)force +{ + __block SFBehaviorRamping _ramping = SFBehaviorRampingDisabled; + [[_connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + }] ramping:feature family:_family complete:^(SFBehaviorRamping ramping) { + _ramping = ramping; + }]; + return _ramping; +} + +- (bool)feature:(NSString *)feature defaultValue:(bool)defaultValue +{ + __block bool enabled = defaultValue; + + [[_connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + }] feature:feature family:_family defaultValue:defaultValue complete:^(bool returnFeature) { + enabled = returnFeature; + }]; + return enabled; + +} + +- (bool)featureEnabled:(NSString *)feature +{ + return [self feature:feature defaultValue:true]; +} + +- (bool)featureDisabled:(NSString *)feature +{ + return ![self feature:feature defaultValue:false]; +} + +- (NSNumber *)configurationNumber:(NSString *)configuration defaultValue:(NSNumber *)defaultValue +{ + __block NSNumber *_number = defaultValue; + + [[_connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + }] configNumber:configuration family:_family complete:^(NSNumber *number) { + if (number) + _number = number; + }]; + return _number; +} + +- (NSString *)configurationString:(NSString *)configuration defaultValue:(NSString *)defaultValue +{ + __block NSString *_string = defaultValue; + + [[_connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + }] configString:configuration family:_family complete:^(NSString *string) { + if (string) + _string = string; + }]; + return _string; +} + +@end + +#endif /* __OBJC2__ */ + diff --git a/keychain/ckks/CKKS.h b/keychain/ckks/CKKS.h index 3b6a8545..45d4fc98 100644 --- a/keychain/ckks/CKKS.h +++ b/keychain/ckks/CKKS.h @@ -53,7 +53,7 @@ extern NSString* const SecCKKSActionDelete; extern NSString* const SecCKKSActionModify; /* Queue States */ -@protocol SecCKKSItemState +@protocol SecCKKSItemState @end typedef NSString CKKSItemState; extern CKKSItemState* const SecCKKSStateNew; @@ -64,14 +64,14 @@ extern CKKSItemState* const SecCKKSStateError; extern CKKSItemState* const SecCKKSStateDeleted; // meta-state: please delete this item! /* Processed States */ -@protocol SecCKKSProcessedState +@protocol SecCKKSProcessedState @end typedef NSString CKKSProcessedState; extern CKKSProcessedState* const SecCKKSProcessedStateLocal; extern CKKSProcessedState* const SecCKKSProcessedStateRemote; /* Key Classes */ -@protocol SecCKKSKeyClass +@protocol SecCKKSKeyClass @end typedef NSString CKKSKeyClass; extern CKKSKeyClass* const SecCKKSKeyClassTLK; @@ -125,9 +125,9 @@ extern NSString* const SecCKRecordCurrentKeyType; /* Current Item CKRecord Keys */ extern NSString* const SecCKRecordCurrentItemType; extern NSString* const SecCKRecordItemRefKey; -//extern NSString* const SecCKRecordHostOSVersionKey; <-- the OS version which last updated the record -/* Device State CKRexord Keys */ + +/* Device State CKRecord Keys */ extern NSString* const SecCKRecordDeviceStateType; extern NSString* const SecCKRecordCirclePeerID; extern NSString* const SecCKRecordCircleStatus; @@ -135,6 +135,8 @@ extern NSString* const SecCKRecordKeyState; extern NSString* const SecCKRecordCurrentTLK; extern NSString* const SecCKRecordCurrentClassA; extern NSString* const SecCKRecordCurrentClassC; +extern NSString* const SecCKSRecordLastUnlockTime; +extern NSString* const SecCKSRecordOSVersionKey; // Similar to SecCKRecordHostOSVersionKey, but better named /* Manifest master CKRecord Keys */ extern NSString* const SecCKRecordManifestType; @@ -153,19 +155,26 @@ extern NSString* const SecCKRecordManifestLeafDERKey; extern NSString* const SecCKRecordManifestLeafDigestKey; /* Zone Key Hierarchy States */ -@protocol SecCKKSZoneKeyState +@protocol SecCKKSZoneKeyState @end typedef NSString CKKSZoneKeyState; +// CKKS is currently logged out +extern CKKSZoneKeyState* const SecCKKSZoneKeyStateLoggedOut; + // Class has just been created. extern CKKSZoneKeyState* const SecCKKSZoneKeyStateInitializing; // CKKSZone has just informed us that its setup is done (and completed successfully). extern CKKSZoneKeyState* const SecCKKSZoneKeyStateInitialized; +// CKKSZone has informed us that zone setup did not work. Try again soon! +extern CKKSZoneKeyState* const SecCKKSZoneKeyStateZoneCreationFailed; // Everything is ready and waiting for input. extern CKKSZoneKeyState* const SecCKKSZoneKeyStateReady; // We're presumably ready, but we'd like to do one or two more checks after we unlock. extern CKKSZoneKeyState* const SecCKKSZoneKeyStateReadyPendingUnlock; +// We're currently refetching the zone +extern CKKSZoneKeyState* const SecCKKSZoneKeyStateFetch; // A Fetch has just been completed which includes some new keys to process extern CKKSZoneKeyState* const SecCKKSZoneKeyStateFetchComplete; // We'd really like a full refetch. @@ -187,6 +196,11 @@ extern CKKSZoneKeyState* const SecCKKSZoneKeyStateHealTLKSharesFailed; // The key hierarchy state machine needs to wait for the fixup operation to complete extern CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForFixupOperation; +// CKKS is resetting the remote zone, due to key hierarchy reasons. Will not proceed until the local reset occurs. +extern CKKSZoneKeyState* const SecCKKSZoneKeyStateResettingZone; +// CKKS is resetting the local data, likely to do a cloudkit reset or a rpc. +extern CKKSZoneKeyState* const SecCKKSZoneKeyStateResettingLocalData; + // Fatal error. Will not proceed unless fixed from outside class. extern CKKSZoneKeyState* const SecCKKSZoneKeyStateError; // This CKKS instance has been cancelled. @@ -198,6 +212,10 @@ NSDictionary* CKKSZoneKeyStateInverseMap(void); NSNumber* CKKSZoneKeyToNumber(CKKSZoneKeyState* state); CKKSZoneKeyState* CKKSZoneKeyRecover(NSNumber* stateNumber); +// Use this to determine if CKKS believes the current state is "transient": that is, should resolve itself with further local processing +// or 'nontransient': further local processing won't progress. Either we're ready, or waiting for the user to unlock, or a remote device to do something. +bool CKKSKeyStateTransient(CKKSZoneKeyState* state); + /* Hide Item Length */ extern const NSUInteger SecCKKSItemPaddingBlockSize; @@ -216,6 +234,9 @@ extern NSString* const CKKSServerExtensionErrorDomain; #define SecCKKSOutgoingQueueItemsAtOnce 100 #define SecCKKSIncomingQueueItemsAtOnce 10 +// Utility functions +NSString* SecCKKSHostOSVersion(void); + #endif // OBJ-C /* C functions to interact with CKKS */ @@ -247,6 +268,9 @@ bool SecCKKSEnforceManifests(void); bool SecCKKSEnableEnforceManifests(void); bool SecCKKSSetEnforceManifests(bool value); +bool SecCKKSReduceRateLimiting(void); +bool SecCKKSSetReduceRateLimiting(bool value); + // Testing support bool SecCKKSTestsEnabled(void); bool SecCKKSTestsEnable(void); @@ -262,11 +286,9 @@ void SecCKKSTestSetDisableSOS(bool set); bool SecCKKSTestDisableKeyNotifications(void); void SecCKKSTestSetDisableKeyNotifications(bool set); - -XPC_RETURNS_RETAINED _Nullable xpc_endpoint_t SecServerCreateCKKSEndpoint(void); - // TODO: handle errors better typedef CF_ENUM(CFIndex, CKKSErrorCode) { + CKKSNotInitialized = 9, CKKSNotLoggedIn = 10, CKKSNoSuchView = 11, @@ -283,6 +305,33 @@ typedef CF_ENUM(CFIndex, CKKSErrorCode) { CKKSNoSuchRecord = 22, CKKSMissingTLKShare = 23, CKKSNoPeersAvailable = 24, + + CKKSSplitKeyHierarchy = 32, + CKKSOrphanedKey = 33, + CKKSInvalidTLK = 34, + CKKSNoTrustedTLKShares = 35, + CKKSKeyUnknownFormat = 36, + CKKSNoSigningKey = 37, + CKKSNoEncryptionKey = 38, + + CKKSNotHSA2 = 40, + CKKSiCloudGreyMode = 41, +}; + +typedef CF_ENUM(CFIndex, CKKSResultDescriptionErrorCode) { + CKKSResultDescriptionNone = 0, + CKKSResultDescriptionPendingKeyReady = 1, + CKKSResultDescriptionPendingSuccessfulFetch = 2, + CKKSResultDescriptionPendingAccountLoggedIn = 3, + CKKSResultDescriptionPendingUnlock = 4, + CKKSResultDescriptionPendingBottledPeerModifyRecords = 5, + CKKSResultDescriptionPendingBottledPeerFetchRecords = 6, + + CKKSResultDescriptionPendingZoneChangeFetchScheduling = 1000, + CKKSResultDescriptionPendingViewChangedScheduling = 1001, + CKKSResultDescriptionPendingZoneInitializeScheduling = 1002, + CKKSResultDescriptionPendingOutgoingQueueScheduling = 1003, + CKKSResultDescriptionPendingKeyHierachyPokeScheduling = 1004, }; // These errors are returned by the CKKS server extension. @@ -377,3 +426,4 @@ CF_ASSUME_NONNULL_END #endif #endif /* CKKS_h */ + diff --git a/keychain/ckks/CKKS.m b/keychain/ckks/CKKS.m index d0d130b6..4c7e99df 100644 --- a/keychain/ckks/CKKS.m +++ b/keychain/ckks/CKKS.m @@ -23,6 +23,7 @@ #include #import +#include #if OCTAGON #import #endif @@ -37,6 +38,7 @@ #import "keychain/ckks/CKKSViewManager.h" #import "keychain/ckks/CKKSKey.h" +#import "keychain/ot/OTManager.h" const SecCKKSItemEncryptionVersion currentCKKSItemEncryptionVersion = CKKSItemEncryptionVersion2; NSString* const SecCKKSActionAdd = @"add"; @@ -101,6 +103,8 @@ NSString* const SecCKRecordKeyState = @"keystate"; NSString* const SecCKRecordCurrentTLK = @"currentTLK"; NSString* const SecCKRecordCurrentClassA = @"currentClassA"; NSString* const SecCKRecordCurrentClassC = @"currentClassC"; +NSString* const SecCKSRecordLastUnlockTime = @"lastunlock"; +NSString* const SecCKSRecordOSVersionKey = @"osver"; NSString* const SecCKRecordManifestType = @"manifest"; NSString* const SecCKRecordManifestDigestValueKey = @"digest_value"; @@ -123,6 +127,7 @@ CKKSZoneKeyState* const SecCKKSZoneKeyStateCancelled = (CKKSZoneKeyState*) @"can CKKSZoneKeyState* const SecCKKSZoneKeyStateInitializing = (CKKSZoneKeyState*) @"initializing"; CKKSZoneKeyState* const SecCKKSZoneKeyStateInitialized = (CKKSZoneKeyState*) @"initialized"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateFetch = (CKKSZoneKeyState*) @"fetching"; CKKSZoneKeyState* const SecCKKSZoneKeyStateFetchComplete = (CKKSZoneKeyState*) @"fetchcomplete"; CKKSZoneKeyState* const SecCKKSZoneKeyStateNeedFullRefetch = (CKKSZoneKeyState*) @"needrefetch"; CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForTLK = (CKKSZoneKeyState*) @"waitfortlk"; @@ -133,6 +138,10 @@ CKKSZoneKeyState* const SecCKKSZoneKeyStateNewTLKsFailed = (CKKSZoneKeyState*) @ CKKSZoneKeyState* const SecCKKSZoneKeyStateHealTLKShares = (CKKSZoneKeyState*) @"healtlkshares"; CKKSZoneKeyState* const SecCKKSZoneKeyStateHealTLKSharesFailed = (CKKSZoneKeyState*) @"healtlksharesfailed"; CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForFixupOperation = (CKKSZoneKeyState*) @"waitforfixupoperation"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateResettingZone = (CKKSZoneKeyState*) @"resetzone"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateResettingLocalData = (CKKSZoneKeyState*) @"resetlocal"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateLoggedOut = (CKKSZoneKeyState*) @"loggedout"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateZoneCreationFailed = (CKKSZoneKeyState*) @"zonecreationfailed"; NSDictionary* CKKSZoneKeyStateMap(void) { static NSDictionary* map = nil; @@ -156,6 +165,11 @@ NSDictionary* CKKSZoneKeyStateMap(void) { SecCKKSZoneKeyStateHealTLKSharesFailed:@13U, SecCKKSZoneKeyStateWaitForFixupOperation:@14U, SecCKKSZoneKeyStateReadyPendingUnlock: @15U, + SecCKKSZoneKeyStateFetch: @16U, + SecCKKSZoneKeyStateResettingZone: @17U, + SecCKKSZoneKeyStateResettingLocalData: @18U, + SecCKKSZoneKeyStateLoggedOut: @19U, + SecCKKSZoneKeyStateZoneCreationFailed: @20U, }; }); return map; @@ -192,6 +206,17 @@ CKKSZoneKeyState* CKKSZoneKeyRecover(NSNumber* stateNumber) { return SecCKKSZoneKeyStateError; } +bool CKKSKeyStateTransient(CKKSZoneKeyState* state) { + // Easier to compare against a blacklist of end states + bool nontransient = [state isEqualToString:SecCKKSZoneKeyStateReady] || + [state isEqualToString:SecCKKSZoneKeyStateReadyPendingUnlock] || + [state isEqualToString:SecCKKSZoneKeyStateWaitForTLK] || + [state isEqualToString:SecCKKSZoneKeyStateWaitForUnlock] || + [state isEqualToString:SecCKKSZoneKeyStateError] || + [state isEqualToString:SecCKKSZoneKeyStateCancelled]; + return !nontransient; +} + const NSUInteger SecCKKSItemPaddingBlockSize = 20; NSString* const SecCKKSAggdPropagationDelay = @"com.apple.security.ckks.propagationdelay"; @@ -281,6 +306,30 @@ bool SecCKKSSetEnforceManifests(bool value) { return CKKSEnforceManifests; } +// defaults write com.apple.security.ckks reduce-rate-limiting YES +static bool CKKSReduceRateLimiting = false; +bool SecCKKSReduceRateLimiting(void) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // Use the default value as above, or apply the preferences value if it exists + NSUserDefaults* defaults = [[NSUserDefaults alloc] initWithSuiteName:SecCKKSUserDefaultsSuite]; + NSString* key = @"reduce-rate-limiting"; + [defaults registerDefaults: @{key: CKKSReduceRateLimiting ? @YES : @NO}]; + + CKKSReduceRateLimiting = !![defaults boolForKey:@"reduce-rate-limiting"]; + secnotice("ckks", "reduce-rate-limiting is %@", CKKSReduceRateLimiting ? @"on" : @"off"); + }); + + return CKKSReduceRateLimiting; +} + +bool SecCKKSSetReduceRateLimiting(bool value) { + (void) SecCKKSReduceRateLimiting(); // Call this once to read the defaults write + CKKSReduceRateLimiting = value; + secnotice("ckks", "reduce-rate-limiting is now %@", CKKSReduceRateLimiting ? @"on" : @"off"); + return CKKSReduceRateLimiting; +} + // Here's a mechanism for CKKS feature flags with default values from NSUserDefaults: /*static bool CKKSShareTLKs = true; bool SecCKKSShareTLKs(void) { @@ -342,16 +391,6 @@ void SecCKKSTestResetFlags(void) { SecCKKSTestSetDisableKeyNotifications(false); } -XPC_RETURNS_RETAINED xpc_endpoint_t -SecServerCreateCKKSEndpoint(void) -{ - if (SecCKKSIsEnabled()) { - return [[CKKSViewManager manager] xpcControlEndpoint]; - } else { - return NULL; - } -} - #else /* NO OCTAGON */ bool SecCKKSIsEnabled(void) { @@ -371,25 +410,22 @@ bool SecCKKSResetSyncing(void) { return SecCKKSIsEnabled(); } -XPC_RETURNS_RETAINED xpc_endpoint_t -SecServerCreateCKKSEndpoint(void) -{ - return NULL; -} #endif /* OCTAGON */ void SecCKKSInitialize(SecDbRef db) { #if OCTAGON - CKKSViewManager* manager = [CKKSViewManager manager]; - [manager initializeZones]; + @autoreleasepool { + CKKSViewManager* manager = [CKKSViewManager manager]; + [manager initializeZones]; - SecDbAddNotifyPhaseBlock(db, ^(SecDbConnectionRef dbconn, SecDbTransactionPhase phase, SecDbTransactionSource source, CFArrayRef changes) { - SecCKKSNotifyBlock(dbconn, phase, source, changes); - }); + SecDbAddNotifyPhaseBlock(db, ^(SecDbConnectionRef dbconn, SecDbTransactionPhase phase, SecDbTransactionSource source, CFArrayRef changes) { + SecCKKSNotifyBlock(dbconn, phase, source, changes); + }); - [manager.completedSecCKKSInitialize fulfill]; + [manager.completedSecCKKSInitialize fulfill]; + } #endif } @@ -452,3 +488,47 @@ void SecCKKSPerformLocalResync() { }]; #endif } + +NSString* SecCKKSHostOSVersion() +{ +#ifdef PLATFORM + // Use complicated macro magic to get the string value passed in as preprocessor define PLATFORM. +#define PLATFORM_VALUE(f) #f +#define PLATFORM_OBJCSTR(f) @PLATFORM_VALUE(f) + NSString* platform = (PLATFORM_OBJCSTR(PLATFORM)); +#undef PLATFORM_OBJCSTR +#undef PLATFORM_VALUE +#else + NSString* platform = "unknown"; +#warning No PLATFORM defined; why? +#endif + + NSString* osversion = nil; + + // If we can get the build information from sysctl, use it. + char release[256]; + size_t releasesize = sizeof(release); + bool haveSysctlInfo = true; + haveSysctlInfo &= (0 == sysctlbyname("kern.osrelease", release, &releasesize, NULL, 0)); + + char version[256]; + size_t versionsize = sizeof(version); + haveSysctlInfo &= (0 == sysctlbyname("kern.osversion", version, &versionsize, NULL, 0)); + + if(haveSysctlInfo) { + // Null-terminate for extra safety + release[sizeof(release)-1] = '\0'; + version[sizeof(version)-1] = '\0'; + osversion = [NSString stringWithFormat:@"%s (%s)", release, version]; + } + + if(!osversion) { + // Otherwise, use the not-really-supported fallback. + osversion = [[NSProcessInfo processInfo] operatingSystemVersionString]; + + // subtly improve osversion (but it's okay if that does nothing) + osversion = [osversion stringByReplacingOccurrencesOfString:@"Version" withString:@""]; + } + + return [NSString stringWithFormat:@"%@ %@", platform, osversion]; +} diff --git a/keychain/ckks/CKKSAPSReceiver.h b/keychain/ckks/CKKSAPSReceiver.h index e9788bc9..7f83dc0a 100644 --- a/keychain/ckks/CKKSAPSReceiver.h +++ b/keychain/ckks/CKKSAPSReceiver.h @@ -31,7 +31,7 @@ NS_ASSUME_NONNULL_BEGIN -@protocol CKKSZoneUpdateReceiver +@protocol CKKSZoneUpdateReceiver - (void)notifyZoneChange:(CKRecordZoneNotification* _Nullable)notification; @end diff --git a/keychain/ckks/CKKSAPSReceiver.m b/keychain/ckks/CKKSAPSReceiver.m index c8bc2158..57fa30a6 100644 --- a/keychain/ckks/CKKSAPSReceiver.m +++ b/keychain/ckks/CKKSAPSReceiver.m @@ -65,7 +65,7 @@ static dispatch_queue_t aps_dispatch_queue; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - aps_dispatch_queue = dispatch_queue_create("aps-callback-queue", DISPATCH_QUEUE_SERIAL); + aps_dispatch_queue = dispatch_queue_create("aps-callback-queue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); }); return aps_dispatch_queue; } diff --git a/keychain/ckks/CKKSAnalytics.h b/keychain/ckks/CKKSAnalytics.h new file mode 100644 index 00000000..37962904 --- /dev/null +++ b/keychain/ckks/CKKSAnalytics.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import + +#if OCTAGON +#import "Analytics/SFAnalytics.h" + +extern NSString* const CKKSAnalyticsInCircle; +extern NSString* const CKKSAnalyticsHasTLKs; +extern NSString* const CKKSAnalyticsSyncedClassARecently; +extern NSString* const CKKSAnalyticsSyncedClassCRecently; +extern NSString* const CKKSAnalyticsIncomingQueueIsErrorFree; +extern NSString* const CKKSAnalyticsOutgoingQueueIsErrorFree; +extern NSString* const CKKSAnalyticsInSync; +extern NSString* const CKKSAnalyticsValidCredentials; +extern NSString* const CKKSAnalyticsLastUnlock; +extern NSString* const CKKSAnalyticsLastKeystateReady; +extern NSString* const CKKSAnalyticsLastInCircle; + +@class CKKSKeychainView; + +@protocol CKKSAnalyticsFailableEvent +@end +typedef NSString CKKSAnalyticsFailableEvent; +extern CKKSAnalyticsFailableEvent* const CKKSEventProcessIncomingQueueClassA; +extern CKKSAnalyticsFailableEvent* const CKKSEventProcessIncomingQueueClassC; +extern CKKSAnalyticsFailableEvent* const CKKSEventProcessOutgoingQueue; +extern CKKSAnalyticsFailableEvent* const CKKSEventUploadChanges; +extern CKKSAnalyticsFailableEvent* const CKKSEventStateError; +extern CKKSAnalyticsFailableEvent* const CKKSEventProcessHealKeyHierarchy; + +extern CKKSAnalyticsFailableEvent* const OctagonEventPreflightBottle; +extern CKKSAnalyticsFailableEvent* const OctagonEventLaunchBottle; +extern CKKSAnalyticsFailableEvent* const OctagonEventScrubBottle; +extern CKKSAnalyticsFailableEvent* const OctagonEventSignIn; +extern CKKSAnalyticsFailableEvent* const OctagonEventSignOut; +extern CKKSAnalyticsFailableEvent* const OctagonEventRestoreBottle; +extern CKKSAnalyticsFailableEvent* const OctagonEventRamp; +extern CKKSAnalyticsFailableEvent* const OctagonEventBottleCheck; +extern CKKSAnalyticsFailableEvent* const OctagonEventCoreFollowUp; + +extern CKKSAnalyticsFailableEvent* const OctagonEventRestoredSignedBottlePeer; +extern CKKSAnalyticsFailableEvent* const OctagonEventRestoredOctagonPeerEncryptionKey; +extern CKKSAnalyticsFailableEvent* const OctagonEventRestoredOctagonPeerSigningKey; +extern CKKSAnalyticsFailableEvent* const OctagonEventRestoreComplete; + + +@protocol CKKSAnalyticsSignpostEvent +@end +typedef NSString CKKSAnalyticsSignpostEvent; +extern CKKSAnalyticsSignpostEvent* const CKKSEventPushNotificationReceived; +extern CKKSAnalyticsSignpostEvent* const CKKSEventItemAddedToOutgoingQueue; +extern CKKSAnalyticsSignpostEvent* const CKKSEventReachabilityTimerExpired; +extern CKKSAnalyticsSignpostEvent* const CKKSEventMissingLocalItemsFound; + +@protocol CKKSAnalyticsActivity +@end +typedef NSString CKKSAnalyticsActivity; +extern CKKSAnalyticsActivity* const CKKSActivityOTFetchRampState; +extern CKKSAnalyticsActivity* const CKKSActivityOctagonSignIn; +extern CKKSAnalyticsActivity* const CKKSActivityOctagonPreflightBottle; +extern CKKSAnalyticsActivity* const CKKSActivityOctagonLaunchBottle; +extern CKKSAnalyticsActivity* const CKKSActivityOctagonRestore; +extern CKKSAnalyticsActivity* const CKKSActivityScrubBottle; +extern CKKSAnalyticsActivity* const CKKSActivityBottleCheck; + +@interface CKKSAnalytics : SFAnalytics + ++ (instancetype)logger; + +- (void)logSuccessForEvent:(CKKSAnalyticsFailableEvent*)event inView:(CKKSKeychainView*)view; +- (void)logRecoverableError:(NSError*)error + forEvent:(CKKSAnalyticsFailableEvent*)event + inView:(CKKSKeychainView*)view + withAttributes:(NSDictionary*)attributes; + +- (void)logRecoverableError:(NSError*)error + forEvent:(CKKSAnalyticsFailableEvent*)event + zoneName:(NSString*)zoneName + withAttributes:(NSDictionary *)attributes; + + +- (void)logUnrecoverableError:(NSError*)error + forEvent:(CKKSAnalyticsFailableEvent*)event + withAttributes:(NSDictionary *)attributes; + +- (void)logUnrecoverableError:(NSError*)error + forEvent:(CKKSAnalyticsFailableEvent*)event + inView:(CKKSKeychainView*)view + withAttributes:(NSDictionary*)attributes; + +- (void)noteEvent:(CKKSAnalyticsSignpostEvent*)event; +- (void)noteEvent:(CKKSAnalyticsSignpostEvent*)event inView:(CKKSKeychainView*)view; + +- (void)setDateProperty:(NSDate*)date forKey:(NSString*)key inView:(CKKSKeychainView *)view; +- (NSDate *)datePropertyForKey:(NSString *)key inView:(CKKSKeychainView *)view; + +@end + +@interface CKKSAnalytics (UnitTesting) + +- (NSDate*)dateOfLastSuccessForEvent:(CKKSAnalyticsFailableEvent*)event inView:(CKKSKeychainView*)view; +- (NSDictionary *)errorChain:(NSError *)error depth:(NSUInteger)depth; + +@end + +#endif + + diff --git a/keychain/ckks/CKKSAnalytics.m b/keychain/ckks/CKKSAnalytics.m new file mode 100644 index 00000000..f26019f9 --- /dev/null +++ b/keychain/ckks/CKKSAnalytics.m @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import +#import +#import + +#import "keychain/ckks/CKKSAnalytics.h" +#import "keychain/ot/OTDefines.h" +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSViewManager.h" +#import "keychain/ckks/CKKSKeychainView.h" +#import "Analytics/SFAnalytics.h" +#include +#include + +NSString* const CKKSAnalyticsInCircle = @"inCircle"; +NSString* const CKKSAnalyticsHasTLKs = @"TLKs"; +NSString* const CKKSAnalyticsSyncedClassARecently = @"inSyncA"; +NSString* const CKKSAnalyticsSyncedClassCRecently = @"inSyncC"; +NSString* const CKKSAnalyticsIncomingQueueIsErrorFree = @"IQNOE"; +NSString* const CKKSAnalyticsOutgoingQueueIsErrorFree = @"OQNOE"; +NSString* const CKKSAnalyticsInSync = @"inSync"; +NSString* const CKKSAnalyticsValidCredentials = @"validCredentials"; +NSString* const CKKSAnalyticsLastUnlock = @"lastUnlock"; +NSString* const CKKSAnalyticsLastKeystateReady = @"lastKSR"; +NSString* const CKKSAnalyticsLastInCircle = @"lastInCircle"; + +static NSString* const CKKSAnalyticsAttributeRecoverableError = @"recoverableError"; +static NSString* const CKKSAnalyticsAttributeZoneName = @"zone"; +static NSString* const CKKSAnalyticsAttributeErrorDomain = @"errorDomain"; +static NSString* const CKKSAnalyticsAttributeErrorCode = @"errorCode"; +static NSString* const CKKSAnalyticsAttributeErrorChain = @"errorChain"; + +CKKSAnalyticsFailableEvent* const CKKSEventProcessIncomingQueueClassA = (CKKSAnalyticsFailableEvent*)@"CKKSEventProcessIncomingQueueClassA"; +CKKSAnalyticsFailableEvent* const CKKSEventProcessIncomingQueueClassC = (CKKSAnalyticsFailableEvent*)@"CKKSEventProcessIncomingQueueClassC"; +CKKSAnalyticsFailableEvent* const CKKSEventProcessOutgoingQueue = (CKKSAnalyticsFailableEvent*)@"CKKSEventProcessOutgoingQueue"; +CKKSAnalyticsFailableEvent* const CKKSEventUploadChanges = (CKKSAnalyticsFailableEvent*)@"CKKSEventUploadChanges"; +CKKSAnalyticsFailableEvent* const CKKSEventStateError = (CKKSAnalyticsFailableEvent*)@"CKKSEventStateError"; +CKKSAnalyticsFailableEvent* const CKKSEventProcessHealKeyHierarchy = (CKKSAnalyticsFailableEvent *)@"CKKSEventProcessHealKeyHierarchy"; + +NSString* const OctagonEventFailureReason = @"FailureReason"; + +CKKSAnalyticsFailableEvent* const OctagonEventPreflightBottle = (CKKSAnalyticsFailableEvent*)@"OctagonEventPreflightBottle"; +CKKSAnalyticsFailableEvent* const OctagonEventLaunchBottle = (CKKSAnalyticsFailableEvent*)@"OctagonEventLaunchBottle"; +CKKSAnalyticsFailableEvent* const OctagonEventRestoreBottle = (CKKSAnalyticsFailableEvent*)@"OctagonEventRestoreBottle"; +CKKSAnalyticsFailableEvent* const OctagonEventScrubBottle = (CKKSAnalyticsFailableEvent*)@"OctagonEventScrubBottle"; +CKKSAnalyticsFailableEvent* const OctagonEventSignIn = (CKKSAnalyticsFailableEvent *)@"OctagonEventSignIn"; +CKKSAnalyticsFailableEvent* const OctagonEventSignOut = (CKKSAnalyticsFailableEvent *)@"OctagonEventSignIn"; +CKKSAnalyticsFailableEvent* const OctagonEventRamp = (CKKSAnalyticsFailableEvent *)@"OctagonEventRamp"; +CKKSAnalyticsFailableEvent* const OctagonEventBottleCheck = (CKKSAnalyticsFailableEvent *)@"OctagonEventBottleCheck"; +CKKSAnalyticsFailableEvent* const OctagonEventCoreFollowUp = (CKKSAnalyticsFailableEvent *)@"OctagonEventCoreFollowUp"; + +CKKSAnalyticsSignpostEvent* const CKKSEventPushNotificationReceived = (CKKSAnalyticsSignpostEvent*)@"CKKSEventPushNotificationReceived"; +CKKSAnalyticsSignpostEvent* const CKKSEventItemAddedToOutgoingQueue = (CKKSAnalyticsSignpostEvent*)@"CKKSEventItemAddedToOutgoingQueue"; +CKKSAnalyticsSignpostEvent* const CKKSEventMissingLocalItemsFound = (CKKSAnalyticsSignpostEvent*)@"CKKSEventMissingLocalItemsFound"; +CKKSAnalyticsSignpostEvent* const CKKSEventReachabilityTimerExpired = (CKKSAnalyticsSignpostEvent *)@"CKKSEventReachabilityTimerExpired"; + +CKKSAnalyticsActivity* const CKKSActivityOTFetchRampState = (CKKSAnalyticsActivity *)@"CKKSActivityOTFetchRampState"; +CKKSAnalyticsActivity* const CKKSActivityOctagonSignIn = (CKKSAnalyticsActivity *)@"CKKSActivityOctagonSignIn"; +CKKSAnalyticsActivity* const CKKSActivityOctagonPreflightBottle = (CKKSAnalyticsActivity *)@"CKKSActivityOctagonPreflightBottle"; +CKKSAnalyticsActivity* const CKKSActivityOctagonLaunchBottle = (CKKSAnalyticsActivity *)@"CKKSActivityOctagonLaunchBottle"; +CKKSAnalyticsActivity* const CKKSActivityOctagonRestore = (CKKSAnalyticsActivity *)@"CKKSActivityOctagonRestore"; +CKKSAnalyticsActivity* const CKKSActivityScrubBottle = (CKKSAnalyticsActivity *)@"CKKSActivityScrubBottle"; +CKKSAnalyticsActivity* const CKKSActivityBottleCheck = (CKKSAnalyticsActivity *)@"CKKSActivityBottleCheck"; + +@implementation CKKSAnalytics + ++ (NSString*)databasePath +{ + // This block exists because we moved database locations in 11.3 for easier sandboxing of securityuploadd, so we're cleaning up. + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + WithPathInKeychainDirectory(CFSTR("ckks_analytics_v2.db"), ^(const char *filename) { + remove(filename); + }); + WithPathInKeychainDirectory(CFSTR("ckks_analytics_v2.db-wal"), ^(const char *filename) { + remove(filename); + }); + WithPathInKeychainDirectory(CFSTR("ckks_analytics_v2.db-shm"), ^(const char *filename) { + remove(filename); + }); + }); + + WithPathInKeychainDirectory(CFSTR("Analytics"), ^(const char *path) { +#if TARGET_OS_IPHONE + mode_t permissions = 0775; +#else + mode_t permissions = 0700; +#endif // TARGET_OS_IPHONE + int ret = mkpath_np(path, permissions); + if (!(ret == 0 || ret == EEXIST)) { + secerror("could not create path: %s (%s)", path, strerror(ret)); + } + chmod(path, permissions); + }); + return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"Analytics/ckks_analytics.db") path]; +} + ++ (instancetype)logger +{ + // just here because I want it in the header for discoverability + return [super logger]; +} + +- (void)logSuccessForEvent:(CKKSAnalyticsFailableEvent*)event inView:(CKKSKeychainView*)view +{ + [self logSuccessForEventNamed:[NSString stringWithFormat:@"%@-%@", view.zoneName, event]]; + [self setDateProperty:[NSDate date] forKey:[NSString stringWithFormat:@"last_success_%@-%@", view.zoneName, event]]; +} + +- (bool)isCKPartialError:(NSError *)error +{ + return [error.domain isEqualToString:CKErrorDomain] && error.code == CKErrorPartialFailure; +} + +- (void)addCKPartialError:(NSMutableDictionary *)errorDictionary error:(NSError *)error depth:(NSUInteger)depth +{ + // capture one random underlaying error + if ([self isCKPartialError:error]) { + NSDictionary *partialErrors = error.userInfo[CKPartialErrorsByItemIDKey]; + if ([partialErrors isKindOfClass:[NSDictionary class]]) { + for (NSString *key in partialErrors) { + NSError* ckError = partialErrors[key]; + if (![ckError isKindOfClass:[NSError class]]) + continue; + if ([ckError.domain isEqualToString:CKErrorDomain] && ckError.code == CKErrorBatchRequestFailed) { + continue; + } + NSDictionary *res = [self errorChain:ckError depth:(depth + 1)]; + if (res) { + errorDictionary[@"oneCloudKitPartialFailure"] = res; + break; + } + } + } + } +} + +// if we have underlying errors, capture the chain below the top-most error +- (NSDictionary *)errorChain:(NSError *)error depth:(NSUInteger)depth +{ + NSMutableDictionary *errorDictionary = nil; + + if (depth > 5 || ![error isKindOfClass:[NSError class]]) + return nil; + + errorDictionary = [@{ + @"domain" : error.domain, + @"code" : @(error.code), + } mutableCopy]; + + errorDictionary[@"child"] = [self errorChain:error.userInfo[NSUnderlyingErrorKey] depth:(depth + 1)]; + [self addCKPartialError:errorDictionary error:error depth:(depth + 1)]; + + return errorDictionary; +} +- (void)logRecoverableError:(NSError*)error forEvent:(CKKSAnalyticsFailableEvent*)event zoneName:(NSString*)zoneName withAttributes:(NSDictionary *)attributes +{ + if (error == nil){ + return; + } + NSMutableDictionary* eventAttributes = [NSMutableDictionary dictionary]; + + /* Don't allow caller to overwrite our attributes, lets merge them first */ + if (attributes) { + [eventAttributes setValuesForKeysWithDictionary:attributes]; + } + + [eventAttributes setValuesForKeysWithDictionary:@{ + CKKSAnalyticsAttributeRecoverableError : @(YES), + CKKSAnalyticsAttributeZoneName : zoneName, + CKKSAnalyticsAttributeErrorDomain : error.domain, + CKKSAnalyticsAttributeErrorCode : @(error.code) + }]; + + eventAttributes[CKKSAnalyticsAttributeErrorChain] = [self errorChain:error.userInfo[NSUnderlyingErrorKey] depth:0]; + [self addCKPartialError:eventAttributes error:error depth:0]; + + [super logSoftFailureForEventNamed:event withAttributes:eventAttributes]; +} +- (void)logRecoverableError:(NSError*)error forEvent:(CKKSAnalyticsFailableEvent*)event inView:(CKKSKeychainView*)view withAttributes:(NSDictionary *)attributes +{ + if (error == nil){ + return; + } + NSMutableDictionary* eventAttributes = [NSMutableDictionary dictionary]; + + /* Don't allow caller to overwrite our attributes, lets merge them first */ + if (attributes) { + [eventAttributes setValuesForKeysWithDictionary:attributes]; + } + + [eventAttributes setValuesForKeysWithDictionary:@{ + CKKSAnalyticsAttributeRecoverableError : @(YES), + CKKSAnalyticsAttributeZoneName : view.zoneName, + CKKSAnalyticsAttributeErrorDomain : error.domain, + CKKSAnalyticsAttributeErrorCode : @(error.code) + }]; + + eventAttributes[CKKSAnalyticsAttributeErrorChain] = [self errorChain:error.userInfo[NSUnderlyingErrorKey] depth:0]; + [self addCKPartialError:eventAttributes error:error depth:0]; + + [super logSoftFailureForEventNamed:event withAttributes:eventAttributes]; +} + +- (void)logUnrecoverableError:(NSError*)error forEvent:(CKKSAnalyticsFailableEvent*)event inView:(CKKSKeychainView*)view withAttributes:(NSDictionary *)attributes +{ + if (error == nil){ + return; + } + NSMutableDictionary* eventAttributes = [NSMutableDictionary dictionary]; + if (attributes) { + [eventAttributes setValuesForKeysWithDictionary:attributes]; + } + + eventAttributes[CKKSAnalyticsAttributeErrorChain] = [self errorChain:error.userInfo[NSUnderlyingErrorKey] depth:0]; + [self addCKPartialError:eventAttributes error:error depth:0]; + + [eventAttributes setValuesForKeysWithDictionary:@{ + CKKSAnalyticsAttributeRecoverableError : @(NO), + CKKSAnalyticsAttributeZoneName : view.zoneName, + CKKSAnalyticsAttributeErrorDomain : error.domain, + CKKSAnalyticsAttributeErrorCode : @(error.code) + }]; + + [self logHardFailureForEventNamed:event withAttributes:eventAttributes]; +} + +- (void)logUnrecoverableError:(NSError*)error forEvent:(CKKSAnalyticsFailableEvent*)event withAttributes:(NSDictionary *)attributes +{ + if (error == nil){ + return; + } + NSMutableDictionary* eventAttributes = [NSMutableDictionary dictionary]; + + /* Don't allow caller to overwrite our attributes, lets merge them first */ + if (attributes) { + [eventAttributes setValuesForKeysWithDictionary:attributes]; + } + + eventAttributes[CKKSAnalyticsAttributeErrorChain] = [self errorChain:error.userInfo[NSUnderlyingErrorKey] depth:0]; + [self addCKPartialError:eventAttributes error:error depth:0]; + + [eventAttributes setValuesForKeysWithDictionary:@{ + CKKSAnalyticsAttributeRecoverableError : @(NO), + CKKSAnalyticsAttributeZoneName : OctagonEventAttributeZoneName, + CKKSAnalyticsAttributeErrorDomain : error.domain, + CKKSAnalyticsAttributeErrorCode : @(error.code) + }]; + + [self logHardFailureForEventNamed:event withAttributes:eventAttributes]; +} + +- (void)noteEvent:(CKKSAnalyticsSignpostEvent*)event +{ + [self noteEventNamed:event]; +} +- (void)noteEvent:(CKKSAnalyticsSignpostEvent*)event inView:(CKKSKeychainView*)view +{ + [self noteEventNamed:[NSString stringWithFormat:@"%@-%@", view.zoneName, event]]; +} + +- (NSDate*)dateOfLastSuccessForEvent:(CKKSAnalyticsFailableEvent*)event inView:(CKKSKeychainView*)view +{ + return [self datePropertyForKey:[NSString stringWithFormat:@"last_success_%@-%@", view.zoneName, event]]; +} + +- (void)setDateProperty:(NSDate*)date forKey:(NSString*)key inView:(CKKSKeychainView *)view +{ + [self setDateProperty:date forKey:[NSString stringWithFormat:@"%@-%@", key, view.zoneName]]; +} +- (NSDate *)datePropertyForKey:(NSString *)key inView:(CKKSKeychainView *)view +{ + return [self datePropertyForKey:[NSString stringWithFormat:@"%@-%@", key, view.zoneName]]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ckks/CKKSAnalyticsLogger.h b/keychain/ckks/CKKSAnalyticsLogger.h deleted file mode 100644 index 6d249200..00000000 --- a/keychain/ckks/CKKSAnalyticsLogger.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -#if OCTAGON -#import "Analytics/SFAnalyticsLogger.h" - -@class CKKSKeychainView; - -@protocol CKKSAnalyticsFailableEvent -@end -typedef NSString CKKSAnalyticsFailableEvent; -extern CKKSAnalyticsFailableEvent* const CKKSEventProcessIncomingQueueClassA; -extern CKKSAnalyticsFailableEvent* const CKKSEventProcessIncomingQueueClassC; -extern CKKSAnalyticsFailableEvent* const CKKSEventUploadChanges; -extern CKKSAnalyticsFailableEvent* const CKKSEventStateError; - -@protocol CKKSAnalyticsSignpostEvent -@end -typedef NSString CKKSAnalyticsSignpostEvent; -extern CKKSAnalyticsSignpostEvent* const CKKSEventPushNotificationReceived; -extern CKKSAnalyticsSignpostEvent* const CKKSEventItemAddedToOutgoingQueue; - -@interface CKKSAnalyticsLogger : SFAnalyticsLogger - -+ (instancetype)logger; - -- (void)logSuccessForEvent:(CKKSAnalyticsFailableEvent*)event inView:(CKKSKeychainView*)view; -- (void)logRecoverableError:(NSError*)error forEvent:(CKKSAnalyticsFailableEvent*)event inView:(CKKSKeychainView*)view withAttributes:(NSDictionary *)attributes; -- (void)logUnrecoverableError:(NSError*)error forEvent:(CKKSAnalyticsFailableEvent*)event inView:(CKKSKeychainView*)view withAttributes:(NSDictionary *)attributes; - -- (void)noteEvent:(CKKSAnalyticsSignpostEvent*)event inView:(CKKSKeychainView*)view; - -@end - -@interface CKKSAnalyticsLogger (UniteTesting) - -- (NSDate*)dateOfLastSuccessForEvent:(CKKSAnalyticsFailableEvent*)event inView:(CKKSKeychainView*)view; - -@end - -#endif diff --git a/keychain/ckks/CKKSAnalyticsLogger.m b/keychain/ckks/CKKSAnalyticsLogger.m deleted file mode 100644 index 952ae55c..00000000 --- a/keychain/ckks/CKKSAnalyticsLogger.m +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#if OCTAGON - -#import "CKKSAnalyticsLogger.h" -#import "debugging.h" -#import "CKKS.h" -#import "CKKSViewManager.h" -#import "CKKSKeychainView.h" -#include -#import "Analytics/SFAnalyticsLogger.h" -#import - -static NSString* const CKKSAnalyticsAttributeRecoverableError = @"recoverableError"; -static NSString* const CKKSAnalyticsAttributeZoneName = @"zone"; -static NSString* const CKKSAnalyticsAttributeErrorDomain = @"errorDomain"; -static NSString* const CKKSAnalyticsAttributeErrorCode = @"errorCode"; - -static NSString* const CKKSAnalyticsInCircle = @"inCircle"; -static NSString* const CKKSAnalyticsDeviceID = @"ckdeviceID"; -static NSString* const CKKSAnalyticsHasTLKs = @"TLKs"; -static NSString* const CKKSAnalyticsSyncedClassARecently = @"inSyncA"; -static NSString* const CKKSAnalyticsSyncedClassCRecently = @"inSyncC"; -static NSString* const CKKSAnalyticsIncomingQueueIsErrorFree = @"IQNOE"; -static NSString* const CKKSAnalyticsOutgoingQueueIsErrorFree = @"OQNOE"; -static NSString* const CKKSAnalyticsInSync = @"inSync"; - -CKKSAnalyticsFailableEvent* const CKKSEventProcessIncomingQueueClassA = (CKKSAnalyticsFailableEvent*)@"CKKSEventProcessIncomingQueueClassA"; -CKKSAnalyticsFailableEvent* const CKKSEventProcessIncomingQueueClassC = (CKKSAnalyticsFailableEvent*)@"CKKSEventProcessIncomingQueueClassC"; -CKKSAnalyticsFailableEvent* const CKKSEventUploadChanges = (CKKSAnalyticsFailableEvent*)@"CKKSEventUploadChanges"; -CKKSAnalyticsFailableEvent* const CKKSEventStateError = (CKKSAnalyticsFailableEvent*)@"CKKSEventStateError"; - -CKKSAnalyticsSignpostEvent* const CKKSEventPushNotificationReceived = (CKKSAnalyticsSignpostEvent*)@"CKKSEventPushNotificationReceived"; -CKKSAnalyticsSignpostEvent* const CKKSEventItemAddedToOutgoingQueue = (CKKSAnalyticsSignpostEvent*)@"CKKSEventItemAddedToOutgoingQueue"; - -@implementation CKKSAnalyticsLogger - -+ (NSString*)databasePath -{ - return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"ckks_analytics_v2.db") path]; -} - -+ (instancetype)logger -{ - // just here because I want it in the header for discoverability - return [super logger]; -} - -- (void)logSuccessForEvent:(CKKSAnalyticsFailableEvent*)event inView:(CKKSKeychainView*)view -{ - [self logSuccessForEventNamed:[NSString stringWithFormat:@"%@-%@", view.zoneName, event]]; - [self setDateProperty:[NSDate date] forKey:[NSString stringWithFormat:@"last_success_%@-%@", view.zoneName, event]]; -} - -- (void)logRecoverableError:(NSError*)error forEvent:(CKKSAnalyticsFailableEvent*)event inView:(CKKSKeychainView*)view withAttributes:(NSDictionary *)attributes -{ - NSDictionary* eventAttributes = @{ CKKSAnalyticsAttributeRecoverableError : @(YES), - CKKSAnalyticsAttributeZoneName : view.zoneName, - CKKSAnalyticsAttributeErrorDomain : error.domain, - CKKSAnalyticsAttributeErrorCode : @(error.code) }; - - if (attributes) { - /* Don't allow caller to overwrite our attributes */ - NSMutableDictionary *mergedAttributes = [attributes mutableCopy]; - [mergedAttributes setValuesForKeysWithDictionary:eventAttributes]; - eventAttributes = mergedAttributes; - } - - [super logSoftFailureForEventNamed:event withAttributes:eventAttributes]; -} - -- (void)logUnrecoverableError:(NSError*)error forEvent:(CKKSAnalyticsFailableEvent*)event inView:(CKKSKeychainView*)view withAttributes:(NSDictionary *)attributes -{ - if (error == nil) - return; - NSDictionary* eventAttributes = @{ CKKSAnalyticsAttributeRecoverableError : @(NO), - CKKSAnalyticsAttributeZoneName : view.zoneName, - CKKSAnalyticsAttributeErrorDomain : error.domain, - CKKSAnalyticsAttributeErrorCode : @(error.code) }; - - if (attributes) { - /* Don't allow caller to overwrite our attributes */ - NSMutableDictionary *mergedAttributes = [attributes mutableCopy]; - [mergedAttributes setValuesForKeysWithDictionary:eventAttributes]; - eventAttributes = mergedAttributes; - } - - [self logHardFailureForEventNamed:event withAttributes:eventAttributes]; -} - -- (void)noteEvent:(CKKSAnalyticsSignpostEvent*)event inView:(CKKSKeychainView*)view -{ - [self noteEventNamed:[NSString stringWithFormat:@"%@-%@", view.zoneName, event]]; -} - -- (NSDate*)dateOfLastSuccessForEvent:(CKKSAnalyticsFailableEvent*)event inView:(CKKSKeychainView*)view -{ - return [self datePropertyForKey:[NSString stringWithFormat:@"last_success_%@-%@", view.zoneName, event]]; -} - -- (NSDictionary*)extraValuesToUploadToServer -{ - NSMutableDictionary* values = [NSMutableDictionary dictionary]; - CKKSCKAccountStateTracker* accountTracker = [[CKKSViewManager manager] accountTracker]; - BOOL inCircle = accountTracker && accountTracker.currentCircleStatus == kSOSCCInCircle; - values[CKKSAnalyticsInCircle] = @(inCircle); - - NSString *ckdeviceID = accountTracker.ckdeviceID; - if (ckdeviceID) - values[CKKSAnalyticsDeviceID] = ckdeviceID; - for (NSString* viewName in [[CKKSViewManager manager] viewList]) { - CKKSKeychainView* view = [CKKSViewManager findOrCreateView:viewName]; - NSDate* dateOfLastSyncClassA = [self dateOfLastSuccessForEvent:CKKSEventProcessIncomingQueueClassA inView:view]; - NSDate* dateOfLastSyncClassC = [self dateOfLastSuccessForEvent:CKKSEventProcessIncomingQueueClassC inView:view]; - - NSInteger fuzzyDaysSinceClassASync = [CKKSAnalyticsLogger fuzzyDaysSinceDate:dateOfLastSyncClassA]; - NSInteger fuzzyDaysSinceClassCSync = [CKKSAnalyticsLogger fuzzyDaysSinceDate:dateOfLastSyncClassC]; - [values setValue:@(fuzzyDaysSinceClassASync) forKey:[NSString stringWithFormat:@"%@-daysSinceClassASync", viewName]]; - [values setValue:@(fuzzyDaysSinceClassCSync) forKey:[NSString stringWithFormat:@"%@-daysSinceClassCSync", viewName]]; - - BOOL hasTLKs = [view.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateReady]; - BOOL syncedClassARecently = fuzzyDaysSinceClassASync < 7; - BOOL syncedClassCRecently = fuzzyDaysSinceClassCSync < 7; - BOOL incomingQueueIsErrorFree = view.lastIncomingQueueOperation.error == nil; - BOOL outgoingQueueIsErrorFree = view.lastOutgoingQueueOperation.error == nil; - - NSString* hasTLKsKey = [NSString stringWithFormat:@"%@-%@", viewName, CKKSAnalyticsHasTLKs]; - NSString* syncedClassARecentlyKey = [NSString stringWithFormat:@"%@-%@", viewName, CKKSAnalyticsSyncedClassARecently]; - NSString* syncedClassCRecentlyKey = [NSString stringWithFormat:@"%@-%@", viewName, CKKSAnalyticsSyncedClassCRecently]; - NSString* incomingQueueIsErrorFreeKey = [NSString stringWithFormat:@"%@-%@", viewName, CKKSAnalyticsIncomingQueueIsErrorFree]; - NSString* outgoingQueueIsErrorFreeKey = [NSString stringWithFormat:@"%@-%@", viewName, CKKSAnalyticsOutgoingQueueIsErrorFree]; - - values[hasTLKsKey] = @(hasTLKs); - values[syncedClassARecentlyKey] = @(syncedClassARecently); - values[syncedClassCRecentlyKey] = @(syncedClassCRecently); - values[incomingQueueIsErrorFreeKey] = @(incomingQueueIsErrorFree); - values[outgoingQueueIsErrorFreeKey] = @(outgoingQueueIsErrorFree); - - BOOL weThinkWeAreInSync = inCircle && hasTLKs && syncedClassARecently && syncedClassCRecently && incomingQueueIsErrorFree && outgoingQueueIsErrorFree; - NSString* inSyncKey = [NSString stringWithFormat:@"%@-%@", viewName, CKKSAnalyticsInSync]; - values[inSyncKey] = @(weThinkWeAreInSync); - } - - return values; -} - -@end - -#endif // OCTAGON diff --git a/keychain/ckks/CKKSCKAccountStateTracker.h b/keychain/ckks/CKKSCKAccountStateTracker.h index 19370999..fb055091 100644 --- a/keychain/ckks/CKKSCKAccountStateTracker.h +++ b/keychain/ckks/CKKSCKAccountStateTracker.h @@ -51,7 +51,7 @@ typedef NS_ENUM(NSInteger, CKKSAccountStatus) { CKKSAccountStatusNoAccount = 3, }; -@protocol CKKSAccountStateListener +@protocol CKKSAccountStateListener - (void)ckAccountStatusChange:(CKKSAccountStatus)oldStatus to:(CKKSAccountStatus)currentStatus; @end @@ -62,6 +62,10 @@ typedef NS_ENUM(NSInteger, CKKSAccountStatus) { @property (nullable) CKAccountInfo* currentCKAccountInfo; @property SOSCCStatus currentCircleStatus; +@property (readonly,atomic) CKKSAccountStatus currentComputedAccountStatus; +@property (nullable,readonly,atomic) NSError* currentAccountError; +@property CKKSCondition* currentComputedAccountStatusValid; + // Fetched and memoized from CloudKit; we can't afford deadlocks with their callbacks @property (nullable, copy) NSString* ckdeviceID; @property (nullable) NSError* ckdeviceIDError; diff --git a/keychain/ckks/CKKSCKAccountStateTracker.m b/keychain/ckks/CKKSCKAccountStateTracker.m index 9c340e19..ee8a40ba 100644 --- a/keychain/ckks/CKKSCKAccountStateTracker.m +++ b/keychain/ckks/CKKSCKAccountStateTracker.m @@ -27,16 +27,19 @@ #include #include #include +#include #include #import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CloudKitCategories.h" #import "keychain/ckks/CKKSCKAccountStateTracker.h" - +#import "keychain/ckks/CKKSAnalytics.h" @interface CKKSCKAccountStateTracker () @property (readonly) Class nsnotificationCenterClass; @property CKKSAccountStatus currentComputedAccountStatus; +@property (nullable, atomic) NSError* currentAccountError; @property dispatch_queue_t queue; @@ -59,10 +62,11 @@ _currentCircleStatus = kSOSCCError; _currentComputedAccountStatus = CKKSAccountStatusUnknown; + _currentComputedAccountStatusValid = [[CKKSCondition alloc] init]; _container = container; - _queue = dispatch_queue_create("ck-account-state", DISPATCH_QUEUE_SERIAL); + _queue = dispatch_queue_create("ck-account-state", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); _firstCKAccountFetch = false; _firstSOSCircleFetch = false; @@ -90,9 +94,11 @@ if(!strongSelf) { return; } - [strongSelf notifyCKAccountStatusChange:nil]; - [strongSelf notifyCircleChange:nil]; - [strongSelf.finishedInitialDispatches fulfill]; + @autoreleasepool { + [strongSelf notifyCKAccountStatusChange:nil]; + [strongSelf notifyCircleChange:nil]; + [strongSelf.finishedInitialDispatches fulfill]; + } }); } return self; @@ -104,11 +110,12 @@ } -(NSString*)descriptionInternal: (NSString*) selfString { - return [NSString stringWithFormat:@"<%@: %@ (%@ %@)", + return [NSString stringWithFormat:@"<%@: %@ (%@ %@) %@>", selfString, [self currentStatus], self.currentCKAccountInfo, - SOSCCGetStatusDescription(self.currentCircleStatus)]; + SOSCCGetStatusDescription(self.currentCircleStatus), + self.currentAccountError ?: @""]; } -(NSString*)description { @@ -139,8 +146,11 @@ dispatch_queue_t objQueue = dispatch_queue_create([queueName UTF8String], DISPATCH_QUEUE_SERIAL); [self.changeListeners setObject: listener forKey: objQueue]; + secinfo("ckksaccount", "adding a new listener: %@", listener); + // If we know the current account status, let this listener know if(self.currentComputedAccountStatus != CKKSAccountStatusUnknown) { + secinfo("ckksaccount", "notifying new listener %@ of current state %d", listener, (int)self.currentComputedAccountStatus); dispatch_group_t g = dispatch_group_create(); if(!g) { @@ -205,6 +215,10 @@ if(ckAccountInfo.accountStatus == CKAccountStatusAvailable) { [self.container fetchCurrentDeviceIDWithCompletionHandler:^(NSString* deviceID, NSError* ckerror) { __strong __typeof(self) strongSelf = weakSelf; + if(!strongSelf) { + secerror("ckksaccount: Received fetchCurrentDeviceIDWithCompletionHandler callback with null AccountStateTracker"); + return; + } // Make sure you synchronize here; if we've logged out before the callback returns, don't record the result dispatch_async(strongSelf.queue, ^{ @@ -254,6 +268,11 @@ if(sosccstatus == kSOSCCInCircle) { [CKKSCKAccountStateTracker fetchCirclePeerID:^(NSString* peerID, NSError* error) { __strong __typeof(self) strongSelf = weakSelf; + if(!strongSelf) { + secerror("ckksaccount: Received fetchCirclePeerID callback with null AccountStateTracker"); + return; + } + dispatch_async(strongSelf.queue, ^{ __strong __typeof(self) innerstrongSelf = weakSelf; @@ -281,6 +300,57 @@ } } +- (bool)_onqueueDetermineLoggedIn:(NSError**)error { + // We are logged in if we are: + // in CKAccountStatusAvailable + // and supportsDeviceToDeviceEncryption == true + // and the iCloud account is not in grey mode + // and in circle + dispatch_assert_queue(self.queue); + if(self.currentCKAccountInfo) { + if(self.currentCKAccountInfo.accountStatus != CKAccountStatusAvailable) { + if(error) { + *error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSNotLoggedIn + description:@"iCloud account is logged out"]; + } + return false; + } else if(!self.currentCKAccountInfo.supportsDeviceToDeviceEncryption) { + if(error) { + *error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSNotHSA2 + description:@"iCloud account is not HSA2"]; + } + return false; + } else if(!self.currentCKAccountInfo.hasValidCredentials) { + if(error) { + *error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSiCloudGreyMode + description:@"iCloud account is in grey mode"]; + } + return false; + } + } else { + if(error) { + *error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSNotLoggedIn + description:@"No current iCloud account status"]; + } + return false; + } + + if(self.currentCircleStatus != kSOSCCInCircle) { + if(error) { + *error = [NSError errorWithDomain:(__bridge NSString*)kSOSErrorDomain + code:kSOSErrorNotInCircle + description:@"Not in circle"]; + } + return false; + } + + return true; +} + -(void)_onqueueUpdateAccountState:(CKAccountInfo*)ckAccountInfo circle:(SOSCCStatus)sosccstatus deliveredSemaphore:(dispatch_semaphore_t)finishedSema { dispatch_assert_queue(self.queue); @@ -300,7 +370,9 @@ if(self.currentCircleStatus != sosccstatus) { secnotice("ckksaccount", "moving to circle status: %@", SOSCCGetStatusDescription(sosccstatus)); self.currentCircleStatus = sosccstatus; - + if (sosccstatus == kSOSCCInCircle) { + [[CKKSAnalytics logger] setDateProperty:[NSDate date] forKey:CKKSAnalyticsLastInCircle]; + } [self _onqueueUpdateCirclePeerID: sosccstatus]; } @@ -310,28 +382,17 @@ return; } - // We are CKKSAccountStatusAvailable if we are: - // in CKAccountStatusAvailable - // and in circle - // and supportsDeviceToDeviceEncryption == true CKKSAccountStatus oldComputedStatus = self.currentComputedAccountStatus; - if(self.currentCKAccountInfo) { - if(self.currentCKAccountInfo.accountStatus == CKAccountStatusAvailable) { - // CloudKit thinks we're logged in. Double check! - if(self.currentCKAccountInfo.supportsDeviceToDeviceEncryption && self.currentCircleStatus == kSOSCCInCircle) { - self.currentComputedAccountStatus = CKKSAccountStatusAvailable; - } else { - self.currentComputedAccountStatus = CKKSAccountStatusNoAccount; - } - - } else { - // Account status is not CKAccountStatusAvailable; no more checking required. - self.currentComputedAccountStatus = CKKSAccountStatusNoAccount; - } + NSError* error = nil; + if([self _onqueueDetermineLoggedIn:&error]) { + self.currentComputedAccountStatus = CKKSAccountStatusAvailable; + self.currentAccountError = nil; } else { - // No CKAccountInfo? We haven't received an update from cloudd yet; Change nothing. + self.currentComputedAccountStatus = CKKSAccountStatusNoAccount; + self.currentAccountError = error; } + [self.currentComputedAccountStatusValid fulfill]; if(oldComputedStatus == self.currentComputedAccountStatus) { secnotice("ckksaccount", "No change in computed account status: %@ (%@ %@)", diff --git a/keychain/ckks/CKKSControl.h b/keychain/ckks/CKKSControl.h index 32aedf63..2e3434db 100644 --- a/keychain/ckks/CKKSControl.h +++ b/keychain/ckks/CKKSControl.h @@ -28,6 +28,13 @@ NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSUInteger, CKKSKnownBadState) { + CKKSKnownStatePossiblyGood = 0, // State might be good: give your operation a shot! + CKKSKnownStateTLKsMissing = 1, // CKKS doesn't have the TLKs: your operation will likely not succeed + CKKSKnownStateWaitForUnlock = 2, // CKKS has some important things to do, but the device is locked. Your operation will likely not succeed +}; + @interface CKKSControl : NSObject - (instancetype)init NS_UNAVAILABLE; @@ -42,13 +49,12 @@ NS_ASSUME_NONNULL_BEGIN - (void)rpcFetchAndProcessClassAChanges:(NSString* _Nullable)viewName reply:(void (^)(NSError* _Nullable error))reply; - (void)rpcPushOutgoingChanges:(NSString* _Nullable)viewName reply:(void (^)(NSError* _Nullable error))reply; -- (void)rpcPerformanceCounters: (void(^)(NSDictionary *,NSError*))reply; -- (void)rpcGetAnalyticsSysdiagnoseWithReply:(void (^)(NSString* sysdiagnose, NSError* error))reply; -- (void)rpcGetAnalyticsJSONWithReply: (void (^)(NSData* json, NSError* error))reply; -- (void)rpcForceUploadAnalyticsWithReply: (void (^)(BOOL success, NSError* error))reply; +- (void)rpcPerformanceCounters:(void(^)(NSDictionary *,NSError*))reply; +- (void)rpcGetCKDeviceIDWithReply:(void (^)(NSString* ckdeviceID))reply; // convenience wrapper for rpcStatus:reply: - (void)rpcTLKMissing:(NSString* _Nullable)viewName reply:(void (^)(bool missing))reply; +- (void)rpcKnownBadState:(NSString* _Nullable)viewName reply:(void (^)(CKKSKnownBadState))reply; + (CKKSControl* _Nullable)controlObject:(NSError* _Nullable __autoreleasing* _Nullable)error; diff --git a/keychain/ckks/CKKSControl.m b/keychain/ckks/CKKSControl.m index 276c41b6..3f56cf49 100644 --- a/keychain/ckks/CKKSControl.m +++ b/keychain/ckks/CKKSControl.m @@ -30,6 +30,7 @@ #import "keychain/ckks/CKKSControl.h" #import "keychain/ckks/CKKSControlProtocol.h" +#import "keychain/ckks/CKKSControlServer.h" #include @@ -109,27 +110,11 @@ }]; } -- (void)rpcGetAnalyticsSysdiagnoseWithReply:(void (^)(NSString* sysdiagnose, NSError* error))reply { - [[self.connection remoteObjectProxyWithErrorHandler:^(NSError* error) { - reply(nil, error); - }] rpcGetAnalyticsSysdiagnoseWithReply:^(NSString* sysdiagnose, NSError* error){ - reply(sysdiagnose, error); - }]; -} - -- (void)rpcGetAnalyticsJSONWithReply:(void (^)(NSData* json, NSError* error))reply { - [[self.connection remoteObjectProxyWithErrorHandler:^(NSError* error) { - reply(nil, error); - }] rpcGetAnalyticsJSONWithReply:^(NSData* json, NSError* error){ - reply(json, error); - }]; -} - -- (void)rpcForceUploadAnalyticsWithReply: (void (^)(BOOL success, NSError* error))reply { - [[self.connection remoteObjectProxyWithErrorHandler:^(NSError* error) { - reply(false, error); - }] rpcForceUploadAnalyticsWithReply:^(BOOL success, NSError* error){ - reply(success, error); +- (void)rpcGetCKDeviceIDWithReply:(void (^)(NSString *))reply { + [[self.connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + reply(nil); + }] rpcGetCKDeviceIDWithReply:^(NSString *ckdeviceID) { + reply(ckdeviceID); }]; } @@ -157,27 +142,43 @@ }]; } -+ (CKKSControl*)controlObject:(NSError* __autoreleasing *)error { +- (void)rpcKnownBadState:(NSString* _Nullable)viewName reply:(void (^)(CKKSKnownBadState))reply { + [self rpcStatus:viewName reply:^(NSArray* results, NSError* blockError) { + bool tlkMissing = false; + bool waitForUnlock = false; - CFErrorRef cferror = NULL; - xpc_endpoint_t endpoint = _SecSecuritydCopyCKKSEndpoint(&cferror); - if (endpoint == NULL) { - NSString* errorstr = NULL; + CKKSKnownBadState response = CKKSKnownStatePossiblyGood; - if(cferror) { - errorstr = CFBridgingRelease(CFErrorCopyDescription(cferror)); - } + // We can now change this hack, but this change needs to be addition-only: CKKS: remove "global" hack from rpcStatus + // Use this hack + for(NSDictionary* result in results) { + NSString* name = result[@"view"]; + NSString* keystate = result[@"keystate"]; - NSString* errorDescription = [NSString stringWithFormat:@"no CKKSControl endpoint available: %@", errorstr ? errorstr : @"unknown error"]; - if(error) { - *error = [NSError errorWithDomain:@"securityd" code:-1 userInfo:@{NSLocalizedDescriptionKey: errorDescription}]; + if([name isEqualToString:@"global"]) { + // this is global status; no view implicated + continue; + } + + if ([keystate isEqualToString:@"waitfortlk"] || [keystate isEqualToString:@"error"]) { + tlkMissing = true; + } + if ([keystate isEqualToString:@"waitforunlock"]) { + waitForUnlock = true; + } } - return nil; - } - NSXPCListenerEndpoint *listenerEndpoint = [[NSXPCListenerEndpoint alloc] init]; - [listenerEndpoint _setEndpoint:endpoint]; - NSXPCConnection* connection = [[NSXPCConnection alloc] initWithListenerEndpoint:listenerEndpoint]; + response = (tlkMissing ? CKKSKnownStateTLKsMissing : + (waitForUnlock ? CKKSKnownStateWaitForUnlock : + CKKSKnownStatePossiblyGood)); + + reply(response); + }]; +} + ++ (CKKSControl*)controlObject:(NSError* __autoreleasing *)error { + + NSXPCConnection* connection = [[NSXPCConnection alloc] initWithMachServiceName:@(kSecuritydCKKSServiceName) options:0]; if (connection == nil) { if(error) { diff --git a/keychain/ckks/CKKSControlProtocol.h b/keychain/ckks/CKKSControlProtocol.h index 2492a3c6..bbf3bc40 100644 --- a/keychain/ckks/CKKSControlProtocol.h +++ b/keychain/ckks/CKKSControlProtocol.h @@ -23,7 +23,7 @@ #import -@protocol CKKSControlProtocol +@protocol CKKSControlProtocol - (void)performanceCounters:(void(^)(NSDictionary *))reply; - (void)rpcResetLocal: (NSString*)viewName reply: (void(^)(NSError* result)) reply; - (void)rpcResetCloudKit: (NSString*)viewName reply: (void(^)(NSError* result)) reply; @@ -33,9 +33,7 @@ - (void)rpcFetchAndProcessChanges:(NSString*)viewName reply: (void(^)(NSError* result)) reply; - (void)rpcFetchAndProcessClassAChanges:(NSString*)viewName reply: (void(^)(NSError* result)) reply; - (void)rpcPushOutgoingChanges:(NSString*)viewName reply: (void(^)(NSError* result)) reply; -- (void)rpcGetAnalyticsSysdiagnoseWithReply:(void (^)(NSString* sysdiagnose, NSError* error))reply; -- (void)rpcGetAnalyticsJSONWithReply:(void (^)(NSData* json, NSError* error))reply; -- (void)rpcForceUploadAnalyticsWithReply:(void (^)(BOOL success, NSError* error))reply; +- (void)rpcGetCKDeviceIDWithReply: (void (^)(NSString* ckdeviceID))reply; @end NSXPCInterface* CKKSSetupControlProtocol(NSXPCInterface* interface); diff --git a/keychain/ckks/CKKSControlProtocol.m b/keychain/ckks/CKKSControlProtocol.m index 10df4da8..5a73df3b 100644 --- a/keychain/ckks/CKKSControlProtocol.m +++ b/keychain/ckks/CKKSControlProtocol.m @@ -101,9 +101,7 @@ NSXPCInterface* CKKSSetupControlProtocol(NSXPCInterface* interface) { [interface setClasses:errClasses forSelector:@selector(rpcFetchAndProcessChanges:reply:) argumentIndex:0 ofReply:YES]; [interface setClasses:errClasses forSelector:@selector(rpcFetchAndProcessClassAChanges:reply:) argumentIndex:0 ofReply:YES]; [interface setClasses:errClasses forSelector:@selector(rpcPushOutgoingChanges:reply:) argumentIndex:0 ofReply:YES]; - [interface setClasses:errClasses forSelector:@selector(rpcGetAnalyticsJSONWithReply:) argumentIndex:1 ofReply:YES]; - [interface setClasses:errClasses forSelector:@selector(rpcForceUploadAnalyticsWithReply:) argumentIndex:1 ofReply:YES]; - [interface setClasses:errClasses forSelector:@selector(rpcGetAnalyticsSysdiagnoseWithReply:) argumentIndex:1 ofReply:YES]; + [interface setClasses:errClasses forSelector:@selector(rpcGetCKDeviceIDWithReply:) argumentIndex:0 ofReply:YES]; } @catch(NSException* e) { secerror("CKKSSetupControlProtocol failed, continuing, but you might crash later: %@", e); diff --git a/keychain/ckks/CKKSControlServer.h b/keychain/ckks/CKKSControlServer.h new file mode 100644 index 00000000..e2864dd4 --- /dev/null +++ b/keychain/ckks/CKKSControlServer.h @@ -0,0 +1,12 @@ +#ifndef _CKKSCONTROLSERVER_H_ +#define _CKKSCONTROLSERVER_H_ + +#define kSecuritydCKKSServiceName "com.apple.securityd.ckks" + +__BEGIN_DECLS + +void CKKSControlServerInitialize(void); + +__END_DECLS + +#endif /* !_CKKSCONTROLSERVER_H_ */ diff --git a/keychain/ckks/CKKSControlServer.m b/keychain/ckks/CKKSControlServer.m new file mode 100644 index 00000000..fecffc4c --- /dev/null +++ b/keychain/ckks/CKKSControlServer.m @@ -0,0 +1,60 @@ +#import +#import + +#import "SecEntitlements.h" +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSControlProtocol.h" +#import "keychain/ckks/CKKSControlServer.h" +#import "keychain/ckks/CKKSViewManager.h" + +@interface CKKSControlServer : NSObject +@end + +@implementation CKKSControlServer + +- (BOOL)listener:(__unused NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection { +#if OCTAGON + NSNumber *num = [newConnection valueForEntitlement:(__bridge NSString *)kSecEntitlementPrivateCKKS]; + if (![num isKindOfClass:[NSNumber class]] || ![num boolValue]) { + secerror("ckks: Client pid: %d doesn't have entitlement: %@", + [newConnection processIdentifier], kSecEntitlementPrivateCKKS); + return NO; + } + + // In the future, we should consider vending a proxy object that can return a nicer error. + if (!SecCKKSIsEnabled()) { + secerror("ckks: Client pid: %d attempted to use CKKS, but CKKS is not enabled.", + newConnection.processIdentifier); + return NO; + } + + newConnection.exportedInterface = CKKSSetupControlProtocol([NSXPCInterface interfaceWithProtocol:@protocol(CKKSControlProtocol)]); + newConnection.exportedObject = [CKKSViewManager manager]; + + [newConnection resume]; + + return YES; +#else + return NO; +#endif /* OCTAGON */ +} + +@end + +void +CKKSControlServerInitialize(void) +{ + static dispatch_once_t once; + static CKKSControlServer *server; + static NSXPCListener *listener; + + dispatch_once(&once, ^{ + @autoreleasepool { + server = [CKKSControlServer new]; + + listener = [[NSXPCListener alloc] initWithMachServiceName:@(kSecuritydCKKSServiceName)]; + listener.delegate = server; + [listener resume]; + } + }); +} diff --git a/keychain/ckks/CKKSCurrentKeyPointer.m b/keychain/ckks/CKKSCurrentKeyPointer.m index 77e826bb..0d556eb1 100644 --- a/keychain/ckks/CKKSCurrentKeyPointer.m +++ b/keychain/ckks/CKKSCurrentKeyPointer.m @@ -47,6 +47,25 @@ return [NSString stringWithFormat:@"", self.zoneID.zoneName, self.keyclass, self.currentKeyUUID]; } +- (instancetype)copyWithZone:(NSZone*)zone { + CKKSCurrentKeyPointer* copy = [super copyWithZone:zone]; + copy.keyclass = [self.keyclass copyWithZone:zone]; + copy.currentKeyUUID = [self.currentKeyUUID copyWithZone:zone]; + return copy; +} +- (BOOL)isEqual: (id) object { + if(![object isKindOfClass:[CKKSCurrentKeyPointer class]]) { + return NO; + } + + CKKSCurrentKeyPointer* obj = (CKKSCurrentKeyPointer*) object; + + return ([self.zoneID isEqual: obj.zoneID] && + ((self.currentKeyUUID == nil && obj.currentKeyUUID == nil) || [self.currentKeyUUID isEqual: obj.currentKeyUUID]) && + ((self.keyclass == nil && obj.keyclass == nil) || [self.keyclass isEqual:obj.keyclass]) && + YES) ? YES : NO; +} + #pragma mark - CKKSCKRecordHolder methods - (NSString*) CKRecordName { @@ -217,6 +236,18 @@ self.currentClassCPointer.currentKeyUUID, self.classC]; } } +- (instancetype)copyWithZone:(NSZone*)zone { + CKKSCurrentKeySet* copy = [[[self class] alloc] init]; + copy.currentTLKPointer = [self.currentTLKPointer copyWithZone:zone]; + copy.currentClassAPointer = [self.currentClassAPointer copyWithZone:zone]; + copy.currentClassCPointer = [self.currentClassCPointer copyWithZone:zone]; + copy.tlk = [self.tlk copyWithZone:zone]; + copy.classA = [self.classA copyWithZone:zone]; + copy.classC = [self.classC copyWithZone:zone]; + + copy.error = [self.error copyWithZone:zone]; + return copy; +} @end #endif // OCTAGON diff --git a/keychain/ckks/CKKSDeviceStateEntry.h b/keychain/ckks/CKKSDeviceStateEntry.h index cd3ac7cc..d7b07910 100644 --- a/keychain/ckks/CKKSDeviceStateEntry.h +++ b/keychain/ckks/CKKSDeviceStateEntry.h @@ -34,6 +34,8 @@ #import "keychain/ckks/CKKSRecordHolder.h" #import "keychain/ckks/CKKSSQLDatabaseObject.h" +NS_ASSUME_NONNULL_BEGIN + /* * This is the backing class for "device state" records: each device in an iCloud account copies * some state about itself into each keychain view it wants to participate in. @@ -46,13 +48,16 @@ @interface CKKSDeviceStateEntry : CKKSCKRecordHolder @property NSString* device; -@property NSString* circlePeerID; +@property (nullable) NSString* osVersion; +@property (nullable) NSDate* lastUnlockTime; + +@property (nullable) NSString* circlePeerID; @property SOSCCStatus circleStatus; -@property CKKSZoneKeyState* keyState; +@property (nullable) CKKSZoneKeyState* keyState; -@property NSString* currentTLKUUID; -@property NSString* currentClassAUUID; -@property NSString* currentClassCUUID; +@property (nullable) NSString* currentTLKUUID; +@property (nullable) NSString* currentClassAUUID; +@property (nullable) NSString* currentClassCUUID; + (instancetype)fromDatabase:(NSString*)device zoneID:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; + (instancetype)tryFromDatabase:(NSString*)device zoneID:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; @@ -60,16 +65,20 @@ + (NSArray*)allInZone:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; - (instancetype)init NS_UNAVAILABLE; -- (instancetype)initForDevice:(NSString*)device - circlePeerID:(NSString*)circlePeerID +- (instancetype)initForDevice:(NSString* _Nullable)device + osVersion:(NSString* _Nullable)osVersion + lastUnlockTime:(NSDate* _Nullable)lastUnlockTime + circlePeerID:(NSString* _Nullable)circlePeerID circleStatus:(SOSCCStatus)circleStatus - keyState:(CKKSZoneKeyState*)keyState - currentTLKUUID:(NSString*)currentTLKUUID - currentClassAUUID:(NSString*)currentClassAUUID - currentClassCUUID:(NSString*)currentClassCUUID + keyState:(CKKSZoneKeyState* _Nullable)keyState + currentTLKUUID:(NSString* _Nullable)currentTLKUUID + currentClassAUUID:(NSString* _Nullable)currentClassAUUID + currentClassCUUID:(NSString* _Nullable)currentClassCUUID zoneID:(CKRecordZoneID*)zoneID - encodedCKRecord:(NSData*)encodedrecord; + encodedCKRecord:(NSData* _Nullable)encodedrecord; @end +NS_ASSUME_NONNULL_END + #endif // OCTAGON #endif /* CKKSDeviceStateEntry_h */ diff --git a/keychain/ckks/CKKSDeviceStateEntry.m b/keychain/ckks/CKKSDeviceStateEntry.m index 38af3b74..e520e181 100644 --- a/keychain/ckks/CKKSDeviceStateEntry.m +++ b/keychain/ckks/CKKSDeviceStateEntry.m @@ -36,6 +36,8 @@ @implementation CKKSDeviceStateEntry - (instancetype)initForDevice:(NSString*)device + osVersion:(NSString*)osVersion + lastUnlockTime:(NSDate*)lastUnlockTime circlePeerID:(NSString*)circlePeerID circleStatus:(SOSCCStatus)circleStatus keyState:(CKKSZoneKeyState*)keyState @@ -49,6 +51,9 @@ encodedCKRecord:encodedrecord zoneID:zoneID])) { _device = device; + _osVersion = osVersion; + _lastUnlockTime = lastUnlockTime; + _circleStatus = circleStatus; _keyState = keyState; @@ -113,9 +118,11 @@ -(NSString*)description { NSDate* updated = self.storedCKRecord.modificationDate; - return [NSString stringWithFormat:@"", + return [NSString stringWithFormat:@"", self.device, self.circlePeerID, + self.osVersion, + self.lastUnlockTime, self.zoneID.zoneName, SOSAccountGetSOSCCStatusString(self.circleStatus), self.keyState, @@ -135,6 +142,8 @@ return ([self.zoneID isEqual: obj.zoneID] && ((self.device == nil && obj.device == nil) || [self.device isEqual: obj.device]) && + ((self.osVersion == nil && obj.osVersion == nil) || [self.osVersion isEqual:obj.osVersion]) && + ((self.lastUnlockTime == nil && obj.lastUnlockTime == nil) || [self.lastUnlockTime isEqual:obj.lastUnlockTime]) && ((self.circlePeerID == nil && obj.circlePeerID == nil) || [self.circlePeerID isEqual: obj.circlePeerID]) && (self.circleStatus == obj.circleStatus) && ((self.keyState == nil && obj.keyState == nil) || [self.keyState isEqual: obj.keyState]) && @@ -182,6 +191,9 @@ userInfo:nil]; } + record[SecCKSRecordOSVersionKey] = self.osVersion; + record[SecCKSRecordLastUnlockTime] = self.lastUnlockTime; + record[SecCKRecordCircleStatus] = [self sosCCStatusToCKType: self.circleStatus]; record[SecCKRecordKeyState] = CKKSZoneKeyToNumber(self.keyState); @@ -203,11 +215,20 @@ return false; } - if(![record.recordID.recordName isEqualToString: [self CKRecordName]]) { return false; } + if((!(self.lastUnlockTime == nil && record[SecCKSRecordLastUnlockTime] == nil)) && + ![record[SecCKSRecordLastUnlockTime] isEqual: self.lastUnlockTime]) { + return false; + } + + if((!(self.osVersion == nil && record[SecCKSRecordOSVersionKey] == nil)) && + ![record[SecCKSRecordOSVersionKey] isEqualToString: self.osVersion]) { + return false; + } + if((!(self.circlePeerID == nil && record[SecCKRecordCirclePeerID] == nil)) && ![record[SecCKRecordCirclePeerID] isEqualToString: self.circlePeerID]) { return false; @@ -244,7 +265,9 @@ [self setStoredCKRecord:record]; - self.device = [CKKSDeviceStateEntry nameFromCKRecordID: record.recordID];; + self.osVersion = record[SecCKSRecordOSVersionKey]; + self.lastUnlockTime = record[SecCKSRecordLastUnlockTime]; + self.device = [CKKSDeviceStateEntry nameFromCKRecordID: record.recordID]; self.circlePeerID = record[SecCKRecordCirclePeerID]; @@ -263,7 +286,7 @@ } + (NSArray*)sqlColumns { - return @[@"device", @"ckzone", @"peerid", @"circlestatus", @"keystate", @"currentTLK", @"currentClassA", @"currentClassC", @"ckrecord"]; + return @[@"device", @"ckzone", @"osversion", @"lastunlock", @"peerid", @"circlestatus", @"keystate", @"currentTLK", @"currentClassA", @"currentClassC", @"ckrecord"]; } - (NSDictionary*)whereClauseToFindSelf { @@ -271,8 +294,12 @@ } - (NSDictionary*)sqlValues { + NSISO8601DateFormatter* dateFormat = [[NSISO8601DateFormatter alloc] init]; + return @{@"device": self.device, @"ckzone": CKKSNilToNSNull(self.zoneID.zoneName), + @"osversion": CKKSNilToNSNull(self.osVersion), + @"lastunlock": CKKSNilToNSNull(self.lastUnlockTime ? [dateFormat stringFromDate:self.lastUnlockTime] : nil), @"peerid": CKKSNilToNSNull(self.circlePeerID), @"circlestatus": (__bridge NSString*)SOSAccountGetSOSCCStatusString(self.circleStatus), @"keystate": CKKSNilToNSNull(self.keyState), @@ -284,8 +311,13 @@ } + (instancetype)fromDatabaseRow:(NSDictionary*)row { + NSISO8601DateFormatter* dateFormat = [[NSISO8601DateFormatter alloc] init]; + return [[CKKSDeviceStateEntry alloc] initForDevice:row[@"device"] - circlePeerID:CKKSNSNullToNil(row[@"peerid"]) circleStatus:SOSAccountGetSOSCCStatusFromString((__bridge CFStringRef) CKKSNSNullToNil(row[@"circlestatus"])) + osVersion:CKKSNSNullToNil(row[@"osversion"]) + lastUnlockTime:[row[@"lastunlock"] isEqual: [NSNull null]] ? nil : [dateFormat dateFromString: row[@"lastunlock"]] + circlePeerID:CKKSNSNullToNil(row[@"peerid"]) + circleStatus:SOSAccountGetSOSCCStatusFromString((__bridge CFStringRef) CKKSNSNullToNil(row[@"circlestatus"])) keyState:CKKSNSNullToNil(row[@"keystate"]) currentTLKUUID:CKKSNSNullToNil(row[@"currentTLK"]) currentClassAUUID:CKKSNSNullToNil(row[@"currentClassA"]) diff --git a/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.h b/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.h index f9459459..400ca965 100644 --- a/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.h +++ b/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.h @@ -26,6 +26,7 @@ #if OCTAGON @class CKKSKeychainView; #import "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ckks/CKKSZoneChangeFetcher.h" NS_ASSUME_NONNULL_BEGIN @@ -38,13 +39,17 @@ NS_ASSUME_NONNULL_BEGIN @property (nullable, weak) CKKSKeychainView* ckks; @property CKRecordZoneID* zoneID; +@property NSSet* fetchReasons; + @property NSMutableDictionary* modifications; @property NSMutableDictionary* deletions; @property (nullable) CKServerChangeToken* serverChangeToken; - (instancetype)init NS_UNAVAILABLE; -- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks ckoperationGroup:(CKOperationGroup*)ckoperationGroup; +- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks + fetchReasons:(NSSet*)fetchReasons + ckoperationGroup:(CKOperationGroup*)ckoperationGroup; @end diff --git a/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.m b/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.m index 528ba34e..a2eb44d1 100644 --- a/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.m +++ b/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.m @@ -52,20 +52,23 @@ return nil; } -- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks ckoperationGroup:(CKOperationGroup*)ckoperationGroup { +- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks + fetchReasons:(NSSet*)fetchReasons + ckoperationGroup:(CKOperationGroup*)ckoperationGroup { if(self = [super init]) { _ckks = ckks; _ckoperationGroup = ckoperationGroup; - self.zoneID = ckks.zoneID; + _fetchReasons = fetchReasons; + _zoneID = ckks.zoneID; - self.resync = false; + _resync = false; - self.modifications = [[NSMutableDictionary alloc] init]; - self.deletions = [[NSMutableDictionary alloc] init]; + _modifications = [[NSMutableDictionary alloc] init]; + _deletions = [[NSMutableDictionary alloc] init]; // Can't fetch unless the zone is created. - [self addNullableDependency:ckks.viewSetupOperation]; + [self addNullableDependency:ckks.zoneSetupOperation]; } return self; } @@ -175,16 +178,16 @@ return false; } - ckksnotice("ckksfetch", ckks, "Beginning fetch(%@) starting at change token %@", ckks.zoneName, ckse.changeToken); - - options.previousServerChangeToken = ckse.changeToken; - - if(ckse.changeToken == nil) { - // First sync is special. + // If this is the first sync, or an API fetch, use QoS userInitated + if(ckse.changeToken == nil || [self.fetchReasons containsObject:CKKSFetchBecauseAPIFetchRequest]) { qos = NSQualityOfServiceUserInitiated; } + + options.previousServerChangeToken = ckse.changeToken; } + ckksnotice("ckksfetch", ckks, "Beginning fetch(%@) starting at change token %@ with QoS %d", ckks.zoneName, options.previousServerChangeToken, (int)qos); + self.fetchRecordZoneChangesOperation = [[ckks.fetchRecordZoneChangesOperationClass alloc] initWithRecordZoneIDs: @[ckks.zoneID] optionsByRecordZoneID:@{ckks.zoneID: options}]; self.fetchRecordZoneChangesOperation.fetchAllChanges = YES; @@ -256,7 +259,7 @@ } ckksnotice("ckksfetch", blockCKKS, "Record zone fetch complete: changeToken=%@ clientChangeTokenData=%@ changed=%lu deleted=%lu error=%@", serverChangeToken, clientChangeTokenData, - (unsigned long)strongSelf.deletions.count, + (unsigned long)strongSelf.modifications.count, (unsigned long)strongSelf.deletions.count, recordZoneError); @@ -330,6 +333,8 @@ return false; } + ckksnotice("ckksfetch", blockCKKS, "Finished processing fetch for %@", recordZoneID); + return true; }]; } @@ -350,7 +355,7 @@ strongSelf.error = operationError; } - //[CKKSPowerCollection CKKSPowerEvent:kCKKSPowerEventFetchAllChanges zone:ckks.zoneName count:strongSelf.fetchedItems]; + [CKKSPowerCollection CKKSPowerEvent:kCKKSPowerEventFetchAllChanges zone:ckks.zoneName count:strongSelf.fetchedItems]; // Trigger the fake 'we're done' operation. diff --git a/keychain/ckks/CKKSGroupOperation.h b/keychain/ckks/CKKSGroupOperation.h index d157762c..ccbd4a17 100644 --- a/keychain/ckks/CKKSGroupOperation.h +++ b/keychain/ckks/CKKSGroupOperation.h @@ -33,6 +33,10 @@ BOOL finished; } ++ (instancetype)operationWithBlock:(void (^)(void))block; ++ (instancetype)named:(NSString*)name withBlock:(void (^)(void))block; ++ (instancetype)named:(NSString*)name withBlockTakingSelf:(void(^)(CKKSGroupOperation* strongOp))block; + @property NSOperationQueue* operationQueue; - (instancetype)init; diff --git a/keychain/ckks/CKKSGroupOperation.m b/keychain/ckks/CKKSGroupOperation.m index 1ea9ea85..4ead9621 100644 --- a/keychain/ckks/CKKSGroupOperation.m +++ b/keychain/ckks/CKKSGroupOperation.m @@ -64,6 +64,7 @@ [strongSelf groupStart]; }]; + [self.startOperation removeDependenciesUponCompletion]; // The finish operation will 'finish' us _finishOperation = [NSBlockOperation blockOperationWithBlock:^{ @@ -75,6 +76,7 @@ [strongSelf completeOperation]; }]; + [self.finishOperation removeDependenciesUponCompletion]; [self.finishOperation addDependency: self.startOperation]; [self.operationQueue addOperation: self.finishOperation]; @@ -113,9 +115,14 @@ - (NSString*)description { if(self.isFinished) { if(self.error) { - return [NSString stringWithFormat: @"<%@: finished %@ - %@>", [self selfname], self.finishDate, self.error]; + return [NSString stringWithFormat: @"<%@: %@ %@ - %@>", [self selfname], + [self operationStateString], + self.finishDate, + self.error]; } else { - return [NSString stringWithFormat: @"<%@: finished %@>", [self selfname], self.finishDate]; + return [NSString stringWithFormat: @"<%@: %@ %@>", [self selfname], + [self operationStateString], + self.finishDate]; } } @@ -133,9 +140,9 @@ NSString* opsString = [ops componentsJoinedByString:@", "]; if(self.error) { - return [NSString stringWithFormat: @"<%@: [%@] error:%@>", [self selfname], opsString, self.error]; + return [NSString stringWithFormat: @"<%@: %@ [%@] error:%@>", [self selfname], [self operationStateString], opsString, self.error]; } else { - return [NSString stringWithFormat: @"<%@: [%@]%@>", [self selfname], opsString, [self pendingDependenciesString:@" dep:"]]; + return [NSString stringWithFormat: @"<%@: %@ [%@]%@>", [self selfname], [self operationStateString], opsString, [self pendingDependenciesString:@" dep:"]]; } } @@ -202,8 +209,8 @@ NSArray* finishDependencies = [self.finishOperation.dependencies copy]; for(NSOperation* finishDep in finishDependencies) { - if(![ops containsObject: finishDep]) { - // This is finish dependency that we don't control. + if(!([ops containsObject: finishDep] || [finishDep isEqual:self.startOperation])) { + // This is finish dependency that we don't control (and isn't our start operation) // Since we're cancelled, don't wait for it. [self.finishOperation removeDependency: finishDep]; } @@ -289,6 +296,31 @@ } } ++ (instancetype)operationWithBlock:(void (^)(void))block { + CKKSGroupOperation* op = [[CKKSGroupOperation alloc] init]; + NSBlockOperation* blockOp = [NSBlockOperation blockOperationWithBlock:block]; + [op runBeforeGroupFinished:blockOp]; + return op; +} + ++(instancetype)named:(NSString*)name withBlock:(void(^)(void)) block { + CKKSGroupOperation* blockOp = [CKKSGroupOperation operationWithBlock: block]; + blockOp.name = name; + return blockOp; +} + ++ (instancetype)named:(NSString*)name withBlockTakingSelf:(void(^)(CKKSGroupOperation* strongOp))block +{ + CKKSGroupOperation* op = [[CKKSGroupOperation alloc] init]; + __weak __typeof(op) weakOp = op; + [op runBeforeGroupFinished:[NSBlockOperation blockOperationWithBlock:^{ + __strong __typeof(op) strongOp = weakOp; + block(strongOp); + }]]; + op.name = name; + return op; +} + @end #endif // OCTAGON diff --git a/keychain/ckks/CKKSHealKeyHierarchyOperation.m b/keychain/ckks/CKKSHealKeyHierarchyOperation.m index 130da74e..fdf0b0cb 100644 --- a/keychain/ckks/CKKSHealKeyHierarchyOperation.m +++ b/keychain/ckks/CKKSHealKeyHierarchyOperation.m @@ -26,6 +26,8 @@ #import "CKKSKey.h" #import "CKKSHealKeyHierarchyOperation.h" #import "CKKSGroupOperation.h" +#import "CKKSAnalytics.h" +#import "keychain/ckks/CloudKitCategories.h" #if OCTAGON @@ -146,8 +148,8 @@ newTLK = topKey; } else if(![newTLK.uuid isEqualToString: topKey.uuid]) { ckkserror("ckksheal", ckks, "key hierarchy has split: there's two top keys. Currently we don't handle this situation."); - [ckks _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateError withError: [NSError errorWithDomain:@"securityd" - code:0 + [ckks _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateError withError: [NSError errorWithDomain:CKKSErrorDomain + code:CKKSSplitKeyHierarchy userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Key hierarchy has split: %@ and %@ are roots", newTLK, topKey]}]]; return true; @@ -168,16 +170,7 @@ } else { // Otherwise, something has gone horribly wrong. enter error state. ckkserror("ckksheal", ckks, "CKKS claims %@ is not a valid TLK: %@", newTLK, error); - NSError* newError = nil; - if(error) { - newError = [NSError errorWithDomain:@"securityd" - code:0 - userInfo:@{NSLocalizedDescriptionKey: @"invalid TLK from CloudKit", NSUnderlyingErrorKey: error}]; - } else { - newError = [NSError errorWithDomain:@"securityd" - code:0 - userInfo:@{NSLocalizedDescriptionKey: @"invalid TLK from CloudKit"}]; - } + NSError* newError = [NSError errorWithDomain:CKKSErrorDomain code:CKKSInvalidTLK description:@"Invalid TLK from CloudKit (during heal)" underlying:error]; [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError withError:newError]; return true; } @@ -220,9 +213,14 @@ newClassAKey = [CKKSKey randomKeyWrappedByParent:newTLK error:&error]; [newClassAKey saveKeyMaterialToKeychain:&error]; - if(error) { + if(error && [ckks.lockStateTracker isLockedError:error]) { + ckksnotice("ckksheal", ckks, "Couldn't create a new class A key, but keybag appears to be locked. Entering waitforunlock."); + [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateWaitForUnlock withError:error]; + return true; + } else if(error) { ckkserror("ckksheal", ckks, "couldn't create new classA key: %@", error); - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError withError:[NSError errorWithDomain: @"securityd" code:0 userInfo:@{NSLocalizedDescriptionKey: @"couldn't create new classA key", NSUnderlyingErrorKey: error}]]; + [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError withError:error]; + return true; } keyset.classA = newClassAKey; @@ -233,9 +231,14 @@ newClassCKey = [CKKSKey randomKeyWrappedByParent:newTLK error:&error]; [newClassCKey saveKeyMaterialToKeychain:&error]; - if(error) { - ckkserror("ckksheal", ckks, "couldn't create new classC key: %@", error); - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError withError:[NSError errorWithDomain: @"securityd" code:0 userInfo:@{NSLocalizedDescriptionKey: @"couldn't create new classC key", NSUnderlyingErrorKey: error}]]; + if(error && [ckks.lockStateTracker isLockedError:error]) { + ckksnotice("ckksheal", ckks, "Couldn't create a new class C key, but keybag appears to be locked. Entering waitforunlock."); + [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateWaitForUnlock withError:error]; + return true; + } else if(error) { + ckkserror("ckksheal", ckks, "couldn't create new class C key: %@", error); + [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError withError:error]; + return true; } keyset.classC = newClassCKey; @@ -243,6 +246,8 @@ changedCurrentClassC = true; } + ckksnotice("ckksheal", ckks, "Attempting to move to new key hierarchy: %@", keyset); + // Note: we never make a new TLK here. So, don't save it back to CloudKit. //if(newTLK) { // [recordsToSave addObject: [newTLK CKRecordWithZoneID: ckks.zoneID]]; @@ -279,7 +284,7 @@ // Kick off the CKOperation - ckksinfo("ckksheal", ckks, "Saving new keys %@ to cloudkit %@", recordsToSave, ckks.database); + ckksnotice("ckksheal", ckks, "Saving new records %@", recordsToSave); // Use the spare operation trick to wait for the CKModifyRecordsOperation to complete self.cloudkitModifyOperationFinished = [NSBlockOperation named:@"heal-cloudkit-modify-operation-finished" withBlock:^{}]; @@ -296,8 +301,7 @@ modifyRecordsOp = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:recordsToSave recordIDsToDelete:recordIDsToDelete]; modifyRecordsOp.atomic = YES; modifyRecordsOp.longLived = NO; // The keys are only in memory; mark this explicitly not long-lived - modifyRecordsOp.timeoutIntervalForRequest = 2; - modifyRecordsOp.qualityOfService = NSQualityOfServiceUtility; // relatively important. Use Utility. + modifyRecordsOp.qualityOfService = NSQualityOfServiceUserInitiated; // This needs to happen for CKKS to be usable by PCS/cloudd. Make it happen. modifyRecordsOp.group = self.ckoperationGroup; ckksnotice("ckksheal", ckks, "Operation group is %@", self.ckoperationGroup); @@ -323,8 +327,9 @@ ckksnotice("ckksheal", strongCKKS, "Completed Key Heal CloudKit operation with error: %@", error); - [strongCKKS dispatchSync: ^bool{ + [strongCKKS dispatchSyncWithAccountKeys: ^bool{ if(error == nil) { + [[CKKSAnalytics logger] logSuccessForEvent:CKKSEventProcessHealKeyHierarchy inView:ckks]; // Success. Persist the keys to the CKKS database. // Save the new CKRecords to the before persisting to database @@ -371,6 +376,7 @@ } } else { // ERROR. This isn't a total-failure error state, but one that should kick off a healing process. + [[CKKSAnalytics logger] logUnrecoverableError:error forEvent:CKKSEventProcessHealKeyHierarchy inView:ckks withAttributes:NULL]; ckkserror("ckksheal", strongCKKS, "couldn't save new key hierarchy to CloudKit: %@", error); [strongCKKS _onqueueCKWriteFailed:error attemptedRecordsChanged:attemptedRecords]; [strongCKKS _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateNewTLKsFailed withError: nil]; @@ -387,14 +393,18 @@ } // Check if CKKS can recover this TLK. - [ckks _onqueueWithAccountKeysCheckTLK:keyset.tlk error:&error]; + bool haveTLK = [ckks _onqueueWithAccountKeysCheckTLK:keyset.tlk error:&error]; if(error && [ckks.lockStateTracker isLockedError:error]) { ckksnotice("ckkskey", ckks, "Failed to load TLK from keychain, keybag is locked. Entering waitforunlock: %@", error); [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateWaitForUnlock withError:nil]; return false; - } else if(error) { - ckkserror("ckksheal", ckks, "CKKS wasn't sure about TLK, triggering move to bad state: %@", error); + } else if(error && error.code == errSecItemNotFound) { + ckkserror("ckksheal", ckks, "CKKS couldn't find TLK, triggering move to wait state: %@", error); [ckks _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateWaitForTLK withError: nil]; + + } else if(!haveTLK) { + ckkserror("ckksheal", ckks, "CKKS errored examining TLK, triggering move to bad state: %@", error); + [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError withError:error]; return false; } diff --git a/keychain/ckks/CKKSHealTLKSharesOperation.m b/keychain/ckks/CKKSHealTLKSharesOperation.m index be883bd4..90413363 100644 --- a/keychain/ckks/CKKSHealTLKSharesOperation.m +++ b/keychain/ckks/CKKSHealTLKSharesOperation.m @@ -89,7 +89,7 @@ ckksnotice("ckksshare", ckks, "Key set is %@", keyset); } - //[CKKSPowerCollection CKKSPowerEvent:kCKKSPowerEventTLKShareProcessing zone:ckks.zoneName]; + [CKKSPowerCollection CKKSPowerEvent:kCKKSPowerEventTLKShareProcessing zone:ckks.zoneName]; // Okay! Perform the checks. if(![keyset.tlk loadKeyMaterialFromKeychain:&error] || error) { @@ -140,8 +140,7 @@ recordIDsToDelete:recordIDsToDelete]; modifyRecordsOp.atomic = YES; modifyRecordsOp.longLived = NO; - modifyRecordsOp.timeoutIntervalForRequest = 10; - modifyRecordsOp.qualityOfService = NSQualityOfServiceUtility; // relatively important. Use Utility. + modifyRecordsOp.qualityOfService = NSQualityOfServiceUserInitiated; // very important: get the TLKShares off-device ASAP modifyRecordsOp.group = self.ckoperationGroup; ckksnotice("ckksshare", ckks, "Operation group is %@", self.ckoperationGroup); diff --git a/keychain/ckks/CKKSIncomingQueueEntry.h b/keychain/ckks/CKKSIncomingQueueEntry.h index 1b3971f8..991e9a59 100644 --- a/keychain/ckks/CKKSIncomingQueueEntry.h +++ b/keychain/ckks/CKKSIncomingQueueEntry.h @@ -51,7 +51,8 @@ NS_ASSUME_NONNULL_BEGIN zoneID:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; -+ (NSDictionary*)countsByState:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; ++ (NSDictionary*)countsByStateInZone:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; ++ (NSInteger)countByState:(CKKSItemState *)state zone:(CKRecordZoneID*)zoneID error: (NSError * __autoreleasing *)error; @end diff --git a/keychain/ckks/CKKSIncomingQueueEntry.m b/keychain/ckks/CKKSIncomingQueueEntry.m index acd12e9c..94e6b5fa 100644 --- a/keychain/ckks/CKKSIncomingQueueEntry.m +++ b/keychain/ckks/CKKSIncomingQueueEntry.m @@ -125,7 +125,7 @@ state: row[@"state"]]; } -+ (NSDictionary*)countsByState:(CKRecordZoneID*)zoneID error: (NSError * __autoreleasing *) error { ++ (NSDictionary*)countsByStateInZone:(CKRecordZoneID*)zoneID error: (NSError * __autoreleasing *) error { NSMutableDictionary* results = [[NSMutableDictionary alloc] init]; [CKKSSQLDatabaseObject queryDatabaseTable: [[self class] sqlTable] @@ -141,6 +141,22 @@ return results; } ++ (NSInteger)countByState:(CKKSItemState *)state zone:(CKRecordZoneID*)zoneID error: (NSError * __autoreleasing *) error { + __block NSInteger result = -1; + + [CKKSSQLDatabaseObject queryDatabaseTable: [[self class] sqlTable] + where: @{@"ckzone": CKKSNilToNSNull(zoneID.zoneName), @"state": state } + columns: @[@"count(*)"] + groupBy: nil + orderBy: nil + limit: -1 + processRow: ^(NSDictionary* row) { + result = [row[@"count(*)"] integerValue]; + } + error: error]; + return result; +} + @end #endif diff --git a/keychain/ckks/CKKSIncomingQueueOperation.m b/keychain/ckks/CKKSIncomingQueueOperation.m index e2e7ecde..131c72e1 100644 --- a/keychain/ckks/CKKSIncomingQueueOperation.m +++ b/keychain/ckks/CKKSIncomingQueueOperation.m @@ -28,7 +28,7 @@ #import "CKKSOutgoingQueueEntry.h" #import "CKKSKey.h" #import "CKKSManifest.h" -#import "CKKSAnalyticsLogger.h" +#import "CKKSAnalytics.h" #import "CKKSPowerCollection.h" #import "keychain/ckks/CKKSCurrentItemPointer.h" @@ -43,6 +43,7 @@ @interface CKKSIncomingQueueOperation () @property bool newOutgoingEntries; @property bool pendingClassAEntries; +@property bool missingKey; @end @implementation CKKSIncomingQueueOperation @@ -59,6 +60,8 @@ [self addDependency: ckks.keyStateReadyDependency]; } + [self addNullableDependency: ckks.holdIncomingQueueOperation]; + _errorOnClassAFailure = errorOnClassAFailure; _pendingClassAEntries = false; @@ -169,8 +172,8 @@ } } else if ([error.domain isEqualToString:@"securityd"] && error.code == errSecItemNotFound) { - ckkserror("ckksincoming", ckks, "Coudn't find key in keychain; attempting to poke key hierarchy: %@", error) - [ckks _onqueueAdvanceKeyStateMachineToState: nil withError: nil]; + ckkserror("ckksincoming", ckks, "Coudn't find key in keychain; will attempt to poke key hierarchy: %@", error) + self.missingKey = true; } else { ckkserror("ckksincoming", ckks, "Couldn't decrypt IQE %@ for some reason: %@", iqe, error); @@ -265,6 +268,10 @@ [ckks.notifyViewChangedScheduler trigger]; } + if(self.missingKey) { + [ckks.pokeKeyStateMachineScheduler trigger]; + } + if ([CKKSManifest shouldSyncManifests]) { [egoManifest updateWithNewOrChangedRecords:newOrChangedRecords deletedRecordIDs:deletedRecordIDs]; } @@ -298,7 +305,7 @@ return; } - [ckks dispatchSyncWithAccountKeys: ^bool{ + [ckks dispatchSync: ^bool{ if(self.cancelled) { ckksnotice("ckksincoming", ckks, "CKKSIncomingQueueOperation cancelled, quitting"); return false; @@ -321,18 +328,17 @@ __block NSError* error = nil; if ([CKKSManifest shouldSyncManifests]) { - NSDictionary* stateCounts = [CKKSIncomingQueueEntry countsByState:ckks.zoneID error:&error]; - if (error) { + NSInteger unauthenticatedItemCount = [CKKSIncomingQueueEntry countByState:SecCKKSStateUnauthenticated zone:ckks.zoneID error:&error]; + if (error || unauthenticatedItemCount < 0) { ckkserror("ckksincoming", ckks, "Error fetching incoming queue state counts: %@", error); self.error = error; return false; } - NSUInteger unauthenticatedItemCount = stateCounts[SecCKKSStateUnauthenticated].unsignedIntegerValue; // take any existing unauthenticated entries and put them back in the new state NSArray* unauthenticatedEntries = nil; NSString* lastMaxUUID = nil; - NSUInteger numEntriesProcessed = 0; + NSInteger numEntriesProcessed = 0; while (numEntriesProcessed < unauthenticatedItemCount && (unauthenticatedEntries == nil || unauthenticatedEntries.count == SecCKKSIncomingQueueItemsAtOnce)) { if(self.cancelled) { ckksnotice("ckksincoming", ckks, "CKKSIncomingQueueOperation cancelled, quitting"); @@ -394,7 +400,7 @@ break; } - //[CKKSPowerCollection CKKSPowerEvent:kCKKSPowerEventOutgoingQueue zone:ckks.zoneName count:[queueEntries count]]; + [CKKSPowerCollection CKKSPowerEvent:kCKKSPowerEventOutgoingQueue zone:ckks.zoneName count:[queueEntries count]]; if (![self processQueueEntries:queueEntries withManifest:ckks.latestManifest egoManifest:ckks.egoManifest]) { ckksnotice("ckksincoming", ckks, "processQueueEntries didn't complete successfully"); @@ -437,7 +443,7 @@ return; } - CKKSAnalyticsLogger* logger = [CKKSAnalyticsLogger logger]; + CKKSAnalytics* logger = [CKKSAnalytics logger]; if (!strongSelf.error) { [logger logSuccessForEvent:CKKSEventProcessIncomingQueueClassC inView:ckks]; diff --git a/keychain/ckks/CKKSItem.m b/keychain/ckks/CKKSItem.m index 2b9dde4e..e8ab777e 100644 --- a/keychain/ckks/CKKSItem.m +++ b/keychain/ckks/CKKSItem.m @@ -33,7 +33,6 @@ #include #include -#include #import #import @@ -189,46 +188,7 @@ plaintextPCSServiceIdentifier: (NSNumber*) pcsServiceIdentifier } + (void)setOSVersionInRecord: (CKRecord*) record { -#ifdef PLATFORM - // Use complicated macro magic to get the string value passed in as preprocessor define PLATFORM. -#define PLATFORM_VALUE(f) #f -#define PLATFORM_OBJCSTR(f) @PLATFORM_VALUE(f) - NSString* platform = (PLATFORM_OBJCSTR(PLATFORM)); -#undef PLATFORM_OBJCSTR -#undef PLATFORM_VALUE -#else - NSString* platform = "unknown"; -#warning No PLATFORM defined; why? -#endif - - NSString* osversion = nil; - - // If we can get the build information from sysctl, use it. - char release[256]; - size_t releasesize = sizeof(release); - bool haveSysctlInfo = true; - haveSysctlInfo &= (0 == sysctlbyname("kern.osrelease", release, &releasesize, NULL, 0)); - - char version[256]; - size_t versionsize = sizeof(version); - haveSysctlInfo &= (0 == sysctlbyname("kern.osversion", version, &versionsize, NULL, 0)); - - if(haveSysctlInfo) { - // Null-terminate for extra safety - release[sizeof(release)-1] = '\0'; - version[sizeof(version)-1] = '\0'; - osversion = [NSString stringWithFormat:@"%s (%s)", release, version]; - } - - if(!osversion) { - // Otherwise, use the not-really-supported fallback. - osversion = [[NSProcessInfo processInfo] operatingSystemVersionString]; - - // subtly improve osversion (but it's okay if that does nothing) - osversion = [osversion stringByReplacingOccurrencesOfString:@"Version" withString:@""]; - } - - record[SecCKRecordHostOSVersionKey] = [NSString stringWithFormat:@"%@ %@", platform, osversion]; + record[SecCKRecordHostOSVersionKey] = SecCKKSHostOSVersion(); } - (CKRecord*) updateCKRecord: (CKRecord*) record zoneID: (CKRecordZoneID*) zoneID { diff --git a/keychain/ckks/CKKSKey.m b/keychain/ckks/CKKSKey.m index fc10d37a..a927bec6 100644 --- a/keychain/ckks/CKKSKey.m +++ b/keychain/ckks/CKKSKey.m @@ -35,6 +35,10 @@ #include #include +@interface CKKSKey () +@property CKKSAESSIVKey* aessivkey; +@end + @implementation CKKSKey - (instancetype)init { @@ -235,10 +239,28 @@ } // Attempt to load this key from the keychain - if([self loadKeyMaterialFromKeychain:error]) { + NSError* keychainError = nil; + if([self loadKeyMaterialFromKeychain:&keychainError]) { + return self.aessivkey; + } + + // Uhh, okay, if that didn't work, try to unwrap via the key hierarchy + NSError* keyHierarchyError = nil; + if([self unwrapViaKeyHierarchy:&keyHierarchyError]) { + // Attempt to save this new key, but don't error if it fails + NSError* resaveError = nil; + if(![self saveKeyMaterialToKeychain:&resaveError] || resaveError) { + secerror("ckkskey: Resaving missing key failed, continuing: %@", resaveError); + } + return self.aessivkey; } + // Pick an error to report + if(error) { + *error = keyHierarchyError ? keyHierarchyError : keychainError; + } + return nil; } @@ -493,7 +515,7 @@ NSError* originalError = localError; // If we found the item or errored in some interesting way, return. - if(localError == nil) { + if(result) { return result; } if(localError && localError.code != errSecItemNotFound) { @@ -592,13 +614,11 @@ } // We didn't early-return. Use whatever error the original fetch produced. - if(error && originalError) { + if(error) { *error = [NSError errorWithDomain:@"securityd" - code:originalError.code - userInfo:@{NSLocalizedDescriptionKey: - [NSString stringWithFormat:@"Couldn't load %@ from keychain: %d", key, (int)originalError.code], - NSUnderlyingErrorKey: originalError, - }]; + code:originalError ? originalError.code : errSecParam + description:[NSString stringWithFormat:@"Couldn't load %@ from keychain: %d", key, (int)originalError.code] + underlying:originalError]; } return result; @@ -614,11 +634,17 @@ NSData* b64keymaterial = result[(id)kSecValueData]; NSData* keymaterial = [[NSData alloc] initWithBase64EncodedData:b64keymaterial options:0]; if(!keymaterial) { + secnotice("ckkskey", "Unable to unbase64 key: %@", self); + if(error) { + *error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSKeyUnknownFormat + description:[NSString stringWithFormat:@"unable to unbase64 key: %@", self]]; + } return false; } CKKSAESSIVKey* key = [[CKKSAESSIVKey alloc] initWithBytes: (uint8_t*) keymaterial.bytes len:keymaterial.length]; - _aessivkey = key; + self.aessivkey = key; if(resave) { secnotice("ckkskey", "Resaving %@ as per request", self); diff --git a/keychain/ckks/CKKSKeychainView.h b/keychain/ckks/CKKSKeychainView.h index b7fe760f..0aa9d38a 100644 --- a/keychain/ckks/CKKSKeychainView.h +++ b/keychain/ckks/CKKSKeychainView.h @@ -27,6 +27,7 @@ #import "keychain/ckks/CKKSAPSReceiver.h" #import "keychain/ckks/CKKSLockStateTracker.h" +#import "keychain/ckks/CKKSReachabilityTracker.h" #import "keychain/ckks/CloudKitDependencies.h" #include @@ -71,6 +72,7 @@ NS_ASSUME_NONNULL_BEGIN @property CKKSCondition* loggedIn; @property CKKSCondition* loggedOut; +@property CKKSCondition* accountStateKnown; @property CKKSLockStateTracker* lockStateTracker; @@ -86,6 +88,9 @@ NS_ASSUME_NONNULL_BEGIN @property (nullable) CKKSManifest* latestManifest; @property (nullable) CKKSResultOperation* keyStateReadyDependency; +// Wait for the key state to become 'nontransient': no pending operation is expected to advance it (at least until user intervenes) +@property (nullable) CKKSResultOperation* keyStateNonTransientDependency; + // True if we believe there's any items in the keychain which haven't been brought up in CKKS yet @property bool droppedItems; @@ -98,9 +103,6 @@ NS_ASSUME_NONNULL_BEGIN @property (weak) CKKSNearFutureScheduler* savedTLKNotifier; -// Differs from the zonesetupoperation: zoneSetup is only for CK modifications, viewSetup handles local db changes too -@property CKKSResultOperation* viewSetupOperation; - /* Used for debugging: just what happened last time we ran this? */ @property CKKSIncomingQueueOperation* lastIncomingQueueOperation; @property CKKSNewTLKOperation* lastNewTLKOperation; @@ -115,12 +117,16 @@ NS_ASSUME_NONNULL_BEGIN /* Used for testing: pause operation types by adding operations here */ @property NSOperation* holdReencryptOutgoingItemsOperation; @property NSOperation* holdOutgoingQueueOperation; +@property NSOperation* holdIncomingQueueOperation; @property NSOperation* holdLocalSynchronizeOperation; @property CKKSResultOperation* holdFixupOperation; /* Trigger this to tell the whole machine that this view has changed */ @property CKKSNearFutureScheduler* notifyViewChangedScheduler; +/* trigger this to request key state machine poking */ +@property CKKSNearFutureScheduler* pokeKeyStateMachineScheduler; + // These are available when you're in a dispatchSyncWithAccountKeys call, but at no other time // These must be pre-fetched before you get on the CKKS queue, otherwise we end up with CKKS<->SQLite<->SOSAccountQueue deadlocks @property (nonatomic, readonly) CKKSSelves* currentSelfPeers; @@ -132,6 +138,7 @@ NS_ASSUME_NONNULL_BEGIN zoneName:(NSString*)zoneName accountTracker:(CKKSCKAccountStateTracker*)accountTracker lockStateTracker:(CKKSLockStateTracker*)lockStateTracker + reachabilityTracker:(CKKSReachabilityTracker *)reachabilityTracker savedTLKNotifier:(CKKSNearFutureScheduler*)savedTLKNotifier peerProvider:(id)peerProvider fetchRecordZoneChangesOperationClass:(Class)fetchRecordZoneChangesOperationClass @@ -150,11 +157,11 @@ NS_ASSUME_NONNULL_BEGIN rateLimiter:(CKKSRateLimiter*)rateLimiter syncCallback:(SecBoolNSErrorCallback)syncCallback; -- (void)setCurrentItemForAccessGroup:(SecDbItemRef)newItem +- (void)setCurrentItemForAccessGroup:(NSData*)newItemPersistentRef hash:(NSData*)newItemSHA1 accessGroup:(NSString*)accessGroup identifier:(NSString*)identifier - replacing:(SecDbItemRef _Nullable)oldItem + replacing:(NSData* _Nullable)oldCurrentItemPersistentRef hash:(NSData* _Nullable)oldItemSHA1 complete:(void (^)(NSError* operror))complete; @@ -182,6 +189,8 @@ NS_ASSUME_NONNULL_BEGIN - (CKKSIncomingQueueOperation*)processIncomingQueue:(bool)failOnClassA; - (CKKSIncomingQueueOperation*)processIncomingQueue:(bool)failOnClassA after:(CKKSResultOperation* _Nullable)after; +- (CKKSScanLocalItemsOperation*)scanLocalItems:(NSString*)name; + // Schedules a process queueoperation to happen after the next device unlock. This may be Immediately, if the device is unlocked. - (void)processIncomingQueueAfterNextUnlock; @@ -197,10 +206,7 @@ NS_ASSUME_NONNULL_BEGIN - (CKKSResultOperation*)fetchAndProcessCKChanges:(CKKSFetchBecause*)because; - (CKKSResultOperation*)resetLocalData; -- (CKKSResultOperation*)resetCloudKitZone; - -// Call this to pick and start the next key hierarchy operation for the zone -- (void)advanceKeyStateMachine; +- (CKKSResultOperation*)resetCloudKitZone:(CKOperationGroup*)operationGroup; // Call this to tell the key state machine that you think some new data has arrived that it is interested in - (void)keyStateMachineRequestProcess; @@ -208,18 +214,14 @@ NS_ASSUME_NONNULL_BEGIN // For our serial queue to work with how handleKeychainEventDbConnection is called from the main thread, // every block on our queue must have a SecDBConnectionRef available to it before it begins on the queue. // Use these helper methods to make sure those exist. -- (void)dispatchAsync:(bool (^)(void))block; - (void)dispatchSync:(bool (^)(void))block; - (void)dispatchSyncWithAccountKeys:(bool (^)(void))block; -/* Synchronous operations which must be called from inside a dispatchAsync or dispatchSync block */ +/* Synchronous operations which must be called from inside a dispatchAsyncWithAccountKeys or dispatchSync block */ // Call this to request the key hierarchy state machine to fetch new updates - (void)_onqueueKeyStateMachineRequestFetch; -// Call this to request the key hierarchy state machine to refetch everything in Cloudkit -- (void)_onqueueKeyStateMachineRequestFullRefetch; - // Call this to request the key hierarchy state machine to reprocess - (void)_onqueueKeyStateMachineRequestProcess; @@ -243,7 +245,7 @@ NS_ASSUME_NONNULL_BEGIN - (bool)_onqueueCKRecordChanged:(CKRecord*)record resync:(bool)resync; - (bool)_onqueueCKRecordDeleted:(CKRecordID*)recordID recordType:(NSString*)recordType resync:(bool)resync; -// For this key, who doesn't yet have a CKKSTLKShare for it? +// For this key, who doesn't yet have a CKKSTLKShare for it, shared to their current Octagon keys? // Note that we really want a record sharing the TLK to ourselves, so this function might return // a non-empty set even if all peers have the TLK: it wants us to make a record for ourself. - (NSSet>* _Nullable)_onqueueFindPeersMissingShare:(CKKSKey*)key error:(NSError* __autoreleasing*)error; diff --git a/keychain/ckks/CKKSKeychainView.m b/keychain/ckks/CKKSKeychainView.m index 2b9260ff..664cfcf7 100644 --- a/keychain/ckks/CKKSKeychainView.m +++ b/keychain/ckks/CKKSKeychainView.m @@ -53,13 +53,12 @@ #import "CKKSManifest.h" #import "CKKSManifestLeafRecord.h" #import "CKKSZoneChangeFetcher.h" -#import "CKKSAnalyticsLogger.h" +#import "CKKSAnalytics.h" #import "keychain/ckks/CKKSDeviceStateEntry.h" #import "keychain/ckks/CKKSNearFutureScheduler.h" #import "keychain/ckks/CKKSCurrentItemPointer.h" #import "keychain/ckks/CKKSUpdateCurrentItemPointerOperation.h" #import "keychain/ckks/CKKSUpdateDeviceStateOperation.h" -#import "keychain/ckks/CKKSLockStateTracker.h" #import "keychain/ckks/CKKSNotifier.h" #import "keychain/ckks/CloudKitCategories.h" #import "keychain/ckks/CKKSTLKShare.h" @@ -77,13 +76,20 @@ #include #include #include +#include #if OCTAGON @interface CKKSKeychainView() -@property bool setupSuccessful; @property bool keyStateFetchRequested; @property bool keyStateFullRefetchRequested; @property bool keyStateProcessRequested; + +@property bool keyStateCloudKitDeleteRequested; +@property NSHashTable* cloudkitDeleteZoneOperations; + +@property bool keyStateLocalResetRequested; +@property NSHashTable* localResetOperations; + @property (atomic) NSString *activeTLK; @property (readonly) Class notifierClass; @@ -117,8 +123,9 @@ zoneName: (NSString*) zoneName accountTracker:(CKKSCKAccountStateTracker*) accountTracker lockStateTracker:(CKKSLockStateTracker*) lockStateTracker + reachabilityTracker:(CKKSReachabilityTracker *)reachabilityTracker savedTLKNotifier:(CKKSNearFutureScheduler*) savedTLKNotifier - peerProvider:(id)peerProvider + peerProvider:(id)peerProvider fetchRecordZoneChangesOperationClass: (Class) fetchRecordZoneChangesOperationClass fetchRecordsOperationClass: (Class)fetchRecordsOperationClass queryOperationClass:(Class)queryOperationClass @@ -131,6 +138,7 @@ if(self = [super initWithContainer:container zoneName:zoneName accountTracker:accountTracker + reachabilityTracker:reachabilityTracker fetchRecordZoneChangesOperationClass:fetchRecordZoneChangesOperationClass fetchRecordsOperationClass:fetchRecordsOperationClass queryOperationClass:queryOperationClass @@ -141,9 +149,12 @@ _loggedIn = [[CKKSCondition alloc] init]; _loggedOut = [[CKKSCondition alloc] init]; + _accountStateKnown = [[CKKSCondition alloc] init]; _incomingQueueOperations = [NSHashTable weakObjectsHashTable]; _outgoingQueueOperations = [NSHashTable weakObjectsHashTable]; + _cloudkitDeleteZoneOperations = [NSHashTable weakObjectsHashTable]; + _localResetOperations = [NSHashTable weakObjectsHashTable]; _zoneChangeFetcher = [[CKKSZoneChangeFetcher alloc] initWithCKKSKeychainView: self]; _notifierClass = notifierClass; @@ -151,6 +162,7 @@ initialDelay:250*NSEC_PER_MSEC continuingDelay:1*NSEC_PER_SEC keepProcessAlive:true + dependencyDescriptionCode:CKKSResultDescriptionPendingViewChangedScheduling block:^{ __strong __typeof(self) strongSelf = weakSelf; [strongSelf.notifierClass post:[NSString stringWithFormat:@"com.apple.security.view-change.%@", strongSelf.zoneName]]; @@ -169,14 +181,14 @@ _currentPeerProvider = peerProvider; [_currentPeerProvider registerForPeerChangeUpdates:self]; - _setupSuccessful = false; - _keyHierarchyConditions = [[NSMutableDictionary alloc] init]; [CKKSZoneKeyStateMap() enumerateKeysAndObjectsUsingBlock:^(CKKSZoneKeyState * _Nonnull key, NSNumber * _Nonnull obj, BOOL * _Nonnull stop) { [self.keyHierarchyConditions setObject: [[CKKSCondition alloc] init] forKey:key]; }]; - self.keyHierarchyState = SecCKKSZoneKeyStateInitializing; + // Use the keyHierarchyState setter to modify the zone key state map + self.keyHierarchyState = SecCKKSZoneKeyStateLoggedOut; + _keyHierarchyError = nil; _keyHierarchyOperationGroup = nil; _keyStateMachineOperation = nil; @@ -188,24 +200,42 @@ _keyStateReadyDependency = [self createKeyStateReadyDependency: @"Key state has become ready for the first time." ckoperationGroup:[CKOperationGroup CKKSGroupWithName:@"initial-key-state-ready-scan"]]; - dispatch_time_t initializeDelay = SecCKKSTestsEnabled() ? NSEC_PER_MSEC * 600 : NSEC_PER_SEC * 30; + _keyStateNonTransientDependency = [self createKeyStateNontransientDependency]; + + dispatch_time_t initializeDelay = SecCKKSReduceRateLimiting() ? NSEC_PER_MSEC * 600 : NSEC_PER_SEC * 30; _initializeScheduler = [[CKKSNearFutureScheduler alloc] initWithName:[NSString stringWithFormat: @"%@-zone-initializer", self.zoneName] initialDelay:0 continuingDelay:initializeDelay keepProcessAlive:false - block:^{ - __strong __typeof(self) strongSelf = weakSelf; - ckksnotice("ckks", strongSelf, "initialize-scheduler restarting setup"); - [strongSelf maybeRestartSetup]; - }]; - - dispatch_time_t initialOutgoingQueueDelay = SecCKKSTestsEnabled() ? NSEC_PER_MSEC * 200 : NSEC_PER_SEC * 1; - dispatch_time_t continuingOutgoingQueueDelay = SecCKKSTestsEnabled() ? NSEC_PER_MSEC * 500 : NSEC_PER_SEC * 30; + dependencyDescriptionCode:CKKSResultDescriptionPendingZoneInitializeScheduling + block:^{}]; + + dispatch_time_t initialOutgoingQueueDelay = SecCKKSReduceRateLimiting() ? NSEC_PER_MSEC * 200 : NSEC_PER_SEC * 1; + dispatch_time_t continuingOutgoingQueueDelay = SecCKKSReduceRateLimiting() ? NSEC_PER_MSEC * 200 : NSEC_PER_SEC * 30; _outgoingQueueOperationScheduler = [[CKKSNearFutureScheduler alloc] initWithName:[NSString stringWithFormat: @"%@-outgoing-queue-scheduler", self.zoneName] initialDelay:initialOutgoingQueueDelay continuingDelay:continuingOutgoingQueueDelay keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionPendingOutgoingQueueScheduling block:^{}]; + + + dispatch_time_t initialKeyHierachyPokeDelay = SecCKKSReduceRateLimiting() ? NSEC_PER_MSEC * 100 : NSEC_PER_MSEC * 500; + dispatch_time_t continuingKeyHierachyPokeDelay = SecCKKSReduceRateLimiting() ? NSEC_PER_MSEC * 200 : NSEC_PER_SEC * 5; + _pokeKeyStateMachineScheduler = [[CKKSNearFutureScheduler alloc] initWithName:[NSString stringWithFormat: @"%@-reprocess-scheduler", self.zoneName] + initialDelay:initialKeyHierachyPokeDelay + continuingDelay:continuingKeyHierachyPokeDelay + keepProcessAlive:true + dependencyDescriptionCode:CKKSResultDescriptionPendingKeyHierachyPokeScheduling + block:^{ + __strong __typeof(self) strongSelf = weakSelf; + [strongSelf dispatchSyncWithAccountKeys: ^bool{ + __strong __typeof(weakSelf) strongBlockSelf = weakSelf; + + [strongBlockSelf _onqueueAdvanceKeyStateMachineToState:nil withError:nil]; + return true; + }]; + }]; } return self; } @@ -226,16 +256,17 @@ if((keyHierarchyState == nil && _keyHierarchyState == nil) || ([keyHierarchyState isEqualToString:_keyHierarchyState])) { // No change, do nothing. } else { - // Fixup the condition variables + // Fixup the condition variables as part of setting this state if(_keyHierarchyState) { self.keyHierarchyConditions[_keyHierarchyState] = [[CKKSCondition alloc] init]; } + + _keyHierarchyState = keyHierarchyState; + if(keyHierarchyState) { [self.keyHierarchyConditions[keyHierarchyState] fulfill]; } } - - _keyHierarchyState = keyHierarchyState; } - (NSString *)lastActiveTLKUUID @@ -243,204 +274,181 @@ return self.activeTLK; } -- (void)maybeRestartSetup { - [self dispatchSync: ^bool{ - if([self.viewSetupOperation isPending] || [self.viewSetupOperation isExecuting]) { - ckksinfo("ckks", self, "setup is in-flight. Ignoring timer fire"); - return false; - } +- (void)_onqueueResetSetup:(CKKSZoneKeyState*)newState resetMessage:(NSString*)resetMessage ckoperationGroup:(CKOperationGroup*)group { + [super resetSetup]; - [self resetSetup]; - [self restartCurrentAccountStateOperation]; - return true; - }]; -} + self.keyHierarchyState = newState; + self.keyHierarchyError = nil; -- (void)resetSetup { - [super resetSetup]; - self.setupSuccessful = false; + [self.keyStateMachineOperation cancel]; + self.keyStateMachineOperation = nil; - // Key hierarchy state machine resets, too - self.keyHierarchyState = SecCKKSZoneKeyStateInitializing; - _keyHierarchyError = nil; -} + self.keyStateFetchRequested = false; + self.keyStateProcessRequested = false; - - (void)_onqueueHandleCKLogin { - if(!SecCKKSIsEnabled()) { - ckksnotice("ckks", self, "Skipping CloudKit initialization due to disabled CKKS"); - return; - } + self.keyHierarchyOperationGroup = group; - dispatch_assert_queue(self.queue); + NSOperation* oldKSRD = self.keyStateReadyDependency; + self.keyStateReadyDependency = [self createKeyStateReadyDependency:resetMessage ckoperationGroup:self.keyHierarchyOperationGroup]; + if(oldKSRD) { + [oldKSRD addDependency:self.keyStateReadyDependency]; + [self.waitingQueue addOperation:oldKSRD]; + } - __weak __typeof(self) weakSelf = self; + NSOperation* oldKSNTD = self.keyStateNonTransientDependency; + self.keyStateNonTransientDependency = [self createKeyStateNontransientDependency]; + if(oldKSNTD) { + [oldKSNTD addDependency:self.keyStateNonTransientDependency]; + [self.waitingQueue addOperation:oldKSNTD]; + } +} - CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state: self.zoneName]; - [self handleCKLogin:ckse.ckzonecreated zoneSubscribed:ckse.ckzonesubscribed]; +- (CKKSResultOperation*)createPendingInitializationOperation { - self.viewSetupOperation = [CKKSResultOperation operationWithBlock: ^{ + __weak __typeof(self) weakSelf = self; + CKKSResultOperation* initializationOp = [CKKSGroupOperation named:@"view-initialization" withBlockTakingSelf:^(CKKSGroupOperation * _Nonnull strongOp) { __strong __typeof(weakSelf) strongSelf = weakSelf; - if(!strongSelf) { - ckkserror("ckks", strongSelf, "received callback for released object"); - return; - } - - __block bool quit = false; - [strongSelf dispatchSync: ^bool { - ckksnotice("ckks", strongSelf, "Zone setup progress: %@ %d %@ %d %@", - [CKKSCKAccountStateTracker stringFromAccountStatus:strongSelf.accountStatus], - strongSelf.zoneCreated, strongSelf.zoneCreatedError, strongSelf.zoneSubscribed, strongSelf.zoneSubscribedError); + __block CKKSResultOperation* zoneCreationOperation = nil; + [strongSelf dispatchSync:^bool { + CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state: self.zoneName]; + zoneCreationOperation = [self handleCKLogin:ckse.ckzonecreated zoneSubscribed:ckse.ckzonesubscribed]; + return true; + }]; - NSError* error = nil; - CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state: strongSelf.zoneName]; - ckse.ckzonecreated = strongSelf.zoneCreated; - ckse.ckzonesubscribed = strongSelf.zoneSubscribed; - - // Although, if the zone subscribed error says there's no zone, mark down that there's no zone - if(strongSelf.zoneSubscribedError && - [strongSelf.zoneSubscribedError.domain isEqualToString:CKErrorDomain] && strongSelf.zoneSubscribedError.code == CKErrorPartialFailure) { - NSError* subscriptionError = strongSelf.zoneSubscribedError.userInfo[CKPartialErrorsByItemIDKey][strongSelf.zoneID]; - if(subscriptionError && [subscriptionError.domain isEqualToString:CKErrorDomain] && subscriptionError.code == CKErrorZoneNotFound) { - - ckkserror("ckks", strongSelf, "zone subscription error appears to say the zone doesn't exist, fixing status: %@", strongSelf.zoneSubscribedError); - ckse.ckzonecreated = false; - } + CKKSResultOperation* viewInitializationOperation = [CKKSResultOperation named:@"view-initialization" withBlockTakingSelf:^(CKKSResultOperation * _Nonnull strongInternalOp) { + __strong __typeof(weakSelf) strongSelf = weakSelf; + if(!strongSelf) { + ckkserror("ckks", strongSelf, "received callback for released object"); + return; } - [ckse saveToDatabase: &error]; - if(error) { - ckkserror("ckks", strongSelf, "couldn't save zone creation status for %@: %@", strongSelf.zoneName, error); - } + [strongSelf dispatchSyncWithAccountKeys: ^bool { + ckksnotice("ckks", strongSelf, "Zone setup progress: %@ %d %@ %d %@", + [CKKSCKAccountStateTracker stringFromAccountStatus:strongSelf.accountStatus], + strongSelf.zoneCreated, strongSelf.zoneCreatedError, strongSelf.zoneSubscribed, strongSelf.zoneSubscribedError); - if(!strongSelf.zoneCreated || !strongSelf.zoneSubscribed || strongSelf.accountStatus != CKAccountStatusAvailable) { - // Something has gone very wrong. Error out and maybe retry. - quit = true; + NSError* error = nil; + CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state: strongSelf.zoneName]; + ckse.ckzonecreated = strongSelf.zoneCreated; + ckse.ckzonesubscribed = strongSelf.zoneSubscribed; + + // Although, if the zone subscribed error says there's no zone, mark down that there's no zone + if(strongSelf.zoneSubscribedError && + [strongSelf.zoneSubscribedError.domain isEqualToString:CKErrorDomain] && strongSelf.zoneSubscribedError.code == CKErrorPartialFailure) { + NSError* subscriptionError = strongSelf.zoneSubscribedError.userInfo[CKPartialErrorsByItemIDKey][strongSelf.zoneID]; + if(subscriptionError && [subscriptionError.domain isEqualToString:CKErrorDomain] && subscriptionError.code == CKErrorZoneNotFound) { + + ckkserror("ckks", strongSelf, "zone subscription error appears to say the zone doesn't exist, fixing status: %@", strongSelf.zoneSubscribedError); + ckse.ckzonecreated = false; + } + } - // Note that CKKSZone has probably called [handleLogout]; which means we have a key hierarchy reset queued up. Error here anyway. - NSError* realReason = strongSelf.zoneCreatedError ? strongSelf.zoneCreatedError : strongSelf.zoneSubscribedError; - strongSelf.viewSetupOperation.error = realReason; - [strongSelf _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateError withError: realReason]; + [ckse saveToDatabase: &error]; + if(error) { + ckkserror("ckks", strongSelf, "couldn't save zone creation status for %@: %@", strongSelf.zoneName, error); + } - // We're supposed to be up, but something has gone wrong. Blindly retry until it works. - if(strongSelf.accountStatus == CKKSAccountStatusAvailable) { - [strongSelf.initializeScheduler trigger]; - ckksnotice("ckks", strongSelf, "We're logged in, but setup didn't work. Scheduling retry for %@", strongSelf.initializeScheduler.nextFireTime); + if(!strongSelf.zoneCreated || !strongSelf.zoneSubscribed) { + // Go into 'zonecreationfailed' + strongInternalOp.error = strongSelf.zoneCreatedError ? strongSelf.zoneCreatedError : strongSelf.zoneSubscribedError; + [strongSelf _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateZoneCreationFailed withError:strongInternalOp.error]; + + return true; + } else { + [strongSelf _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateInitialized withError:nil]; } - return true; - } else { - strongSelf.setupSuccessful = true; - } - return true; + return true; + }]; }]; - if(quit) { - ckkserror("ckks", strongSelf, "Quitting setup."); - return; - } - - // We can't enter the account queue until an account exists. Before this point, we don't know if one does. - [strongSelf dispatchSyncWithAccountKeys: ^bool{ - // Change our condition variables to reflect that we think we're logged in - strongSelf.loggedOut = [[CKKSCondition alloc] initToChain: strongSelf.loggedOut]; - [strongSelf.loggedIn fulfill]; + [viewInitializationOperation addDependency:zoneCreationOperation]; + [strongOp runBeforeGroupFinished:viewInitializationOperation]; + }]; - CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state: strongSelf.zoneName]; + return initializationOp; +} - // Check if we believe we've synced this zone before. - if(ckse.changeToken == nil) { - strongSelf.keyHierarchyOperationGroup = [CKOperationGroup CKKSGroupWithName:@"initial-setup"]; +- (void)_onqueuePerformKeyStateInitialized:(CKKSZoneStateEntry*)ckse { - ckksnotice("ckks", strongSelf, "No existing change token; going to try to match local items with CloudKit ones."); + // Check if we believe we've synced this zone before. + if(ckse.changeToken == nil) { + self.keyHierarchyOperationGroup = [CKOperationGroup CKKSGroupWithName:@"initial-setup"]; - // Onboard this keychain: there's likely items in it that we haven't synced yet. - // But, there might be items in The Cloud that correspond to these items, with UUIDs that we don't know yet. - // First, fetch all remote items. - CKKSResultOperation* fetch = [strongSelf.zoneChangeFetcher requestSuccessfulFetch:CKKSFetchBecauseInitialStart]; - fetch.name = @"initial-fetch"; + ckksnotice("ckks", self, "No existing change token; going to try to match local items with CloudKit ones."); - // Next, try to process them (replacing local entries) - CKKSIncomingQueueOperation* initialProcess = [strongSelf processIncomingQueue: true after: fetch ]; - initialProcess.name = @"initial-process-incoming-queue"; + // Onboard this keychain: there's likely items in it that we haven't synced yet. + // But, there might be items in The Cloud that correspond to these items, with UUIDs that we don't know yet. + // First, fetch all remote items. + CKKSResultOperation* fetch = [self.zoneChangeFetcher requestSuccessfulFetch:CKKSFetchBecauseInitialStart]; + fetch.name = @"initial-fetch"; - // If all that succeeds, iterate through all keychain items and find the ones which need to be uploaded - strongSelf.initialScanOperation = [[CKKSScanLocalItemsOperation alloc] initWithCKKSKeychainView:strongSelf ckoperationGroup:strongSelf.keyHierarchyOperationGroup]; - strongSelf.initialScanOperation.name = @"initial-scan-operation"; - [strongSelf.initialScanOperation addNullableDependency:strongSelf.lockStateTracker.unlockDependency]; - [strongSelf.initialScanOperation addDependency: initialProcess]; - [strongSelf scheduleOperation: strongSelf.initialScanOperation]; + // Next, try to process them (replacing local entries) + CKKSIncomingQueueOperation* initialProcess = [self processIncomingQueue:true after:fetch]; + initialProcess.name = @"initial-process-incoming-queue"; - } else { - // Likely a restart of securityd! + // If all that succeeds, iterate through all keychain items and find the ones which need to be uploaded + self.initialScanOperation = [self scanLocalItems:@"initial-scan-operation" + ckoperationGroup:self.keyHierarchyOperationGroup + after:initialProcess]; - // First off, are there any in-flight queue entries? If so, put them back into New. - // If they're truly in-flight, we'll "conflict" with ourselves, but that should be fine. - NSError* error = nil; - [self _onqueueResetAllInflightOQE:&error]; - if(error) { - ckkserror("ckks", self, "Couldn't reset in-flight OQEs, bad behavior ahead: %@", error); - } + } else { + // Likely a restart of securityd! - // Are there any fixups to run first? - strongSelf.lastFixupOperation = [CKKSFixups fixup:ckse.lastFixup for:strongSelf]; - if(strongSelf.lastFixupOperation) { - ckksnotice("ckksfixup", strongSelf, "We have a fixup to perform: %@", strongSelf.lastFixupOperation); - [strongSelf scheduleOperation:strongSelf.lastFixupOperation]; - } + // First off, are there any in-flight queue entries? If so, put them back into New. + // If they're truly in-flight, we'll "conflict" with ourselves, but that should be fine. + NSError* error = nil; + [self _onqueueResetAllInflightOQE:&error]; + if(error) { + ckkserror("ckks", self, "Couldn't reset in-flight OQEs, bad behavior ahead: %@", error); + } - strongSelf.keyHierarchyOperationGroup = [CKOperationGroup CKKSGroupWithName:@"restart-setup"]; + // Are there any fixups to run first? + self.lastFixupOperation = [CKKSFixups fixup:ckse.lastFixup for:self]; + if(self.lastFixupOperation) { + ckksnotice("ckksfixup", self, "We have a fixup to perform: %@", self.lastFixupOperation); + [self scheduleOperation:self.lastFixupOperation]; + } - if ([CKKSManifest shouldSyncManifests]) { - strongSelf.egoManifest = [CKKSEgoManifest tryCurrentEgoManifestForZone:strongSelf.zoneName]; - } + self.keyHierarchyOperationGroup = [CKOperationGroup CKKSGroupWithName:@"restart-setup"]; - // If it's been more than 24 hours since the last fetch, fetch and process everything. - // Otherwise, just kick off the local queue processing. + if ([CKKSManifest shouldSyncManifests]) { + self.egoManifest = [CKKSEgoManifest tryCurrentEgoManifestForZone:self.zoneName]; + } - NSDate* now = [NSDate date]; - NSDateComponents* offset = [[NSDateComponents alloc] init]; - [offset setHour:-24]; - NSDate* deadline = [[NSCalendar currentCalendar] dateByAddingComponents:offset toDate:now options:0]; + // If it's been more than 24 hours since the last fetch, fetch and process everything. + // Otherwise, just kick off the local queue processing. - NSOperation* initialProcess = nil; - if(ckse.lastFetchTime == nil || [ckse.lastFetchTime compare: deadline] == NSOrderedAscending) { - initialProcess = [strongSelf fetchAndProcessCKChanges:CKKSFetchBecauseSecuritydRestart after:strongSelf.lastFixupOperation]; - } else { - initialProcess = [strongSelf processIncomingQueue:false after:strongSelf.lastFixupOperation]; - } + NSDate* now = [NSDate date]; + NSDateComponents* offset = [[NSDateComponents alloc] init]; + [offset setHour:-24]; + NSDate* deadline = [[NSCalendar currentCalendar] dateByAddingComponents:offset toDate:now options:0]; - if([CKKSManifest shouldSyncManifests]) { - if (!strongSelf.egoManifest) { - ckksnotice("ckksmanifest", strongSelf, "No ego manifest on restart; rescanning"); - strongSelf.initialScanOperation = [[CKKSScanLocalItemsOperation alloc] initWithCKKSKeychainView:strongSelf ckoperationGroup:strongSelf.keyHierarchyOperationGroup]; - strongSelf.initialScanOperation.name = @"initial-scan-operation"; - [strongSelf.initialScanOperation addNullableDependency:strongSelf.lastFixupOperation]; - [strongSelf.initialScanOperation addNullableDependency:strongSelf.lockStateTracker.unlockDependency]; - [strongSelf.initialScanOperation addDependency: initialProcess]; - [strongSelf scheduleOperation: strongSelf.initialScanOperation]; - } - } + NSOperation* initialProcess = nil; + if(ckse.lastFetchTime == nil || [ckse.lastFetchTime compare: deadline] == NSOrderedAscending) { + initialProcess = [self fetchAndProcessCKChanges:CKKSFetchBecauseSecuritydRestart after:self.lastFixupOperation]; - // Process outgoing queue after re-start - [strongSelf processOutgoingQueueAfter:strongSelf.lastFixupOperation ckoperationGroup:strongSelf.keyHierarchyOperationGroup]; - } + // Also, kick off a scan local items: it'll find any out-of-sync issues in the local keychain + self.initialScanOperation = [self scanLocalItems:@"24-hr-scan-operation" + ckoperationGroup:self.keyHierarchyOperationGroup + after:initialProcess]; + } else { + initialProcess = [self processIncomingQueue:false after:self.lastFixupOperation]; + } - // Tell the key state machine to fire off. It should either: - // Wait for the fixup operation to occur - // Be initialized - if(strongSelf.lastFixupOperation) { - [strongSelf _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateWaitForFixupOperation withError: nil]; - } else { - [strongSelf _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateInitialized withError: nil]; + if([CKKSManifest shouldSyncManifests]) { + if (!self.egoManifest && !self.initialScanOperation) { + ckksnotice("ckksmanifest", self, "No ego manifest on restart; rescanning"); + self.initialScanOperation = [self scanLocalItems:@"initial-scan-operation" + ckoperationGroup:self.keyHierarchyOperationGroup + after:initialProcess]; } - return true; - }]; - }]; - self.viewSetupOperation.name = @"view-setup"; + } - [self.viewSetupOperation addNullableDependency: self.zoneSetupOperation]; - [self scheduleAccountStatusOperation: self.viewSetupOperation]; + // Process outgoing queue after re-start + [self processOutgoingQueueAfter:self.lastFixupOperation ckoperationGroup:self.keyHierarchyOperationGroup]; + } } - (bool)_onqueueResetLocalData: (NSError * __autoreleasing *) error { @@ -525,132 +533,131 @@ } } - [self _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateInitializing withError:nil]; - return (localerror == nil && !setError); } -- (CKKSResultOperation*)resetLocalData { - __weak __typeof(self) weakSelf = self; - - CKKSGroupOperation* resetFollowUp = [[CKKSGroupOperation alloc] init]; - resetFollowUp.name = @"local-reset-follow-up-group"; - __weak __typeof(resetFollowUp) weakResetFollowUp = resetFollowUp; +- (CKKSResultOperation*)createPendingResetLocalDataOperation { + @synchronized(self.localResetOperations) { + CKKSResultOperation* pendingResetLocalOperation = (CKKSResultOperation*) [self findFirstPendingOperation:self.localResetOperations]; + if(!pendingResetLocalOperation) { + __weak __typeof(self) weakSelf = self; + pendingResetLocalOperation = [CKKSResultOperation named:@"reset-local" withBlockTakingSelf:^(CKKSResultOperation * _Nonnull strongOp) { + __strong __typeof(self) strongSelf = weakSelf; + __block NSError* error = nil; - CKKSResultOperation* op = [[CKKSResultOperation alloc] init]; - op.name = @"local-reset"; + [strongSelf dispatchSync: ^bool{ + [strongSelf _onqueueResetLocalData: &error]; + return true; + }]; - __weak __typeof(op) weakOp = op; - [op addExecutionBlock:^{ - __strong __typeof(self) strongSelf = weakSelf; - __strong __typeof(op) strongOp = weakOp; - __strong __typeof(resetFollowUp) strongResetFollowUp = weakResetFollowUp; - if(!strongSelf || !strongOp || !strongResetFollowUp) { - return; + strongOp.error = error; + }]; + [pendingResetLocalOperation linearDependencies:self.localResetOperations]; } + return pendingResetLocalOperation; + } +} - __block NSError* error = nil; - - [strongSelf dispatchSync: ^bool{ - [strongSelf _onqueueResetLocalData: &error]; +- (CKKSResultOperation*)resetLocalData { + // Not overly thread-safe, but a single read is okay + CKKSAccountStatus accountStatus = self.accountStatus; + ckksnotice("ckksreset", self, "Requesting local data reset"); + + // If we're currently signed in, the reset operation will be handled by the CKKS key state machine, and a reset should end up in 'ready' + if(accountStatus == CKKSAccountStatusAvailable) { + __block CKKSResultOperation* resetOperation = nil; + [self dispatchSyncWithAccountKeys:^bool { + self.keyStateLocalResetRequested = true; + resetOperation = [self createPendingResetLocalDataOperation]; + [self _onqueueAdvanceKeyStateMachineToState:nil withError:nil]; return true; }]; - if(error) { - ckksnotice("ckksreset", strongSelf, "Local reset finished with error %@", error); - strongOp.error = error; - } else { - if(strongSelf.accountStatus == CKKSAccountStatusAvailable) { - // Since we're logged in, we expect a reset to fix up the key hierarchy - ckksnotice("ckksreset", strongSelf, "logged in; re-initializing zone"); - [self.initializeScheduler trigger]; - - ckksnotice("ckksreset", strongSelf, "waiting for key hierarchy to become ready"); - CKKSResultOperation* waitOp = [CKKSResultOperation named:@"waiting-for-key-hierarchy" withBlock:^{}]; - [waitOp timeout: 60*NSEC_PER_SEC]; - [waitOp addNullableDependency:strongSelf.keyStateReadyDependency]; - - [strongResetFollowUp runBeforeGroupFinished:waitOp]; - } else { - ckksnotice("ckksreset", strongSelf, "logged out; not initializing zone"); - } - } - }]; - - // On a reset, all other operations should be cancelled - [self cancelAllOperations]; - [resetFollowUp runBeforeGroupFinished:op]; - [self scheduleOperationWithoutDependencies:resetFollowUp]; - return resetFollowUp; -} - -- (CKKSResultOperation*)resetCloudKitZone { - // On a reset, we should cancel all existing operations - [self cancelAllOperations]; - CKKSResultOperation* reset = [super beginResetCloudKitZoneOperation]; - - __weak __typeof(self) weakSelf = self; - CKKSGroupOperation* resetFollowUp = [[CKKSGroupOperation alloc] init]; - resetFollowUp.name = @"cloudkit-reset-follow-up-group"; - - __weak __typeof(resetFollowUp) weakResetFollowUp = resetFollowUp; - [resetFollowUp runBeforeGroupFinished: [CKKSResultOperation named:@"cloudkit-reset-follow-up" withBlock: ^{ - __strong __typeof(weakSelf) strongSelf = weakSelf; - if(!strongSelf) { - ckkserror("ckks", strongSelf, "received callback for released object"); - return; - } - __strong __typeof(resetFollowUp) strongResetFollowUp = weakResetFollowUp; + __weak __typeof(self) weakSelf = self; + CKKSGroupOperation* viewReset = [CKKSGroupOperation named:@"local-data-reset" withBlockTakingSelf:^(CKKSGroupOperation *strongOp) { + __strong __typeof(weakSelf) strongSelf = weakSelf; + // Now that the local reset finished, wait for the key hierarchy state machine to churn + ckksnotice("ckksreset", strongSelf, "waiting for key hierarchy to become ready (after local reset)"); + CKKSResultOperation* waitOp = [CKKSResultOperation named:@"waiting-for-local-reset" withBlock:^{}]; + [waitOp timeout: 60*NSEC_PER_SEC]; + [waitOp addNullableDependency:strongSelf.keyStateReadyDependency]; + + [strongOp runBeforeGroupFinished:waitOp]; + }]; + [viewReset addSuccessDependency:resetOperation]; - if(!reset.error) { - ckksnotice("ckks", strongSelf, "Successfully deleted zone %@", strongSelf.zoneName); + [self scheduleOperationWithoutDependencies:viewReset]; + return viewReset; + } else { + // Since we're logged out, we must run the reset ourselves + __weak __typeof(self) weakSelf = self; + CKKSResultOperation* pendingResetLocalOperation = [CKKSResultOperation named:@"reset-local" + withBlockTakingSelf:^(CKKSResultOperation * _Nonnull strongOp) { + __strong __typeof(self) strongSelf = weakSelf; __block NSError* error = nil; [strongSelf dispatchSync: ^bool{ [strongSelf _onqueueResetLocalData: &error]; - strongSelf.setupSuccessful = false; return true; }]; - if(strongSelf.accountStatus == CKKSAccountStatusAvailable) { - // Since we're logged in, we expect a reset to fix up the key hierarchy - ckksnotice("ckksreset", strongSelf, "re-initializing zone"); - [self.initializeScheduler trigger]; - - ckksnotice("ckksreset", strongSelf, "waiting for key hierarchy to become ready"); - CKKSResultOperation* waitOp = [CKKSResultOperation named:@"waiting-for-reset" withBlock:^{}]; - [waitOp timeout: 60*NSEC_PER_SEC]; - [waitOp addNullableDependency:strongSelf.keyStateReadyDependency]; + strongOp.error = error; + }]; + [self scheduleOperationWithoutDependencies:pendingResetLocalOperation]; + return pendingResetLocalOperation; + } +} - [strongResetFollowUp runBeforeGroupFinished:waitOp]; - } else { - ckksnotice("ckksreset", strongSelf, "logged out; not initializing zone"); - } - } else { - // Shouldn't ever happen, since reset is a successDependency - ckkserror("ckks", strongSelf, "Couldn't reset zone %@: %@", strongSelf.zoneName, reset.error); +- (CKKSResultOperation*)createPendingDeleteZoneOperation:(CKOperationGroup*)operationGroup { + @synchronized(self.cloudkitDeleteZoneOperations) { + CKKSResultOperation* pendingDeleteOperation = (CKKSResultOperation*) [self findFirstPendingOperation:self.cloudkitDeleteZoneOperations]; + if(!pendingDeleteOperation) { + pendingDeleteOperation = [self deleteCloudKitZoneOperation:operationGroup]; + [pendingDeleteOperation linearDependencies:self.cloudkitDeleteZoneOperations]; } - }]]; - - [resetFollowUp addSuccessDependency:reset]; - [self scheduleOperationWithoutDependencies:resetFollowUp]; - return resetFollowUp; + return pendingDeleteOperation; + } } -- (void)advanceKeyStateMachine { - __weak __typeof(self) weakSelf = self; +- (CKKSResultOperation*)resetCloudKitZone:(CKOperationGroup*)operationGroup { + // Not overly thread-safe, but a single read is okay + if(self.accountStatus == CKKSAccountStatusAvailable) { + // Actually running the delete operation will be handled by the CKKS key state machine + ckksnotice("ckksreset", self, "Requesting reset of CK zone (logged in)"); - [self dispatchAsync: ^bool{ - __strong __typeof(weakSelf) strongSelf = weakSelf; - if(!strongSelf) { - ckkserror("ckks", strongSelf, "received callback for released object"); - false; - } + __block CKKSResultOperation* deleteOperation = nil; + [self dispatchSyncWithAccountKeys:^bool { + self.keyStateCloudKitDeleteRequested = true; + deleteOperation = [self createPendingDeleteZoneOperation:operationGroup]; + [self _onqueueAdvanceKeyStateMachineToState:nil withError:nil]; + return true; + }]; - [strongSelf _onqueueAdvanceKeyStateMachineToState: nil withError: nil]; - return true; - }]; -}; + __weak __typeof(self) weakSelf = self; + CKKSGroupOperation* viewReset = [CKKSGroupOperation named:[NSString stringWithFormat:@"cloudkit-view-reset-%@", self.zoneName] + withBlockTakingSelf:^(CKKSGroupOperation *strongOp) { + __strong __typeof(self) strongSelf = weakSelf; + // Now that the delete finished, wait for the key hierarchy state machine + ckksnotice("ckksreset", strongSelf, "waiting for key hierarchy to become ready (after cloudkit reset)"); + CKKSResultOperation* waitOp = [CKKSResultOperation named:@"waiting-for-reset" withBlock:^{}]; + [waitOp timeout: 60*NSEC_PER_SEC]; + [waitOp addNullableDependency:strongSelf.keyStateReadyDependency]; + + [strongOp runBeforeGroupFinished:waitOp]; + }]; + + [viewReset addDependency:deleteOperation]; + [self.waitingQueue addOperation:viewReset]; + + return viewReset; + } else { + // Since we're logged out, we just need to run this ourselves + ckksnotice("ckksreset", self, "Requesting reset of CK zone (logged out)"); + CKKSResultOperation* deleteOperation = [self createPendingDeleteZoneOperation:operationGroup]; + [self scheduleOperationWithoutDependencies:deleteOperation]; + return deleteOperation; + } +} - (void)_onqueueKeyStateMachineRequestFetch { dispatch_assert_queue(self.queue); @@ -663,25 +670,22 @@ [self _onqueueAdvanceKeyStateMachineToState: nil withError: nil]; } -- (void)_onqueueKeyStateMachineRequestFullRefetch { - dispatch_assert_queue(self.queue); - - self.keyStateFullRefetchRequested = true; - [self _onqueueAdvanceKeyStateMachineToState: nil withError: nil]; +- (void)keyStateMachineRequestProcess { + // Since bools are atomic, we don't need to get on-queue here + // Just set the flag high and hope + self.keyStateProcessRequested = true; + [self.pokeKeyStateMachineScheduler trigger]; } -- (void)keyStateMachineRequestProcess { - __weak __typeof(self) weakSelf = self; - [self dispatchAsync: ^bool{ - __strong __typeof(weakSelf) strongSelf = weakSelf; - if(!strongSelf) { - ckkserror("ckks", strongSelf, "received callback for released object"); - return false; - } +- (void)_onqueueKeyStateMachineRequestProcess { + dispatch_assert_queue(self.queue); - [strongSelf _onqueueKeyStateMachineRequestProcess]; - return true; - }]; + // Set the request flag, then nudge the key state machine. + // If it was idle, then it should launch a process. If there was an active process, this flag will stay high + // and the process will be launched later. + + self.keyStateProcessRequested = true; + [self _onqueueAdvanceKeyStateMachineToState: nil withError: nil]; } - (CKKSResultOperation*)createKeyStateReadyDependency:(NSString*)message ckoperationGroup:(CKOperationGroup*)group { @@ -697,25 +701,22 @@ if(strongSelf.droppedItems) { // While we weren't in 'ready', keychain modifications might have come in and were dropped on the floor. Find them! ckksnotice("ckkskey", strongSelf, "Launching scan operation for missed items"); - CKKSScanLocalItemsOperation* scanOperation = [[CKKSScanLocalItemsOperation alloc] initWithCKKSKeychainView: strongSelf ckoperationGroup:group]; - [strongSelf scheduleOperation: scanOperation]; + [self scanLocalItems:@"ready-again-scan" ckoperationGroup:group after:nil]; } return true; }]; }]; keyStateReadyDependency.name = [NSString stringWithFormat: @"%@-key-state-ready", self.zoneName]; + keyStateReadyDependency.descriptionErrorCode = CKKSResultDescriptionPendingKeyReady; return keyStateReadyDependency; } -- (void)_onqueueKeyStateMachineRequestProcess { - dispatch_assert_queue(self.queue); - - // Set the request flag, then nudge the key state machine. - // If it was idle, then it should launch a process. If there was an active process, this flag will stay high - // and the process will be launched later. - - self.keyStateProcessRequested = true; - [self _onqueueAdvanceKeyStateMachineToState: nil withError: nil]; +- (CKKSResultOperation*)createKeyStateNontransientDependency { + __weak __typeof(self) weakSelf = self; + return [CKKSResultOperation named:[NSString stringWithFormat: @"%@-key-state-nontransient", self.zoneName] withBlock:^{ + __strong __typeof(self) strongSelf = weakSelf; + ckksnotice("ckkskey", strongSelf, "Key state is now non-transient"); + }]; } // The operations suggested by this state machine should call _onqueueAdvanceKeyStateMachineToState once they are complete. @@ -726,25 +727,33 @@ dispatch_assert_queue(self.queue); __weak __typeof(self) weakSelf = self; - // Resetting back to 'initializing' takes all precedence. - if([state isEqual: SecCKKSZoneKeyStateInitializing]) { - ckksnotice("ckkskey", self, "Resetting the key hierarchy state machine back to 'initializing'"); + // Resetting back to 'loggedout' takes all precedence. + if([state isEqual:SecCKKSZoneKeyStateLoggedOut]) { + ckksnotice("ckkskey", self, "Resetting the key hierarchy state machine back to '%@'", state); - [self.keyStateMachineOperation cancel]; - self.keyStateMachineOperation = nil; + [self _onqueueResetSetup:SecCKKSZoneKeyStateLoggedOut + resetMessage:@"Key state has become ready for the first time (after reset)." + ckoperationGroup:[CKOperationGroup CKKSGroupWithName:@"key-state-after-logout"]]; - self.keyHierarchyState = SecCKKSZoneKeyStateInitializing; - self.keyHierarchyError = nil; - self.keyStateFetchRequested = false; - self.keyStateProcessRequested = false; + [self _onqueueHandleKeyStateNonTransientDependency]; + return; + } - self.keyHierarchyOperationGroup = [CKOperationGroup CKKSGroupWithName:@"key-state-reset"]; - NSOperation* oldKSRD = self.keyStateReadyDependency; - self.keyStateReadyDependency = [self createKeyStateReadyDependency:@"Key state has become ready for the first time (after reset)." ckoperationGroup:self.keyHierarchyOperationGroup]; - if(oldKSRD) { - [oldKSRD addDependency:self.keyStateReadyDependency]; - [self.waitingQueue addOperation:oldKSRD]; - } + // Resetting back to 'initialized' also takes precedence + if([state isEqual:SecCKKSZoneKeyStateInitializing]) { + ckksnotice("ckkskey", self, "Resetting the key hierarchy state machine back to '%@'", state); + + [self _onqueueResetSetup:SecCKKSZoneKeyStateInitializing + resetMessage:@"Key state has become ready for the first time (after re-initializing)." + ckoperationGroup:[CKOperationGroup CKKSGroupWithName:@"key-state-reset-to-initializing"]]; + + // Begin initialization, but rate-limit it + self.keyStateMachineOperation = [self createPendingInitializationOperation]; + [self.keyStateMachineOperation addNullableDependency:self.initializeScheduler.operationDependency]; + [self.initializeScheduler trigger]; + [self scheduleOperation:self.keyStateMachineOperation]; + + [self _onqueueHandleKeyStateNonTransientDependency]; return; } @@ -753,13 +762,13 @@ [self.keyHierarchyState isEqualToString: SecCKKSZoneKeyStateCancelled] || self.keyHierarchyError != nil) { // Error state: nowhere to go. Early-exit. - ckkserror("ckkskey", self, "Asked to advance state machine from non-exit state %@: %@", self.keyHierarchyState, self.keyHierarchyError); + ckkserror("ckkskey", self, "Asked to advance state machine from non-exit state %@ (to %@): %@", self.keyHierarchyState, state, self.keyHierarchyError); return; } - if(error != nil || [state isEqual: SecCKKSZoneKeyStateError]) { + if([state isEqual: SecCKKSZoneKeyStateError]) { // But wait! Is this a "we're locked" error? - if([self.lockStateTracker isLockedError:error]) { + if(error && [self.lockStateTracker isLockedError:error]) { ckkserror("ckkskey", self, "advised of 'keychain locked' error, ignoring: coming from state (%@): %@", self.keyHierarchyState, error); // After the next unlock, fake that we received the last zone transition CKKSZoneKeyState* lastState = self.keyHierarchyState; @@ -774,22 +783,29 @@ }]; }]; state = nil; + + self.keyHierarchyState = SecCKKSZoneKeyStateWaitForUnlock; + [self.keyStateMachineOperation addNullableDependency:self.lockStateTracker.unlockDependency]; [self scheduleOperation:self.keyStateMachineOperation]; + [self _onqueueHandleKeyStateNonTransientDependency]; + return; + } else { // Error state: record the error and exit early ckkserror("ckkskey", self, "advised of error: coming from state (%@): %@", self.keyHierarchyState, error); - [[CKKSAnalyticsLogger logger] logUnrecoverableError:error - forEvent:CKKSEventStateError - inView:self - withAttributes:@{ @"previousKeyHierarchyState" : self.keyHierarchyState }]; + [[CKKSAnalytics logger] logUnrecoverableError:error + forEvent:CKKSEventStateError + inView:self + withAttributes:@{ @"previousKeyHierarchyState" : self.keyHierarchyState }]; self.keyHierarchyState = SecCKKSZoneKeyStateError; self.keyHierarchyError = error; + [self _onqueueHandleKeyStateNonTransientDependency]; return; } } @@ -803,11 +819,13 @@ self.keyHierarchyOperationGroup = nil; [self.keyStateReadyDependency cancel]; self.keyStateReadyDependency = nil; + + [self.keyStateNonTransientDependency cancel]; + self.keyStateNonTransientDependency = nil; return; } // Now that the current or new state isn't an error or a cancel, proceed. - if(self.keyStateMachineOperation && ![self.keyStateMachineOperation isFinished]) { if(state == nil) { // we started this operation to move the state machine. Since you aren't asking for a state transition, and there's an active operation, no need to do anything @@ -824,6 +842,17 @@ state = self.keyHierarchyState; } +#if DEBUG + // During testing, keep the developer honest: this function should always have the self identities + if(self.currentSelfPeersError) { + NSAssert(self.currentSelfPeersError.code != CKKSNoPeersAvailable, @"Must have viable (or errored) self peers to advance key state"); + } +#endif + + // Do any of these state transitions below want to change which state we're in? + CKKSZoneKeyState* nextState = nil; + NSError* nextError = nil; + // Many of our decisions below will be based on what keys exist. Help them out. CKKSCurrentKeySet* keyset = [[CKKSCurrentKeySet alloc] initForZone:self.zoneID]; NSError* localerror = nil; @@ -831,7 +860,7 @@ NSArray* remoteKeys = [CKKSKey remoteKeys:self.zoneID error: &localerror]; // We also are checking for OutgoingQueueEntries in the reencrypt state; this is a sign that our key hierarchy is out of date. - NSArray* outdatedOQEs = [CKKSOutgoingQueueEntry allInState: SecCKKSStateReencrypt zoneID:self.zoneID error: &localerror]; + NSInteger outdatedOQEs = [CKKSOutgoingQueueEntry countByState:SecCKKSStateReencrypt zone:self.zoneID error:&localerror]; SecADSetValueForScalarKey((__bridge CFStringRef) SecCKKSAggdViewKeyCount, [localKeys count]); @@ -839,6 +868,7 @@ ckkserror("ckkskey", self, "couldn't fetch keys and OQEs from local database, entering error state: %@", localerror); self.keyHierarchyState = SecCKKSZoneKeyStateError; self.keyHierarchyError = localerror; + [self _onqueueHandleKeyStateNonTransientDependency]; return; } @@ -849,12 +879,45 @@ NSError* hierarchyError = nil; - if([state isEqualToString: SecCKKSZoneKeyStateInitializing]) { - if(state != nil) { - // Wait for CKKSZone to finish initialization. - ckkserror("ckkskey", self, "Asked to advance state machine (to %@) while CK zone still initializing.", state); - } - return; + if(self.keyStateCloudKitDeleteRequested || [state isEqualToString:SecCKKSZoneKeyStateResettingZone]) { + // CloudKit reset requests take precedence over all other state transitions + ckksnotice("ckkskey", self, "Deleting the CloudKit Zone"); + CKKSGroupOperation* op = [[CKKSGroupOperation alloc] init]; + + CKKSResultOperation* deleteOp = [self createPendingDeleteZoneOperation:self.keyHierarchyOperationGroup]; + [op runBeforeGroupFinished: deleteOp]; + + NSOperation* nextStateOp = [self operationToEnterState:SecCKKSZoneKeyStateResettingLocalData keyStateError:nil named:@"state-resetting-local"]; + [nextStateOp addDependency:deleteOp]; + [op runBeforeGroupFinished:nextStateOp]; + + self.keyStateMachineOperation = op; + self.keyStateCloudKitDeleteRequested = false; + + // Also, pending operations should be cancelled + [self cancelPendingOperations]; + + } else if(self.keyStateLocalResetRequested || [state isEqualToString:SecCKKSZoneKeyStateResettingLocalData]) { + // Local reset requests take precedence over all other state transitions + ckksnotice("ckkskey", self, "Resetting local data"); + CKKSGroupOperation* op = [[CKKSGroupOperation alloc] init]; + + CKKSResultOperation* resetOp = [self createPendingResetLocalDataOperation]; + [op runBeforeGroupFinished: resetOp]; + + NSOperation* nextStateOp = [self operationToEnterState:SecCKKSZoneKeyStateInitializing keyStateError:nil named:@"state-resetting-initialize"]; + [nextStateOp addDependency:resetOp]; + [op runBeforeGroupFinished:nextStateOp]; + + self.keyStateMachineOperation = op; + self.keyStateLocalResetRequested = false; + + + } else if([state isEqualToString:SecCKKSZoneKeyStateZoneCreationFailed]) { + //Prepare to go back into initializing, as soon as the initializeScheduler is happy + self.keyStateMachineOperation = [self operationToEnterState:SecCKKSZoneKeyStateInitializing keyStateError:nil named:@"recover-from-cloudkit-failure"]; + [self.keyStateMachineOperation addNullableDependency:self.initializeScheduler.operationDependency]; + [self.initializeScheduler trigger]; } else if([state isEqualToString: SecCKKSZoneKeyStateReady]) { if(self.keyStateProcessRequested || [remoteKeys count] > 0) { @@ -866,15 +929,13 @@ } else if(self.keyStateFullRefetchRequested) { // In ready, but someone has requested a full fetch. Kick it off. - ckksnotice("ckkskey", self, "Kicking off a key refetch based on request:%d", self.keyStateFetchRequested); - [self _onqueueKeyHierarchyRefetch]; - state = SecCKKSZoneKeyStateNeedFullRefetch; + ckksnotice("ckkskey", self, "Kicking off a full key refetch based on request:%d", self.keyStateFullRefetchRequested); + nextState = SecCKKSZoneKeyStateNeedFullRefetch; } else if(self.keyStateFetchRequested) { // In ready, but someone has requested a fetch. Kick it off. ckksnotice("ckkskey", self, "Kicking off a key refetch based on request:%d", self.keyStateFetchRequested); - [self _onqueueKeyHierarchyFetch]; - state = SecCKKSZoneKeyStateInitialized; // Don't go to 'ready', go to 'initialized', since we want to fetch again + nextState = SecCKKSZoneKeyStateFetch; // Don't go to 'ready', go to 'initialized', since we want to fetch again } // TODO: kick off a key roll if one has been requested @@ -884,40 +945,56 @@ if(![checkedstate isEqualToString:SecCKKSZoneKeyStateReady] || hierarchyError) { // Things is bad. Kick off a heal to fix things up. ckksnotice("ckkskey", self, "Thought we were ready, but the key hierarchy is %@: %@", checkedstate, hierarchyError); - state = checkedstate; - + nextState = checkedstate; + if([nextState isEqualToString:SecCKKSZoneKeyStateError]) { + nextError = hierarchyError; + } } } } else if([state isEqualToString: SecCKKSZoneKeyStateInitialized]) { // We're initialized and CloudKit is ready. See what needs done... - // Check if we have an existing key hierarchy - CKKSKey* tlk = [CKKSKey currentKeyForClass:SecCKKSKeyClassTLK zoneID:self.zoneID error:&error]; - CKKSKey* classA = [CKKSKey currentKeyForClass:SecCKKSKeyClassA zoneID:self.zoneID error:&error]; - CKKSKey* classC = [CKKSKey currentKeyForClass:SecCKKSKeyClassC zoneID:self.zoneID error:&error]; + CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state:self.zoneName]; + [self _onqueuePerformKeyStateInitialized:ckse]; - if(error && !([error.domain isEqual: @"securityd"] && error.code == errSecItemNotFound)) { - ckkserror("ckkskey", self, "Error examining existing key hierarchy: %@", error); - } + // We need to either: + // Wait for the fixup operation to occur + // Go into 'ready' + // Or start a key state fetch + if(self.lastFixupOperation && ![self.lastFixupOperation isFinished]) { + nextState = SecCKKSZoneKeyStateWaitForFixupOperation; + } else { + // Check if we have an existing key hierarchy in keyset + if(keyset.error && !([keyset.error.domain isEqual: @"securityd"] && keyset.error.code == errSecItemNotFound)) { + ckkserror("ckkskey", self, "Error examining existing key hierarchy: %@", error); + } - if(tlk && classA && classC && !error) { - // This is likely a restart of securityd, and we think we're ready. Double check. + if(keyset.tlk && keyset.classA && keyset.classC && !keyset.error) { + // This is likely a restart of securityd, and we think we're ready. Double check. + + CKKSZoneKeyState* checkedstate = [self _onqueueEnsureKeyHierarchyHealth:keyset error:&hierarchyError]; + if([checkedstate isEqualToString:SecCKKSZoneKeyStateReady] && !hierarchyError) { + ckksnotice("ckkskey", self, "Already have existing key hierarchy for %@; using it.", self.zoneID.zoneName); + } else { + ckksnotice("ckkskey", self, "Initial scan shows key hierarchy is %@: %@", checkedstate, hierarchyError); + } + nextState = checkedstate; - CKKSZoneKeyState* checkedstate = [self _onqueueEnsureKeyHierarchyHealth:keyset error:&hierarchyError]; - if([checkedstate isEqualToString:SecCKKSZoneKeyStateReady] && !hierarchyError) { - ckksnotice("ckkskey", self, "Already have existing key hierarchy for %@; using it.", self.zoneID.zoneName); } else { - ckksnotice("ckkskey", self, "Initial scan shows key hierarchy is %@: %@", checkedstate, hierarchyError); - state = checkedstate; + // We have no local key hierarchy. One might exist in CloudKit, or it might not. + ckksnotice("ckkskey", self, "No existing key hierarchy for %@. Check if there's one in CloudKit...", self.zoneID.zoneName); + nextState = SecCKKSZoneKeyStateFetch; } + } - } else { - // We have no local key hierarchy. One might exist in CloudKit, or it might not. - ckksnotice("ckkskey", self, "No existing key hierarchy for %@. Check if there's one in CloudKit...", self.zoneID.zoneName); + } else if([state isEqualToString:SecCKKSZoneKeyStateFetch]) { + ckksnotice("ckkskey", self, "Starting a key hierarchy fetch"); + [self _onqueueKeyHierarchyFetch]; - [self _onqueueKeyHierarchyFetch]; - } + } else if([state isEqualToString: SecCKKSZoneKeyStateNeedFullRefetch]) { + ckksnotice("ckkskey", self, "Starting a key hierarchy full refetch"); + [self _onqueueKeyHierarchyRefetch]; } else if([state isEqualToString:SecCKKSZoneKeyStateWaitForFixupOperation]) { // We should enter 'initialized' when the fixup operation completes @@ -943,18 +1020,19 @@ // Huh. We appear to have current key pointers, but the keys themselves don't exist. That's weird. // Transfer to the "unhealthy" state to request a fix ckksnotice("ckkskey", self, "We appear to have current key pointers but no keys to match them. Moving to 'unhealthy'"); - state = SecCKKSZoneKeyStateUnhealthy; + nextState = SecCKKSZoneKeyStateUnhealthy; } else { // No remote keys, and the pointers look sane? Do we have an existing key hierarchy? CKKSZoneKeyState* checkedstate = [self _onqueueEnsureKeyHierarchyHealth:keyset error:&hierarchyError]; if([checkedstate isEqualToString:SecCKKSZoneKeyStateReady] && !hierarchyError) { ckksnotice("ckkskey", self, "After fetch, everything looks good."); + nextState = checkedstate; } else if(localKeys.count == 0 && remoteKeys.count == 0) { ckksnotice("ckkskey", self, "After fetch, we don't have any key hierarchy. Making a new one: %@", hierarchyError); self.keyStateMachineOperation = [[CKKSNewTLKOperation alloc] initWithCKKSKeychainView: self ckoperationGroup:self.keyHierarchyOperationGroup]; } else { ckksnotice("ckkskey", self, "After fetch, we have a possibly unhealthy key hierarchy. Moving to %@: %@", checkedstate, hierarchyError); - state = checkedstate; + nextState = checkedstate; } } @@ -965,15 +1043,25 @@ // Someone has requsted a reprocess! Run a ProcessReceivedKeysOperation. ckksnotice("ckkskey", self, "Received a nudge that our TLK might be here! Starting operation to check."); [self _onqueueKeyHierarchyProcess]; + } else { + // Should we nuke this zone? + if([self _onqueueOtherDevicesReportHavingTLKs:keyset]) { + ckksnotice("ckkskey", self, "Other devices report having TLK(%@). Entering a waiting state", keyset.currentTLKPointer); + } else { + ckksnotice("ckkskey", self, "No other devices have TLK(%@). Beginning zone reset...", keyset.currentTLKPointer); + nextState = SecCKKSZoneKeyStateResettingZone; + } } } else if([state isEqualToString: SecCKKSZoneKeyStateWaitForUnlock]) { - // will be handled later. ckksnotice("ckkskey", self, "Requested to enter waitforunlock"); + self.keyStateMachineOperation = [self operationToEnterState:SecCKKSZoneKeyStateInitialized keyStateError:nil named:@"key-state-after-unlock"]; + [self.keyStateMachineOperation addNullableDependency: self.lockStateTracker.unlockDependency]; } else if([state isEqualToString: SecCKKSZoneKeyStateReadyPendingUnlock]) { - // will be handled later. - ckksnotice("ckkskey", self, "Believe we're ready, but recheck after unlock"); + ckksnotice("ckkskey", self, "Believe we're ready, but rechecking after unlock"); + self.keyStateMachineOperation = [self operationToEnterState:SecCKKSZoneKeyStateInitialized keyStateError:nil named:@"key-state-after-unlock"]; + [self.keyStateMachineOperation addNullableDependency: self.lockStateTracker.unlockDependency]; } else if([state isEqualToString: SecCKKSZoneKeyStateBadCurrentPointers]) { // The current key pointers are broken, but we're not sure why. @@ -988,18 +1076,7 @@ ckksnotice("ckkskey", self, "Creating new TLK shares didn't work. Attempting to refetch!"); [self _onqueueKeyHierarchyFetch]; - } else if([state isEqualToString: SecCKKSZoneKeyStateNeedFullRefetch]) { - ckksnotice("ckkskey", self, "Informed of request for full refetch"); - [self _onqueueKeyHierarchyRefetch]; - - } else { - ckkserror("ckks", self, "asked to advance state machine to unknown state: %@", state); - self.keyHierarchyState = state; - return; - } - - // Check our other states: did the above code ask for a fix up? Are we in ready? - if([state isEqualToString:SecCKKSZoneKeyStateUnhealthy]) { + } else if([state isEqualToString:SecCKKSZoneKeyStateUnhealthy]) { ckksnotice("ckkskey", self, "Looks like the key hierarchy is unhealthy. Launching fix."); self.keyStateMachineOperation = [[CKKSHealKeyHierarchyOperation alloc] initWithCKKSKeychainView:self ckoperationGroup:self.keyHierarchyOperationGroup]; @@ -1008,34 +1085,27 @@ self.keyStateMachineOperation = [[CKKSHealTLKSharesOperation alloc] initWithCKKSKeychainView:self ckoperationGroup:self.keyHierarchyOperationGroup]; - } else if([state isEqualToString: SecCKKSZoneKeyStateWaitForUnlock] || [state isEqualToString:SecCKKSZoneKeyStateReadyPendingUnlock]) { - // We're in a hold state: waiting for the keybag to unlock so we can reenter the key hierarchy state machine - // After the next unlock, poke ourselves - self.keyStateMachineOperation = [NSBlockOperation named:@"key-state-after-unlock" withBlock:^{ - __strong __typeof(self) strongSelf = weakSelf; - if(!strongSelf) { - return; - } - [strongSelf dispatchSyncWithAccountKeys:^bool{ - [strongSelf _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateInitialized withError:nil]; - return true; - }]; - }]; - [self.keyStateMachineOperation addNullableDependency: self.lockStateTracker.unlockDependency]; - + } else { + ckkserror("ckks", self, "asked to advance state machine to unknown state: %@", state); + self.keyHierarchyState = state; + [self _onqueueHandleKeyStateNonTransientDependency]; + return; } - // Handle the key state ready dependency - if([state isEqualToString:SecCKKSZoneKeyStateReady] || [state isEqualToString:SecCKKSZoneKeyStateReadyPendingUnlock]) { + // If we're in ready and not entering a non-ready state, we should activate the ready dependency. Otherwise, we should create it. + if(([state isEqualToString:SecCKKSZoneKeyStateReady] || [state isEqualToString:SecCKKSZoneKeyStateReadyPendingUnlock]) && + (nextState == nil || [nextState isEqualToString:SecCKKSZoneKeyStateReady] || [nextState isEqualToString:SecCKKSZoneKeyStateReadyPendingUnlock])) { + // Ready enough! + [[CKKSAnalytics logger] setDateProperty:[NSDate date] forKey:CKKSAnalyticsLastKeystateReady inView:self]; if(self.keyStateReadyDependency) { [self scheduleOperation: self.keyStateReadyDependency]; self.keyStateReadyDependency = nil; } // If there are any OQEs waiting to be encrypted, launch an op to fix them - if([outdatedOQEs count] > 0u) { + if(outdatedOQEs > 0) { ckksnotice("ckksreencrypt", self, "Reencrypting outgoing items as the key hierarchy is ready"); CKKSReencryptOutgoingItemsOperation* op = [[CKKSReencryptOutgoingItemsOperation alloc] initWithCKKSKeychainView:self ckoperationGroup:self.keyHierarchyOperationGroup]; [self scheduleOperation:op]; @@ -1048,32 +1118,154 @@ } } + NSAssert(!((self.keyStateMachineOperation != nil) && + (nextState != nil)), + @"Should have a machine operation or a next state, not both"); + // Start any operations, or log that we aren't if(self.keyStateMachineOperation) { [self scheduleOperation: self.keyStateMachineOperation]; + ckksnotice("ckkskey", self, "Now in key state: %@", state); + self.keyHierarchyState = state; - } else if([state isEqualToString:SecCKKSZoneKeyStateWaitForTLK]) { - ckksnotice("ckkskey", self, "Entering key state %@", state); } else if([state isEqualToString:SecCKKSZoneKeyStateError]) { ckksnotice("ckkskey", self, "Entering key state 'error'"); + self.keyHierarchyState = state; + + } else if(nextState == nil) { + ckksnotice("ckkskey", self, "Entering key state: %@", state); + self.keyHierarchyState = state; + + } else if(![state isEqualToString: nextState]) { + ckksnotice("ckkskey", self, "Staying in state %@, but proceeding to %@ as soon as possible", self.keyHierarchyState, nextState); + self.keyStateMachineOperation = [self operationToEnterState:nextState keyStateError:nextError named:@"next-key-state"]; + [self scheduleOperation: self.keyStateMachineOperation]; + } else { - // Nothing to do and not in a waiting state? Awesome; we must be in the ready state. + // Nothing to do and not in a waiting state? This is likely a bug, but, hey: pretend to be in ready! if(!([state isEqualToString:SecCKKSZoneKeyStateReady] || [state isEqualToString:SecCKKSZoneKeyStateReadyPendingUnlock])) { - ckksnotice("ckkskey", self, "No action to take in state %@; we must be ready.", state); - state = SecCKKSZoneKeyStateReady; + ckkserror("ckkskey", self, "No action to take in state %@; BUG, but: maybe we're ready?", state); + nextState = SecCKKSZoneKeyStateReady; + self.keyStateMachineOperation = [self operationToEnterState:nextState keyStateError:nil named:@"next-key-state"]; + [self scheduleOperation: self.keyStateMachineOperation]; + } + } + + [self _onqueueHandleKeyStateNonTransientDependency]; +} + +- (void)_onqueueHandleKeyStateNonTransientDependency { + dispatch_assert_queue(self.queue); + + if(CKKSKeyStateTransient(self.keyHierarchyState)) { + if(self.keyStateNonTransientDependency == nil || [self.keyStateNonTransientDependency isFinished]) { + self.keyStateNonTransientDependency = [self createKeyStateNontransientDependency]; + } + } else { + // Nontransient: go for it + if(self.keyStateNonTransientDependency) { + [self scheduleOperation: self.keyStateNonTransientDependency]; + self.keyStateNonTransientDependency = nil; + } + } +} + +- (NSOperation*)operationToEnterState:(CKKSZoneKeyState*)state keyStateError:(NSError* _Nullable)keyStateError named:(NSString*)name { + __weak __typeof(self) weakSelf = self; + + return [NSBlockOperation named:name withBlock:^{ + __strong __typeof(self) strongSelf = weakSelf; + if(!strongSelf) { + return; + } + [strongSelf dispatchSyncWithAccountKeys:^bool{ + [strongSelf _onqueueAdvanceKeyStateMachineToState:state withError:keyStateError]; + return true; + }]; + }]; +} + +- (bool)_onqueueOtherDevicesReportHavingTLKs:(CKKSCurrentKeySet*)keyset +{ + dispatch_assert_queue(self.queue); + + //Has there been any activity indicating that other trusted devices have keys in the past 45 days, or untrusted devices in the past 4? + // (We chose 4 as devices attempt to upload their device state every 3 days. If a device is unceremoniously kicked out of circle, we normally won't immediately reset.) + NSDate* now = [NSDate date]; + NSDateComponents* trustedOffset = [[NSDateComponents alloc] init]; + [trustedOffset setDay:-45]; + NSDate* trustedDeadline = [[NSCalendar currentCalendar] dateByAddingComponents:trustedOffset toDate:now options:0]; + + NSDateComponents* untrustedOffset = [[NSDateComponents alloc] init]; + [untrustedOffset setDay:-4]; + NSDate* untrustedDeadline = [[NSCalendar currentCalendar] dateByAddingComponents:untrustedOffset toDate:now options:0]; - self.keyHierarchyOperationGroup = nil; - if(self.keyStateReadyDependency) { - [self scheduleOperation: self.keyStateReadyDependency]; - self.keyStateReadyDependency = nil; + NSMutableSet* trustedPeerIDs = [NSMutableSet set]; + for(id peer in self.currentTrustedPeers) { + [trustedPeerIDs addObject:peer.peerID]; + } + + NSError* localerror = nil; + + NSArray* allDeviceStates = [CKKSDeviceStateEntry allInZone:self.zoneID error:&localerror]; + if(localerror) { + ckkserror("ckkskey", self, "Error fetching device states: %@", localerror); + localerror = nil; + return true; + } + for(CKKSDeviceStateEntry* device in allDeviceStates) { + if([trustedPeerIDs containsObject:device.circlePeerID]) { + // Is this a recent DSE? If it's older than the deadline, skip it + if([device.storedCKRecord.modificationDate compare:trustedDeadline] == NSOrderedAscending) { + ckksnotice("ckkskey", self, "Trusted device state (%@) is too old; ignoring", device); + continue; + } + } else { + // Device is untrusted. How does it fare with the untrustedDeadline? + if([device.storedCKRecord.modificationDate compare:untrustedDeadline] == NSOrderedAscending) { + ckksnotice("ckkskey", self, "Device (%@) is not trusted and from too long ago; ignoring device state (%@)", device.circlePeerID, device); + continue; + } else { + ckksnotice("ckkskey", self, "Device (%@) is not trusted, but very recent. Including in heuristic: %@", device.circlePeerID, device); } } + + if([device.keyState isEqualToString:SecCKKSZoneKeyStateReady] || + [device.keyState isEqualToString:SecCKKSZoneKeyStateReadyPendingUnlock]) { + ckksnotice("ckkskey", self, "Other device (%@) has keys; it should send them to us", device); + return true; + } } - ckksnotice("ckkskey", self, "Advancing to key state: %@", state); - self.keyHierarchyState = state; + + NSArray* tlkShares = [CKKSTLKShare allForUUID:keyset.currentTLKPointer.currentKeyUUID + zoneID:self.zoneID + error:&localerror]; + if(localerror) { + ckkserror("ckkskey", self, "Error fetching device states: %@", localerror); + localerror = nil; + return false; + } + + for(CKKSTLKShare* tlkShare in tlkShares) { + if([trustedPeerIDs containsObject:tlkShare.senderPeerID] && + [tlkShare.storedCKRecord.modificationDate compare:trustedDeadline] == NSOrderedDescending) { + ckksnotice("ckkskey", self, "Trusted TLK Share (%@) created recently; other devices have keys and should send them to us", tlkShare); + return true; + } + } + + // Okay, how about the untrusted deadline? + for(CKKSTLKShare* tlkShare in tlkShares) { + if([tlkShare.storedCKRecord.modificationDate compare:untrustedDeadline] == NSOrderedDescending) { + ckksnotice("ckkskey", self, "Untrusted TLK Share (%@) created very recently; other devices might have keys and should rejoin the circle (and send them to us)", tlkShare); + return true; + } + } + + return false; } -// For this key, who doesn't yet have a CKKSTLKShare for it? +// For this key, who doesn't yet have a valid CKKSTLKShare for it? // Note that we really want a record sharing the TLK to ourselves, so this function might return // a non-empty set even if all peers have the TLK: it wants us to make a record for ourself. - (NSSet>*)_onqueueFindPeersMissingShare:(CKKSKey*)key error:(NSError* __autoreleasing*)error { @@ -1125,12 +1317,22 @@ // Determine if we think this peer has enough things shared to them bool alreadyShared = false; for(CKKSTLKShare* existingPeerShare in currentPeerShares) { + // If an SOS Peer sent this share, is its signature still valid? Or did the signing key change? + if([existingPeerShare.senderPeerID hasPrefix:CKKSSOSPeerPrefix]) { + NSError* signatureError = nil; + if(![existingPeerShare signatureVerifiesWithPeerSet:self.currentTrustedPeers error:&signatureError]) { + ckksnotice("ckksshare", self, "Existing TLKShare's signature doesn't verify with current peer set: %@ %@", signatureError, existingPeerShare); + continue; + } + } + if([existingPeerShare.tlkUUID isEqualToString: key.uuid] && [trustedPeerIDs containsObject:existingPeerShare.senderPeerID]) { // Was this shared to us? if([peer.peerID isEqualToString: self.currentSelfPeers.currentSelf.peerID]) { - // We only count this as 'found' if we did the sharing - if([existingPeerShare.senderPeerID isEqualToString:self.currentSelfPeers.currentSelf.peerID]) { + // We only count this as 'found' if we did the sharing and it's to our current keys + if([existingPeerShare.senderPeerID isEqualToString:self.currentSelfPeers.currentSelf.peerID] && + [existingPeerShare.receiver.publicEncryptionKey isEqual:self.currentSelfPeers.currentSelf.publicEncryptionKey]) { ckksnotice("ckksshare", self, "Local peer %@ is shared %@ via self: %@", peer, key, existingPeerShare); alreadyShared = true; } else { @@ -1138,16 +1340,23 @@ } } else { - // Some other peer has a trusted share. Cool! - ckksnotice("ckksshare", self, "Peer %@ is shared %@ via trusted %@", peer, key, existingPeerShare); - alreadyShared = true; + // Was this shared to the remote peer's current keys? + if([peer.publicEncryptionKey isEqual: existingPeerShare.receiver.publicEncryptionKey]) { + // Some other peer has a trusted share. Cool! + ckksnotice("ckksshare", self, "Peer %@ is shared %@ via trusted %@", peer, key, existingPeerShare); + alreadyShared = true; + } else { + ckksnotice("ckksshare", self, "Peer %@ has a share for %@, but to old keys: %@", peer, key, existingPeerShare); + } } } } if(!alreadyShared) { - // Add this peer to our set - [peersMissingShares addObject:peer]; + // Add this peer to our set, if it has an encryption key to receive the share + if(peer.publicEncryptionKey) { + [peersMissingShares addObject:peer]; + } } } @@ -1193,6 +1402,11 @@ } for(id peer in remainingPeers) { + if(!peer.publicEncryptionKey) { + ckksnotice("ckksshare", self, "No need to make TLK for %@; they don't have any encryption keys", peer); + continue; + } + // Create a share for this peer. ckksnotice("ckksshare", self, "Creating share of %@ as %@ for %@", key, self.currentSelfPeers.currentSelf, peer); CKKSTLKShare* newShare = [CKKSTLKShare share:key @@ -1303,6 +1517,9 @@ if(localerror && [self.lockStateTracker isLockedError: localerror]) { ckkserror("ckkskey", self, "Couldn't find missing TLK shares due to lock state: %@", localerror); probablyOkIfUnlocked = true; + } else if([localerror.domain isEqualToString:CKKSErrorDomain] && localerror.code == CKKSNoPeersAvailable) { + ckkserror("ckkskey", self, "Couldn't find missing TLK shares due to missing peers, likely due to lock state: %@", localerror); + probablyOkIfUnlocked = true; } else if(localerror) { if(error) { @@ -1480,13 +1697,12 @@ // We don't want to fix it up here, in the closing moments of a transaction if([error.domain isEqualToString:CKKSErrorDomain] && error.code == CKKSNoUUIDOnItem) { ckksnotice("ckks", self, "Launching scan operation to find UUID"); - CKKSScanLocalItemsOperation* scanOperation = [[CKKSScanLocalItemsOperation alloc] initWithCKKSKeychainView: self ckoperationGroup:operationGroup]; - [self scheduleOperation: scanOperation]; + [self scanLocalItems:@"uuid-find-scan" ckoperationGroup:operationGroup after:nil]; } // If the problem is 'couldn't load key', tell the key hierarchy state machine to fix it if([error.domain isEqualToString:CKKSErrorDomain] && error.code == errSecItemNotFound) { - [self _onqueueAdvanceKeyStateMachineToState: nil withError: nil]; + [self.pokeKeyStateMachineScheduler trigger]; } return true; @@ -1543,11 +1759,11 @@ }]; } --(void)setCurrentItemForAccessGroup:(SecDbItemRef)newItem +-(void)setCurrentItemForAccessGroup:(NSData* _Nonnull)newItemPersistentRef hash:(NSData*)newItemSHA1 accessGroup:(NSString*)accessGroup identifier:(NSString*)identifier - replacing:(SecDbItemRef)oldItem + replacing:(NSData* _Nullable)oldCurrentItemPersistentRef hash:(NSData*)oldItemSHA1 complete:(void (^) (NSError* operror)) complete { @@ -1560,104 +1776,52 @@ return; } - __weak __typeof(self) weakSelf = self; - - [self dispatchSync:^bool { - NSError* error = nil; - CFErrorRef cferror = NULL; - - NSString* newItemUUID = nil; - NSString* oldItemUUID = nil; - - // Now that we're on the db queue, ensure that the given hashes for the items match the hashes as they are now. - // That is, the items haven't changed since the caller knew about the item. - NSData* newItemComputedSHA1 = (NSData*) CFBridgingRelease(CFRetainSafe(SecDbItemGetSHA1(newItem, &cferror))); - if(!newItemComputedSHA1 || cferror || - ![newItemComputedSHA1 isEqual:newItemSHA1]) { - ckksnotice("ckkscurrent", self, "Hash mismatch for new item: %@ vs %@", newItemComputedSHA1, newItemSHA1); - error = [NSError errorWithDomain:CKKSErrorDomain - code:CKKSItemChanged - description:@"New item has changed; hashes mismatch. Refetch and try again."]; - complete(error); - CFReleaseNull(cferror); - return false; - } + // Not being in a CloudKit account is an automatic failure. + // But, wait a good long while for the CloudKit account state to be known (in the case of daemon startup) + [self.accountStateKnown wait:(SecCKKSTestsEnabled() ? 1*NSEC_PER_SEC : 30*NSEC_PER_SEC)]; - newItemUUID = (NSString*) CFBridgingRelease(CFRetainSafe(SecDbItemGetValue(newItem, &v10itemuuid, &cferror))); - if(!newItemUUID || cferror) { - ckkserror("ckkscurrent", self, "Error fetching UUID for new item: %@", cferror); - complete((__bridge NSError*) cferror); - CFReleaseNull(cferror); - return false; - } + if(self.accountStatus != CKKSAccountStatusAvailable) { + NSError* error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSNotLoggedIn + description:@"User is not signed into iCloud."]; + ckksnotice("ckkscurrent", self, "Rejecting current item pointer set since we don't have an iCloud account."); + complete(error); + return; + } - // We pass this into the change operation. If it's nil, that's an indicator that the old item doesn't exist in the keychain anymore - NSData* oldItemComputedSHA1 = nil; - if(oldItem) { - oldItemComputedSHA1 = (NSData*) CFBridgingRelease(CFRetainSafe(SecDbItemGetSHA1(oldItem, &cferror))); - if(!oldItemComputedSHA1 || cferror || - ![oldItemComputedSHA1 isEqual:oldItemSHA1]) { - ckksnotice("ckkscurrent", self, "Hash mismatch for old item: %@ vs %@", oldItemComputedSHA1, oldItemSHA1); - error = [NSError errorWithDomain:CKKSErrorDomain - code:CKKSItemChanged - description:@"Old item has changed; hashes mismatch. Refetch and try again."]; - complete(error); - CFReleaseNull(cferror); - return false; - } + ckksnotice("ckkscurrent", self, "Starting change current pointer operation for %@-%@", accessGroup, identifier); + CKKSUpdateCurrentItemPointerOperation* ucipo = [[CKKSUpdateCurrentItemPointerOperation alloc] initWithCKKSKeychainView:self + newItem:newItemPersistentRef + hash:newItemSHA1 + accessGroup:accessGroup + identifier:identifier + replacing:oldCurrentItemPersistentRef + hash:oldItemSHA1 + ckoperationGroup:[CKOperationGroup CKKSGroupWithName:@"currentitem-api"]]; - oldItemUUID = (NSString*) CFBridgingRelease(CFRetainSafe(SecDbItemGetValue(oldItem, &v10itemuuid, &cferror))); - if(!oldItemUUID || cferror) { - ckkserror("ckkscurrent", self, "Error fetching UUID for old item: %@", cferror); - complete((__bridge NSError*) cferror); - CFReleaseNull(cferror); - return false; - } - } + __weak __typeof(self) weakSelf = self; + CKKSResultOperation* returnCallback = [CKKSResultOperation operationWithBlock:^{ + __strong __typeof(self) strongSelf = weakSelf; - // Not being in a CloudKit account is an automatic failure. - if(self.accountStatus != CKKSAccountStatusAvailable) { - ckksnotice("ckkscurrent", self, "Rejecting current item pointer set since we don't have an iCloud account."); - error = [NSError errorWithDomain:CKKSErrorDomain - code:CKKSNotLoggedIn - description:@"User is not signed into iCloud."]; - complete(error); - return false; + if(ucipo.error) { + ckkserror("ckkscurrent", strongSelf, "Failed setting a current item pointer for %@ with %@", ucipo.currentPointerIdentifier, ucipo.error); + } else { + ckksnotice("ckkscurrent", strongSelf, "Finished setting a current item pointer for %@", ucipo.currentPointerIdentifier); } + complete(ucipo.error); + }]; + returnCallback.name = @"setCurrentItem-return-callback"; + [returnCallback addDependency: ucipo]; + [self scheduleOperation: returnCallback]; - // At this point, we've completed all the checks we need for the SecDbItems. Try to launch this boat! - NSString* currentIdentifier = [NSString stringWithFormat:@"%@-%@", accessGroup, identifier]; - ckksnotice("ckkscurrent", self, "Setting current pointer for %@ to %@ (from %@)", currentIdentifier, newItemUUID, oldItemUUID); - CKKSUpdateCurrentItemPointerOperation* ucipo = [[CKKSUpdateCurrentItemPointerOperation alloc] initWithCKKSKeychainView:self - currentPointer:(NSString*)currentIdentifier - oldItemUUID:(NSString*)oldItemUUID - oldItemHash:oldItemComputedSHA1 - newItemUUID:(NSString*)newItemUUID - ckoperationGroup:[CKOperationGroup CKKSGroupWithName:@"currentitem-api"]]; - CKKSResultOperation* returnCallback = [CKKSResultOperation operationWithBlock:^{ - __strong __typeof(self) strongSelf = weakSelf; - - if(ucipo.error) { - ckkserror("ckkscurrent", strongSelf, "Failed setting a current item pointer for %@ with %@", currentIdentifier, ucipo.error); - } else { - ckksnotice("ckkscurrent", strongSelf, "Finished setting a current item pointer for %@", currentIdentifier); - } - complete(ucipo.error); - }]; - returnCallback.name = @"setCurrentItem-return-callback"; - [returnCallback addDependency: ucipo]; - [self scheduleOperation: returnCallback]; - - // Now, schedule ucipo. It modifies the CloudKit zone, so it should insert itself into the list of OutgoingQueueOperations. - // Then, we won't have simultaneous zone-modifying operations. - [ucipo linearDependencies:self.outgoingQueueOperations]; + // Now, schedule ucipo. It modifies the CloudKit zone, so it should insert itself into the list of OutgoingQueueOperations. + // Then, we won't have simultaneous zone-modifying operations. + [ucipo linearDependencies:self.outgoingQueueOperations]; - // If this operation hasn't started within 60 seconds, cancel it and return a "timed out" error. - [ucipo timeout:60*NSEC_PER_SEC]; + // If this operation hasn't started within 60 seconds, cancel it and return a "timed out" error. + [ucipo timeout:60*NSEC_PER_SEC]; - [self scheduleOperation:ucipo]; - return true; - }]; + [self scheduleOperation:ucipo]; return; } @@ -1675,6 +1839,9 @@ } // Not being in a CloudKit account is an automatic failure. + // But, wait a good long while for the CloudKit account state to be known (in the case of daemon startup) + [self.accountStateKnown wait:(SecCKKSTestsEnabled() ? 1*NSEC_PER_SEC : 30*NSEC_PER_SEC)]; + if(self.accountStatus != CKKSAccountStatusAvailable) { ckksnotice("ckkscurrent", self, "Rejecting current item pointer get since we don't have an iCloud account."); complete(NULL, [NSError errorWithDomain:CKKSErrorDomain @@ -1839,8 +2006,6 @@ [op addNullableDependency:self.outgoingQueueOperationScheduler.operationDependency]; [self.outgoingQueueOperationScheduler trigger]; - [op addNullableDependency: self.initialScanOperation]; - [self scheduleOperation: op]; ckksnotice("ckksoutgoing", self, "Scheduled %@", op); return op; @@ -1893,31 +2058,37 @@ return op; } +- (CKKSScanLocalItemsOperation*)scanLocalItems:(NSString*)operationName { + return [self scanLocalItems:operationName ckoperationGroup:nil after:nil]; +} + +- (CKKSScanLocalItemsOperation*)scanLocalItems:(NSString*)operationName ckoperationGroup:(CKOperationGroup*)operationGroup after:(NSOperation*)after { + CKKSScanLocalItemsOperation* scanOperation = [[CKKSScanLocalItemsOperation alloc] initWithCKKSKeychainView:self ckoperationGroup:operationGroup]; + scanOperation.name = operationName; + + [scanOperation addNullableDependency:self.lastFixupOperation]; + [scanOperation addNullableDependency:self.lockStateTracker.unlockDependency]; + [scanOperation addNullableDependency:self.keyStateReadyDependency]; + [scanOperation addNullableDependency:after]; + + [self scheduleOperation: scanOperation]; + return scanOperation; +} + - (CKKSUpdateDeviceStateOperation*)updateDeviceState:(bool)rateLimit waitForKeyHierarchyInitialization:(uint64_t)timeout ckoperationGroup:(CKOperationGroup*)ckoperationGroup { + __weak __typeof(self) weakSelf = self; // If securityd just started, the key state might be in some transient early state. Wait a bit. CKKSResultOperation* waitForKeyReady = [CKKSResultOperation named:@"device-state-wait" withBlock:^{ __strong __typeof(self) strongSelf = weakSelf; - __block bool wait = timeout > 0; - if(!wait) { - return; - } - - // Determine if we're in an initializing state. Otherwise, don't bother waiting. - [strongSelf dispatchSync:^bool { - wait = [strongSelf.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateInitializing] || - [strongSelf.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateInitialized]; - return false; - }]; - - if(wait) { - [strongSelf.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:timeout]; - } - ckksnotice("ckksdevice", strongSelf, "Finished waiting for key hierarchy state, currently %@", strongSelf.keyHierarchyState); + ckksnotice("ckksdevice", strongSelf, "Finished waiting for key hierarchy transient state, currently %@", strongSelf.keyHierarchyState); }]; + + [waitForKeyReady addNullableDependency:self.keyStateNonTransientDependency]; + [waitForKeyReady timeout:timeout]; [self.waitingQueue addOperation:waitForKeyReady]; CKKSUpdateDeviceStateOperation* op = [[CKKSUpdateDeviceStateOperation alloc] initWithCKKSKeychainView:self rateLimit:rateLimit ckoperationGroup:ckoperationGroup]; @@ -2014,8 +2185,16 @@ ckkserror("ckksdevice", self, "No peer ID available"); } + // Reset the last unlock time to 'day' granularity in UTC + NSCalendar* calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierISO8601]; + calendar.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; + NSDate* lastUnlockDay = self.lockStateTracker.lastUnlockTime; + lastUnlockDay = lastUnlockDay ? [calendar startOfDayForDate:lastUnlockDay] : nil; + // We only really want the oldcdse for its encodedCKRecord, so make a new cdse here CKKSDeviceStateEntry* newcdse = [[CKKSDeviceStateEntry alloc] initForDevice:accountTracker.ckdeviceID + osVersion:SecCKKSHostOSVersion() + lastUnlockTime:lastUnlockDay circlePeerID:accountTracker.accountCirclePeerID circleStatus:accountTracker.currentCircleStatus keyState:self.keyHierarchyState @@ -2656,48 +2835,92 @@ if(![proposedTLK wrapsSelf]) { ckkserror("ckksshare", self, "Potential TLK %@ does not wrap self; skipping TLK share checking", proposedTLK); } else { - if(!self.currentSelfPeers.currentSelf || self.currentSelfPeersError) { - ckkserror("ckksshare", self, "Couldn't fetch self peers: %@", self.currentSelfPeersError); - if(error) { - *error = self.currentSelfPeersError; + bool tlkShares = [self _onqueueWithAccountKeysCheckTLKFromShares:proposedTLK error:&localerror]; + // We only want to error out if a positive error occurred. "No shares" is okay. + if(!tlkShares || localerror) { + bool noTrustedTLKShares = [localerror.domain isEqualToString:CKKSErrorDomain] && localerror.code == CKKSNoTrustedTLKShares; + bool noSelfPeer = [localerror.domain isEqualToString:CKKSErrorDomain] && localerror.code == CKKSNoEncryptionKey; + + // If this error was something worse than 'couldn't unwrap for reasons including there not being data', report it + if(!(noTrustedTLKShares || noSelfPeer)) { + if(error) { + *error = localerror; + } + ckkserror("ckksshare", self, "Errored unwrapping TLK with TLKShares: %@", localerror); + return false; + } else { + ckkserror("ckksshare", self, "Non-fatal error unwrapping TLK with TLKShares: %@", localerror); } - return false; } + } - if(!self.currentTrustedPeers || self.currentTrustedPeersError) { - ckkserror("ckksshare", self, "Couldn't fetch trusted peers: %@", self.currentTrustedPeersError); - if(error) { - *error = self.currentTrustedPeersError; + if([proposedTLK loadKeyMaterialFromKeychain:error]) { + // Hurray! + return true; + } else { + return false; + } +} + +// This version only examines if this TLK is recoverable from TLK shares +- (bool)_onqueueWithAccountKeysCheckTLKFromShares:(CKKSKey*)proposedTLK error:(NSError* __autoreleasing *)error { + NSError* localerror = NULL; + if(!self.currentSelfPeers.currentSelf || self.currentSelfPeersError) { + ckkserror("ckksshare", self, "Couldn't fetch self peers: %@", self.currentSelfPeersError); + if(error) { + if([self.lockStateTracker isLockedError:self.currentSelfPeersError]) { + // Locked error should propagate + *error = self.currentSelfPeersError; + } else { + *error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSNoEncryptionKey + description:@"No current self peer" + underlying:self.currentSelfPeersError]; } - return false; } + return false; + } + + if(!self.currentTrustedPeers || self.currentTrustedPeersError) { + ckkserror("ckksshare", self, "Couldn't fetch trusted peers: %@", self.currentTrustedPeersError); + if(error) { + *error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSNoPeersAvailable + description:@"No trusted peers" + underlying:self.currentTrustedPeersError]; + } + return false; + } + + NSError* lastShareError = nil; - NSArray* possibleShares = [CKKSTLKShare allFor:self.currentSelfPeers.currentSelf.peerID + for(id selfPeer in self.currentSelfPeers.allSelves) { + NSArray* possibleShares = [CKKSTLKShare allFor:selfPeer.peerID keyUUID:proposedTLK.uuid zoneID:self.zoneID error:&localerror]; if(localerror) { - ckkserror("ckksshare", self, "Error fetching CKKSTLKShares: %@", localerror); + ckkserror("ckksshare", self, "Error fetching CKKSTLKShares for %@: %@", selfPeer, localerror); } if(possibleShares.count == 0) { - ckksnotice("ckksshare", self, "No CKKSTLKShares for %@", proposedTLK); + ckksnotice("ckksshare", self, "No CKKSTLKShares to %@ for %@", selfPeer, proposedTLK); + continue; } for(CKKSTLKShare* possibleShare in possibleShares) { NSError* possibleShareError = nil; - ckksnotice("ckksshare", self, "Checking possible TLK share %@ as %@", - possibleShare, self.currentSelfPeers.currentSelf); + ckksnotice("ckksshare", self, "Checking possible TLK share %@ as %@", possibleShare, selfPeer); - CKKSKey* possibleKey = [possibleShare recoverTLK:self.currentSelfPeers.currentSelf + CKKSKey* possibleKey = [possibleShare recoverTLK:selfPeer trustedPeers:self.currentTrustedPeers error:&possibleShareError]; if(possibleShareError) { ckkserror("ckksshare", self, "Unable to unwrap TLKShare(%@) as %@: %@", - possibleShare, self.currentSelfPeers.currentSelf, possibleShareError); + possibleShare, selfPeer, possibleShareError); ckkserror("ckksshare", self, "Current trust set: %@", self.currentTrustedPeers); - // TODO: save error + lastShareError = possibleShareError; continue; } @@ -2705,16 +2928,16 @@ if(possibleShareError) { ckkserror("ckksshare", self, "Unwrapped TLKShare(%@) does not unwrap proposed TLK(%@) as %@: %@", possibleShare, proposedTLK, self.currentSelfPeers.currentSelf, possibleShareError); - // TODO save error + lastShareError = possibleShareError; continue; } if(result) { ckksnotice("ckksshare", self, "TLKShare(%@) unlocked TLK(%@) as %@", - possibleShare, proposedTLK, self.currentSelfPeers.currentSelf); + possibleShare, proposedTLK, selfPeer); // The proposed TLK is trusted key material. Persist it as a "trusted" key. - [proposedTLK saveKeyMaterialToKeychain:true error: &possibleShareError]; + [proposedTLK saveKeyMaterialToKeychain:true error:&possibleShareError]; if(possibleShareError) { ckkserror("ckksshare", self, "Couldn't store the new TLK(%@) to the keychain: %@", proposedTLK, possibleShareError); if(error) { @@ -2728,21 +2951,13 @@ } } - if([proposedTLK loadKeyMaterialFromKeychain:error]) { - // Hurray! - return true; - } else { - return false; + if(error) { + *error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSNoTrustedTLKShares + description:[NSString stringWithFormat:@"No trusted TLKShares for %@", proposedTLK] + underlying:lastShareError]; } -} - -- (void) dispatchAsync: (bool (^)(void)) block { - // We need to call kc_with_dbt, which blocks. Route up through a global queue... - __weak __typeof(self) weakSelf = self; - - dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ - [weakSelf dispatchSync:block]; - }); + return false; } - (bool)dispatchSyncWithConnection:(SecDbConnectionRef _Nonnull)dbconn block:(bool (^)(void))block { @@ -2768,6 +2983,10 @@ - (void)dispatchSync: (bool (^)(void)) block { // important enough to block this thread. Must get a connection first, though! + + // Please don't jetsam us... + os_transaction_t transaction = os_transaction_create([[NSString stringWithFormat:@"com.apple.securityd.ckks.%@", self.zoneName] UTF8String]); + CFErrorRef cferror = NULL; kc_with_dbt(true, &cferror, ^bool (SecDbConnectionRef dbt) { return [self dispatchSyncWithConnection:dbt block:block]; @@ -2775,11 +2994,13 @@ if(cferror) { ckkserror("ckks", self, "error getting database connection, major problems ahead: %@", cferror); } + + (void)transaction; } - (void)dispatchSyncWithAccountKeys:(bool (^)(void))block { - [SOSAccount performOnAccountQueue: ^{ + [SOSAccount performOnQuietAccountQueue: ^{ NSError* selfPeersError = nil; CKKSSelves* currentSelfPeers = [self.currentPeerProvider fetchSelfPeers:&selfPeersError]; @@ -2817,18 +3038,33 @@ [self fetchAndProcessCKChanges:CKKSFetchBecauseAPNS]; } +- (void)superHandleCKLogin { + [super handleCKLogin]; +} + - (void)handleCKLogin { ckksnotice("ckks", self, "received a notification of CK login"); + if(!SecCKKSIsEnabled()) { + ckksnotice("ckks", self, "Skipping CloudKit initialization due to disabled CKKS"); + return; + } __weak __typeof(self) weakSelf = self; CKKSResultOperation* login = [CKKSResultOperation named:@"ckks-login" withBlock:^{ __strong __typeof(self) strongSelf = weakSelf; - [strongSelf dispatchSync:^bool{ - strongSelf.accountStatus = CKKSAccountStatusAvailable; - [strongSelf _onqueueHandleCKLogin]; + [strongSelf dispatchSyncWithAccountKeys:^bool{ + [strongSelf superHandleCKLogin]; + + // Reset key hierarchy state machine to initializing + [strongSelf _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateInitializing withError:nil]; return true; }]; + + // Change our condition variables to reflect that we think we're logged in + strongSelf.loggedOut = [[CKKSCondition alloc] initToChain:strongSelf.loggedOut]; + [strongSelf.loggedIn fulfill]; + [strongSelf.accountStateKnown fulfill]; }]; [self scheduleAccountStatusOperation:login]; @@ -2855,15 +3091,18 @@ ckkserror("ckks", strongSelf, "error while resetting local data: %@", error); } + [self _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateLoggedOut withError:nil]; + + strongSelf.loggedIn = [[CKKSCondition alloc] initToChain: strongSelf.loggedIn]; + [strongSelf.loggedOut fulfill]; + [strongSelf.accountStateKnown fulfill]; + // Tell all pending sync clients that we don't expect to ever sync for(NSString* callbackUUID in strongSelf.pendingSyncCallbacks.allKeys) { [strongSelf callSyncCallbackWithErrorNoAccount:strongSelf.pendingSyncCallbacks[callbackUUID]]; strongSelf.pendingSyncCallbacks[callbackUUID] = nil; } - strongSelf.loggedIn = [[CKKSCondition alloc] initToChain: strongSelf.loggedIn]; - [strongSelf.loggedOut fulfill]; - return true; }]; }]; @@ -2901,7 +3140,6 @@ if(isChangeTokenExpiredError) { ckkserror("ckks", self, "Received notice that our change token is out of date. Resetting local data..."); - [self cancelAllOperations]; CKKSResultOperation* resetOp = [self resetLocalData]; CKKSResultOperation* resetHandler = [CKKSResultOperation named:@"local-reset-handler" withBlock:^{ __strong __typeof(self) strongSelf = weakSelf; @@ -2911,10 +3149,9 @@ } if(resetOp.error) { - ckksnotice("ckks", strongSelf, "CloudKit-inspired local reset of %@ ended with error: %@", strongSelf.zoneID, error); + ckksnotice("ckksreset", strongSelf, "CloudKit-inspired local reset of %@ ended with error: %@", strongSelf.zoneID, error); } else { - ckksnotice("ckksreset", strongSelf, "re-initializing zone %@", strongSelf.zoneID); - [self.initializeScheduler trigger]; + ckksnotice("ckksreset", strongSelf, "CloudKit-inspired local reset of %@ ended successfully", strongSelf.zoneID); } }]; @@ -2936,9 +3173,8 @@ } if(isDeletedZoneError) { - ckkserror("ckks", self, "Received notice that our zone does not exist. Resetting all data."); - [self cancelAllOperations]; - CKKSResultOperation* resetOp = [self resetCloudKitZone]; + ckkserror("ckks", self, "Received notice that our zone does not exist. Resetting local data."); + CKKSResultOperation* resetOp = [self resetLocalData]; CKKSResultOperation* resetHandler = [CKKSResultOperation named:@"reset-handler" withBlock:^{ __strong __typeof(self) strongSelf = weakSelf; if(!strongSelf) { @@ -2947,7 +3183,9 @@ } if(resetOp.error) { - ckksnotice("ckksreset", strongSelf, "CloudKit-inspired zone reset of %@ ended with error: %@", strongSelf.zoneID, resetOp.error); + ckksnotice("ckksreset", strongSelf, "CloudKit-inspired local reset of %@ ended with error: %@", strongSelf.zoneID, resetOp.error); + } else { + ckksnotice("ckksreset", strongSelf, "CloudKit-inspired local reset of %@ ended successfully", strongSelf.zoneID); } }]; @@ -3004,24 +3242,33 @@ } } +- (void)cancelPendingOperations { + @synchronized(self.outgoingQueueOperations) { + for(NSOperation* op in self.outgoingQueueOperations) { + [op cancel]; + } + [self.outgoingQueueOperations removeAllObjects]; + } + + @synchronized(self.incomingQueueOperations) { + for(NSOperation* op in self.incomingQueueOperations) { + [op cancel]; + } + [self.incomingQueueOperations removeAllObjects]; + } + + [super cancelAllOperations]; +} + - (void)cancelAllOperations { [self.zoneSetupOperation cancel]; [self.keyStateMachineOperation cancel]; [self.keyStateReadyDependency cancel]; + [self.keyStateNonTransientDependency cancel]; [self.zoneChangeFetcher cancel]; [self.notifyViewChangedScheduler cancel]; - for(NSOperation* op in self.outgoingQueueOperations) { - [op cancel]; - } - [self.outgoingQueueOperations removeAllObjects]; - - for(NSOperation* op in self.incomingQueueOperations) { - [op cancel]; - } - [self.incomingQueueOperations removeAllObjects]; - - [super cancelAllOperations]; + [self cancelPendingOperations]; [self dispatchSync:^bool{ [self _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateCancelled withError: nil]; @@ -3044,10 +3291,11 @@ CKKSManifest* manifest = [CKKSManifest latestTrustedManifestForZone:self.zoneName error:&error]; [self dispatchSync: ^bool { - NSString* uuidTLK = [CKKSKey currentKeyForClass:SecCKKSKeyClassTLK zoneID:self.zoneID error:&error].uuid; - NSString* uuidClassA = [CKKSKey currentKeyForClass:SecCKKSKeyClassA zoneID:self.zoneID error:&error].uuid; - NSString* uuidClassC = [CKKSKey currentKeyForClass:SecCKKSKeyClassC zoneID:self.zoneID error:&error].uuid; - + CKKSCurrentKeySet* keyset = [[CKKSCurrentKeySet alloc] initForZone:self.zoneID]; + if(keyset.error) { + error = keyset.error; + } + NSString* manifestGeneration = manifest ? [NSString stringWithFormat:@"%lu", (unsigned long)manifest.generationCount] : nil; if(error) { @@ -3063,7 +3311,7 @@ [mutDeviceStates addObject: [obj description]]; }]; - NSArray* tlkShares = [CKKSTLKShare allForUUID:uuidTLK zoneID:self.zoneID error:&error]; + NSArray* tlkShares = [CKKSTLKShare allForUUID:keyset.currentTLKPointer.currentKeyUUID zoneID:self.zoneID error:&error]; NSMutableArray* mutTLKShares = [[NSMutableArray alloc] init]; [tlkShares enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { [mutTLKShares addObject: [obj description]]; @@ -3079,7 +3327,6 @@ @"lockstatetracker": stringify(self.lockStateTracker), @"accounttracker": stringify(self.accountTracker), @"fetcher": stringify(self.zoneChangeFetcher), - @"setup": boolstr([self.viewSetupOperation isFinished]), @"zoneCreated": boolstr(self.zoneCreated), @"zoneCreatedError": stringify(self.zoneCreatedError), @"zoneSubscribed": boolstr(self.zoneSubscribed), @@ -3088,20 +3335,22 @@ @"keystate": CKKSNilToNSNull(self.keyHierarchyState), @"keyStateError": stringify(self.keyHierarchyError), @"statusError": stringify(error), - @"oqe": CKKSNilToNSNull([CKKSOutgoingQueueEntry countsByState:self.zoneID error:&error]), - @"iqe": CKKSNilToNSNull([CKKSIncomingQueueEntry countsByState:self.zoneID error:&error]), + @"oqe": CKKSNilToNSNull([CKKSOutgoingQueueEntry countsByStateInZone:self.zoneID error:&error]), + @"iqe": CKKSNilToNSNull([CKKSIncomingQueueEntry countsByStateInZone:self.zoneID error:&error]), @"ckmirror": CKKSNilToNSNull([CKKSMirrorEntry countsByParentKey:self.zoneID error:&error]), @"devicestates": CKKSNilToNSNull(mutDeviceStates), @"tlkshares": CKKSNilToNSNull(mutTLKShares), @"keys": CKKSNilToNSNull([CKKSKey countsByClass:self.zoneID error:&error]), - @"currentTLK": CKKSNilToNSNull(uuidTLK), - @"currentClassA": CKKSNilToNSNull(uuidClassA), - @"currentClassC": CKKSNilToNSNull(uuidClassC), + @"currentTLK": CKKSNilToNSNull(keyset.tlk.uuid), + @"currentClassA": CKKSNilToNSNull(keyset.classA.uuid), + @"currentClassC": CKKSNilToNSNull(keyset.classC.uuid), + @"currentTLKPtr": CKKSNilToNSNull(keyset.currentTLKPointer.currentKeyUUID), + @"currentClassAPtr": CKKSNilToNSNull(keyset.currentClassAPointer.currentKeyUUID), + @"currentClassCPtr": CKKSNilToNSNull(keyset.currentClassCPointer.currentKeyUUID), @"currentManifestGen": CKKSNilToNSNull(manifestGeneration), @"zoneSetupOperation": stringify(self.zoneSetupOperation), - @"viewSetupOperation": stringify(self.viewSetupOperation), @"keyStateOperation": stringify(self.keyStateMachineOperation), @"lastIncomingQueueOperation": stringify(self.lastIncomingQueueOperation), @"lastNewTLKOperation": stringify(self.lastNewTLKOperation), diff --git a/keychain/ckks/CKKSLocalSynchronizeOperation.m b/keychain/ckks/CKKSLocalSynchronizeOperation.m index 5d14ba1c..88cc6a98 100644 --- a/keychain/ckks/CKKSLocalSynchronizeOperation.m +++ b/keychain/ckks/CKKSLocalSynchronizeOperation.m @@ -27,6 +27,7 @@ #import "keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.h" #import "keychain/ckks/CKKSScanLocalItemsOperation.h" #import "keychain/ckks/CKKSMirrorEntry.h" +#import "keychain/ckks/CKKSIncomingQueueEntry.h" #import "keychain/ckks/CloudKitCategories.h" #if OCTAGON @@ -123,7 +124,13 @@ return; } - if(scan.recordsFound > 0) { + NSError* error = nil; + NSArray* iqes = [CKKSIncomingQueueEntry allUUIDs:ckks.zoneID error:&error]; + if(error) { + ckkserror("ckksresync", ckks, "Couldn't fetch IQEs: %@", error); + } + + if(scan.recordsFound > 0 || iqes.count > 0) { if(strongSelf.restartCount >= 3) { // we've restarted too many times. Fail and stop. ckkserror("ckksresync", ckks, "restarted synchronization too often; Failing"); diff --git a/keychain/ckks/CKKSLockStateTracker.h b/keychain/ckks/CKKSLockStateTracker.h index 0780a2a7..502ac6f6 100644 --- a/keychain/ckks/CKKSLockStateTracker.h +++ b/keychain/ckks/CKKSLockStateTracker.h @@ -25,8 +25,17 @@ #import +@protocol CKKSLockStateNotification +- (void)lockStateChangeNotification:(bool)unlocked; +@end + +NS_ASSUME_NONNULL_BEGIN + @interface CKKSLockStateTracker : NSObject -@property NSOperation* unlockDependency; +@property (nullable) NSOperation* unlockDependency; +@property (readonly) bool isLocked; + +@property (readonly,nullable) NSDate* lastUnlockTime; - (instancetype)init; @@ -36,8 +45,11 @@ // Check if this error code is related to keybag is locked and we should retry later - (bool)isLockedError:(NSError*)error; +-(void)addLockStateObserver:(id)object; + // Ask AKS if the user's keybag is locked + (bool)queryAKSLocked; @end +NS_ASSUME_NONNULL_END #endif // OCTAGON diff --git a/keychain/ckks/CKKSLockStateTracker.m b/keychain/ckks/CKKSLockStateTracker.m index 49680e8d..a0e5b828 100644 --- a/keychain/ckks/CKKSLockStateTracker.m +++ b/keychain/ckks/CKKSLockStateTracker.m @@ -28,13 +28,18 @@ #include #import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSResultOperation.h" #import "keychain/ckks/CKKSGroupOperation.h" #import "keychain/ckks/CKKSLockStateTracker.h" @interface CKKSLockStateTracker () -@property bool isLocked; +@property (readwrite) bool isLocked; @property dispatch_queue_t queue; @property NSOperationQueue* operationQueue; +@property NSHashTable> *observers; + +@property (nullable) NSDate* lastUnlockedTime; + @end @implementation CKKSLockStateTracker @@ -45,6 +50,7 @@ _operationQueue = [[NSOperationQueue alloc] init]; _isLocked = true; + _observers = [NSHashTable weakObjectsHashTable]; [self resetUnlockDependency]; __weak __typeof(self) weakSelf = self; @@ -64,16 +70,33 @@ return self; } +- (NSDate*)lastUnlockTime { + // If unlocked, the last unlock time is now. Otherwise, used the cached value. + __block NSDate* date = nil; + dispatch_sync(self.queue, ^{ + if(self.isLocked) { + date = self.lastUnlockedTime; + } else { + date = [NSDate date]; + self.lastUnlockedTime = date; + } + }); + return date; +} + -(NSString*)description { - return [NSString stringWithFormat: @"", self.isLocked ? @"locked" : @"unlocked"]; + return [NSString stringWithFormat: @"", + self.isLocked ? @"locked" : @"unlocked", + self.isLocked ? self.lastUnlockedTime : @"now"]; } -(void)resetUnlockDependency { if(self.unlockDependency == nil || ![self.unlockDependency isPending]) { - self.unlockDependency = [NSBlockOperation blockOperationWithBlock: ^{ + CKKSResultOperation* op = [CKKSResultOperation named:@"keybag-unlocked-dependency" withBlock: ^{ secinfo("ckks", "Keybag unlocked"); }]; - self.unlockDependency.name = @"keybag-unlocked-dependency"; + op.descriptionErrorCode = CKKSResultDescriptionPendingUnlock; + self.unlockDependency = op; } } @@ -92,16 +115,33 @@ -(void)_onqueueRecheck { dispatch_assert_queue(self.queue); + static bool first = true; bool wasLocked = self.isLocked; self.isLocked = [CKKSLockStateTracker queryAKSLocked]; - if(wasLocked != self.isLocked) { + if(wasLocked != self.isLocked || first) { + first = false; if(self.isLocked) { // We're locked now. [self resetUnlockDependency]; + + if(wasLocked) { + self.lastUnlockedTime = [NSDate date]; + } } else { [self.operationQueue addOperation: self.unlockDependency]; self.unlockDependency = nil; + self.lastUnlockedTime = [NSDate date]; + } + + bool isUnlocked = (self.isLocked == false); + for (id observer in _observers) { + __strong typeof(observer) strongObserver = observer; + if (strongObserver == NULL) + return; + dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ + [strongObserver lockStateChangeNotification:isUnlocked]; + }); } } } @@ -117,6 +157,17 @@ && error.code == errSecInteractionNotAllowed; } +-(void)addLockStateObserver:(id)object +{ + dispatch_async(self.queue, ^{ + [self->_observers addObject:object]; + bool isUnlocked = (self.isLocked == false); + dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ + [object lockStateChangeNotification:isUnlocked]; + }); + }); +} + @end diff --git a/keychain/ckks/CKKSLogger.h b/keychain/ckks/CKKSLogger.h deleted file mode 100644 index a3b8b673..00000000 --- a/keychain/ckks/CKKSLogger.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -#if __OBJC2__ - -@interface SFAnalyticsLogger : NSObject - -+ (instancetype)logger; - -- (void)logSuccessForEventNamed:(NSString*)eventName; -- (void)logHardFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary*)attributes; -- (void)logSoftFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary*)attributes; - -- (void)noteEventNamed:(NSString*)eventName; - -// -------------------------------- -// Things below are for subclasses - -// Override to create a concrete logger instance -@property (readonly, class) NSString* databasePath; - -// Storing dates -- (void)setDateProperty:(NSDate*)date forKey:(NSString*)key; -- (NSDate*)datePropertyForKey:(NSString*)key; -- (NSArray*)datePropertyKeysToUploadToServer; - -- (NSData*)getLoggingJSONWithError:(NSError**)error; -- (BOOL)forceUploadWithError:(NSError**)error; - -// -------------------------------- -// Things below are for unit testing - -@property (readonly) dispatch_queue_t splunkLoggingQueue; -@property (readonly) NSURL* splunkUploadURL; -@property (readonly) NSString* splunkTopicName; -@property (readonly) NSURL* splunkBagURL; -@property (readonly) BOOL allowsInsecureSplunkCert; -@property BOOL ignoreServerDisablingMessages; - -@end - -#endif diff --git a/keychain/ckks/CKKSLogger.m b/keychain/ckks/CKKSLogger.m deleted file mode 100644 index 5cc74413..00000000 --- a/keychain/ckks/CKKSLogger.m +++ /dev/null @@ -1,706 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#if OCTAGON - -#import "CKKSLogger.h" -#import "debugging.h" -#import "CKKS.h" -#import "CKKSViewManager.h" -#import "keychain/ckks/CKKSKeychainView.h" -#include -#import -#import - -NSString* const CKKSLoggerTableSuccessCount = @"success_count"; -NSString* const CKKSLoggerColumnEventType = @"event_type"; -NSString* const CKKSLoggerColumnSuccessCount = @"success_count"; -NSString* const CKKSLoggerColumnFailureCount = @"failure_count"; - -NSString* const CKKSLoggerTableFailures = @"failures"; -NSString* const CKKSLoggerColumnData = @"data"; - -NSString* const CKKSLoggerUploadDate = @"upload_date"; -NSString* const CKKSLoggerLastClassASync = @"last_class_a_sync"; -NSString* const CKKSLoggerLastClassCSync = @"last_class_c_sync"; - -NSString* const CKKSLoggerDaysSinceLastSyncClassA = @"lastSyncClassA"; -NSString* const CKKSLoggerDaysSinceLastSyncClassC = @"lastSyncClassC"; - -NSString* const CKKSLoggerSplunkTopic = @"topic"; -NSString* const CKKSLoggerSplunkEventTime = @"eventTime"; -NSString* const CKKSLoggerSplunkPostTime = @"postTime"; -NSString* const CKKSLoggerSplunkEvents = @"events"; -NSString* const CKKSLoggerSplunkEventType = @"eventType"; -NSString* const CKKSLoggerMetricsBase = @"metricsBase"; - -NSString* const CKKSLoggerValueSuccess = @"success"; - -#define CKKS_SPLUNK_DEV 0 - -#if CKKS_SPLUNK_DEV -#define SECONDS_BETWEEN_UPLOADS 10 -#else -// three days = 60 seconds times 60 minutes * 72 hours -#define SECONDS_BETWEEN_UPLOADS (60 * 60 * 72) -#endif - -NSString* const CKKSLoggingTableSchema = @"CREATE TABLE IF NOT EXISTS failures (\n" - @"id INTEGER PRIMARY KEY AUTOINCREMENT,\n" - @"data BLOB\n" - @");\n" - @"CREATE TRIGGER IF NOT EXISTS maintain_ring_buffer AFTER INSERT ON failures\n" - @"BEGIN\n" - @"DELETE FROM failures WHERE id != NEW.id AND id % 999 = NEW.id % 999;\n" - @"END;\n" - @"CREATE TABLE IF NOT EXISTS success_count (\n" - @"event_type STRING PRIMARY KEY,\n" - @"success_count INTEGER,\n" - @"failure_count INTEGER\n" - @");\n"; - -static NSString* CKKSLoggingTablePath() -{ - return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"ckks_analytics_v1.db") path]; -} - -@interface CKKSLoggerSQLiteStore : SFSQLite - -+ (instancetype)sharedStore; - -@property (readonly, strong) NSArray* failureRecords; -@property (readwrite, strong) NSDate* uploadDate; - -- (void)incrementSuccessCountForEventType:(NSString*)eventType; -- (void)incrementFailureCountForEventType:(NSString*)eventType; -- (NSInteger)successCountForEventType:(NSString*)eventType; -- (NSInteger)failureCountForEventType:(NSString*)eventType; -- (void)addFailureRecord:(NSDictionary*)valueDict; -- (void)clearAllData; - -- (NSDictionary*)summaryCounts; - -@end - -@implementation CKKSLogger { - NSURL* _splunkUploadURL; - NSString* _splunkTopicName; - NSURL* _splunkBagURL; - dispatch_queue_t _queue; - NSInteger _secondsBetweenUploads; - NSDictionary* _metricsBase; // data the server provides and wants us to send back - NSArray* _blacklistedFields; - NSArray* _blacklistedEvents; - - unsigned int _allowInsecureSplunkCert:1; - unsigned int _disableLogging:1; - unsigned int _disableUploads:1; - unsigned int _ignoreServersMessagesTellingUsToGoAway:1; -} - -@synthesize splunkUploadURL = _splunkUploadURL; -@synthesize splunkBagURL = _splunkBagURL; -@synthesize splunkTopicName = _splunkTopicName; -@synthesize splunkLoggingQueue = _queue; - -+ (instancetype)logger -{ -#if TARGET_OS_SIMULATOR - return nil; -#endif - static CKKSLogger* __sharedLogger; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - __sharedLogger = [[CKKSLogger alloc] init]; - }); - - return __sharedLogger; -} - -- (instancetype)init -{ - if (self = [super init]) { - _queue = dispatch_queue_create("com.apple.security.ckks.logging", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - _secondsBetweenUploads = SECONDS_BETWEEN_UPLOADS; - - NSDictionary* systemDefaultValues = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle bundleWithPath:@"/System/Library/Frameworks/Security.framework"] pathForResource:@"CKKSLogging" ofType:@"plist"]]; - _splunkTopicName = systemDefaultValues[@"splunk_topic"]; - _splunkUploadURL = [NSURL URLWithString:systemDefaultValues[@"splunk_uploadURL"]]; - _splunkBagURL = [NSURL URLWithString:systemDefaultValues[@"splunk_bagURL"]]; - _allowInsecureSplunkCert = [[systemDefaultValues valueForKey:@"splunk_allowInsecureCertificate"] boolValue]; - NSString* splunkEndpoint = systemDefaultValues[@"splunk_endpointDomain"]; - - NSUserDefaults* defaults = [[NSUserDefaults alloc] initWithSuiteName:SecCKKSUserDefaultsSuite]; - NSString* userDefaultsSplunkTopic = [defaults stringForKey:@"splunk_topic"]; - if (userDefaultsSplunkTopic) { - _splunkTopicName = userDefaultsSplunkTopic; - } - - NSURL* userDefaultsSplunkUploadURL = [NSURL URLWithString:[defaults stringForKey:@"splunk_uploadURL"]]; - if (userDefaultsSplunkUploadURL) { - _splunkUploadURL = userDefaultsSplunkUploadURL; - } - - NSURL* userDefaultsSplunkBagURL = [NSURL URLWithString:[defaults stringForKey:@"splunk_bagURL"]]; - if (userDefaultsSplunkUploadURL) { - _splunkBagURL = userDefaultsSplunkBagURL; - } - - BOOL userDefaultsAllowInsecureSplunkCert = [defaults boolForKey:@"splunk_allowInsecureCertificate"]; - _allowInsecureSplunkCert |= userDefaultsAllowInsecureSplunkCert; - - NSString* userDefaultsSplunkEndpoint = [defaults stringForKey:@"splunk_endpointDomain"]; - if (userDefaultsSplunkEndpoint) { - splunkEndpoint = userDefaultsSplunkEndpoint; - } - -#if CKKS_SPLUNK_DEV - _ignoreServersMessagesTellingUsToGoAway = YES; - - if (!_splunkUploadURL && splunkEndpoint) { - NSString* urlString = [NSString stringWithFormat:@"https://%@/report/2/%@", splunkEndpoint, _splunkTopicName]; - _splunkUploadURL = [NSURL URLWithString:urlString]; - } -#else - (void)splunkEndpoint; -#endif - } - - return self; -} - -- (void)setLastSuccessfulClassASyncDate:(NSDate*)lastSuccessfulClassASyncDate -{ - dispatch_sync(_queue, ^{ - [[CKKSLoggerSQLiteStore sharedStore] setDateProperty:lastSuccessfulClassASyncDate forKey:CKKSLoggerLastClassASync]; - }); -} - -- (NSDate*)lastSuccessfulClassASyncDate -{ - __block NSDate* result = nil; - dispatch_sync(_queue, ^{ - result = [self _onQueueLastSuccessfulClassASyncDate]; - }); - - return result; -} - -- (NSDate*)_onQueueLastSuccessfulClassASyncDate -{ - dispatch_assert_queue(_queue); - return [[CKKSLoggerSQLiteStore sharedStore] datePropertyForKey:CKKSLoggerLastClassASync] ?: [NSDate distantPast]; -} - -- (void)setLastSuccessfulClassCSyncDate:(NSDate*)lastSuccessfulClassCSyncDate -{ - dispatch_sync(_queue, ^{ - [[CKKSLoggerSQLiteStore sharedStore] setDateProperty:lastSuccessfulClassCSyncDate forKey:CKKSLoggerLastClassCSync]; - }); -} - -- (NSDate*)lastSuccessfulClassCSyncDate -{ - __block NSDate* result = nil; - dispatch_sync(_queue, ^{ - result = [self _onQueueLastSuccessfulClassCSyncDate]; - }); - - return result; -} - -- (NSDate*)_onQueueLastSuccessfulClassCSyncDate -{ - dispatch_assert_queue(_queue); - return [[CKKSLoggerSQLiteStore sharedStore] datePropertyForKey:CKKSLoggerLastClassCSync] ?: [NSDate distantPast]; -} - -- (void)logSuccessForEventNamed:(NSString*)eventName -{ - [self logEventNamed:eventName value:nil isSuccess:YES]; -} - -- (void)logFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary*)attributes -{ - [self logEventNamed:eventName value:attributes isSuccess:NO]; -} - -- (void)logEventNamed:(NSString*)eventName value:(NSDictionary*)valueDict isSuccess:(BOOL)isSuccess -{ - __weak __typeof(self) weakSelf = self; - dispatch_async(_queue, ^{ - - __strong __typeof(self) strongSelf = weakSelf; - if (!strongSelf) { - return; - } - - if (strongSelf->_disableLogging || [strongSelf->_blacklistedEvents containsObject:eventName]) { - return; - } - - CKKSLoggerSQLiteStore* store = [CKKSLoggerSQLiteStore sharedStore]; - if (isSuccess) { - [store incrementSuccessCountForEventType:eventName]; - } - else { - [store incrementFailureCountForEventType:eventName]; - NSMutableDictionary* eventDict = valueDict.mutableCopy; - eventDict[CKKSLoggerSplunkTopic] = strongSelf->_splunkTopicName; - eventDict[CKKSLoggerSplunkEventType] = eventName; - eventDict[CKKSLoggerSplunkEventTime] = @([[NSDate date] timeIntervalSince1970] * 1000); - eventDict[CKKSLoggerMetricsBase] = strongSelf->_metricsBase ?: [NSDictionary dictionary]; - - for (NSString* blacklistedField in strongSelf->_blacklistedFields) { - [eventDict removeObjectForKey:blacklistedField]; - } - - [store addFailureRecord:eventDict]; - } - - NSDate* uploadDate = store.uploadDate; - NSDate* nowDate = [NSDate date]; - if (uploadDate) { - if ([nowDate compare:uploadDate] == NSOrderedDescending) { - [self _onQueueUploadDataWithError:nil]; - } - } - else { - store.uploadDate = [nowDate dateByAddingTimeInterval:strongSelf->_secondsBetweenUploads]; - } - }); -} - -// this method is kind of evil for the fact that it has side-effects in pulling other things besides the metricsURL from the server, and as such should NOT be memoized. -// TODO redo this, probably to return a dictionary. -- (NSURL*)splunkUploadURL -{ - dispatch_assert_queue(_queue); - - if (_splunkUploadURL) { - return _splunkUploadURL; - } - - __weak __typeof(self) weakSelf = self; - dispatch_semaphore_t sem = dispatch_semaphore_create(0); - - __block NSError* error = nil; - NSURLSessionConfiguration *defaultConfiguration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; - NSURLSession* storeBagSession = [NSURLSession sessionWithConfiguration:defaultConfiguration - delegate:self - delegateQueue:nil]; - - NSURL* requestEndpoint = _splunkBagURL; - __block NSURL* result = nil; - NSURLSessionDataTask* storeBagTask = [storeBagSession dataTaskWithURL:requestEndpoint completionHandler:^(NSData * _Nullable data, - NSURLResponse * _Nullable __unused response, - NSError * _Nullable responseError) { - - __strong __typeof(self) strongSelf = weakSelf; - if (!strongSelf) { - return; - } - - if (data && !responseError) { - NSData *responseData = data; // shut up compiler - NSDictionary* responseDict = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error]; - if([responseDict isKindOfClass:NSDictionary.class] && !error) { - if (!self->_ignoreServersMessagesTellingUsToGoAway) { - strongSelf->_disableLogging = [[responseDict valueForKey:@"disabled"] boolValue]; - if (strongSelf->_disableLogging || [[responseDict valueForKey:@"sendDisabled"] boolValue]) { - // then don't upload anything right now - secerror("not returning a splunk URL because uploads are disabled"); - dispatch_semaphore_signal(sem); - return; - } - - NSUInteger millisecondsBetweenUploads = [[responseDict valueForKey:@"postFrequency"] unsignedIntegerValue] / 1000; - if (millisecondsBetweenUploads > 0) { - strongSelf->_secondsBetweenUploads = millisecondsBetweenUploads; - } - - strongSelf->_blacklistedEvents = responseDict[@"blacklistedEvents"]; - strongSelf->_blacklistedFields = responseDict[@"blacklistedFields"]; - } - - strongSelf->_metricsBase = responseDict[@"metricsBase"]; - - NSString* metricsEndpoint = responseDict[@"metricsUrl"]; - if([metricsEndpoint isKindOfClass:NSString.class]) { - /* Lives our URL */ - NSString* endpoint = [metricsEndpoint stringByAppendingFormat:@"/2/%@", strongSelf->_splunkTopicName]; - secnotice("ckks", "got metrics endpoint: %@", endpoint); - NSURL* endpointURL = [NSURL URLWithString:endpoint]; - if([endpointURL.scheme isEqualToString:@"https"]) { - result = endpointURL; - } - } - } - } - else { - error = responseError; - } - if(error) { - secnotice("ckks", "Unable to fetch splunk endpoint at URL: %@ -- error: %@", requestEndpoint, error.description); - } - else if(!result) { - secnotice("ckks", "Malformed iTunes config payload!"); - } - - dispatch_semaphore_signal(sem); - }]; - - [storeBagTask resume]; - dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); - - return result; -} - -- (BOOL)forceUploadWithError:(NSError**)error -{ - __block BOOL result = NO; - dispatch_sync(_queue, ^{ - result = [self _onQueueUploadDataWithError:error]; - }); - return result; -} - -- (BOOL)_onQueueUploadDataWithError:(NSError**)error -{ - dispatch_assert_queue(_queue); - - NSData* json = [self _onQueueGetLoggingJSONWithError:error]; - if (json && [self _onQueuePostJSON:json error:error]) { - secinfo("ckks", "uploading sync health data: %@", json); - - CKKSLoggerSQLiteStore* store = [CKKSLoggerSQLiteStore sharedStore]; - [store clearAllData]; - store.uploadDate = [NSDate dateWithTimeIntervalSinceNow:_secondsBetweenUploads]; - return YES; - } - else { - return NO; - } -} - -- (BOOL)_onQueuePostJSON:(NSData*)json error:(NSError**)error -{ - dispatch_assert_queue(_queue); - - /* - * Create the NSURLSession - * We use the ephemeral session config because we don't need cookies or cache - */ - NSURLSessionConfiguration *defaultConfiguration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; - NSURLSession* postSession = [NSURLSession sessionWithConfiguration:defaultConfiguration - delegate:self - delegateQueue:nil]; - - /* - * Create the request - */ - NSURL* postEndpoint = self.splunkUploadURL; - if (!postEndpoint) { - secerror("failed to get a splunk upload endpoint - not uploading"); - return NO; - } - - NSMutableURLRequest* postRequest = [[NSMutableURLRequest alloc] init]; - postRequest.URL = postEndpoint; - postRequest.HTTPMethod = @"POST"; - postRequest.HTTPBody = json; - - /* - * Create the upload task. - */ - dispatch_semaphore_t sem = dispatch_semaphore_create(0); - __block BOOL uploadSuccess = NO; - NSURLSessionDataTask* uploadTask = [postSession dataTaskWithRequest:postRequest - completionHandler:^(NSData * _Nullable __unused data, NSURLResponse * _Nullable response, NSError * _Nullable requestError) { - if(requestError) { - secerror("Error in uploading the events to splunk: %@", requestError); - } - else if (![response isKindOfClass:NSHTTPURLResponse.class]){ - Class class = response.class; - secerror("Received the wrong kind of response: %@", NSStringFromClass(class)); - } - else { - NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response; - if(httpResponse.statusCode >= 200 && httpResponse.statusCode < 300) { - /* Success */ - uploadSuccess = YES; - secnotice("ckks", "Splunk upload success"); - } - else { - secnotice("ckks", "Splunk upload unexpected status to URL: %@ -- status: %d", postEndpoint, (int)(httpResponse.statusCode)); - } - } - dispatch_semaphore_signal(sem); - }]; - - secnotice("ckks", "Splunk upload start"); - [uploadTask resume]; - dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); - return uploadSuccess; -} - -#define SECOND_PER_DAY (60 * 60 * 24) - -- (NSInteger)fuzzyDaysSinceDate:(NSDate*)date -{ - NSTimeInterval timeIntervalSinceDate = [[NSDate date] timeIntervalSinceDate:date]; - if (timeIntervalSinceDate < SECOND_PER_DAY) { - return 0; - } - else if (timeIntervalSinceDate < (SECOND_PER_DAY * 7)) { - return 1; - } - else if (timeIntervalSinceDate < (SECOND_PER_DAY * 30)) { - return 7; - } - else if (timeIntervalSinceDate < (SECOND_PER_DAY * 365)) { - return 30; - } - else { - return 365; - } -} - -- (NSData*)getLoggingJSONWithError:(NSError**)error -{ - __block NSData* json = nil; - dispatch_sync(_queue, ^{ - json = [self _onQueueGetLoggingJSONWithError:error]; - }); - - return json; -} - -- (NSData*)_onQueueGetLoggingJSONWithError:(NSError**)error -{ - dispatch_assert_queue(_queue); - - CKKSLoggerSQLiteStore* store = [CKKSLoggerSQLiteStore sharedStore]; - NSArray* failureRecords = [store failureRecords]; - - NSDictionary* successCounts = [store summaryCounts]; - NSInteger totalSuccessCount = 0; - NSInteger totalFailureCount = 0; - for (NSDictionary* perEventTypeSuccessCounts in successCounts.objectEnumerator) { - totalSuccessCount += [perEventTypeSuccessCounts[CKKSLoggerColumnSuccessCount] integerValue]; - totalFailureCount += [perEventTypeSuccessCounts[CKKSLoggerColumnFailureCount] integerValue]; - } - - NSDate* now = [NSDate date]; - - NSMutableDictionary* healthSummaryEvent = [[NSMutableDictionary alloc] init]; - healthSummaryEvent[CKKSLoggerSplunkTopic] = _splunkTopicName ?: [NSNull null]; - healthSummaryEvent[CKKSLoggerSplunkEventTime] = @([now timeIntervalSince1970] * 1000); - healthSummaryEvent[CKKSLoggerSplunkEventType] = @"manifestHealthSummary"; - healthSummaryEvent[CKKSLoggerColumnSuccessCount] = @(totalSuccessCount); - healthSummaryEvent[CKKSLoggerColumnFailureCount] = @(totalFailureCount); - healthSummaryEvent[CKKSLoggerMetricsBase] = _metricsBase ?: [NSDictionary dictionary]; - - for (NSString* viewName in [CKKSViewManager viewList]) { - CKKSKeychainView* view = [CKKSViewManager findOrCreateView:viewName]; - [healthSummaryEvent setValue:@([self fuzzyDaysSinceDate:[self _onQueueLastSuccessfulClassASyncDate]]) forKey:[NSString stringWithFormat:@"%@-%@", view.zoneName, CKKSLoggerDaysSinceLastSyncClassA]]; - [healthSummaryEvent setValue:@([self fuzzyDaysSinceDate:[self _onQueueLastSuccessfulClassCSyncDate]]) forKey:[NSString stringWithFormat:@"%@-%@", view.zoneName, CKKSLoggerDaysSinceLastSyncClassC]]; - } - - NSMutableArray* splunkRecords = failureRecords.mutableCopy; - [splunkRecords addObject:healthSummaryEvent]; - - NSDictionary* jsonDict = @{CKKSLoggerSplunkPostTime : @([now timeIntervalSince1970] * 1000), @"events" : splunkRecords}; - - return [NSJSONSerialization dataWithJSONObject:jsonDict options:NSJSONWritingPrettyPrinted error:error]; -} - -- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge - completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler { - assert(completionHandler); - (void)session; - secnotice("ckks", "Splunk upload challenge"); - NSURLCredential *cred = nil; - SecTrustResultType result = kSecTrustResultInvalid; - - if ([challenge previousFailureCount] > 0) { - // Previous failures occurred, bail - completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); - - } else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { - /* - * Evaluate trust for the certificate - */ - - SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; - - OSStatus status = SecTrustEvaluate(serverTrust, &result); - if (status == errSecSuccess && (result == kSecTrustResultProceed || result == kSecTrustResultUnspecified)) { - /* - * All is well, accept the credentials - */ - - cred = [NSURLCredential credentialForTrust:serverTrust]; - completionHandler(NSURLSessionAuthChallengeUseCredential, cred); - } else if (_allowInsecureSplunkCert) { - secnotice("ckks", "Force Accepting Splunk Credential"); - - cred = [NSURLCredential credentialForTrust:serverTrust]; - completionHandler(NSURLSessionAuthChallengeUseCredential, cred); - } else { - /* - * An error occurred in evaluating trust, bail - */ - completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); - } - } else { - /* - * Just perform the default handling - */ - completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); - } - -} - -- (BOOL)ignoreServerDisablingMessages -{ - return _ignoreServersMessagesTellingUsToGoAway; -} - -- (void)setIgnoreServerDisablingMessages:(BOOL)ignoreServer -{ - _ignoreServersMessagesTellingUsToGoAway = ignoreServer ? YES : NO; -} - -@end - -@implementation CKKSLoggerSQLiteStore - -+ (instancetype)sharedStore -{ - static CKKSLoggerSQLiteStore* store = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - store = [[self alloc] initWithPath:CKKSLoggingTablePath() schema:CKKSLoggingTableSchema]; - [store open]; - }); - - return store; -} - -- (void)dealloc -{ - [self close]; -} - -- (NSInteger)successCountForEventType:(NSString*)eventType -{ - return [[[[self select:@[CKKSLoggerColumnSuccessCount] from:CKKSLoggerTableSuccessCount where:@"event_type = ?" bindings:@[eventType]] firstObject] valueForKey:CKKSLoggerColumnSuccessCount] integerValue]; -} - -- (void)incrementSuccessCountForEventType:(NSString*)eventType -{ - @try { - NSInteger successCount = [self successCountForEventType:eventType]; - NSInteger failureCount = [self failureCountForEventType:eventType]; - [self insertOrReplaceInto:CKKSLoggerTableSuccessCount values:@{CKKSLoggerColumnEventType : eventType, CKKSLoggerColumnSuccessCount : @(successCount + 1), CKKSLoggerColumnFailureCount : @(failureCount)}]; - } @catch (id ue) { - secerror("incrementSuccessCountForEventType exception: %@", ue); - } -} - -- (NSInteger)failureCountForEventType:(NSString*)eventType -{ - return [[[[self select:@[CKKSLoggerColumnFailureCount] from:CKKSLoggerTableSuccessCount where:@"event_type = ?" bindings:@[eventType]] firstObject] valueForKey:CKKSLoggerColumnFailureCount] integerValue]; -} - -- (void)incrementFailureCountForEventType:(NSString*)eventType -{ - @try { - NSInteger successCount = [self successCountForEventType:eventType]; - NSInteger failureCount = [self failureCountForEventType:eventType]; - [self insertOrReplaceInto:CKKSLoggerTableSuccessCount values:@{CKKSLoggerColumnEventType : eventType, CKKSLoggerColumnSuccessCount : @(successCount), CKKSLoggerColumnFailureCount : @(failureCount + 1)}]; - } @catch (id ue) { - secerror("incrementFailureCountForEventType exception: %@", ue); - } -} - -- (NSDictionary*)summaryCounts -{ - NSMutableDictionary* successCountsDict = [NSMutableDictionary dictionary]; - NSArray* rows = [self selectAllFrom:CKKSLoggerTableSuccessCount where:nil bindings:nil]; - for (NSDictionary* rowDict in rows) { - successCountsDict[rowDict[CKKSLoggerColumnEventType]] = @{CKKSLoggerColumnSuccessCount : rowDict[CKKSLoggerColumnSuccessCount], CKKSLoggerColumnFailureCount : rowDict[CKKSLoggerColumnFailureCount]}; - } - - return successCountsDict; -} - -- (NSArray*)failureRecords -{ - NSArray* recordBlobs = [self select:@[CKKSLoggerColumnData] from:CKKSLoggerTableFailures]; - - NSMutableArray* failureRecords = [[NSMutableArray alloc] init]; - for (NSDictionary* row in recordBlobs) { - NSDictionary* deserializedRecord = [NSPropertyListSerialization propertyListWithData:row[CKKSLoggerColumnData] options:0 format:nil error:nil]; - [failureRecords addObject:deserializedRecord]; - } - - return failureRecords; -} - -- (void)addFailureRecord:(NSDictionary*)valueDict -{ - @try { - NSError* error = nil; - NSData* serializedRecord = [NSPropertyListSerialization dataWithPropertyList:valueDict format:NSPropertyListBinaryFormat_v1_0 options:0 error:&error]; - if(!error && serializedRecord) { - [self insertOrReplaceInto:CKKSLoggerTableFailures values:@{CKKSLoggerColumnData : serializedRecord}]; - } - if(error && !serializedRecord) { - secerror("Couldn't serialize failure record: %@", error); - } - } @catch (id ue) { - secerror("addFailureRecord exception: %@", ue); - } -} - -- (NSDate*)uploadDate -{ - return [self datePropertyForKey:CKKSLoggerUploadDate]; -} - -- (void)setUploadDate:(NSDate*)uploadDate -{ - [self setDateProperty:uploadDate forKey:CKKSLoggerUploadDate]; -} - -- (void)clearAllData -{ - [self deleteFrom:CKKSLoggerTableSuccessCount where:@"event_type like ?" bindings:@[@"%"]]; - [self deleteFrom:CKKSLoggerTableFailures where:@"id >= 0" bindings:nil]; -} - -@end - -#endif // OCTAGON diff --git a/keychain/ckks/CKKSLogging.plist b/keychain/ckks/CKKSLogging.plist deleted file mode 100644 index 060222c3..00000000 --- a/keychain/ckks/CKKSLogging.plist +++ /dev/null @@ -1,16 +0,0 @@ - - - - - splunk_topic - xp_sear_keysync - splunk_allowInsecureCertificate - - splunk_bagURL - https://xp.apple.com/config/1/report/xp_sear_keysync - SyncManifests - - EnforceManifests - - - diff --git a/keychain/ckks/CKKSManifest.m b/keychain/ckks/CKKSManifest.m index 66587a72..7b2c78f5 100644 --- a/keychain/ckks/CKKSManifest.m +++ b/keychain/ckks/CKKSManifest.m @@ -1394,7 +1394,8 @@ static NSUInteger LeafBucketIndexForUUID(NSString* uuid) SOSPeerInfoRef peerInfo = (SOSPeerInfoRef)peerInfoPtr; CFErrorRef blockError = NULL; SecKeyRef secPublicKey = SOSPeerInfoCopyOctagonSigningPublicKey(peerInfo, &blockError); - if (!secPublicKey || error) { + if (!secPublicKey || blockError) { + CFReleaseNull(secPublicKey); CFReleaseNull(blockError); return; } diff --git a/keychain/ckks/CKKSNearFutureScheduler.h b/keychain/ckks/CKKSNearFutureScheduler.h index b8670e01..1bc7294a 100644 --- a/keychain/ckks/CKKSNearFutureScheduler.h +++ b/keychain/ckks/CKKSNearFutureScheduler.h @@ -21,8 +21,12 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if OCTAGON + #import #import +#import + NS_ASSUME_NONNULL_BEGIN /* @@ -41,17 +45,21 @@ NS_ASSUME_NONNULL_BEGIN // Will execute every time futureBlock is called, just after the future block. // Operations added in the futureBlock will receive the next operationDependency, so they won't run again until futureBlock occurs again. -@property (nullable, readonly) NSOperation* operationDependency; +@property (readonly) CKKSResultOperation* operationDependency; + +// dependencyDescriptionCode will be integrated into the operationDependency as per the rules in CKKSResultOperation.h - (instancetype)initWithName:(NSString*)name delay:(dispatch_time_t)ns keepProcessAlive:(bool)keepProcessAlive + dependencyDescriptionCode:(NSInteger)code block:(void (^_Nonnull)(void))futureOperation; - (instancetype)initWithName:(NSString*)name initialDelay:(dispatch_time_t)initialDelay continuingDelay:(dispatch_time_t)continuingDelay keepProcessAlive:(bool)keepProcessAlive + dependencyDescriptionCode:(NSInteger)code block:(void (^_Nonnull)(void))futureBlock; - (void)trigger; @@ -64,3 +72,4 @@ NS_ASSUME_NONNULL_BEGIN @end NS_ASSUME_NONNULL_END +#endif // OCTAGON diff --git a/keychain/ckks/CKKSNearFutureScheduler.m b/keychain/ckks/CKKSNearFutureScheduler.m index 5d1ed527..583a900e 100644 --- a/keychain/ckks/CKKSNearFutureScheduler.m +++ b/keychain/ckks/CKKSNearFutureScheduler.m @@ -21,9 +21,12 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if OCTAGON + #import "CKKSNearFutureScheduler.h" #import "CKKSCondition.h" #import "keychain/ckks/NSOperationCategories.h" +#import "keychain/ckks/CKKSResultOperation.h" #include @interface CKKSNearFutureScheduler () @@ -31,7 +34,8 @@ @property dispatch_time_t initialDelay; @property dispatch_time_t continuingDelay; -@property NSOperation* operationDependency; +@property NSInteger operationDependencyDescriptionCode; +@property CKKSResultOperation* operationDependency; @property (nonnull) NSOperationQueue* operationQueue; @property NSDate* predictedNextFireTime; @@ -47,21 +51,31 @@ @implementation CKKSNearFutureScheduler --(instancetype)initWithName:(NSString*)name delay:(dispatch_time_t)ns keepProcessAlive:(bool)keepProcessAlive block:(void (^)(void))futureBlock +-(instancetype)initWithName:(NSString*)name + delay:(dispatch_time_t)ns + keepProcessAlive:(bool)keepProcessAlive + dependencyDescriptionCode:(NSInteger)code + block:(void (^)(void))futureBlock { - return [self initWithName:name initialDelay:ns continuingDelay:ns keepProcessAlive:keepProcessAlive block:futureBlock]; + return [self initWithName:name + initialDelay:ns + continuingDelay:ns + keepProcessAlive:keepProcessAlive + dependencyDescriptionCode:code + block:futureBlock]; } -(instancetype)initWithName:(NSString*)name initialDelay:(dispatch_time_t)initialDelay continuingDelay:(dispatch_time_t)continuingDelay keepProcessAlive:(bool)keepProcessAlive + dependencyDescriptionCode:(NSInteger)code block:(void (^)(void))futureBlock { if((self = [super init])) { _name = name; - _queue = dispatch_queue_create([[NSString stringWithFormat:@"near-future-scheduler-%@",name] UTF8String], DISPATCH_QUEUE_SERIAL); + _queue = dispatch_queue_create([[NSString stringWithFormat:@"near-future-scheduler-%@",name] UTF8String], DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); _initialDelay = initialDelay; _continuingDelay = continuingDelay; _futureBlock = futureBlock; @@ -73,13 +87,16 @@ _keepProcessAlive = keepProcessAlive; _operationQueue = [[NSOperationQueue alloc] init]; + _operationDependencyDescriptionCode = code; _operationDependency = [self makeOperationDependency]; } return self; } -- (NSOperation*)makeOperationDependency { - return [NSBlockOperation named:[NSString stringWithFormat:@"nfs-%@", self.name] withBlock:^{}]; +- (CKKSResultOperation*)makeOperationDependency { + CKKSResultOperation* op = [CKKSResultOperation named:[NSString stringWithFormat:@"nfs-%@", self.name] withBlock:^{}]; + op.descriptionErrorCode = self.operationDependencyDescriptionCode; + return op; } -(NSString*)description { @@ -198,3 +215,5 @@ } @end + +#endif // OCTAGON diff --git a/keychain/ckks/CKKSNewTLKOperation.m b/keychain/ckks/CKKSNewTLKOperation.m index b9d09a86..8af09132 100644 --- a/keychain/ckks/CKKSNewTLKOperation.m +++ b/keychain/ckks/CKKSNewTLKOperation.m @@ -231,6 +231,11 @@ // Generate the TLK sharing records for all trusted peers NSMutableSet* tlkShares = [NSMutableSet set]; for(id trustedPeer in ckks.currentTrustedPeers) { + if(!trustedPeer.publicEncryptionKey) { + ckksnotice("ckkstlk", ckks, "No need to make TLK for %@; they don't have any encryption keys", trustedPeer); + continue; + } + ckksnotice("ckkstlk", ckks, "Generating TLK(%@) share for %@", newTLK, trustedPeer); CKKSTLKShare* share = [CKKSTLKShare share:newTLK as:ckks.currentSelfPeers.currentSelf to:trustedPeer epoch:-1 poisoned:0 error:&error]; @@ -248,8 +253,7 @@ modifyRecordsOp = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:recordsToSave recordIDsToDelete:recordIDsToDelete]; modifyRecordsOp.atomic = YES; modifyRecordsOp.longLived = NO; // The keys are only in memory; mark this explicitly not long-lived - modifyRecordsOp.timeoutIntervalForRequest = 2; - modifyRecordsOp.qualityOfService = NSQualityOfServiceUtility; // relatively important. Use Utility. + modifyRecordsOp.qualityOfService = NSQualityOfServiceUserInitiated; // This needs to happen before CKKS is available for PCS/CloudKit use. modifyRecordsOp.group = self.ckoperationGroup; ckksnotice("ckkstlk", ckks, "Operation group is %@", self.ckoperationGroup); diff --git a/keychain/ckks/CKKSNotifier.h b/keychain/ckks/CKKSNotifier.h index 64b550fd..312bbb3f 100644 --- a/keychain/ckks/CKKSNotifier.h +++ b/keychain/ckks/CKKSNotifier.h @@ -29,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN // There's terrible testing support for notify_post, but that's what our clients // are listening for. Use this structure to mock out notification sending for testing. -@protocol CKKSNotifier +@protocol CKKSNotifier + (void)post:(NSString*)notification; @end diff --git a/keychain/ckks/CKKSOutgoingQueueEntry.h b/keychain/ckks/CKKSOutgoingQueueEntry.h index aadeb473..a4a91c21 100644 --- a/keychain/ckks/CKKSOutgoingQueueEntry.h +++ b/keychain/ckks/CKKSOutgoingQueueEntry.h @@ -73,7 +73,8 @@ zoneID:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; -+ (NSDictionary*)countsByState:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; ++ (NSDictionary*)countsByStateInZone:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; ++ (NSInteger)countByState:(CKKSItemState *)state zone:(CKRecordZoneID*)zoneID error: (NSError * __autoreleasing *) error; @end diff --git a/keychain/ckks/CKKSOutgoingQueueEntry.m b/keychain/ckks/CKKSOutgoingQueueEntry.m index 032e604a..cff41eed 100644 --- a/keychain/ckks/CKKSOutgoingQueueEntry.m +++ b/keychain/ckks/CKKSOutgoingQueueEntry.m @@ -307,7 +307,7 @@ accessGroup:row[@"accessgroup"]]; } -+ (NSDictionary*)countsByState:(CKRecordZoneID*)zoneID error: (NSError * __autoreleasing *) error { ++ (NSDictionary*)countsByStateInZone:(CKRecordZoneID*)zoneID error: (NSError * __autoreleasing *) error { NSMutableDictionary* results = [[NSMutableDictionary alloc] init]; [CKKSSQLDatabaseObject queryDatabaseTable: [[self class] sqlTable] @@ -323,6 +323,23 @@ return results; } ++ (NSInteger)countByState:(CKKSItemState *)state zone:(CKRecordZoneID*)zoneID error: (NSError * __autoreleasing *) error { + __block NSInteger result = -1; + + [CKKSSQLDatabaseObject queryDatabaseTable: [[self class] sqlTable] + where: @{@"ckzone": CKKSNilToNSNull(zoneID.zoneName), @"state": state } + columns: @[@"count(*)"] + groupBy: nil + orderBy: nil + limit: -1 + processRow: ^(NSDictionary* row) { + result = [row[@"count(*)"] integerValue]; + } + error: error]; + return result; +} + + @end #endif diff --git a/keychain/ckks/CKKSOutgoingQueueOperation.m b/keychain/ckks/CKKSOutgoingQueueOperation.m index ea8a9540..d8869334 100644 --- a/keychain/ckks/CKKSOutgoingQueueOperation.m +++ b/keychain/ckks/CKKSOutgoingQueueOperation.m @@ -29,7 +29,7 @@ #import "CKKSOutgoingQueueEntry.h" #import "CKKSReencryptOutgoingItemsOperation.h" #import "CKKSManifest.h" -#import "CKKSAnalyticsLogger.h" +#import "CKKSAnalytics.h" #include #include @@ -55,14 +55,12 @@ _ckks = ckks; _ckoperationGroup = ckoperationGroup; - [self addNullableDependency:ckks.viewSetupOperation]; [self addNullableDependency:ckks.holdOutgoingQueueOperation]; // Depend on all previous CKKSOutgoingQueueOperations [self linearDependencies:ckks.outgoingQueueOperations]; // We also depend on the view being setup and the key hierarchy being reasonable - [self addNullableDependency:ckks.viewSetupOperation]; [self addNullableDependency:ckks.keyStateReadyDependency]; } return self; @@ -97,12 +95,13 @@ return false; } - //[CKKSPowerCollection CKKSPowerEvent:kCKKSPowerEventOutgoingQueue zone:ckks.zoneName count:[queueEntries count]]; + [CKKSPowerCollection CKKSPowerEvent:kCKKSPowerEventOutgoingQueue zone:ckks.zoneName count:[queueEntries count]]; ckksinfo("ckksoutgoing", ckks, "processing outgoing queue: %@", queueEntries); NSMutableDictionary* recordsToSave = [[NSMutableDictionary alloc] init]; - NSMutableSet* oqesModified = [[NSMutableSet alloc] init]; + NSMutableSet* recordIDsModified = [[NSMutableSet alloc] init]; + NSMutableSet*oqesModified = [[NSMutableSet alloc] init]; NSMutableArray* recordIDsToDelete = [[NSMutableArray alloc] init]; CKKSCurrentKeyPointer* currentClassAKeyPointer = [CKKSCurrentKeyPointer fromDatabase: SecCKKSKeyClassA zoneID:ckks.zoneID error: &error]; @@ -155,7 +154,8 @@ if([oqe.action isEqualToString: SecCKKSActionAdd]) { CKRecord* record = [oqe.item CKRecordWithZoneID: ckks.zoneID]; recordsToSave[record.recordID] = record; - [oqesModified addObject: record.recordID]; + [recordIDsModified addObject: record.recordID]; + [oqesModified addObject:oqe]; [ckks _onqueueChangeOutgoingQueueEntry:oqe toState:SecCKKSStateInFlight error:&error]; if(error) { @@ -166,7 +166,8 @@ } else if ([oqe.action isEqualToString: SecCKKSActionDelete]) { CKRecordID* recordIDToDelete = [[CKRecordID alloc] initWithRecordName: oqe.item.uuid zoneID: ckks.zoneID]; [recordIDsToDelete addObject: recordIDToDelete]; - [oqesModified addObject: recordIDToDelete]; + [recordIDsModified addObject: recordIDToDelete]; + [oqesModified addObject:oqe]; [ckks _onqueueChangeOutgoingQueueEntry:oqe toState:SecCKKSStateInFlight error:&error]; if(error) { @@ -184,7 +185,8 @@ // treat as an add. CKRecord* record = [oqe.item CKRecordWithZoneID: ckks.zoneID]; recordsToSave[record.recordID] = record; - [oqesModified addObject: record.recordID]; + [recordIDsModified addObject: record.recordID]; + [oqesModified addObject:oqe]; [ckks _onqueueChangeOutgoingQueueEntry:oqe toState:SecCKKSStateInFlight error:&error]; if(error) { @@ -208,7 +210,8 @@ // Grab the old ckrecord and update it CKRecord* record = [oqe.item updateCKRecord: ckme.item.storedCKRecord zoneID: ckks.zoneID]; recordsToSave[record.recordID] = record; - [oqesModified addObject: record.recordID]; + [recordIDsModified addObject: record.recordID]; + [oqesModified addObject:oqe]; [ckks _onqueueChangeOutgoingQueueEntry:oqe toState:SecCKKSStateInFlight error:&error]; if(error) { @@ -234,6 +237,15 @@ return true; } + bool uploadingPCSEntries = false; + for(CKKSOutgoingQueueEntry* oqe in oqesModified) { + // PCS always sets these fields, and nothing else does + if(oqe.item.plaintextPCSPublicKey || oqe.item.plaintextPCSPublicIdentity || oqe.item.plaintextPCSServiceIdentifier) { + uploadingPCSEntries = true; + break; + } + } + self.itemsProcessed = recordsToSave.count; NSBlockOperation* modifyComplete = [[NSBlockOperation alloc] init]; @@ -265,16 +277,16 @@ return; } - //CKKSAnalyticsLogger* logger = [CKKSAnalyticsLogger logger]; + CKKSAnalytics* logger = [CKKSAnalytics logger]; - [strongCKKS dispatchSync: ^bool{ + [strongCKKS dispatchSyncWithAccountKeys: ^bool{ if(ckerror) { ckkserror("ckksoutgoing", strongCKKS, "error processing outgoing queue: %@", ckerror); - /*[logger logRecoverableError:ckerror + [logger logRecoverableError:ckerror forEvent:CKKSEventProcessOutgoingQueue inView:strongCKKS - withAttributes:NULL];*/ + withAttributes:NULL]; // Tell CKKS about any out-of-date records [strongCKKS _onqueueCKWriteFailed:ckerror attemptedRecordsChanged:recordsToSave]; @@ -282,61 +294,73 @@ // Check if these are due to key records being out of date. We'll see a CKErrorBatchRequestFailed, with a bunch of errors inside if([ckerror.domain isEqualToString:CKErrorDomain] && (ckerror.code == CKErrorPartialFailure)) { NSMutableDictionary* failedRecords = ckerror.userInfo[CKPartialErrorsByItemIDKey]; - ckksnotice("ckksoutgoing", strongCKKS, "failed records %@", failedRecords); - for(CKRecordID* recordID in failedRecords.allKeys) { - NSError* recordError = failedRecords[recordID]; - - if(recordError.code == CKErrorServerRecordChanged) { - if([recordID.recordName isEqualToString: SecCKKSKeyClassA] || - [recordID.recordName isEqualToString: SecCKKSKeyClassC]) { - // The current key pointers have updated without our knowledge, so CloudKit failed this operation. Mark all records as 'needs reencryption' and kick that off. - [strongSelf _onqueueModifyAllRecords:failedRecords.allKeys as:SecCKKSStateReencrypt]; - - // Note that _onqueueCKWriteFailed is responsible for kicking the key state machine, so we don't need to do it here. - // This will wait for the key hierarchy to become 'ready' - CKKSReencryptOutgoingItemsOperation* op = [[CKKSReencryptOutgoingItemsOperation alloc] initWithCKKSKeychainView:strongCKKS ckoperationGroup:strongSelf.ckoperationGroup]; - [strongCKKS scheduleOperation: op]; - - // Quit the loop so we only do this once - break; - } else { - // CKErrorServerRecordChanged on an item update means that we've been overwritten. - if([oqesModified containsObject:recordID]) { - [strongSelf _onqueueModifyRecordAsError:recordID recordError:recordError]; + + bool askForReencrypt = false; + + if([strongSelf _onqueueIsErrorBadEtagOnKeyPointersOnly:ckerror]) { + // The current key pointers have updated without our knowledge, so CloudKit failed this operation. Mark all records as 'needs reencryption' and kick that off. + ckksnotice("ckksoutgoing", strongCKKS, "Error is simply due to current key pointers changing; marking all records as 'needs reencrypt'"); + [strongSelf _onqueueModifyAllRecords:failedRecords.allKeys as:SecCKKSStateReencrypt]; + askForReencrypt = true; + } else { + // Iterate all failures, and reset each item + for(CKRecordID* recordID in failedRecords) { + NSError* recordError = failedRecords[recordID]; + + ckksnotice("ckksoutgoing", strongCKKS, "failed record: %@ %@", recordID, recordError); + + if(recordError.code == CKErrorServerRecordChanged) { + if([recordID.recordName isEqualToString: SecCKKSKeyClassA] || + [recordID.recordName isEqualToString: SecCKKSKeyClassC]) { + // Note that _onqueueCKWriteFailed is responsible for kicking the key state machine, so we don't need to do it here. + askForReencrypt = true; + } else { + // CKErrorServerRecordChanged on an item update means that we've been overwritten. + if([recordIDsModified containsObject:recordID]) { + [strongSelf _onqueueModifyRecordAsError:recordID recordError:recordError]; + } } - } - } else if(recordError.code == CKErrorBatchRequestFailed) { - // Also fine. This record only didn't succeed because something else failed. - // OQEs should be placed back into the 'new' state, unless they've been overwritten by a new OQE. Other records should be ignored. - - if([oqesModified containsObject:recordID]) { - NSError* localerror = nil; - CKKSOutgoingQueueEntry* inflightOQE = [CKKSOutgoingQueueEntry tryFromDatabase:recordID.recordName state:SecCKKSStateInFlight zoneID:recordID.zoneID error:&localerror]; - [strongCKKS _onqueueChangeOutgoingQueueEntry:inflightOQE toState:SecCKKSStateNew error:&localerror]; - if(localerror) { - ckkserror("ckksoutgoing", strongCKKS, "Couldn't clean up outgoing queue entry: %@", localerror); + } else if(recordError.code == CKErrorBatchRequestFailed) { + // Also fine. This record only didn't succeed because something else failed. + // OQEs should be placed back into the 'new' state, unless they've been overwritten by a new OQE. Other records should be ignored. + + if([recordIDsModified containsObject:recordID]) { + NSError* localerror = nil; + CKKSOutgoingQueueEntry* inflightOQE = [CKKSOutgoingQueueEntry tryFromDatabase:recordID.recordName state:SecCKKSStateInFlight zoneID:recordID.zoneID error:&localerror]; + [strongCKKS _onqueueChangeOutgoingQueueEntry:inflightOQE toState:SecCKKSStateNew error:&localerror]; + if(localerror) { + ckkserror("ckksoutgoing", strongCKKS, "Couldn't clean up outgoing queue entry: %@", localerror); + } } - } - } else { - // Some unknown error occurred on this record. If it's an OQE, move it to the error state. - ckkserror("ckksoutgoing", strongCKKS, "Unknown error on row: %@ %@", recordID, recordError); - if([oqesModified containsObject:recordID]) { - [strongSelf _onqueueModifyRecordAsError:recordID recordError:recordError]; + } else { + // Some unknown error occurred on this record. If it's an OQE, move it to the error state. + ckkserror("ckksoutgoing", strongCKKS, "Unknown error on row: %@ %@", recordID, recordError); + if([recordIDsModified containsObject:recordID]) { + [strongSelf _onqueueModifyRecordAsError:recordID recordError:recordError]; + } } } } + + if(askForReencrypt) { + // This will wait for the key hierarchy to become 'ready' + ckkserror("ckksoutgoing", strongCKKS, "Starting new Reencrypt items operation"); + CKKSReencryptOutgoingItemsOperation* op = [[CKKSReencryptOutgoingItemsOperation alloc] initWithCKKSKeychainView:strongCKKS + ckoperationGroup:strongSelf.ckoperationGroup]; + [strongCKKS scheduleOperation: op]; + } } else { // Some non-partial error occured. We should place all "inflight" OQEs back into the outgoing queue. ckksnotice("ckks", strongCKKS, "Error is scary: putting all inflight OQEs back into state 'new'"); - [strongSelf _onqueueModifyAllRecords:[oqesModified allObjects] as:SecCKKSStateNew]; + [strongSelf _onqueueModifyAllRecords:[recordIDsModified allObjects] as:SecCKKSStateNew]; } - strongSelf.error = error; + strongSelf.error = ckerror; return true; } - ckksnotice("ckksoutgoing", strongCKKS, "Completed processing outgoing queue"); + ckksnotice("ckksoutgoing", strongCKKS, "Completed processing outgoing queue (%d modifications, %d deletions)", (int)savedRecords.count, (int)deletedRecordIDs.count); NSError* error = NULL; CKKSPowerCollection *plstats = [[CKKSPowerCollection alloc] init]; @@ -408,13 +432,13 @@ if(strongSelf.error) { ckkserror("ckksoutgoing", strongCKKS, "Operation failed; rolling back: %@", strongSelf.error); - /*[logger logRecoverableError:strongSelf.error + [logger logRecoverableError:strongSelf.error forEvent:CKKSEventProcessOutgoingQueue inView:strongCKKS - withAttributes:NULL];*/ + withAttributes:NULL]; return false; } else { - //[logger logSuccessForEvent:CKKSEventProcessOutgoingQueue inView:strongCKKS]; + [logger logSuccessForEvent:CKKSEventProcessOutgoingQueue inView:strongCKKS]; } return true; }]; @@ -450,12 +474,11 @@ self.modifyRecordsOperation = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:recordsToSave.allValues recordIDsToDelete:recordIDsToDelete]; self.modifyRecordsOperation.atomic = TRUE; - self.modifyRecordsOperation.timeoutIntervalForRequest = 2; - self.modifyRecordsOperation.qualityOfService = NSQualityOfServiceUtility; + self.modifyRecordsOperation.qualityOfService = uploadingPCSEntries ? NSQualityOfServiceUserInitiated : NSQualityOfServiceUtility; // PCS items are needed for CloudKit to work, so they might be user-initiated self.modifyRecordsOperation.savePolicy = CKRecordSaveIfServerRecordUnchanged; self.modifyRecordsOperation.group = self.ckoperationGroup; - ckksnotice("ckksoutgoing", ckks, "Operation group is %@", self.ckoperationGroup); - ckksnotice("ckksoutgoing", ckks, "Beginning upload for %@ %@", recordsToSave.allValues, recordIDsToDelete); + ckksnotice("ckksoutgoing", ckks, "QoS: %d; operation group is %@", (int)self.modifyRecordsOperation.qualityOfService, self.modifyRecordsOperation.group); + ckksnotice("ckksoutgoing", ckks, "Beginning upload for %@ %@", recordsToSave.allKeys, recordIDsToDelete); self.modifyRecordsOperation.perRecordCompletionBlock = ^(CKRecord *record, NSError * _Nullable error) { __strong __typeof(weakSelf) strongSelf = weakSelf; @@ -539,6 +562,35 @@ } } +- (bool)_onqueueIsErrorBadEtagOnKeyPointersOnly:(NSError*)ckerror { + bool anyOtherErrors = false; + + if([ckerror.domain isEqualToString:CKErrorDomain] && (ckerror.code == CKErrorPartialFailure)) { + NSMutableDictionary* failedRecords = ckerror.userInfo[CKPartialErrorsByItemIDKey]; + + for(CKRecordID* recordID in failedRecords) { + NSError* recordError = failedRecords[recordID]; + + if(recordError.code == CKErrorServerRecordChanged) { + if([recordID.recordName isEqualToString: SecCKKSKeyClassA] || + [recordID.recordName isEqualToString: SecCKKSKeyClassC]) { + // this is fine! + } else { + // Some record other than the key pointers changed. + anyOtherErrors |= true; + break; + } + } else { + // Some other error than ServerRecordChanged + anyOtherErrors |= true; + break; + } + } + } + + return !anyOtherErrors; +} + @end; #endif diff --git a/keychain/ckks/CKKSPeer.h b/keychain/ckks/CKKSPeer.h index 9c6dc3be..bb96afd1 100644 --- a/keychain/ckks/CKKSPeer.h +++ b/keychain/ckks/CKKSPeer.h @@ -25,6 +25,7 @@ #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -70,6 +71,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)trustedPeerSetChanged; @end +extern NSString* const CKKSSOSPeerPrefix; + // These should be replaced by Octagon peers, when those exist @interface CKKSSOSPeer : NSObject @property (readonly) NSString* peerID; @@ -86,8 +89,8 @@ NS_ASSUME_NONNULL_BEGIN @property (readonly) SFECPublicKey* publicEncryptionKey; @property (readonly) SFECPublicKey* publicSigningKey; -@property (readonly) SFECKeyPair* encryptionKey; -@property (readonly) SFECKeyPair* signingKey; +@property SFECKeyPair* encryptionKey; +@property SFECKeyPair* signingKey; - (instancetype)initWithSOSPeerID:(NSString*)syncingPeerID encryptionKey:(SFECKeyPair*)encryptionKey diff --git a/keychain/ckks/CKKSPeer.m b/keychain/ckks/CKKSPeer.m index 094bb7ae..43fbb70c 100644 --- a/keychain/ckks/CKKSPeer.m +++ b/keychain/ckks/CKKSPeer.m @@ -25,6 +25,8 @@ #import "keychain/ckks/CKKSPeer.h" +NSString* const CKKSSOSPeerPrefix = @"spid-"; + @implementation CKKSSelves - (instancetype)initWithCurrent:(id)selfPeer allSelves:(NSSet>*)allSelves { @@ -32,7 +34,8 @@ _currentSelf = selfPeer; // Ensure allSelves contains selfPeer - _allSelves = allSelves ? [allSelves setByAddingObject:selfPeer] : [NSSet setWithObject:selfPeer]; + _allSelves = allSelves ? [allSelves setByAddingObject:selfPeer] : + (selfPeer ? [NSSet setWithObject:selfPeer] : [NSSet set]); } return self; } @@ -58,18 +61,13 @@ [self.publicSigningKey.keyData subdataWithRange:NSMakeRange(0, MIN(16u,self.publicSigningKey.keyData.length))]]; } -- (NSString*)prefix { - return @"spid-"; -} - - (instancetype)initWithSOSPeerID:(NSString*)syncingPeerID encryptionPublicKey:(SFECPublicKey*)encryptionKey signingPublicKey:(SFECPublicKey*)signingKey { if((self = [super init])) { - - if([syncingPeerID hasPrefix:[self prefix]]) { - _spid = [syncingPeerID substringFromIndex:[self prefix].length]; + if([syncingPeerID hasPrefix:CKKSSOSPeerPrefix]) { + _spid = [syncingPeerID substringFromIndex:CKKSSOSPeerPrefix.length]; } else { _spid = syncingPeerID; } @@ -80,7 +78,7 @@ } - (NSString*)peerID { - return [NSString stringWithFormat:@"%@%@", self.prefix, self.spid]; + return [NSString stringWithFormat:@"%@%@", CKKSSOSPeerPrefix, self.spid]; } - (bool)matchesPeer:(id)peer { @@ -106,7 +104,11 @@ signingKey:(SFECKeyPair*)signingKey { if((self = [super init])) { - _spid = syncingPeerID; + if([syncingPeerID hasPrefix:CKKSSOSPeerPrefix]) { + _spid = [syncingPeerID substringFromIndex:CKKSSOSPeerPrefix.length]; + } else { + _spid = syncingPeerID; + } _encryptionKey = encryptionKey; _signingKey = signingKey; } @@ -120,7 +122,7 @@ return self.signingKey.publicKey; } - (NSString*)peerID { - return [NSString stringWithFormat:@"spid-%@", self.spid]; + return [NSString stringWithFormat:@"%@%@", CKKSSOSPeerPrefix, self.spid]; } - (bool)matchesPeer:(id)peer { diff --git a/keychain/ckks/CKKSProcessReceivedKeysOperation.m b/keychain/ckks/CKKSProcessReceivedKeysOperation.m index 98f9ba06..01b78bce 100644 --- a/keychain/ckks/CKKSProcessReceivedKeysOperation.m +++ b/keychain/ckks/CKKSProcessReceivedKeysOperation.m @@ -27,6 +27,7 @@ #import "CKKSCurrentKeyPointer.h" #import "CKKSKey.h" #import "CKKSProcessReceivedKeysOperation.h" +#import "keychain/ckks/CloudKitCategories.h" #if OCTAGON @@ -115,9 +116,8 @@ if([key wrapsSelf]) { tlk = key; } else { - ckkserror("ckkskey", ckks, "current TLK doesn't wrap itself: %@", key); - // TODO: re-fetch? - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateReady withError:error]; + ckkserror("ckkskey", ckks, "current TLK doesn't wrap itself: %@ %@", key, key.parentKeyUUID); + [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateUnhealthy withError:error]; return true; } } @@ -125,8 +125,7 @@ if(!tlk) { ckkserror("ckkskey", ckks, "couldn't find active TLK: %@", currentTLKPointer); - // TODO: re-fetch? - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateReady withError:error]; + [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateUnhealthy withError:error]; return true; } @@ -145,12 +144,7 @@ } else { // Otherwise, something has gone horribly wrong. enter error state. ckkserror("ckkskey", ckks, "CKKS claims %@ is not a valid TLK: %@", tlk, error); - NSError* newError = nil; - if(error) { - newError = [NSError errorWithDomain: @"securityd" code:0 userInfo:@{NSLocalizedDescriptionKey: @"invalid TLK from CloudKit", NSUnderlyingErrorKey: error}]; - } else { - newError = [NSError errorWithDomain: @"securityd" code:0 userInfo:@{NSLocalizedDescriptionKey: @"invalid TLK from CloudKit (unknown error)"}]; - } + NSError* newError = [NSError errorWithDomain:CKKSErrorDomain code:CKKSInvalidTLK description:@"invalid TLK from CloudKit" underlying:error]; [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError withError:newError]; return true; } @@ -167,15 +161,30 @@ if(error != nil || ![topKey.uuid isEqual: tlk.uuid]) { ckkserror("ckkskey", ckks, "new key %@ is orphaned (%@)", key, error); // TODO: possibly re-fetch. Maybe not an actual error state. - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError withError: error ? error : [NSError errorWithDomain: @"securityd" code:0 userInfo:@{NSLocalizedDescriptionKey: @"orphaned key in hierarchy", NSUnderlyingErrorKey: error}]]; + [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError + withError:[NSError errorWithDomain:CKKSErrorDomain + code:CKKSOrphanedKey + description:[NSString stringWithFormat:@"orphaned key(%@) in hierarchy", topKey] + underlying:error]]; return true; + } // Okay, it wraps to the TLK. Can we unwrap it? if(![key unwrapViaKeyHierarchy:&error] || error != nil) { - ckkserror("ckkskey", ckks, "new key %@ claims to wrap to TLK, but we can't unwrap it: %@", topKey, error); - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError withError: error ? error : [NSError errorWithDomain: @"securityd" code:0 userInfo:@{NSLocalizedDescriptionKey: @"orphaned/couldn't unwrap key in hierarchy", NSUnderlyingErrorKey: error}]]; - return true; + if(error && [ckks.lockStateTracker isLockedError:error]) { + ckksnotice("ckkskey", ckks, "Couldn't unwrap new key (%@), but keybag appears to be locked. Entering waitforunlock.", key); + [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateWaitForUnlock withError:error]; + return true; + } else { + ckkserror("ckkskey", ckks, "new key %@ claims to wrap to TLK, but we can't unwrap it: %@", topKey, error); + [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError + withError:[NSError errorWithDomain:CKKSErrorDomain + code:CKKSOrphanedKey + description:[NSString stringWithFormat:@"unwrappable key(%@) in hierarchy: %@", topKey, error] + underlying:error]]; + return true; + } } ckksnotice("ckkskey", ckks, "New key %@ wraps to tlk %@", key, tlk); diff --git a/keychain/ckks/CKKSReachabilityTracker.h b/keychain/ckks/CKKSReachabilityTracker.h new file mode 100644 index 00000000..b2c1c370 --- /dev/null +++ b/keychain/ckks/CKKSReachabilityTracker.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import +#import + +@interface CKKSReachabilityTracker : NSObject +@property NSOperation* reachablityDependency; +@property (readonly) bool currentReachability; // get current reachability value w/o recheck + +- (instancetype)init; +- (void)recheck; +- (bool)isNetworkError:(NSError *)error; + +// only for testing override, the method will be call sync on an internal queue, +// so take that into consideration when you mock this class method. ++ (SCNetworkReachabilityFlags)getReachabilityFlags:(SCNetworkReachabilityRef)target; + +@end + +#endif // OCTAGON + diff --git a/keychain/ckks/CKKSReachabilityTracker.m b/keychain/ckks/CKKSReachabilityTracker.m new file mode 100644 index 00000000..3086e568 --- /dev/null +++ b/keychain/ckks/CKKSReachabilityTracker.m @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import +#import + +#import +#import +#import +#import + +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ckks/CKKSReachabilityTracker.h" +#import "keychain/ckks/CKKSAnalytics.h" + +// force reachability timeout every now and then +#define REACHABILITY_TIMEOUT (12 * 3600 * NSEC_PER_SEC) + +@interface CKKSReachabilityTracker () +@property bool haveNetwork; +@property dispatch_queue_t queue; +@property NSOperationQueue* operationQueue; +@property (assign) SCNetworkReachabilityRef reachability; +@property dispatch_source_t timer; +@end + +@implementation CKKSReachabilityTracker + +static void +callout(SCNetworkReachabilityRef reachability, + SCNetworkReachabilityFlags flags, + void *context) +{ + CKKSReachabilityTracker *tracker = (__bridge id)context; + [tracker _onqueueRecheck:flags]; +} + +- (instancetype)init { + if((self = [super init])) { + _queue = dispatch_queue_create("reachabiltity-tracker", DISPATCH_QUEUE_SERIAL); + _operationQueue = [[NSOperationQueue alloc] init]; + + dispatch_sync(_queue, ^{ + [self _onQueueResetReachabilityDependency]; + }); + + __weak __typeof(self) weakSelf = self; + + if(!SecCKKSTestsEnabled()) { + struct sockaddr_in zeroAddress; + bzero(&zeroAddress, sizeof(zeroAddress)); + zeroAddress.sin_len = sizeof(zeroAddress); + zeroAddress.sin_family = AF_INET; + + _reachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress); + + SCNetworkReachabilityContext context = {0, (__bridge void *)(self), NULL, NULL, NULL}; + SCNetworkReachabilitySetDispatchQueue(_reachability, _queue); + SCNetworkReachabilitySetCallback(_reachability, callout, &context); + } + + [weakSelf recheck]; + } + return self; +} + +-(NSString*)description { + return [NSString stringWithFormat: @"", self.haveNetwork ? @"online" : @"offline"]; +} + +-(bool)currentReachability { + __block bool currentReachability = false; + dispatch_sync(self.queue, ^{ + currentReachability = self.haveNetwork; + }); + return currentReachability; +} + +-(void)_onQueueRunReachablityDependency +{ + dispatch_assert_queue(self.queue); + // We're have network now, or timer expired, either way, execute dependency + if (self.reachablityDependency) { + [self.operationQueue addOperation: self.reachablityDependency]; + self.reachablityDependency = nil; + } + if (self.timer) { + dispatch_source_cancel(self.timer); + self.timer = nil; + } +} + +-(void)_onQueueResetReachabilityDependency { + dispatch_assert_queue(self.queue); + + if(self.reachablityDependency == nil || ![self.reachablityDependency isPending]) { + __weak __typeof(self) weakSelf = self; + + self.reachablityDependency = [NSBlockOperation blockOperationWithBlock: ^{ + __typeof(self) strongSelf = weakSelf; + if (strongSelf == nil) { + return; + } + if (strongSelf.haveNetwork) { + secinfo("ckks", "Network available"); + } else { + secinfo("ckks", "Network still not available, retrying after waiting %2.1f hours", + ((float)(REACHABILITY_TIMEOUT/NSEC_PER_SEC)) / 3600); + } + }]; + self.reachablityDependency.name = @"network-available-dependency"; + + /* + * Make sure we are not stuck forever and retry every REACHABILITY_TIMEOUT + */ + self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, + 0, + (dispatch_source_timer_flags_t)0, + self.queue); + dispatch_source_set_event_handler(self.timer, ^{ + __typeof(self) strongSelf = weakSelf; + if (strongSelf == nil) { + return; + } + if (strongSelf.timer) { + [[CKKSAnalytics logger] noteEvent:CKKSEventReachabilityTimerExpired]; + [strongSelf _onQueueRunReachablityDependency]; + } + }); + + dispatch_source_set_timer(self.timer, + dispatch_time(DISPATCH_TIME_NOW, REACHABILITY_TIMEOUT), + DISPATCH_TIME_FOREVER, //one-shot + 30 * NSEC_PER_SEC); + dispatch_resume(self.timer); + } +} + +-(void)_onqueueRecheck:(SCNetworkReachabilityFlags)flags { + dispatch_assert_queue(self.queue); + + const SCNetworkReachabilityFlags reachabilityFlags = + kSCNetworkReachabilityFlagsReachable + | kSCNetworkReachabilityFlagsConnectionAutomatic +#if TARGET_OS_IPHONE + | kSCNetworkReachabilityFlagsIsWWAN +#endif + ; + + bool hadNetwork = self.haveNetwork; + self.haveNetwork = !!(flags & reachabilityFlags); + + if(hadNetwork != self.haveNetwork) { + if(self.haveNetwork) { + // We're have network now + [self _onQueueRunReachablityDependency]; + } else { + [self _onQueueResetReachabilityDependency]; + } + } +} + ++ (SCNetworkReachabilityFlags)getReachabilityFlags:(SCNetworkReachabilityRef)target +{ + SCNetworkReachabilityFlags flags; + if (SCNetworkReachabilityGetFlags(target, &flags)) + return flags; + return 0; +} + +-(void)recheck { + dispatch_sync(self.queue, ^{ + SCNetworkReachabilityFlags flags = [CKKSReachabilityTracker getReachabilityFlags:self.reachability]; + [self _onqueueRecheck:flags]; + }); +} + +-(bool)isNetworkError:(NSError *)error { + if (error == nil) + return false; + return ([error.domain isEqualToString:CKErrorDomain] && + (error.code == CKErrorNetworkUnavailable + || error.code == CKErrorNetworkFailure)); +} + +@end + +#endif // OCTAGON + diff --git a/keychain/ckks/CKKSRecordHolder.m b/keychain/ckks/CKKSRecordHolder.m index 13b2a78f..34bca844 100644 --- a/keychain/ckks/CKKSRecordHolder.m +++ b/keychain/ckks/CKKSRecordHolder.m @@ -26,6 +26,7 @@ #include #import +#import #import "CKKSItem.h" #import "CKKSSIV.h" @@ -63,8 +64,7 @@ if(!_encodedCKRecord) { return nil; } - NSKeyedUnarchiver *coder = [[NSKeyedUnarchiver alloc] initForReadingWithData:_encodedCKRecord]; - coder.requiresSecureCoding = YES; + NSKeyedUnarchiver *coder = [[NSKeyedUnarchiver alloc] initForReadingFromData:_encodedCKRecord error:nil]; CKRecord* ckRecord = [[CKRecord alloc] initWithCoder:coder]; [coder finishDecoding]; @@ -79,11 +79,9 @@ self.zoneID = ckRecord.recordID.zoneID; self.ckRecordType = ckRecord.recordType; - NSMutableData* data = [NSMutableData data]; - NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; [ckRecord encodeWithCoder:archiver]; - [archiver finishEncoding]; - _encodedCKRecord = data; + _encodedCKRecord = archiver.encodedData; } - (CKRecord*) CKRecordWithZoneID: (CKRecordZoneID*) zoneID { diff --git a/keychain/ckks/CKKSReencryptOutgoingItemsOperation.m b/keychain/ckks/CKKSReencryptOutgoingItemsOperation.m index 3b975a66..397516af 100644 --- a/keychain/ckks/CKKSReencryptOutgoingItemsOperation.m +++ b/keychain/ckks/CKKSReencryptOutgoingItemsOperation.m @@ -47,7 +47,7 @@ _ckks = ckks; _ckoperationGroup = ckoperationGroup; - [self addNullableDependency:ckks.viewSetupOperation]; + [self addNullableDependency:ckks.keyStateReadyDependency]; [self addNullableDependency:ckks.holdReencryptOutgoingItemsOperation]; // We also depend on the key hierarchy being reasonable @@ -109,8 +109,8 @@ NSDictionary* item = [CKKSItemEncrypter decryptItemToDictionary: oqe.item error:&error]; if(error) { if ([error.domain isEqualToString:@"securityd"] && error.code == errSecItemNotFound) { - ckkserror("ckksreencrypt", ckks, "Coudn't find key in keychain; attempting to poke key hierarchy: %@", error) - [ckks _onqueueAdvanceKeyStateMachineToState: nil withError: nil]; + ckkserror("ckksreencrypt", ckks, "Coudn't find key in keychain; attempting to poke key hierarchy: %@", error); + [ckks.pokeKeyStateMachineScheduler trigger]; } else { ckkserror("ckksreencrypt", ckks, "Couldn't decrypt item %@: %@", oqe, error); } diff --git a/keychain/ckks/CKKSResultOperation.h b/keychain/ckks/CKKSResultOperation.h index b387ba5b..95a14286 100644 --- a/keychain/ckks/CKKSResultOperation.h +++ b/keychain/ckks/CKKSResultOperation.h @@ -27,6 +27,8 @@ #import #import "keychain/ckks/NSOperationCategories.h" +NS_ASSUME_NONNULL_BEGIN + @class CKKSCondition; #define CKKSResultErrorDomain @"CKKSResultOperationError" @@ -36,11 +38,18 @@ enum { CKKSResultTimedOut = 3, }; +#define CKKSResultDescriptionErrorDomain @"CKKSResultOperationDescriptionError" + @interface CKKSResultOperation : NSBlockOperation -@property NSError* error; -@property NSDate* finishDate; +@property (nullable) NSError* error; +@property (nullable) NSDate* finishDate; @property CKKSCondition* completionHandlerDidRunCondition; +@property NSInteger descriptionErrorCode; // Set to non-0 for inclusion of this operation in NSError chains. Code is application-dependent. + +// If you subclass CKKSResultOperation, this is the method corresponding to descriptionErrorCode. Fill it in to your heart's content. +- (NSError* _Nullable)descriptionError; + // Very similar to addDependency, but: // if the dependent operation has an error or is canceled, cancel this operation - (void)addSuccessDependency:(CKKSResultOperation*)operation; @@ -66,7 +75,11 @@ enum { // Call this to prevent the timeout on this operation from occuring. // Upon return, either this operation is cancelled, or the timeout will never fire. - (void)invalidateTimeout; + +// Reports the state of this operation. Used for making up description strings. +- (NSString*)operationStateString; @end +NS_ASSUME_NONNULL_END #endif // OCTAGON diff --git a/keychain/ckks/CKKSResultOperation.m b/keychain/ckks/CKKSResultOperation.m index f92f957f..94612530 100644 --- a/keychain/ckks/CKKSResultOperation.m +++ b/keychain/ckks/CKKSResultOperation.m @@ -54,12 +54,16 @@ return self; } +- (NSString*)operationStateString { + return ([self isFinished] ? [NSString stringWithFormat:@"finished %@", self.finishDate] : + [self isCancelled] ? @"cancelled" : + [self isExecuting] ? @"executing" : + [self isReady] ? @"ready" : + @"pending"); +} + - (NSString*)description { - NSString* state = ([self isFinished] ? [NSString stringWithFormat:@"finished %@", self.finishDate] : - [self isCancelled] ? @"cancelled" : - [self isExecuting] ? @"executing" : - [self isReady] ? @"ready" : - @"pending"); + NSString* state = [self operationStateString]; if(self.error) { return [NSString stringWithFormat: @"<%@: %@ error:%@>", [self selfname], state, self.error]; @@ -86,6 +90,10 @@ strongSelf.finishingBlock(); completionBlock(); [strongSelf.completionHandlerDidRunCondition fulfill]; + + for (NSOperation *op in strongSelf.dependencies) { + [strongSelf removeDependency:op]; + } }]; } @@ -109,14 +117,57 @@ }); } +- (NSError* _Nullable)dependenciesDescriptionError { + NSError* underlyingReason = nil; + NSArray* dependencies = [self.dependencies copy]; + dependencies = [dependencies objectsAtIndexes: [dependencies indexesOfObjectsPassingTest: ^BOOL (id obj, + NSUInteger idx, + BOOL* stop) { + return [obj isFinished] ? NO : YES; + }]]; + + for(NSOperation* dependency in dependencies) { + if([dependency isKindOfClass:[CKKSResultOperation class]]) { + CKKSResultOperation* ro = (CKKSResultOperation*)dependency; + underlyingReason = [ro descriptionError] ?: underlyingReason; + } + } + + return underlyingReason; +} + +// Returns, for this CKKSResultOperation, an error describing this operation or its dependents. +// Used mainly by other CKKSResultOperations who time out waiting for this operation to start/complete. +- (NSError* _Nullable)descriptionError { + if(self.descriptionErrorCode != 0) { + return [NSError errorWithDomain:CKKSResultDescriptionErrorDomain + code:self.descriptionErrorCode + userInfo:nil]; + } else { + return [self dependenciesDescriptionError]; + } +} + +- (NSError*)_onqueueTimeoutError { + // Find if any of our dependencies are CKKSResultOperations with a custom reason for existing + + NSError* underlyingReason = [self descriptionError]; + + NSError* error = [NSError errorWithDomain:CKKSResultErrorDomain + code:CKKSResultTimedOut + description:[NSString stringWithFormat:@"Operation(%@) timed out waiting to start for [%@]", + [self selfname], + [self pendingDependenciesString:@""]] + underlying:underlyingReason]; + return error; +} + - (instancetype)timeout:(dispatch_time_t)timeout { __weak __typeof(self) weakSelf = self; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, timeout), self.timeoutQueue, ^{ __strong __typeof(self) strongSelf = weakSelf; if(strongSelf.timeoutCanOccur) { - strongSelf.error = [NSError errorWithDomain:CKKSResultErrorDomain - code:CKKSResultTimedOut - description:[NSString stringWithFormat:@"Operation(%@) timed out waiting to start for [%@]", [self selfname], [self pendingDependenciesString:@""]]]; + strongSelf.error = [self _onqueueTimeoutError]; strongSelf.timeoutCanOccur = false; [strongSelf cancel]; } @@ -167,7 +218,10 @@ // Already a subresult, just copy it on in self.error = op.error; } else { - self.error = [NSError errorWithDomain:CKKSResultErrorDomain code: CKKSResultSubresultError userInfo:@{ NSUnderlyingErrorKey: op.error}]; + self.error = [NSError errorWithDomain:CKKSResultErrorDomain + code:CKKSResultSubresultError + description:@"Success-dependent operation failed" + underlying:op.error]; } } } diff --git a/keychain/ckks/CKKSScanLocalItemsOperation.h b/keychain/ckks/CKKSScanLocalItemsOperation.h index b1b7754d..2f2d2705 100644 --- a/keychain/ckks/CKKSScanLocalItemsOperation.h +++ b/keychain/ckks/CKKSScanLocalItemsOperation.h @@ -36,6 +36,8 @@ @property size_t recordsFound; @property size_t recordsAdded; +@property size_t missingLocalItemsFound; + - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks ckoperationGroup:(CKOperationGroup*)ckoperationGroup; diff --git a/keychain/ckks/CKKSScanLocalItemsOperation.m b/keychain/ckks/CKKSScanLocalItemsOperation.m index cc42a1d5..a60a5ff0 100644 --- a/keychain/ckks/CKKSScanLocalItemsOperation.m +++ b/keychain/ckks/CKKSScanLocalItemsOperation.m @@ -23,10 +23,12 @@ #if OCTAGON +#import "keychain/ckks/CKKSAnalytics.h" #import "keychain/ckks/CKKSKeychainView.h" #import "keychain/ckks/CKKSNearFutureScheduler.h" #import "keychain/ckks/CKKSScanLocalItemsOperation.h" #import "keychain/ckks/CKKSMirrorEntry.h" +#import "keychain/ckks/CKKSIncomingQueueEntry.h" #import "keychain/ckks/CKKSOutgoingQueueEntry.h" #import "keychain/ckks/CKKSGroupOperation.h" #import "keychain/ckks/CKKSKey.h" @@ -39,10 +41,13 @@ #include #include #include +#include +#import +#import @interface CKKSScanLocalItemsOperation () @property CKOperationGroup* ckoperationGroup; -@property (assign) NSUInteger processsedItems; +@property (assign) NSUInteger processedItems; @end @implementation CKKSScanLocalItemsOperation @@ -82,6 +87,9 @@ __block NSError* error = nil; __block bool newEntries = false; + // We want this set to be empty after scanning, or else the keychain (silently) dropped something on the floor + NSMutableSet* mirrorUUIDs = [NSMutableSet setWithArray:[CKKSMirrorEntry allUUIDs:ckks.zoneID error:&error]]; + // Must query per-class, so: const SecDbSchema *newSchema = current_schema(); for (const SecDbClass *const *class = newSchema->classes; *class != NULL; class++) { @@ -116,7 +124,7 @@ return SecDbItemQuery(q, NULL, dbt, &cferror, ^(SecDbItemRef item, bool *stop) { ckksnotice("ckksscan", ckks, "scanning item: %@", item); - self.processsedItems += 1; + self.processedItems += 1; SecDbItemRef itemToSave = NULL; @@ -179,6 +187,7 @@ if ([CKKSManifest shouldSyncManifests]) { [itemsForManifest addObject:ckme.item]; } + [mirrorUUIDs removeObject:uuid]; ckksinfo("ckksscan", ckks, "Existing mirror entry with UUID %@", uuid); return; } @@ -243,7 +252,45 @@ } } - //[CKKSPowerCollection CKKSPowerEvent:kCKKSPowerEventScanLocalItems zone:ckks.zoneName count:self.processsedItems]; + // We're done checking local keychain for extra items, now let's make sure the mirror doesn't have extra items, either + if (mirrorUUIDs.count > 0) { + ckksnotice("ckksscan", ckks, "keychain missing %lu items from mirror, proceeding with queue scanning", mirrorUUIDs.count); + [mirrorUUIDs minusSet:[NSSet setWithArray:[CKKSIncomingQueueEntry allUUIDs:ckks.zoneID error:&error]]]; + if (error) { + ckkserror("ckksscan", ckks, "unable to inspect incoming queue: %@", error); + self.error = error; + return false; + } + + [mirrorUUIDs minusSet:[NSSet setWithArray:[CKKSOutgoingQueueEntry allUUIDs:ckks.zoneID error:&error]]]; + if (error) { + ckkserror("ckksscan", ckks, "unable to inspect outgoing queue: %@", error); + self.error = error; + return false; + } + + if (mirrorUUIDs.count > 0) { + ckkserror("ckksscan", ckks, "BUG: keychain missing %lu items from mirror and/or queues: %@", mirrorUUIDs.count, mirrorUUIDs); + self.missingLocalItemsFound = mirrorUUIDs.count; + + [[CKKSAnalytics logger] logMetric:[NSNumber numberWithUnsignedInteger:mirrorUUIDs.count] withName:CKKSEventMissingLocalItemsFound]; + + for (NSString* uuid in mirrorUUIDs) { + CKKSMirrorEntry* ckme = [CKKSMirrorEntry tryFromDatabase:uuid zoneID:ckks.zoneID error:&error]; + [ckks _onqueueCKRecordChanged:ckme.item.storedCKRecord resync:true]; + } + + // And, if you're not in the tests, try to collect a sysdiagnose I guess? + // Re-enable IMCore autosysdiagnose capture to securityd + //if(SecIsInternalRelease() && !SecCKKSTestsEnabled()) { + // [[IMCloudKitHooks sharedInstance] tryToAutoCollectLogsWithErrorString:@"35810558" sendLogsTo:@"rowdy_bot@icloud.com"]; + //} + } else { + ckksnotice("ckksscan", ckks, "No missing local items found"); + } + } + + [CKKSPowerCollection CKKSPowerEvent:kCKKSPowerEventScanLocalItems zone:ckks.zoneName count:self.processedItems]; if ([CKKSManifest shouldSyncManifests]) { // TODO: this manifest needs to incorporate peer manifests @@ -272,6 +319,10 @@ [ckks processOutgoingQueue:self.ckoperationGroup]; } + if(self.missingLocalItemsFound > 0) { + [ckks processIncomingQueue:false]; + } + ckksnotice("ckksscan", ckks, "Completed scan"); ckks.droppedItems = false; return true; diff --git a/keychain/ckks/CKKSSynchronizeOperation.m b/keychain/ckks/CKKSSynchronizeOperation.m index c1c77318..16434514 100644 --- a/keychain/ckks/CKKSSynchronizeOperation.m +++ b/keychain/ckks/CKKSSynchronizeOperation.m @@ -94,7 +94,9 @@ [self dependOnBeforeGroupFinished:outgoingOp]; // Step 2 - CKKSFetchAllRecordZoneChangesOperation* fetchOp = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithCKKSKeychainView:ckks ckoperationGroup:operationGroup]; + CKKSFetchAllRecordZoneChangesOperation* fetchOp = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithCKKSKeychainView:ckks + fetchReasons:[NSSet setWithObject:CKKSFetchBecauseResync] + ckoperationGroup:operationGroup]; fetchOp.name = [NSString stringWithFormat: @"resync-step%u-fetch", self.restartCount * steps + 2]; [fetchOp addSuccessDependency: outgoingOp]; [self runBeforeGroupFinished: fetchOp]; @@ -108,7 +110,9 @@ // Now, get serious: // Step 4 - CKKSFetchAllRecordZoneChangesOperation* fetchAllOp = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithCKKSKeychainView:ckks ckoperationGroup:operationGroup]; + CKKSFetchAllRecordZoneChangesOperation* fetchAllOp = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithCKKSKeychainView:ckks + fetchReasons:[NSSet setWithObject:CKKSFetchBecauseResync] + ckoperationGroup:operationGroup]; fetchAllOp.resync = true; fetchAllOp.name = [NSString stringWithFormat: @"resync-step%u-fetchAll", self.restartCount * steps + 4]; [fetchAllOp addSuccessDependency: incomingOp]; diff --git a/keychain/ckks/CKKSTLKShare.h b/keychain/ckks/CKKSTLKShare.h index 239e492a..18f590a8 100644 --- a/keychain/ckks/CKKSTLKShare.h +++ b/keychain/ckks/CKKSTLKShare.h @@ -69,6 +69,8 @@ typedef NS_ENUM(NSUInteger, SecCKKSTLKShareVersion) { poisoned:(NSInteger)poisoned error:(NSError**)error; +- (bool)signatureVerifiesWithPeerSet:(NSSet>*)peerSet error:(NSError**)error; + // Database loading + (instancetype _Nullable)fromDatabase:(NSString*)uuid receiverPeerID:(NSString*)receiverPeerID diff --git a/keychain/ckks/CKKSTLKShare.m b/keychain/ckks/CKKSTLKShare.m index fd3b269a..20f7b6ff 100644 --- a/keychain/ckks/CKKSTLKShare.m +++ b/keychain/ckks/CKKSTLKShare.m @@ -23,6 +23,8 @@ #if OCTAGON +#import + #import "keychain/ckks/CKKSTLKShare.h" #import "keychain/ckks/CKKSPeer.h" #import "keychain/ckks/CloudKitCategories.h" @@ -95,7 +97,7 @@ } - (NSString*)description { - return [NSString stringWithFormat:@"", self.tlkUUID, self.receiver.peerID, self.senderPeerID]; + return [NSString stringWithFormat:@"", self.tlkUUID, self.receiver, self.senderPeerID]; } - (NSData*)wrap:(CKKSKey*)key publicKey:(SFECPublicKey*)receiverPublicKey error:(NSError* __autoreleasing *)error { @@ -108,18 +110,15 @@ SFIESCiphertext* ciphertext = [sfieso encrypt:plaintext withKey:receiverPublicKey error:error]; // Now use NSCoding to turn the ciphertext into something transportable - NSMutableData* data = [NSMutableData data]; - NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; [ciphertext encodeWithCoder:archiver]; - [archiver finishEncoding]; - return data; + return archiver.encodedData; } - (CKKSKey*)unwrapUsing:(id)localPeer error:(NSError * __autoreleasing *)error { // Unwrap the ciphertext using NSSecureCoding - NSKeyedUnarchiver *coder = [[NSKeyedUnarchiver alloc] initForReadingWithData:self.wrappedTLK]; - coder.requiresSecureCoding = YES; + NSKeyedUnarchiver *coder = [[NSKeyedUnarchiver alloc] initForReadingFromData:self.wrappedTLK error:nil]; SFIESCiphertext* ciphertext = [[SFIESCiphertext alloc] initWithCoder:coder]; [coder finishDecoding]; @@ -229,6 +228,16 @@ } - (bool)verifySignature:(NSData*)signature verifyingPeer:(id)peer error:(NSError* __autoreleasing *)error { + if(!peer.publicSigningKey) { + secerror("ckksshare: no signing key for peer: %@", peer); + if(error) { + *error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSNoSigningKey + description:[NSString stringWithFormat:@"Peer(%@) has no signing key", peer]]; + } + return false; + } + // TODO: the digest operation can't be changed, as we don't have a good way of communicating it, like self.curve SFEC_X962SigningOperation* xso = [[SFEC_X962SigningOperation alloc] initWithKeySpecifier:[[SFECKeySpecifier alloc] initWithCurve:self.curve] digestOperation:[[SFSHA256DigestOperation alloc] init]]; @@ -238,6 +247,35 @@ return ret; } +- (bool)signatureVerifiesWithPeerSet:(NSSet>*)peerSet error:(NSError**)error { + NSError* lastVerificationError = nil; + for(id peer in peerSet) { + if([peer.peerID isEqualToString: self.senderPeerID]) { + // Does the signature verify using this peer? + NSError* localerror = nil; + bool isSigned = [self verifySignature:self.signature verifyingPeer:peer error:&localerror]; + if(localerror) { + secerror("ckksshare: signature didn't verify for %@ %@: %@", self, peer, localerror); + lastVerificationError = localerror; + } + if(isSigned) { + return true; + } + } + } + + if(error) { + if(lastVerificationError) { + *error = lastVerificationError; + } else { + *error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSNoTrustedTLKShares + description:[NSString stringWithFormat:@"No TLK share from %@", self.senderPeerID]]; + } + } + return false; +} + - (instancetype)copyWithZone:(NSZone *)zone { CKKSTLKShare* share = [[[self class] allocWithZone:zone] init]; share.curve = self.curve; diff --git a/keychain/ckks/CKKSUpdateCurrentItemPointerOperation.h b/keychain/ckks/CKKSUpdateCurrentItemPointerOperation.h index 3cdbdd92..47465f9f 100644 --- a/keychain/ckks/CKKSUpdateCurrentItemPointerOperation.h +++ b/keychain/ckks/CKKSUpdateCurrentItemPointerOperation.h @@ -21,21 +21,28 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if OCTAGON + #import "keychain/ckks/CKKSGroupOperation.h" #import "keychain/ckks/CKKSKeychainView.h" +NS_ASSUME_NONNULL_BEGIN -#if OCTAGON @interface CKKSUpdateCurrentItemPointerOperation : CKKSGroupOperation -@property (weak) CKKSKeychainView* ckks; +@property (weak,nullable) CKKSKeychainView* ckks; + +@property NSString* currentPointerIdentifier; - (instancetype)init NS_UNAVAILABLE; -- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks - currentPointer:(NSString*)identifier - oldItemUUID:(NSString*)oldItemUUID - oldItemHash:(NSData*)oldItemHash - newItemUUID:(NSString*)newItemUUID - ckoperationGroup:(CKOperationGroup*)ckoperationGroup; +- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView* _Nonnull)ckks + newItem:(NSData* _Nonnull)newItemPersistentRef + hash:(NSData* _Nonnull)newItemSHA1 + accessGroup:(NSString* _Nonnull)accessGroup + identifier:(NSString* _Nonnull)identifier + replacing:(NSData* _Nullable)oldCurrentItemPersistentRef + hash:(NSData* _Nullable)oldItemSHA1 + ckoperationGroup:(CKOperationGroup* _Nullable)ckoperationGroup; @end +NS_ASSUME_NONNULL_END #endif // OCTAGON diff --git a/keychain/ckks/CKKSUpdateCurrentItemPointerOperation.m b/keychain/ckks/CKKSUpdateCurrentItemPointerOperation.m index 39a2d886..95efedba 100644 --- a/keychain/ckks/CKKSUpdateCurrentItemPointerOperation.m +++ b/keychain/ckks/CKKSUpdateCurrentItemPointerOperation.m @@ -31,39 +31,62 @@ #import "keychain/ckks/CKKSManifest.h" #import "keychain/ckks/CloudKitCategories.h" +#include +#include +#include +#include +#include #import @interface CKKSUpdateCurrentItemPointerOperation () -@property CKModifyRecordsOperation* modifyRecordsOperation; -@property CKOperationGroup* ckoperationGroup; +@property (nullable) CKModifyRecordsOperation* modifyRecordsOperation; +@property (nullable) CKOperationGroup* ckoperationGroup; -@property NSString* currentPointerIdentifier; -@property NSString* oldCurrentItemUUID; -@property NSData* oldCurrentItemHash; -@property NSString* currentItemUUID; +@property (nonnull) NSString* accessGroup; + +@property (nonnull) NSData* newerItemPersistentRef; +@property (nonnull) NSData* newerItemSHA1; +@property (nullable) NSData* oldItemPersistentRef; +@property (nullable) NSData* oldItemSHA1; + +// Store these as properties, so we can release them in our -dealloc +@property (nullable) SecDbItemRef newItem; +@property (nullable) SecDbItemRef oldItem; @end @implementation CKKSUpdateCurrentItemPointerOperation -- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*) ckks - currentPointer:(NSString*)identifier - oldItemUUID:(NSString*)oldItemUUID - oldItemHash:(NSData*)oldItemHash - newItemUUID:(NSString*)newItemUUID +- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks + newItem:(NSData*)newItemPersistentRef + hash:(NSData*)newItemSHA1 + accessGroup:(NSString*)accessGroup + identifier:(NSString*)identifier + replacing:(NSData* _Nullable)oldCurrentItemPersistentRef + hash:(NSData*)oldItemSHA1 ckoperationGroup:(CKOperationGroup*)ckoperationGroup { if((self = [super init])) { _ckks = ckks; - _currentPointerIdentifier = identifier; - _oldCurrentItemUUID = oldItemUUID; - _oldCurrentItemHash = oldItemHash; - _currentItemUUID = newItemUUID; - _ckoperationGroup = ckoperationGroup; + _newerItemPersistentRef = newItemPersistentRef; + _newerItemSHA1 = newItemSHA1; + _oldItemPersistentRef = oldCurrentItemPersistentRef; + _oldItemSHA1 = oldItemSHA1; + + _accessGroup = accessGroup; + + _currentPointerIdentifier = [NSString stringWithFormat:@"%@-%@", accessGroup, identifier]; } return self; } +- (void)dealloc { + if(self) { + CFReleaseNull(self->_newItem); + CFReleaseNull(self->_oldItem); + } +} + - (void)groupStart { CKKSKeychainView* ckks = self.ckks; if(!ckks) { @@ -78,11 +101,75 @@ [ckks dispatchSyncWithAccountKeys:^bool { if(self.cancelled) { - ckksnotice("ckksscan", ckks, "CKKSUpdateCurrentItemPointerOperation cancelled, quitting"); + ckksnotice("ckkscurrent", ckks, "CKKSUpdateCurrentItemPointerOperation cancelled, quitting"); return false; } NSError* error = nil; + CFErrorRef cferror = NULL; + + NSString* newItemUUID = nil; + NSString* oldCurrentItemUUID = nil; + + self.newItem = [self _onqueueFindSecDbItem:self.newerItemPersistentRef accessGroup:self.accessGroup error:&error]; + if(!self.newItem || error) { + ckksnotice("ckkscurrent", ckks, "Couldn't fetch new item, quitting: %@", error); + self.error = error; + return false; + } + + // Now that we're on the db queue, ensure that the given hashes for the items match the hashes as they are now. + // That is, the items haven't changed since the caller knew about the item. + NSData* newItemComputedSHA1 = (NSData*) CFBridgingRelease(CFRetainSafe(SecDbItemGetSHA1(self.newItem, &cferror))); + if(!newItemComputedSHA1 || cferror || + ![newItemComputedSHA1 isEqual:self.newerItemSHA1]) { + ckksnotice("ckkscurrent", ckks, "Hash mismatch for new item: %@ vs %@", newItemComputedSHA1, self.newerItemSHA1); + self.error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSItemChanged + description:@"New item has changed; hashes mismatch. Refetch and try again." + underlying:(NSError*)CFBridgingRelease(cferror)]; + return false; + } + + newItemUUID = (NSString*) CFBridgingRelease(CFRetainSafe(SecDbItemGetValue(self.newItem, &v10itemuuid, &cferror))); + if(!newItemUUID || cferror) { + ckkserror("ckkscurrent", ckks, "Error fetching UUID for new item: %@", cferror); + self.error = (NSError*) CFBridgingRelease(cferror); + return false; + } + + // If the old item is nil, that's an indicator that the old item isn't expected to exist in the keychain anymore + NSData* oldCurrentItemHash = nil; + if(self.oldItemPersistentRef) { + self.oldItem = [self _onqueueFindSecDbItem:self.oldItemPersistentRef accessGroup:self.accessGroup error:&error]; + if(!self.oldItem || error) { + ckksnotice("ckkscurrent", ckks, "Couldn't fetch old item, quitting: %@", error); + self.error = error; + return false; + } + + oldCurrentItemHash = (NSData*) CFBridgingRelease(CFRetainSafe(SecDbItemGetSHA1(self.oldItem, &cferror))); + if(!oldCurrentItemHash || cferror || + ![oldCurrentItemHash isEqual:self.oldItemSHA1]) { + ckksnotice("ckkscurrent", ckks, "Hash mismatch for old item: %@ vs %@", oldCurrentItemHash, self.oldItemSHA1); + self.error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSItemChanged + description:@"Old item has changed; hashes mismatch. Refetch and try again." + underlying:(NSError*)CFBridgingRelease(cferror)]; + return false; + } + + oldCurrentItemUUID = (NSString*) CFBridgingRelease(CFRetainSafe(SecDbItemGetValue(self.oldItem, &v10itemuuid, &cferror))); + if(!oldCurrentItemUUID || cferror) { + ckkserror("ckkscurrent", ckks, "Error fetching UUID for old item: %@", cferror); + self.error = (NSError*) CFBridgingRelease(cferror); + return false; + } + } + + ////////////////////////////// + // At this point, we've completed all the checks we need for the SecDbItems. Try to launch this boat! + ckksnotice("ckkscurrent", ckks, "Setting current pointer for %@ to %@ (from %@)", self.currentPointerIdentifier, newItemUUID, oldCurrentItemUUID); // Ensure that there's no pending pointer update CKKSCurrentItemPointer* cipPending = [CKKSCurrentItemPointer tryFromDatabase:self.currentPointerIdentifier state:SecCKKSProcessedStateRemote zoneID:ckks.zoneID error:&error]; @@ -103,42 +190,46 @@ // have a CIP, but it points to a deleted keychain item. // In that case, we shouldn't error out. // - if(self.oldCurrentItemHash && ![cip.currentItemUUID isEqualToString: self.oldCurrentItemUUID]) { + if(oldCurrentItemHash && ![cip.currentItemUUID isEqualToString: oldCurrentItemUUID]) { - ckksnotice("ckkscurrent", ckks, "Caller's idea of the current item pointer %@ doesn't match (%@); rejecting change of current", cip, self.oldCurrentItemUUID); + ckksnotice("ckkscurrent", ckks, "current item pointer(%@) doesn't match user-supplied UUID (%@); rejecting change of current", cip, oldCurrentItemUUID); self.error = [NSError errorWithDomain:CKKSErrorDomain code:CKKSItemChanged - description:[NSString stringWithFormat:@"Current pointer(%@) does not match user-supplied %@, aborting", cip, self.oldCurrentItemUUID]]; + description:[NSString stringWithFormat:@"Current pointer(%@) does not match user-supplied %@, aborting", cip, oldCurrentItemUUID]]; return false; } // Cool. Since you know what you're updating, you're allowed to update! - cip.currentItemUUID = self.currentItemUUID; + cip.currentItemUUID = newItemUUID; - } else if(self.oldCurrentItemUUID) { + } else if(oldCurrentItemUUID) { // Error case: the client thinks there's a current pointer, but we don't have one ckksnotice("ckkscurrent", ckks, "Requested to update a current item pointer but one doesn't exist at %@; rejecting change of current", self.currentPointerIdentifier); self.error = [NSError errorWithDomain:CKKSErrorDomain code:CKKSItemChanged - description:[NSString stringWithFormat:@"Current pointer(%@) does not match given value of '%@', aborting", cip, self.oldCurrentItemUUID]]; + description:[NSString stringWithFormat:@"Current pointer(%@) does not match given value of '%@', aborting", cip, oldCurrentItemUUID]]; return false; } else { // No current item pointer? How exciting! Let's make you a nice new one. - cip = [[CKKSCurrentItemPointer alloc] initForIdentifier:self.currentPointerIdentifier currentItemUUID:self.currentItemUUID state:SecCKKSProcessedStateLocal zoneID:ckks.zoneID encodedCKRecord:nil]; + cip = [[CKKSCurrentItemPointer alloc] initForIdentifier:self.currentPointerIdentifier + currentItemUUID:newItemUUID + state:SecCKKSProcessedStateLocal + zoneID:ckks.zoneID + encodedCKRecord:nil]; ckksnotice("ckkscurrent", ckks, "Creating a new current item pointer: %@", cip); } // Check if either item is currently in any sync queue, and fail if so NSArray* oqes = [CKKSOutgoingQueueEntry allUUIDs:ckks.zoneID error:&error]; NSArray* iqes = [CKKSIncomingQueueEntry allUUIDs:ckks.zoneID error:&error]; - if([oqes containsObject:self.currentItemUUID] || [iqes containsObject:self.currentItemUUID]) { + if([oqes containsObject:newItemUUID] || [iqes containsObject:newItemUUID]) { error = [NSError errorWithDomain:CKKSErrorDomain code:CKKSLocalItemChangePending - description:[NSString stringWithFormat:@"New item(%@) is being synced; can't set current pointer.", self.currentItemUUID]]; + description:[NSString stringWithFormat:@"New item(%@) is being synced; can't set current pointer.", newItemUUID]]; } - if([oqes containsObject: self.oldCurrentItemUUID] || [iqes containsObject:self.oldCurrentItemUUID]) { + if([oqes containsObject:oldCurrentItemUUID] || [iqes containsObject:oldCurrentItemUUID]) { error = [NSError errorWithDomain:CKKSErrorDomain code:CKKSLocalItemChangePending - description:[NSString stringWithFormat:@"Old item(%@) is being synced; can't set current pointer.", self.oldCurrentItemUUID]]; + description:[NSString stringWithFormat:@"Old item(%@) is being synced; can't set current pointer.", oldCurrentItemUUID]]; } if(error) { @@ -161,7 +252,7 @@ } if ([CKKSManifest shouldSyncManifests]) { - [ckks.egoManifest setCurrentItemUUID:self.currentItemUUID forIdentifier:self.currentPointerIdentifier]; + [ckks.egoManifest setCurrentItemUUID:newItemUUID forIdentifier:self.currentPointerIdentifier]; } ckksnotice("ckkscurrent", ckks, "Saving new current item pointer %@", cip); @@ -183,8 +274,7 @@ self.modifyRecordsOperation = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:recordsToSave.allValues recordIDsToDelete:nil]; self.modifyRecordsOperation.atomic = TRUE; - self.modifyRecordsOperation.timeoutIntervalForRequest = 2; - self.modifyRecordsOperation.qualityOfService = NSQualityOfServiceUtility; + self.modifyRecordsOperation.qualityOfService = NSQualityOfServiceUserInitiated; // We're likely rolling a PCS identity, or creating a new one. User cares. self.modifyRecordsOperation.savePolicy = CKRecordSaveIfServerRecordUnchanged; self.modifyRecordsOperation.group = self.ckoperationGroup; @@ -265,6 +355,79 @@ }]; } +- (SecDbItemRef _Nullable)_onqueueFindSecDbItem:(NSData*)persistentRef accessGroup:(NSString*)accessGroup error:(NSError**)error { + __block SecDbItemRef blockItem = NULL; + CFErrorRef cferror = NULL; + __block NSError* localerror = NULL; + + CKKSKeychainView* ckks = self.ckks; + bool ok = kc_with_dbt(true, &cferror, ^bool (SecDbConnectionRef dbt) { + // Find the items from their persistent refs. + CFErrorRef blockcfError = NULL; + Query *q = query_create_with_limit( (__bridge CFDictionaryRef) @{ + (__bridge NSString *)kSecValuePersistentRef : persistentRef, + (__bridge NSString *)kSecAttrAccessGroup : accessGroup, + }, + NULL, + 1, + &blockcfError); + if(blockcfError || !q) { + ckkserror("ckkscurrent", ckks, "couldn't create query for item persistentRef: %@", blockcfError); + localerror = [NSError errorWithDomain:CKKSErrorDomain + code:errSecParam + description:@"couldn't create query for new item pref" + underlying:(NSError*)CFBridgingRelease(blockcfError)]; + return false; + } + + if(!SecDbItemQuery(q, NULL, dbt, &blockcfError, ^(SecDbItemRef item, bool *stop) { + blockItem = CFRetainSafe(item); + })) { + query_destroy(q, NULL); + ckkserror("ckkscurrent", ckks, "couldn't run query for item pref: %@", blockcfError); + localerror = [NSError errorWithDomain:CKKSErrorDomain + code:errSecParam + description:@"couldn't run query for new item pref" + underlying:(NSError*)CFBridgingRelease(blockcfError)]; + return false; + } + + if(!query_destroy(q, &blockcfError)) { + ckkserror("ckkscurrent", ckks, "couldn't destroy query for item pref: %@", blockcfError); + localerror = [NSError errorWithDomain:CKKSErrorDomain + code:errSecParam + description:@"couldn't destroy query for item pref" + underlying:(NSError*)CFBridgingRelease(blockcfError)]; + return false; + } + return true; + }); + + if(!ok || localerror) { + if(localerror) { + ckkserror("ckkscurrent", ckks, "Query failed: %@", localerror); + if(error) { + *error = localerror; + } + } else { + ckkserror("ckkscurrent", ckks, "Query failed, cferror is %@", cferror); + localerror = [NSError errorWithDomain:CKKSErrorDomain + code:errSecParam + description:@"couldn't run query" + underlying:(NSError*)CFBridgingRelease(cferror)]; + if(*error) { + *error = localerror; + } + } + + CFReleaseSafe(cferror); + return false; + } + + CFReleaseSafe(cferror); + return blockItem; +} + @end #endif // OCTAGON diff --git a/keychain/ckks/CKKSUpdateDeviceStateOperation.m b/keychain/ckks/CKKSUpdateDeviceStateOperation.m index 0a78ec84..6223fcf0 100644 --- a/keychain/ckks/CKKSUpdateDeviceStateOperation.m +++ b/keychain/ckks/CKKSUpdateDeviceStateOperation.m @@ -124,7 +124,6 @@ self.modifyRecordsOperation = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:recordsToSave recordIDsToDelete:nil]; self.modifyRecordsOperation.atomic = TRUE; - self.modifyRecordsOperation.timeoutIntervalForRequest = 2; self.modifyRecordsOperation.qualityOfService = NSQualityOfServiceUtility; self.modifyRecordsOperation.savePolicy = CKRecordSaveAllKeys; // Overwrite anything in CloudKit: this is our state now self.modifyRecordsOperation.group = self.group; diff --git a/keychain/ckks/CKKSViewManager.h b/keychain/ckks/CKKSViewManager.h index 06f24aa7..317930a6 100644 --- a/keychain/ckks/CKKSViewManager.h +++ b/keychain/ckks/CKKSViewManager.h @@ -33,10 +33,12 @@ #import "keychain/ckks/CKKSCondition.h" #import "keychain/ckks/CKKSControlProtocol.h" #import "keychain/ckks/CKKSLockStateTracker.h" +#import "keychain/ckks/CKKSReachabilityTracker.h" #import "keychain/ckks/CKKSNotifier.h" #import "keychain/ckks/CKKSPeer.h" #import "keychain/ckks/CKKSRateLimiter.h" #import "keychain/ckks/CloudKitDependencies.h" +#import "keychain/ot/OTDefines.h" NS_ASSUME_NONNULL_BEGIN @@ -47,6 +49,7 @@ NS_ASSUME_NONNULL_BEGIN @property CKContainer* container; @property CKKSCKAccountStateTracker* accountTracker; @property CKKSLockStateTracker* lockStateTracker; +@property CKKSReachabilityTracker *reachabilityTracker; @property bool initializeNewZones; // Signaled when SecCKKSInitialize is complete, as it's async and likes to fire after tests are complete @@ -68,7 +71,6 @@ NS_ASSUME_NONNULL_BEGIN - (CKKSKeychainView*)findView:(NSString*)viewName; - (CKKSKeychainView*)findOrCreateView:(NSString*)viewName; -+ (CKKSKeychainView*)findOrCreateView:(NSString*)viewName; - (void)setView:(CKKSKeychainView*)obj; - (void)clearView:(NSString*)viewName; @@ -84,12 +86,12 @@ NS_ASSUME_NONNULL_BEGIN added:(SecDbItemRef _Nullable)added deleted:(SecDbItemRef _Nullable)deleted; -- (void)setCurrentItemForAccessGroup:(SecDbItemRef)newItem +- (void)setCurrentItemForAccessGroup:(NSData* _Nonnull)newItemPersistentRef hash:(NSData*)newItemSHA1 accessGroup:(NSString*)accessGroup identifier:(NSString*)identifier viewHint:(NSString*)viewHint - replacing:(SecDbItemRef _Nullable)oldItem + replacing:(NSData* _Nullable)oldCurrentItemPersistentRef hash:(NSData* _Nullable)oldItemSHA1 complete:(void (^)(NSError* operror))complete; @@ -113,9 +115,6 @@ NS_ASSUME_NONNULL_BEGIN // Called by XPC every 24 hours - (void)xpc24HrNotification; -/* Interface to CCKS control channel */ -- (xpc_endpoint_t)xpcControlEndpoint; - /* White-box testing only */ - (CKKSKeychainView*)restartZone:(NSString*)viewName; @@ -130,6 +129,11 @@ NS_ASSUME_NONNULL_BEGIN - (CKKSSelves* _Nullable)fetchSelfPeers:(NSError* __autoreleasing*)error; - (NSSet>* _Nullable)fetchTrustedPeers:(NSError* __autoreleasing*)error; +// For mocking purposes +- (id _Nullable)currentSOSSelf:(NSError**)error; +- (NSSet>*)pastSelves:(NSError**)error; +- (NSArray* _Nullable)loadRestoredBottledKeysOfType:(OctagonKeyType)keyType error:(NSError**)error; + - (void)sendSelfPeerChangedUpdate; - (void)sendTrustedPeerSetChangedUpdate; diff --git a/keychain/ckks/CKKSViewManager.m b/keychain/ckks/CKKSViewManager.m index 1e197fd9..44cadf3f 100644 --- a/keychain/ckks/CKKSViewManager.m +++ b/keychain/ckks/CKKSViewManager.m @@ -31,6 +31,8 @@ #import "keychain/ckks/CKKSCondition.h" #import "keychain/ckks/CloudKitCategories.h" +#import "keychain/ot/OTDefines.h" + #import "SecEntitlements.h" #include @@ -51,7 +53,7 @@ #import #import -#import "CKKSAnalyticsLogger.h" +#import "CKKSAnalytics.h" #endif @interface CKKSViewManager () @@ -78,6 +80,11 @@ #endif @end +#if OCTAGON +@interface CKKSViewManager (lockstateTracker) +@end +#endif + @implementation CKKSViewManager #if OCTAGON @@ -118,6 +125,8 @@ _container = [self makeCKContainer: containerName usePCS:usePCS]; _accountTracker = [[CKKSCKAccountStateTracker alloc] init:self.container nsnotificationCenterClass:nsnotificationCenterClass]; _lockStateTracker = [[CKKSLockStateTracker alloc] init]; + [_lockStateTracker addLockStateObserver:self]; + _reachabilityTracker = [[CKKSReachabilityTracker alloc] init]; _operationQueue = [[NSOperationQueue alloc] init]; @@ -132,7 +141,11 @@ _completedSecCKKSInitialize = [[CKKSCondition alloc] init]; __weak __typeof(self) weakSelf = self; - _savedTLKNotifier = [[CKKSNearFutureScheduler alloc] initWithName: @"newtlks" delay:5*NSEC_PER_SEC keepProcessAlive:true block:^{ + _savedTLKNotifier = [[CKKSNearFutureScheduler alloc] initWithName:@"newtlks" + delay:5*NSEC_PER_SEC + keepProcessAlive:true + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{ [weakSelf notifyNewTLKsInKeychain]; }]; @@ -165,6 +178,88 @@ return container; } +- (void)setupAnalytics +{ + __weak __typeof(self) weakSelf = self; + + // Tests shouldn't continue here; it leads to entitlement crashes with CloudKit if the mocks aren't enabled when this function runs + if(SecCKKSTestsEnabled()) { + return; + } + + [[CKKSAnalytics logger] AddMultiSamplerForName:@"CKKS-healthSummary" withTimeInterval:SFAnalyticsSamplerIntervalOncePerReport block:^NSDictionary *{ + __strong __typeof(self) strongSelf = weakSelf; + if(!strongSelf) { + return nil; + } + + NSMutableDictionary* values = [NSMutableDictionary dictionary]; + BOOL inCircle = (strongSelf.accountTracker.currentCircleStatus == kSOSCCInCircle); + if (inCircle) { + [[CKKSAnalytics logger] setDateProperty:[NSDate date] forKey:CKKSAnalyticsLastInCircle]; + } + values[CKKSAnalyticsInCircle] = @(inCircle); + + BOOL validCredentials = strongSelf.accountTracker.currentCKAccountInfo.hasValidCredentials; + if (!validCredentials) { + values[CKKSAnalyticsValidCredentials] = @(validCredentials); + } + + NSArray* keys = @[ CKKSAnalyticsLastUnlock, CKKSAnalyticsLastInCircle]; + for (NSString * key in keys) { + NSDate *date = [[CKKSAnalytics logger] datePropertyForKey:key]; + values[key] = @([CKKSAnalytics fuzzyDaysSinceDate:date]); + } + return values; + }]; + + for (NSString* viewName in [self viewList]) { + [[CKKSAnalytics logger] AddMultiSamplerForName:[NSString stringWithFormat:@"CKKS-%@-healthSummary", viewName] withTimeInterval:SFAnalyticsSamplerIntervalOncePerReport block:^NSDictionary *{ + __strong __typeof(self) strongSelf = weakSelf; + if(!strongSelf) { + return nil; + } + BOOL inCircle = strongSelf.accountTracker && strongSelf.accountTracker.currentCircleStatus == kSOSCCInCircle; + NSMutableDictionary* values = [NSMutableDictionary dictionary]; + CKKSKeychainView* view = [strongSelf findOrCreateView:viewName]; + NSDate* dateOfLastSyncClassA = [[CKKSAnalytics logger] dateOfLastSuccessForEvent:CKKSEventProcessIncomingQueueClassA inView:view]; + NSDate* dateOfLastSyncClassC = [[CKKSAnalytics logger] dateOfLastSuccessForEvent:CKKSEventProcessIncomingQueueClassC inView:view]; + NSDate* dateOfLastKSR = [[CKKSAnalytics logger] datePropertyForKey:CKKSAnalyticsLastKeystateReady inView:view]; + + NSInteger fuzzyDaysSinceClassASync = [CKKSAnalytics fuzzyDaysSinceDate:dateOfLastSyncClassA]; + NSInteger fuzzyDaysSinceClassCSync = [CKKSAnalytics fuzzyDaysSinceDate:dateOfLastSyncClassC]; + NSInteger fuzzyDaysSinceKSR = [CKKSAnalytics fuzzyDaysSinceDate:dateOfLastKSR]; + [values setValue:@(fuzzyDaysSinceClassASync) forKey:[NSString stringWithFormat:@"%@-daysSinceClassASync", viewName]]; + [values setValue:@(fuzzyDaysSinceClassCSync) forKey:[NSString stringWithFormat:@"%@-daysSinceClassCSync", viewName]]; + [values setValue:@(fuzzyDaysSinceKSR) forKey:[NSString stringWithFormat:@"%@-daysSinceLastKeystateReady", viewName]]; + + BOOL hasTLKs = [view.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateReady] || [view.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateReadyPendingUnlock]; + BOOL syncedClassARecently = fuzzyDaysSinceClassASync < 7; + BOOL syncedClassCRecently = fuzzyDaysSinceClassCSync < 7; + BOOL incomingQueueIsErrorFree = view.lastIncomingQueueOperation.error == nil; + BOOL outgoingQueueIsErrorFree = view.lastOutgoingQueueOperation.error == nil; + + NSString* hasTLKsKey = [NSString stringWithFormat:@"%@-%@", viewName, CKKSAnalyticsHasTLKs]; + NSString* syncedClassARecentlyKey = [NSString stringWithFormat:@"%@-%@", viewName, CKKSAnalyticsSyncedClassARecently]; + NSString* syncedClassCRecentlyKey = [NSString stringWithFormat:@"%@-%@", viewName, CKKSAnalyticsSyncedClassCRecently]; + NSString* incomingQueueIsErrorFreeKey = [NSString stringWithFormat:@"%@-%@", viewName, CKKSAnalyticsIncomingQueueIsErrorFree]; + NSString* outgoingQueueIsErrorFreeKey = [NSString stringWithFormat:@"%@-%@", viewName, CKKSAnalyticsOutgoingQueueIsErrorFree]; + + values[hasTLKsKey] = @(hasTLKs); + values[syncedClassARecentlyKey] = @(syncedClassARecently); + values[syncedClassCRecentlyKey] = @(syncedClassCRecently); + values[incomingQueueIsErrorFreeKey] = @(incomingQueueIsErrorFree); + values[outgoingQueueIsErrorFreeKey] = @(outgoingQueueIsErrorFree); + + BOOL weThinkWeAreInSync = inCircle && hasTLKs && syncedClassARecently && syncedClassCRecently && incomingQueueIsErrorFree && outgoingQueueIsErrorFree; + NSString* inSyncKey = [NSString stringWithFormat:@"%@-%@", viewName, CKKSAnalyticsInSync]; + values[inSyncKey] = @(weThinkWeAreInSync); + + return values; + }]; + } +} + -(void)dealloc { [self clearAllViews]; } @@ -205,6 +300,13 @@ dispatch_once_t globalZoneStateQueueOnce; return _globalRateLimiter; } +- (void)lockStateChangeNotification:(bool)unlocked +{ + if (unlocked) { + [[CKKSAnalytics logger] setDateProperty:[NSDate date] forKey:CKKSAnalyticsLastUnlock]; + } +} + // Mostly exists to be mocked out. -(NSSet*)viewList { return CFBridgingRelease(SOSViewCopyViewSet(kViewSetCKKS)); @@ -267,6 +369,7 @@ dispatch_once_t globalZoneStateQueueOnce; zoneName: viewName accountTracker: self.accountTracker lockStateTracker: self.lockStateTracker + reachabilityTracker: self.reachabilityTracker savedTLKNotifier: self.savedTLKNotifier peerProvider:self fetchRecordZoneChangesOperationClass: self.fetchRecordZoneChangesOperationClass @@ -284,9 +387,6 @@ dispatch_once_t globalZoneStateQueueOnce; return self.views[viewName]; } } -+ (CKKSKeychainView*)findOrCreateView:(NSString*)viewName { - return [[CKKSViewManager manager] findOrCreateView: viewName]; -} - (NSDictionary *)activeTLKs { @@ -305,6 +405,7 @@ dispatch_once_t globalZoneStateQueueOnce; - (CKKSKeychainView*)restartZone:(NSString*)viewName { @synchronized(self.views) { + [self.views[viewName] halt]; self.views[viewName] = nil; } return [self findOrCreateView: viewName]; @@ -325,6 +426,8 @@ dispatch_once_t globalZoneStateQueueOnce; [self findOrCreateView:s]; // initializes any newly-created views } } + + [self setupAnalytics]; } - (NSString*)viewNameForViewHint: (NSString*) viewHint { @@ -421,12 +524,12 @@ dispatch_once_t globalZoneStateQueueOnce; [view handleKeychainEventDbConnection: dbconn added:added deleted:deleted rateLimiter:self.globalRateLimiter syncCallback: syncCallback]; } --(void)setCurrentItemForAccessGroup:(SecDbItemRef)newItem +-(void)setCurrentItemForAccessGroup:(NSData* _Nonnull)newItemPersistentRef hash:(NSData*)newItemSHA1 accessGroup:(NSString*)accessGroup identifier:(NSString*)identifier viewHint:(NSString*)viewHint - replacing:(SecDbItemRef)oldItem + replacing:(NSData* _Nullable)oldCurrentItemPersistentRef hash:(NSData*)oldItemSHA1 complete:(void (^) (NSError* operror)) complete { @@ -440,11 +543,11 @@ dispatch_once_t globalZoneStateQueueOnce; return; } - [view setCurrentItemForAccessGroup:newItem + [view setCurrentItemForAccessGroup:newItemPersistentRef hash:newItemSHA1 accessGroup:accessGroup identifier:identifier - replacing:oldItem + replacing:oldCurrentItemPersistentRef hash:oldItemSHA1 complete:complete]; } @@ -492,7 +595,7 @@ dispatch_once_t globalZoneStateQueueOnce; if(reset) { [manager clearAllViews]; manager = nil; - } else if (manager == nil) { + } else if (manager == nil && SecCKKSIsEnabled()) { manager = [[CKKSViewManager alloc] initCloudKitWithContainerName:SecCKKSContainerName usePCS:SecCKKSContainerUsePCS]; } } @@ -529,26 +632,6 @@ dispatch_once_t globalZoneStateQueueOnce; }]; } -#pragma mark - XPC Endpoint - -- (xpc_endpoint_t)xpcControlEndpoint { - return [_listener.endpoint _endpoint]; -} - -- (BOOL)listener:(__unused NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection { - NSNumber *num = [newConnection valueForEntitlement:(__bridge NSString *)kSecEntitlementPrivateCKKS]; - if (![num isKindOfClass:[NSNumber class]] || ![num boolValue]) { - secinfo("ckks", "Client pid: %d doesn't have entitlement: %@", - [newConnection processIdentifier], kSecEntitlementPrivateCKKS); - return NO; - } - newConnection.exportedInterface = CKKSSetupControlProtocol([NSXPCInterface interfaceWithProtocol:@protocol(CKKSControlProtocol)]); - newConnection.exportedObject = self; - - [newConnection resume]; - - return YES; -} #pragma mark - RPCs to manage and report state - (void)performanceCounters:(void(^)(NSDictionary *counter))reply { @@ -558,10 +641,16 @@ dispatch_once_t globalZoneStateQueueOnce; - (NSArray*)views:(NSString*)viewName operation:(NSString*)opName error:(NSError**)error { NSArray* actualViews = nil; + + // Ensure we've actually set up, but don't wait too long. Clients get impatient. + if([self.completedSecCKKSInitialize wait:5*NSEC_PER_SEC]) { + secerror("ckks: Haven't yet initialized zones; expect failure fetching views"); + } + @synchronized(self.views) { if(viewName) { - secnotice("ckks", "Received a %@ request for zone %@", opName, viewName); CKKSKeychainView* view = self.views[viewName]; + secnotice("ckks", "Received a %@ request for zone %@ (%@)", opName, viewName, view); if(!view) { if(error) { @@ -574,8 +663,8 @@ dispatch_once_t globalZoneStateQueueOnce; actualViews = @[view]; } else { - secnotice("ckks", "Received a %@ request for all zones", opName); actualViews = [self.views.allValues copy]; + secnotice("ckks", "Received a %@ request for all zones: %@", opName, actualViews); } } return actualViews; @@ -590,7 +679,14 @@ dispatch_once_t globalZoneStateQueueOnce; return; } - CKKSResultOperation* op = [CKKSResultOperation named:@"local-reset-zones-waiter" withBlock:^{}]; + CKKSResultOperation* op = [CKKSResultOperation named:@"local-reset-zones-waiter" withBlockTakingSelf:^(CKKSResultOperation * _Nonnull strongOp) { + if(!strongOp.error) { + secnotice("ckksreset", "Completed rpcResetLocal"); + } else { + secnotice("ckks", "Completed rpcResetLocal with error: %@", strongOp.error); + } + reply(CKXPCSuitableError(strongOp.error)); + }]; for(CKKSKeychainView* view in actualViews) { ckksnotice("ckksreset", view, "Beginning local reset for %@", view); @@ -599,14 +695,6 @@ dispatch_once_t globalZoneStateQueueOnce; [op timeout:120*NSEC_PER_SEC]; [self.operationQueue addOperation: op]; - - [op waitUntilFinished]; - if(op.error) { - secnotice("ckksreset", "Completed rpcResetLocal"); - } else { - secnotice("ckksreset", "Completed rpcResetLocal with error: %@", op.error); - } - reply(CKXPCSuitableError(op.error)); } - (void)rpcResetCloudKit:(NSString*)viewName reply: (void(^)(NSError* result)) reply { @@ -618,23 +706,22 @@ dispatch_once_t globalZoneStateQueueOnce; return; } - CKKSResultOperation* op = [CKKSResultOperation named:@"cloudkit-reset-zones-waiter" withBlock:^{}]; + CKKSResultOperation* op = [CKKSResultOperation named:@"cloudkit-reset-zones-waiter" withBlockTakingSelf:^(CKKSResultOperation * _Nonnull strongOp) { + if(!strongOp.error) { + secnotice("ckksreset", "Completed rpcResetCloudKit"); + } else { + secnotice("ckksreset", "Completed rpcResetCloudKit with error: %@", strongOp.error); + } + reply(CKXPCSuitableError(strongOp.error)); + }]; for(CKKSKeychainView* view in actualViews) { ckksnotice("ckksreset", view, "Beginning CloudKit reset for %@", view); - [op addSuccessDependency:[view resetCloudKitZone]]; + [op addSuccessDependency:[view resetCloudKitZone:[CKOperationGroup CKKSGroupWithName:@"api-reset"]]]; } [op timeout:120*NSEC_PER_SEC]; [self.operationQueue addOperation: op]; - - [op waitUntilFinished]; - if(op.error) { - secnotice("ckksreset", "Completed rpcResetCloudKit"); - } else { - secnotice("ckksreset", "Completed rpcResetCloudKit with error: %@", op.error); - } - reply(CKXPCSuitableError(op.error)); } - (void)rpcResync:(NSString*)viewName reply: (void(^)(NSError* result)) reply { @@ -698,58 +785,74 @@ dispatch_once_t globalZoneStateQueueOnce; - (void)rpcStatus: (NSString*)viewName reply: (void(^)(NSArray* result, NSError* error)) reply { NSMutableArray* a = [[NSMutableArray alloc] init]; - // The first element is always the current global state (non-view-specific) - NSError* selfPeersError = nil; - CKKSSelves* selves = [self fetchSelfPeers:&selfPeersError]; - NSError* trustedPeersError = nil; - NSSet>* peers = [self fetchTrustedPeers:&trustedPeersError]; + // Now, query the views about their status + NSError* error = nil; + NSArray* actualViews = [self views:viewName operation:@"status" error:&error]; + if(!actualViews || error) { + reply(nil, error); + return; + } + __weak __typeof(self) weakSelf = self; + CKKSResultOperation* statusOp = [CKKSResultOperation named:@"status-rpc" withBlock:^{ + __strong __typeof(self) strongSelf = weakSelf; - NSMutableArray* mutTrustedPeers = [[NSMutableArray alloc] init]; - [peers enumerateObjectsUsingBlock:^(id _Nonnull obj, BOOL * _Nonnull stop) { - [mutTrustedPeers addObject: [obj description]]; - }]; + // The first element is always the current global state (non-view-specific) + NSError* selfPeersError = nil; + CKKSSelves* selves = [strongSelf fetchSelfPeers:&selfPeersError]; + NSError* trustedPeersError = nil; + NSSet>* peers = [strongSelf fetchTrustedPeers:&trustedPeersError]; -#define stringify(obj) CKKSNilToNSNull([obj description]) - NSDictionary* global = @{ - @"view": @"global", - @"selfPeers": stringify(selves), - @"selfPeersError": CKKSNilToNSNull(selfPeersError), - @"trustedPeers": CKKSNilToNSNull(mutTrustedPeers), - @"trustedPeersError": CKKSNilToNSNull(trustedPeersError), - }; - [a addObject: global]; + // Get account state, even wait for it a little + [self.accountTracker.ckdeviceIDInitialized wait:1*NSEC_PER_SEC]; + NSString *deviceID = self.accountTracker.ckdeviceID; + NSError *deviceIDError = self.accountTracker.ckdeviceIDError; - // Now, query the views about their status - NSArray* actualViews = nil; - if(viewName) { - secnotice("ckks", "Received a status RPC for zone %@", viewName); - CKKSKeychainView* view = self.views[viewName]; + NSMutableArray* mutTrustedPeers = [[NSMutableArray alloc] init]; + [peers enumerateObjectsUsingBlock:^(id _Nonnull obj, BOOL * _Nonnull stop) { + [mutTrustedPeers addObject: [obj description]]; + }]; - if(!view) { - secerror("ckks: Zone %@ does not exist!", viewName); - reply(nil, nil); - return; +#define stringify(obj) CKKSNilToNSNull([obj description]) + NSDictionary* global = @{ + @"view": @"global", + @"selfPeers": stringify(selves), + @"selfPeersError": CKKSNilToNSNull(selfPeersError), + @"trustedPeers": CKKSNilToNSNull(mutTrustedPeers), + @"trustedPeersError": CKKSNilToNSNull(trustedPeersError), + @"reachability": strongSelf.reachabilityTracker.currentReachability ? @"network" : @"no-network", + @"ckdeviceID": CKKSNilToNSNull(deviceID), + @"ckdeviceIDError": CKKSNilToNSNull(deviceIDError), + }; + [a addObject: global]; + + for(CKKSKeychainView* view in actualViews) { + ckksnotice("ckks", view, "Fetching status for %@", view.zoneName); + NSDictionary* status = [view status]; + ckksinfo("ckks", view, "Status is %@", status); + if(status) { + [a addObject: status]; + } } + reply(a, nil); + }]; - actualViews = @[view]; - - } else { - @synchronized(self.views) { - // Can't safely iterate a mutable collection, so copy it. - actualViews = self.views.allValues; - } + // If we're signed in, give the views a few seconds to enter what they consider to be a non-transient state (in case this daemon just launched) + if([self.accountTracker.currentComputedAccountStatusValid wait:5*NSEC_PER_SEC]) { + secerror("ckks status: Haven't yet figured out login state"); } - for(CKKSKeychainView* view in actualViews) { - ckksnotice("ckks", view, "Fetching status for %@", view.zoneName); - NSDictionary* status = [view status]; - ckksinfo("ckks", view, "Status is %@", status); - if(status) { - [a addObject: status]; + if(self.accountTracker.currentComputedAccountStatus == CKKSAccountStatusAvailable) { + CKKSResultOperation* blockOp = [CKKSResultOperation named:@"wait-for-status" withBlock:^{}]; + [blockOp timeout:8*NSEC_PER_SEC]; + for(CKKSKeychainView* view in actualViews) { + [blockOp addNullableDependency:view.keyStateNonTransientDependency]; + [statusOp addDependency:blockOp]; } + [self.operationQueue addOperation:blockOp]; } - reply(a, nil); + [self.operationQueue addOperation:statusOp]; + return; } @@ -762,26 +865,11 @@ dispatch_once_t globalZoneStateQueueOnce; } - (void)rpcFetchAndProcessChanges:(NSString*)viewName classA:(bool)classAError reply: (void(^)(NSError* result)) reply { - NSArray* actualViews = nil; - if(viewName) { - secnotice("ckks", "Received a fetch RPC for zone %@", viewName); - CKKSKeychainView* view = self.views[viewName]; - - if(!view) { - secerror("ckks: Zone %@ does not exist!", viewName); - reply([NSError errorWithDomain:@"securityd" - code:kSOSCCNoSuchView - userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"No view for '%@'", viewName]}]); - return; - } - - actualViews = @[view]; - } else { - secnotice("ckks", "Received a fetch RPC for all zones"); - @synchronized(self.views) { - // Can't safely iterate a mutable collection, so copy it. - actualViews = [self.views.allValues copy]; - } + NSError* error = nil; + NSArray* actualViews = [self views:viewName operation:@"fetch" error:&error]; + if(!actualViews || error) { + reply(error); + return; } CKKSResultOperation* blockOp = [[CKKSResultOperation alloc] init]; @@ -801,30 +889,15 @@ dispatch_once_t globalZoneStateQueueOnce; [blockOp addDependency:op]; } - [self.operationQueue addOperation: [blockOp timeout:60*NSEC_PER_SEC]]; + [self.operationQueue addOperation: [blockOp timeout:(SecCKKSTestsEnabled() ? NSEC_PER_SEC * 5 : NSEC_PER_SEC * 120)]]; } - (void)rpcPushOutgoingChanges:(NSString*)viewName reply: (void(^)(NSError* result))reply { - NSArray* actualViews = nil; - if(viewName) { - secnotice("ckks", "Received a push RPC for zone %@", viewName); - CKKSKeychainView* view = self.views[viewName]; - - if(!view) { - secerror("ckks: Zone %@ does not exist!", viewName); - reply([NSError errorWithDomain:@"securityd" - code:kSOSCCNoSuchView - userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"No view for '%@'", viewName]}]); - return; - } - - actualViews = @[view]; - } else { - secnotice("ckks", "Received a push RPC for all zones"); - @synchronized(self.views) { - // Can't safely iterate a mutable collection, so copy it. - actualViews = [self.views.allValues copy]; - } + NSError* error = nil; + NSArray* actualViews = [self views:viewName operation:@"push" error:&error]; + if(!actualViews || error) { + reply(error); + return; } CKKSResultOperation* blockOp = [[CKKSResultOperation alloc] init]; @@ -844,28 +917,11 @@ dispatch_once_t globalZoneStateQueueOnce; [blockOp addDependency:op]; } - [self.operationQueue addOperation: [blockOp timeout:60*NSEC_PER_SEC]]; -} - -- (void)rpcGetAnalyticsSysdiagnoseWithReply:(void (^)(NSString* sysdiagnose, NSError* error))reply -{ - NSError* error = nil; - NSString* sysdiagnose = [[CKKSAnalyticsLogger logger] getSysdiagnoseDumpWithError:&error]; - reply(sysdiagnose, CKXPCSuitableError(error)); -} - -- (void)rpcGetAnalyticsJSONWithReply:(void (^)(NSData* json, NSError* error))reply -{ - NSError* error = nil; - NSData* json = [[CKKSAnalyticsLogger logger] getLoggingJSON:true error:&error]; - reply(json, CKXPCSuitableError(error)); + [self.operationQueue addOperation: [blockOp timeout:(SecCKKSTestsEnabled() ? NSEC_PER_SEC * 2 : NSEC_PER_SEC * 120)]]; } -- (void)rpcForceUploadAnalyticsWithReply:(void (^)(BOOL success, NSError* error))reply -{ - NSError* error = nil; - BOOL result = [[CKKSAnalyticsLogger logger] forceUploadWithError:&error]; - reply(result, CKXPCSuitableError(error)); +- (void)rpcGetCKDeviceIDWithReply:(void (^)(NSString *))reply { + reply(self.accountTracker.ckdeviceID); } -(void)xpc24HrNotification { @@ -887,9 +943,140 @@ dispatch_once_t globalZoneStateQueueOnce; } } -#pragma mark - CKKSPeerProvider implementation +- (NSArray * _Nullable)loadRestoredBottledKeysOfType:(OctagonKeyType)keyType error:(NSError**)error +{ + CFTypeRef result = NULL; + NSMutableArray* bottledPeerKeychainItems = nil; + + NSDictionary* query = @{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecAttrAccessible: (id)kSecAttrAccessibleWhenUnlocked, + (id)kSecAttrNoLegacy : @YES, + (id)kSecAttrType : [[NSNumber alloc]initWithInt: keyType], + (id)kSecAttrServer : (keyType == 1) ? @"Octagon Signing Key" : @"Octagon Encryption Key", + (id)kSecAttrAccessGroup: @"com.apple.security.ckks", + (id)kSecMatchLimit : (id)kSecMatchLimitAll, + (id)kSecReturnAttributes: @YES, + (id)kSecReturnData: @YES, + }; + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); + + if(status == errSecSuccess && result && isArray(result)) { + bottledPeerKeychainItems = CFBridgingRelease(result); + result = NULL; + } else { + if(error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain + code:status + description:@"could not load bottled peer keys"]; + } + CFReleaseNull(result); + } -- (CKKSSelves*)fetchSelfPeers:(NSError* __autoreleasing *)error { + return bottledPeerKeychainItems; +} + +-(NSDictionary *) keychainItemForPeerID:(NSString*)neededPeerID + keychainItems:(NSArray *)keychainItems + escrowSigningPubKeyHash:(NSString *)hashWeNeedToMatch +{ + NSDictionary* peerItem = nil; + + for(NSDictionary* item in keychainItems){ + if(item && [item count] > 0){ + NSString* peerIDFromItem = [item objectForKey:(id)kSecAttrAccount]; + NSString* hashToConsider = [item objectForKey:(id)kSecAttrLabel]; + if([peerIDFromItem isEqualToString:neededPeerID] && + [hashWeNeedToMatch isEqualToString:hashToConsider]) + { + peerItem = [item copy]; + break; + } + } + } + + return peerItem; +} + +- (NSSet>*)pastSelves:(NSError**)error +{ + NSError* localError = nil; + + // get bottled peer identities from the keychain + NSMutableSet>* allSelves = [NSMutableSet set]; + NSArray* signingKeys = [self loadRestoredBottledKeysOfType:OctagonSigningKey error:&localError]; + if(!signingKeys) { + // Item not found isn't actually an error here + if(error && !(localError && [localError.domain isEqualToString: NSOSStatusErrorDomain] && localError.code == errSecItemNotFound)) { + *error = localError; + } + + return allSelves; + } + + NSArray* encryptionKeys = [self loadRestoredBottledKeysOfType:OctagonEncryptionKey error:&localError]; + if(!encryptionKeys) { + if(error && !(localError && [localError.domain isEqualToString: NSOSStatusErrorDomain] && localError.code == errSecItemNotFound)) { + *error = localError; + } + return allSelves; + } + + for(NSDictionary* signingKey in signingKeys) { + NSError* peerError = nil; + NSString* peerid = signingKey[(id)kSecAttrAccount]; + NSString* hash = signingKey[(id)kSecAttrLabel]; // escrow signing pub key hash + + //use peer id AND escrow signing public key hash to look up the matching item in encryptionKeys list + NSDictionary* encryptionKeyItem = [self keychainItemForPeerID:peerid keychainItems:encryptionKeys escrowSigningPubKeyHash:hash]; + if(!encryptionKeyItem) { + secerror("octagon: no encryption key available to pair with signing key %@,%@", peerid, hash); + continue; + } + + NSData* signingKeyData = signingKey[(id)kSecValueData]; + if(!signingKeyData) { + secerror("octagon: no signing key data for %@,%@", peerid,hash); + continue; + } + + SFECKeyPair* restoredSigningKey = [[SFECKeyPair alloc] initWithData:signingKeyData + specifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384] + error:&peerError]; + if(!restoredSigningKey) { + secerror("octagon: couldn't make signing key for %@,%@: %@", peerid, hash, peerError); + continue; + } + + NSData* encryptionKeyData = [encryptionKeyItem objectForKey:(id)kSecValueData]; + if(!encryptionKeyData) { + secerror("octagon: no encryption key data for %@,%@", peerid,hash); + continue; + } + + SFECKeyPair* restoredEncryptionKey = [[SFECKeyPair alloc] initWithData:encryptionKeyData + specifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384] + error:&peerError]; + if(!restoredEncryptionKey) { + secerror("octagon: couldn't make encryption key for %@,%@: %@", peerid,hash, peerError); + continue; + } + + //create the SOS self peer + CKKSSOSSelfPeer* restoredIdentity = [[CKKSSOSSelfPeer alloc]initWithSOSPeerID:peerid encryptionKey:restoredEncryptionKey signingKey:restoredSigningKey]; + + if(restoredIdentity){ + secnotice("octagon","adding bottled peer identity: %@", restoredIdentity); + [allSelves addObject:restoredIdentity]; + } else { + secerror("octagon: could not create restored identity from: %@: %@", peerid, peerError); + } + } + return allSelves; +} + +- (id _Nullable)currentSOSSelf:(NSError**)error +{ __block SFECKeyPair* signingPrivateKey = nil; __block SFECKeyPair* encryptionPrivateKey = nil; @@ -906,28 +1093,25 @@ dispatch_once_t globalZoneStateQueueOnce; return nil; } - SOSCCPerformWithOctagonSigningKey(^(SecKeyRef signingSecKey, CFErrorRef cferror) { - if(cferror) { - localerror = (__bridge NSError*)cferror; - return; - } - if (!cferror && signingSecKey) { - signingPrivateKey = [[SFECKeyPair alloc] initWithSecKey:signingSecKey]; - } - }); - - SOSCCPerformWithOctagonEncryptionKey(^(SecKeyRef encryptionSecKey, CFErrorRef cferror) { + SOSCCPerformWithAllOctagonKeys(^(SecKeyRef octagonEncryptionKey, SecKeyRef octagonSigningKey, CFErrorRef cferror) { if(cferror) { localerror = (__bridge NSError*)cferror; return; } - if (!cferror && encryptionSecKey) { - encryptionPrivateKey = [[SFECKeyPair alloc] initWithSecKey:encryptionSecKey]; + if (!cferror && octagonEncryptionKey && octagonSigningKey) { + signingPrivateKey = [[SFECKeyPair alloc] initWithSecKey:octagonSigningKey]; + encryptionPrivateKey = [[SFECKeyPair alloc] initWithSecKey:octagonEncryptionKey]; + } else { + localerror = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSNoPeersAvailable + description:@"Not all SOS peer keys available, but no error returned"]; } }); if(localerror) { - secerror("ckkspeer: Error fetching self encryption keys: %@", localerror); + if(![self.lockStateTracker isLockedError:localerror]) { + secerror("ckkspeer: Error fetching self encryption keys: %@", localerror); + } if(error) { *error = localerror; } @@ -937,7 +1121,35 @@ dispatch_once_t globalZoneStateQueueOnce; CKKSSOSSelfPeer* selfPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:peerID encryptionKey:encryptionPrivateKey signingKey:signingPrivateKey]; - CKKSSelves* selves = [[CKKSSelves alloc] initWithCurrent:selfPeer allSelves:nil]; + return selfPeer; +} + +#pragma mark - CKKSPeerProvider implementation + +- (CKKSSelves*)fetchSelfPeers:(NSError* __autoreleasing *)error { + NSError* localError = nil; + + id selfPeer = [self currentSOSSelf:&localError]; + if(!selfPeer || localError) { + if(![self.lockStateTracker isLockedError:localError]) { + secerror("ckks: Error fetching current SOS self: %@", localError); + } + if(error) { + *error = localError; + } + return nil; + } + + NSSet>* allSelves = [self pastSelves:&localError]; + if(!allSelves || localError) { + secerror("ckks: Error fetching past selves: %@", localError); + if(error) { + *error = localError; + } + return nil; + } + + CKKSSelves* selves = [[CKKSSelves alloc] initWithCurrent:selfPeer allSelves:allSelves]; return selves; } @@ -961,28 +1173,36 @@ dispatch_once_t globalZoneStateQueueOnce; } CFStringRef cfpeerID = SOSPeerInfoGetPeerID(sosPeerInfoRef); - SecKeyRef cfOctagonSigningKey = SOSPeerInfoCopyOctagonSigningPublicKey(sosPeerInfoRef, &cfPeerError); - SecKeyRef cfOctagonEncryptionKey = SOSPeerInfoCopyOctagonEncryptionPublicKey(sosPeerInfoRef, &cfPeerError); + SecKeyRef cfOctagonSigningKey = NULL, cfOctagonEncryptionKey = NULL; + + cfOctagonSigningKey = SOSPeerInfoCopyOctagonSigningPublicKey(sosPeerInfoRef, &cfPeerError); + if (cfOctagonSigningKey) { + cfOctagonEncryptionKey = SOSPeerInfoCopyOctagonEncryptionPublicKey(sosPeerInfoRef, &cfPeerError); + } - if(cfPeerError) { + if(cfOctagonSigningKey == NULL || cfOctagonEncryptionKey == NULL) { // Don't log non-debug for -50; it almost always just means this peer didn't have octagon keys - if(!(CFEqualSafe(CFErrorGetDomain(cfPeerError), kCFErrorDomainOSStatus) && (CFErrorGetCode(cfPeerError) == errSecParam))) { + if(cfPeerError == NULL + || !(CFEqualSafe(CFErrorGetDomain(cfPeerError), kCFErrorDomainOSStatus) && (CFErrorGetCode(cfPeerError) == errSecParam))) + { secerror("ckkspeer: error fetching octagon keys for peer: %@ %@", sosPeerInfoRef, cfPeerError); } else { - secinfo("ckkspeer", "Peer doesn't have Octagon keys, but this is expected: %@", cfPeerError); + secinfo("ckkspeer", "Peer(%@) doesn't have Octagon keys, but this is expected: %@", cfpeerID, cfPeerError); } - } else { - SFECPublicKey* signingPublicKey = cfOctagonSigningKey ? [[SFECPublicKey alloc] initWithSecKey:cfOctagonSigningKey] : nil; - SFECPublicKey* encryptionPublicKey = cfOctagonEncryptionKey ? [[SFECPublicKey alloc] initWithSecKey:cfOctagonEncryptionKey] : nil; - - CKKSSOSPeer* peer = [[CKKSSOSPeer alloc] initWithSOSPeerID:(__bridge NSString*)cfpeerID - encryptionPublicKey:encryptionPublicKey - signingPublicKey:signingPublicKey]; - [peerSet addObject:peer]; } + // Add all peers to the trust set: old-style SOS peers will just have null keys + SFECPublicKey* signingPublicKey = cfOctagonSigningKey ? [[SFECPublicKey alloc] initWithSecKey:cfOctagonSigningKey] : nil; + SFECPublicKey* encryptionPublicKey = cfOctagonEncryptionKey ? [[SFECPublicKey alloc] initWithSecKey:cfOctagonEncryptionKey] : nil; + + CKKSSOSPeer* peer = [[CKKSSOSPeer alloc] initWithSOSPeerID:(__bridge NSString*)cfpeerID + encryptionPublicKey:encryptionPublicKey + signingPublicKey:signingPublicKey]; + [peerSet addObject:peer]; + CFReleaseNull(cfOctagonSigningKey); CFReleaseNull(cfOctagonEncryptionKey); + CFReleaseNull(cfPeerError); }); }); @@ -990,48 +1210,56 @@ dispatch_once_t globalZoneStateQueueOnce; } - (void)registerForPeerChangeUpdates:(id)listener { - bool alreadyRegisteredListener = false; - NSEnumerator *enumerator = [self.peerChangeListeners objectEnumerator]; - id value; - - while ((value = [enumerator nextObject])) { - // do pointer comparison - alreadyRegisteredListener |= (value == listener); - } + @synchronized(self.peerChangeListeners) { + bool alreadyRegisteredListener = false; + NSEnumerator *enumerator = [self.peerChangeListeners objectEnumerator]; + id value; + + while ((value = [enumerator nextObject])) { + // do pointer comparison + alreadyRegisteredListener |= (value == listener); + } - if(listener && !alreadyRegisteredListener) { - NSString* queueName = [NSString stringWithFormat: @"ck-peer-change-%@", listener]; + if(listener && !alreadyRegisteredListener) { + NSString* queueName = [NSString stringWithFormat: @"ck-peer-change-%@", listener]; - dispatch_queue_t objQueue = dispatch_queue_create([queueName UTF8String], DISPATCH_QUEUE_SERIAL); - [self.peerChangeListeners setObject: listener forKey: objQueue]; + dispatch_queue_t objQueue = dispatch_queue_create([queueName UTF8String], DISPATCH_QUEUE_SERIAL); + [self.peerChangeListeners setObject: listener forKey: objQueue]; + } } } - (void)iteratePeerListenersOnTheirQueue:(void (^)(id))block { - NSEnumerator *enumerator = [self.peerChangeListeners keyEnumerator]; - dispatch_queue_t dq; - - // Queue up the changes for each listener. - while ((dq = [enumerator nextObject])) { - id listener = [self.peerChangeListeners objectForKey: dq]; - __weak id weakListener = listener; - - if(listener) { - dispatch_async(dq, ^{ - __strong id strongListener = weakListener; - block(strongListener); - }); + @synchronized(self.peerChangeListeners) { + NSEnumerator *enumerator = [self.peerChangeListeners keyEnumerator]; + dispatch_queue_t dq; + + // Queue up the changes for each listener. + while ((dq = [enumerator nextObject])) { + id listener = [self.peerChangeListeners objectForKey: dq]; + __weak id weakListener = listener; + + if(listener) { + dispatch_async(dq, ^{ + __strong id strongListener = weakListener; + block(strongListener); + }); + } } } } - (void)sendSelfPeerChangedUpdate { + [self.completedSecCKKSInitialize wait:5*NSEC_PER_SEC]; // Wait for bringup, but don't worry if this times out + [self iteratePeerListenersOnTheirQueue: ^(id listener) { [listener selfPeerChanged]; }]; } - (void)sendTrustedPeerSetChangedUpdate { + [self.completedSecCKKSInitialize wait:5*NSEC_PER_SEC]; // Wait for bringup, but don't worry if this times out + [self iteratePeerListenersOnTheirQueue: ^(id listener) { [listener trustedPeerSetChanged]; }]; diff --git a/keychain/ckks/CKKSZone.h b/keychain/ckks/CKKSZone.h index 3e4b94ee..8938c2ee 100644 --- a/keychain/ckks/CKKSZone.h +++ b/keychain/ckks/CKKSZone.h @@ -25,7 +25,10 @@ #if OCTAGON #import "keychain/ckks/CKKSCKAccountStateTracker.h" +#import "keychain/ckks/CKKSReachabilityTracker.h" #import "keychain/ckks/CloudKitDependencies.h" +#import "keychain/ckks/CKKSAPSReceiver.h" +#import "keychain/ckks/CKKSGroupOperation.h" NS_ASSUME_NONNULL_BEGIN @@ -39,6 +42,7 @@ NS_ASSUME_NONNULL_BEGIN @property (readonly) NSString* zoneName; @property CKKSGroupOperation* zoneSetupOperation; +@property (nullable) CKOperationGroup* zoneSetupOperationGroup; // set this if you want zone creates to use a different operation group @property bool zoneCreated; @property bool zoneSubscribed; @@ -54,6 +58,7 @@ NS_ASSUME_NONNULL_BEGIN @property (readonly) CKDatabase* database; @property (weak) CKKSCKAccountStateTracker* accountTracker; +@property (weak) CKKSReachabilityTracker* reachabilityTracker; @property (readonly) CKRecordZone* zone; @property (readonly) CKRecordZoneID* zoneID; @@ -70,7 +75,8 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithContainer:(CKContainer*)container zoneName:(NSString*)zoneName - accountTracker:(CKKSCKAccountStateTracker*)tracker + accountTracker:(CKKSCKAccountStateTracker*)accountTracker + reachabilityTracker:(CKKSReachabilityTracker *)reachabilityTracker fetchRecordZoneChangesOperationClass:(Class)fetchRecordZoneChangesOperationClass fetchRecordsOperationClass:(Class)fetchRecordsOperationClass queryOperationClass:(Class)queryOperationClass @@ -79,7 +85,7 @@ NS_ASSUME_NONNULL_BEGIN apsConnectionClass:(Class)apsConnectionClass; -- (CKKSResultOperation* _Nullable)beginResetCloudKitZoneOperation; +- (CKKSResultOperation* _Nullable)deleteCloudKitZoneOperation:(CKOperationGroup* _Nullable)ckoperationGroup; // Called when CloudKit notifies us that we just logged in. // That is, if we transition from any state to CKAccountStatusAvailable. @@ -90,7 +96,7 @@ NS_ASSUME_NONNULL_BEGIN // Actually start a cloudkit login. Pass in whether you believe this zone has been created and if this device has // subscribed to this zone on the server. -- (NSOperation* _Nullable)handleCKLogin:(bool)zoneCreated zoneSubscribed:(bool)zoneSubscribed; +- (CKKSResultOperation* _Nullable)handleCKLogin:(bool)zoneCreated zoneSubscribed:(bool)zoneSubscribed; // Called when CloudKit notifies us that we just logged out. // i.e. we transition from CKAccountStatusAvailable to any other state. @@ -103,8 +109,6 @@ NS_ASSUME_NONNULL_BEGIN // Cancels all operations (no matter what they are). - (void)cancelAllOperations; -// Reissues the call -- (void)restartCurrentAccountStateOperation; // Schedules this operation for execution (if the CloudKit account exists) - (bool)scheduleOperation:(NSOperation*)op; diff --git a/keychain/ckks/CKKSZone.m b/keychain/ckks/CKKSZone.m index d1006737..40c32544 100644 --- a/keychain/ckks/CKKSZone.m +++ b/keychain/ckks/CKKSZone.m @@ -28,6 +28,7 @@ #if OCTAGON #import "CloudKitDependencies.h" #import "keychain/ckks/CKKSCKAccountStateTracker.h" +#import "keychain/ckks/CloudKitCategories.h" #import #import @@ -43,19 +44,22 @@ @property CKDatabaseOperation* zoneSubscriptionOperation; @property NSOperationQueue* operationQueue; -@property NSOperation* accountLoggedInDependency; +@property CKKSResultOperation* accountLoggedInDependency; @property NSHashTable* accountOperations; // Make writable @property bool halted; +@property bool zoneCreateNetworkFailure; +@property bool zoneSubscriptionNetworkFailure; @end @implementation CKKSZone - (instancetype)initWithContainer: (CKContainer*) container zoneName: (NSString*) zoneName - accountTracker:(CKKSCKAccountStateTracker*) tracker + accountTracker:(CKKSCKAccountStateTracker*) accountTracker + reachabilityTracker:(CKKSReachabilityTracker *) reachabilityTracker fetchRecordZoneChangesOperationClass: (Class) fetchRecordZoneChangesOperationClass fetchRecordsOperationClass: (Class)fetchRecordsOperationClass queryOperationClass:(Class)queryOperationClass @@ -66,7 +70,8 @@ if(self = [super init]) { _container = container; _zoneName = zoneName; - _accountTracker = tracker; + _accountTracker = accountTracker; + _reachabilityTracker = reachabilityTracker; _halted = false; @@ -75,11 +80,7 @@ _accountStatus = CKKSAccountStatusUnknown; - __weak __typeof(self) weakSelf = self; - self.accountLoggedInDependency = [NSBlockOperation blockOperationWithBlock:^{ - ckksnotice("ckkszone", weakSelf, "CloudKit account logged in."); - }]; - self.accountLoggedInDependency.name = @"account-logged-in-dependency"; + _accountLoggedInDependency = [self createAccountLoggedInDependency:@"CloudKit account logged in."]; _accountOperations = [NSHashTable weakObjectsHashTable]; @@ -96,6 +97,15 @@ return self; } +- (CKKSResultOperation*)createAccountLoggedInDependency:(NSString*)message { + __weak __typeof(self) weakSelf = self; + CKKSResultOperation* accountLoggedInDependency = [CKKSResultOperation named:@"account-logged-in-dependency" withBlock:^{ + ckksnotice("ckkszone", weakSelf, "%@", message); + }]; + accountLoggedInDependency.descriptionErrorCode = CKKSResultDescriptionPendingAccountLoggedIn; + return accountLoggedInDependency; +} + - (void)initializeZone { [self.accountTracker notifyOnAccountStatusChange:self]; } @@ -122,7 +132,6 @@ [CKKSCKAccountStateTracker stringFromAccountStatus: oldStatus], [CKKSCKAccountStateTracker stringFromAccountStatus: currentStatus]); - __weak __typeof(self) weakSelf = self; switch(currentStatus) { case CKKSAccountStatusAvailable: { ckksnotice("ckkszone", self, "Logged into iCloud."); @@ -138,10 +147,7 @@ case CKKSAccountStatusNoAccount: { ckksnotice("ckkszone", self, "Logging out of iCloud. Shutting down."); - self.accountLoggedInDependency = [NSBlockOperation blockOperationWithBlock:^{ - ckksnotice("ckkszone", weakSelf, "CloudKit account logged in again."); - }]; - self.accountLoggedInDependency.name = @"account-logged-in-dependency"; + self.accountLoggedInDependency = [self createAccountLoggedInDependency:@"CloudKit account logged in again."]; [self handleCKLogout]; } @@ -151,10 +157,7 @@ // We really don't expect to receive this as a notification, but, okay! ckksnotice("ckkszone", self, "Account status has become undetermined. Pausing for %@", self.zoneID.zoneName); - self.accountLoggedInDependency = [NSBlockOperation blockOperationWithBlock:^{ - ckksnotice("ckkszone", weakSelf, "CloudKit account restored from 'unknown'."); - }]; - self.accountLoggedInDependency.name = @"account-logged-in-dependency"; + self.accountLoggedInDependency = [self createAccountLoggedInDependency:@"CloudKit account return from 'unknown'."]; [self handleCKLogout]; } @@ -162,25 +165,15 @@ } } -- (void)restartCurrentAccountStateOperation { - __weak __typeof(self) weakSelf = self; - dispatch_async(self.queue, ^{ - __strong __typeof(self) strongSelf = weakSelf; - ckksnotice("ckksaccount", strongSelf, "Restarting account in state %@", [CKKSCKAccountStateTracker stringFromAccountStatus:strongSelf.accountStatus]); - [strongSelf ckAccountStatusChange:strongSelf.accountStatus to:strongSelf.accountStatus]; - }); -} - -- (NSOperation*)handleCKLogin:(bool)zoneCreated zoneSubscribed:(bool)zoneSubscribed { +- (CKKSResultOperation*)handleCKLogin:(bool)zoneCreated zoneSubscribed:(bool)zoneSubscribed { if(!SecCKKSIsEnabled()) { ckksinfo("ckkszone", self, "Skipping CloudKit registration due to disabled CKKS"); return nil; } - // If we've already started set up, skip doing it again. + // If we've already started set up and that hasn't finished, complain if([self.zoneSetupOperation isPending] || [self.zoneSetupOperation isExecuting]) { - ckksnotice("ckkszone", self, "skipping startup: it's already started"); - return self.zoneSetupOperation; + ckksnotice("ckkszone", self, "Asked to handleCKLogin, but zoneSetupOperation appears to not be complete? %@ Continuing anyway", self.zoneSetupOperation); } self.zoneSetupOperation = [[CKKSGroupOperation alloc] init]; @@ -203,6 +196,7 @@ [self.zoneSetupOperation runBeforeGroupFinished:[CKKSResultOperation named:[NSString stringWithFormat:@"zone-setup-%@", self.zoneName] withBlock:^{ __strong __typeof(weakSelf) strongSelf = weakSelf; __strong __typeof(self.zoneSetupOperation) zoneSetupOperation = weakZoneSetupOperation; + __strong __typeof(self.reachabilityTracker) reachabilityTracker = self.reachabilityTracker; if(!strongSelf || !zoneSetupOperation) { ckkserror("ckkszone", strongSelf, "received callback for released object"); return; @@ -250,6 +244,7 @@ zoneCreationOperation.qualityOfService = NSQualityOfServiceUserInitiated; zoneCreationOperation.database = strongSelf.database; zoneCreationOperation.name = @"zone-creation-operation"; + zoneCreationOperation.group = strongSelf.zoneSetupOperationGroup ?: [CKOperationGroup CKKSGroupWithName:@"zone-creation"];; // Completion blocks don't count for dependencies. Use this intermediate operation hack instead. modifyRecordZonesCompleteOperation = [[NSBlockOperation alloc] init]; @@ -267,14 +262,21 @@ if(!operationError) { ckksnotice("ckkszone", strongSubSelf, "Successfully created zone %@", strongSubSelf.zoneName); strongSubSelf.zoneCreated = true; + strongSubSelf.zoneSetupOperationGroup = nil; } else { ckkserror("ckkszone", strongSubSelf, "Couldn't create zone %@; %@", strongSubSelf.zoneName, operationError); } strongSubSelf.zoneCreatedError = operationError; - + if ([reachabilityTracker isNetworkError:operationError]){ + strongSelf.zoneCreateNetworkFailure = true; + } [strongSubSelf.operationQueue addOperation: modifyRecordZonesCompleteOperation]; }; + if (strongSelf.zoneCreateNetworkFailure) { + [zoneCreationOperation addNullableDependency:reachabilityTracker.reachablityDependency]; + strongSelf.zoneCreateNetworkFailure = false; + } ckksnotice("ckkszone", strongSelf, "Adding CKKSModifyRecordZonesOperation: %@ %@", zoneCreationOperation, zoneCreationOperation.dependencies); strongSelf.zoneCreationOperation = zoneCreationOperation; [setupCompleteOperation addDependency: modifyRecordZonesCompleteOperation]; @@ -323,13 +325,18 @@ strongSubSelf.zoneSubscribedError = operationError; strongSubSelf.zoneSubscriptionOperation = nil; + if ([reachabilityTracker isNetworkError:operationError]){ + strongSelf.zoneSubscriptionNetworkFailure = true; + } [strongSubSelf.operationQueue addOperation: zoneSubscriptionCompleteOperation]; }; - if(modifyRecordZonesCompleteOperation) { - [zoneSubscriptionOperation addDependency:modifyRecordZonesCompleteOperation]; + if (strongSelf.zoneSubscriptionNetworkFailure) { + [zoneSubscriptionOperation addNullableDependency:reachabilityTracker.reachablityDependency]; + strongSelf.zoneSubscriptionNetworkFailure = false; } + [zoneSubscriptionOperation addNullableDependency:modifyRecordZonesCompleteOperation]; strongSelf.zoneSubscriptionOperation = zoneSubscriptionOperation; [setupCompleteOperation addDependency: zoneSubscriptionCompleteOperation]; [zoneSetupOperation runBeforeGroupFinished:zoneSubscriptionOperation]; @@ -346,7 +353,7 @@ } -- (CKKSResultOperation*)beginResetCloudKitZoneOperation { +- (CKKSResultOperation*)deleteCloudKitZoneOperation:(CKOperationGroup* _Nullable)ckoperationGroup { if(!SecCKKSIsEnabled()) { ckksnotice("ckkszone", self, "Skipping CloudKit reset due to disabled CKKS"); return nil; @@ -361,12 +368,18 @@ [self.zoneSubscriptionOperation cancel]; // Step 2: Try to delete the zone + CKDatabaseOperation* zoneDeletionOperation = [[self.modifyRecordZonesOperationClass alloc] initWithRecordZonesToSave: nil recordZoneIDsToDelete: @[self.zoneID]]; zoneDeletionOperation.queuePriority = NSOperationQueuePriorityNormal; zoneDeletionOperation.qualityOfService = NSQualityOfServiceUserInitiated; zoneDeletionOperation.database = self.database; + zoneDeletionOperation.group = ckoperationGroup; + + CKKSGroupOperation* zoneDeletionGroupOperation = [[CKKSGroupOperation alloc] init]; + zoneDeletionGroupOperation.name = [NSString stringWithFormat:@"cloudkit-zone-delete-%@", self.zoneName]; CKKSResultOperation* doneOp = [CKKSResultOperation named:@"zone-reset-watcher" withBlock:^{}]; + [zoneDeletionGroupOperation dependOnBeforeGroupFinished:doneOp]; __weak __typeof(self) weakSelf = self; @@ -398,23 +411,28 @@ } } - ckksinfo("ckkszone", strongSelf, "record zones deletion %@ completed with error: %@", deletedRecordZoneIDs, operationError); + if(operationError) { + ckksnotice("ckkszone", strongSelf, "deletion of record zones %@ completed with error: %@", deletedRecordZoneIDs, operationError); + } else { + ckksnotice("ckkszone", strongSelf, "deletion of record zones %@ completed successfully", deletedRecordZoneIDs); + } if(operationError && fatalError) { // If the error wasn't actually a problem, don't report it upward. doneOp.error = operationError; } - [strongSelf.operationQueue addOperation: doneOp]; + [zoneDeletionGroupOperation runBeforeGroupFinished:doneOp]; }; // If the zone creation operation is still pending, wait for it to complete before attempting zone deletion [zoneDeletionOperation addNullableDependency: self.zoneCreationOperation]; + [zoneDeletionGroupOperation runBeforeGroupFinished:zoneDeletionOperation]; - ckksnotice("ckkszone", self, "deleting zone with %@ %@", zoneDeletionOperation, zoneDeletionOperation.dependencies); - // Don't use scheduleOperation: zone deletions should be attempted even if we're "logged out" - [self.operationQueue addOperation: zoneDeletionOperation]; - self.zoneDeletionOperation = zoneDeletionOperation; - return doneOp; + [zoneDeletionGroupOperation runBeforeGroupFinished:[CKKSResultOperation named:@"print-log-message" withBlock:^{ + __strong __typeof(weakSelf) strongSelf = weakSelf; + ckksnotice("ckkszone", strongSelf, "deleting zones %@ with dependencies %@", zoneDeletionOperation.recordZoneIDsToDelete, zoneDeletionOperation.dependencies); + }]]; + return zoneDeletionGroupOperation; } - (void)notifyZoneChange: (CKRecordZoneNotification*) notification { diff --git a/keychain/ckks/CKKSZoneChangeFetcher.h b/keychain/ckks/CKKSZoneChangeFetcher.h index f03db22a..52f083be 100644 --- a/keychain/ckks/CKKSZoneChangeFetcher.h +++ b/keychain/ckks/CKKSZoneChangeFetcher.h @@ -29,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN /* Fetch Reasons */ -@protocol SecCKKSFetchBecause +@protocol SecCKKSFetchBecause @end typedef NSString CKKSFetchBecause; extern CKKSFetchBecause* const CKKSFetchBecauseAPNS; @@ -40,8 +40,9 @@ extern CKKSFetchBecause* const CKKSFetchBecauseSecuritydRestart; extern CKKSFetchBecause* const CKKSFetchBecausePreviousFetchFailed; extern CKKSFetchBecause* const CKKSFetchBecauseKeyHierarchy; extern CKKSFetchBecause* const CKKSFetchBecauseTesting; +extern CKKSFetchBecause* const CKKSFetchBecauseResync; -@protocol CKKSChangeFetcherErrorOracle +@protocol CKKSChangeFetcherErrorOracle - (bool)isFatalCKFetchError:(NSError*)error; @end @@ -56,6 +57,7 @@ extern CKKSFetchBecause* const CKKSFetchBecauseTesting; @interface CKKSZoneChangeFetcher : NSObject @property (nullable, weak) CKKSKeychainView* ckks; +@property (readonly) NSError* lastCKFetchError; @property CKRecordZoneID* zoneID; - (instancetype)init NS_UNAVAILABLE; diff --git a/keychain/ckks/CKKSZoneChangeFetcher.m b/keychain/ckks/CKKSZoneChangeFetcher.m index 551f870e..bf1737bf 100644 --- a/keychain/ckks/CKKSZoneChangeFetcher.m +++ b/keychain/ckks/CKKSZoneChangeFetcher.m @@ -39,13 +39,33 @@ CKKSFetchBecause* const CKKSFetchBecauseCurrentItemFetchRequest = (CKKSFetchBeca CKKSFetchBecause* const CKKSFetchBecauseInitialStart = (CKKSFetchBecause*) @"initialfetch"; CKKSFetchBecause* const CKKSFetchBecauseSecuritydRestart = (CKKSFetchBecause*) @"restart"; CKKSFetchBecause* const CKKSFetchBecausePreviousFetchFailed = (CKKSFetchBecause*) @"fetchfailed"; +CKKSFetchBecause* const CKKSFetchBecauseNetwork = (CKKSFetchBecause*) @"network"; CKKSFetchBecause* const CKKSFetchBecauseKeyHierarchy = (CKKSFetchBecause*) @"keyhierarchy"; CKKSFetchBecause* const CKKSFetchBecauseTesting = (CKKSFetchBecause*) @"testing"; +CKKSFetchBecause* const CKKSFetchBecauseResync = (CKKSFetchBecause*) @"resync"; + +#pragma mark - CKKSZoneChangeFetchDependencyOperation +@interface CKKSZoneChangeFetchDependencyOperation : CKKSResultOperation +@property CKKSZoneChangeFetcher* owner; +@end + +@implementation CKKSZoneChangeFetchDependencyOperation +- (NSError* _Nullable)descriptionError { + return [NSError errorWithDomain:CKKSResultDescriptionErrorDomain + code:CKKSResultDescriptionPendingSuccessfulFetch + description:@"Fetch failed" + underlying:self.owner.lastCKFetchError]; +} +@end + +#pragma mark - CKKSZoneChangeFetcher @interface CKKSZoneChangeFetcher () @property NSString* name; @property dispatch_queue_t queue; +@property NSError* lastCKFetchError; + @property CKKSFetchAllRecordZoneChangesOperation* currentFetch; @property CKKSResultOperation* currentProcessResult; @@ -70,21 +90,22 @@ CKKSFetchBecause* const CKKSFetchBecauseTesting = (CKKSFetchBecause*) @"testing" _name = [NSString stringWithFormat:@"zone-change-fetcher-%@", _zoneID.zoneName]; _queue = dispatch_queue_create([_name UTF8String], DISPATCH_QUEUE_SERIAL); - [self newSuccesfulFetchDependency]; + _successfulFetchDependency = [self createSuccesfulFetchDependency]; _newRequests = false; // If we're testing, for the initial delay, use 0.2 second. Otherwise, 2s. - dispatch_time_t initialDelay = (SecCKKSTestsEnabled() ? 200 * NSEC_PER_MSEC : 2 * NSEC_PER_SEC); + dispatch_time_t initialDelay = (SecCKKSReduceRateLimiting() ? 200 * NSEC_PER_MSEC : 2 * NSEC_PER_SEC); // If we're testing, for the initial delay, use 2 second. Otherwise, 30s. - dispatch_time_t continuingDelay = (SecCKKSTestsEnabled() ? 2 * NSEC_PER_SEC : 30 * NSEC_PER_SEC); + dispatch_time_t continuingDelay = (SecCKKSReduceRateLimiting() ? 2 * NSEC_PER_SEC : 30 * NSEC_PER_SEC); __weak __typeof(self) weakSelf = self; _fetchScheduler = [[CKKSNearFutureScheduler alloc] initWithName:[NSString stringWithFormat:@"zone-change-fetch-scheduler-%@", self.zoneID.zoneName] initialDelay:initialDelay continuingDelay:continuingDelay keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionPendingZoneChangeFetchScheduling block:^{ [weakSelf maybeCreateNewFetch]; }]; @@ -150,15 +171,20 @@ CKKSFetchBecause* const CKKSFetchBecauseTesting = (CKKSFetchBecause*) @"testing" ckksnotice("ckksfetcher", self.zoneID, "Starting a new fetch for %@", self.zoneID.zoneName); - NSSet* lastFetchReasons = self.currentFetchReasons; + NSMutableSet* lastFetchReasons = self.currentFetchReasons; self.currentFetchReasons = [[NSMutableSet alloc] init]; if(self.newResyncRequests) { - [lastFetchReasons setByAddingObject:@"resync"]; + [lastFetchReasons addObject:CKKSFetchBecauseResync]; } CKOperationGroup* operationGroup = [CKOperationGroup CKKSGroupWithName: [[lastFetchReasons sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"description" ascending:YES]]] componentsJoinedByString:@","]]; - CKKSFetchAllRecordZoneChangesOperation* fetchAllChanges = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithCKKSKeychainView: ckks ckoperationGroup:operationGroup]; + CKKSFetchAllRecordZoneChangesOperation* fetchAllChanges = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithCKKSKeychainView:ckks + fetchReasons:lastFetchReasons + ckoperationGroup:operationGroup]; + if ([lastFetchReasons containsObject:CKKSFetchBecauseNetwork]) { + [fetchAllChanges addNullableDependency: ckks.reachabilityTracker.reachablityDependency]; // wait on network, if its unavailable + } [fetchAllChanges addNullableDependency: self.holdOperation]; fetchAllChanges.resync = self.newResyncRequests; self.newResyncRequests = false; @@ -180,6 +206,8 @@ CKKSFetchBecause* const CKKSFetchBecauseTesting = (CKKSFetchBecause*) @"testing" } dispatch_sync(strongSelf.queue, ^{ + self.lastCKFetchError = fetchAllChanges.error; + if(!fetchAllChanges.error) { // success! notify the listeners. [blockckks scheduleOperation: dependency]; @@ -189,14 +217,15 @@ CKKSFetchBecause* const CKKSFetchBecauseTesting = (CKKSFetchBecause*) @"testing" [strongSelf.fetchScheduler trigger]; } } else { + // The operation errored. Chain the dependency on the current one... + [dependency addSuccessDependency: strongSelf.successfulFetchDependency]; + [blockckks scheduleOperation: dependency]; + if([blockckks isFatalCKFetchError: fetchAllChanges.error]) { ckkserror("ckksfetcher", strongSelf.zoneID, "Notified that %@ is a fatal error. Not restarting fetch.", fetchAllChanges.error); return; } - // The operation errored. Chain the dependency on the current one... - [dependency addSuccessDependency: strongSelf.successfulFetchDependency]; - [blockckks scheduleOperation: dependency]; // And in a bit, try the fetch again. NSNumber* delaySeconds = fetchAllChanges.error.userInfo[CKErrorRetryAfterKey]; @@ -209,7 +238,12 @@ CKKSFetchBecause* const CKKSFetchBecauseTesting = (CKKSFetchBecause*) @"testing" // Add the failed fetch reasons to the new fetch reasons [strongSelf.currentFetchReasons unionSet:lastFetchReasons]; - [strongSelf.currentFetchReasons addObject:CKKSFetchBecausePreviousFetchFailed]; + // If its a network error, make next try depend on network availability + if ([blockckks.reachabilityTracker isNetworkError:fetchAllChanges.error]) { + [strongSelf.currentFetchReasons addObject:CKKSFetchBecauseNetwork]; + } else { + [strongSelf.currentFetchReasons addObject:CKKSFetchBecausePreviousFetchFailed]; + } strongSelf.newRequests = true; strongSelf.newResyncRequests |= fetchAllChanges.resync; [strongSelf.fetchScheduler trigger]; @@ -226,11 +260,11 @@ CKKSFetchBecause* const CKKSFetchBecauseTesting = (CKKSFetchBecause*) @"testing" // creata a new fetch dependency, for all those who come in while this operation is executing self.newRequests = false; - [self newSuccesfulFetchDependency]; + self.successfulFetchDependency = [self createSuccesfulFetchDependency]; } --(void)newSuccesfulFetchDependency { - CKKSResultOperation* dep = [[CKKSResultOperation alloc] init]; +-(CKKSZoneChangeFetchDependencyOperation*)createSuccesfulFetchDependency { + CKKSZoneChangeFetchDependencyOperation* dep = [[CKKSZoneChangeFetchDependencyOperation alloc] init]; __weak __typeof(dep) weakDep = dep; // Since these dependencies might chain, when one runs, break the chain. @@ -244,8 +278,10 @@ CKKSFetchBecause* const CKKSFetchBecauseTesting = (CKKSFetchBecause*) @"testing" } }]; dep.name = @"successful-fetch-dependency"; + dep.descriptionErrorCode = CKKSResultDescriptionPendingSuccessfulFetch; + dep.owner = self; - self.successfulFetchDependency = dep; + return dep; } - (void)holdFetchesUntil:(CKKSResultOperation*)holdOperation { diff --git a/keychain/ckks/CKKSZoneStateEntry.m b/keychain/ckks/CKKSZoneStateEntry.m index f8e808fe..060a9960 100644 --- a/keychain/ckks/CKKSZoneStateEntry.m +++ b/keychain/ckks/CKKSZoneStateEntry.m @@ -24,6 +24,7 @@ #include #import +#import #import "CKKSKeychainView.h" @@ -101,8 +102,7 @@ - (CKServerChangeToken*) getChangeToken { if(self.encodedChangeToken) { - NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:self.encodedChangeToken]; - unarchiver.requiresSecureCoding = YES; + NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:self.encodedChangeToken error:nil]; return [unarchiver decodeObjectOfClass:[CKServerChangeToken class] forKey:NSKeyedArchiveRootObjectKey]; } else { return nil; @@ -110,14 +110,14 @@ } - (void) setChangeToken: (CKServerChangeToken*) token { - self.encodedChangeToken = token ? [NSKeyedArchiver archivedDataWithRootObject:token] : nil; + self.encodedChangeToken = token ? [NSKeyedArchiver archivedDataWithRootObject:token requiringSecureCoding:YES error:nil] : nil; } - (NSData*)encodedRateLimiter { if(self.rateLimiter == nil) { return nil; } - return [NSKeyedArchiver archivedDataWithRootObject: self.rateLimiter]; + return [NSKeyedArchiver archivedDataWithRootObject:self.rateLimiter requiringSecureCoding:YES error:nil]; } - (void)setEncodedRateLimiter:(NSData *)encodedRateLimiter { @@ -126,8 +126,7 @@ return; } - NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:encodedRateLimiter]; - unarchiver.requiresSecureCoding = YES; + NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:encodedRateLimiter error:nil]; self.rateLimiter = [unarchiver decodeObjectOfClass: [CKKSRateLimiter class] forKey:NSKeyedArchiveRootObjectKey]; } diff --git a/keychain/ckks/CloudKitDependencies.h b/keychain/ckks/CloudKitDependencies.h index ae8f9e3a..75ea2414 100644 --- a/keychain/ckks/CloudKitDependencies.h +++ b/keychain/ckks/CloudKitDependencies.h @@ -41,6 +41,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, copy, nullable) NSArray* recordZoneIDsToDelete; @property NSOperationQueuePriority queuePriority; @property NSQualityOfService qualityOfService; +@property (nonatomic, strong, nullable) CKOperationGroup* group; @property (nonatomic, copy, nullable) void (^modifyRecordZonesCompletionBlock) (NSArray* _Nullable savedRecordZones, NSArray* _Nullable deletedRecordZoneIDs, NSError* _Nullable operationError); @@ -108,6 +109,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, copy, nullable) NSArray* recordIDs; @property (nonatomic, copy, nullable) NSArray* desiredKeys; +@property (nonatomic, copy, nullable) CKOperationConfiguration* configuration; @property (nonatomic, copy, nullable) void (^perRecordProgressBlock)(CKRecordID* recordID, double progress); @property (nonatomic, copy, nullable) void (^perRecordCompletionBlock) (CKRecord* _Nullable record, CKRecordID* _Nullable recordID, NSError* _Nullable error); diff --git a/keychain/ckks/NSOperationCategories.h b/keychain/ckks/NSOperationCategories.h index 3672768b..9740dd31 100644 --- a/keychain/ckks/NSOperationCategories.h +++ b/keychain/ckks/NSOperationCategories.h @@ -39,6 +39,9 @@ // Insert yourself as high up the linearized list of dependencies as possible - (void)linearDependenciesWithSelfFirst:(NSHashTable*)collection; +// Set completionBlock to remove all dependencies - break strong references. +- (void)removeDependenciesUponCompletion; + // Return a stringified representation of this operation's live dependencies. - (NSString*)pendingDependenciesString:(NSString*)prefix; @end diff --git a/keychain/ckks/NSOperationCategories.m b/keychain/ckks/NSOperationCategories.m index da565e2c..5d9d2c7d 100644 --- a/keychain/ckks/NSOperationCategories.m +++ b/keychain/ckks/NSOperationCategories.m @@ -115,6 +115,18 @@ [self addDependency:op]; } } + +- (void)removeDependenciesUponCompletion +{ + __weak __typeof(self) weakSelf = self; + self.completionBlock = ^{ + __strong __typeof(weakSelf) strongSelf = weakSelf; + for (NSOperation *op in strongSelf.dependencies) { + [strongSelf removeDependency:op]; + } + }; +} + @end @implementation NSBlockOperation (CKKSUsefulConstructorOperation) diff --git a/keychain/ckks/tests/CKKSCloudKitTests.m b/keychain/ckks/tests/CKKSCloudKitTests.m index f0ad55f8..b91df343 100644 --- a/keychain/ckks/tests/CKKSCloudKitTests.m +++ b/keychain/ckks/tests/CKKSCloudKitTests.m @@ -65,6 +65,7 @@ + (void)setUp { SecCKKSResetSyncing(); SecCKKSTestsEnable(); + SecCKKSSetReduceRateLimiting(true); [super setUp]; #if NO_SERVER diff --git a/keychain/ckks/tests/CKKSConditionTests.m b/keychain/ckks/tests/CKKSConditionTests.m index 091500d1..1c0c6bb2 100644 --- a/keychain/ckks/tests/CKKSConditionTests.m +++ b/keychain/ckks/tests/CKKSConditionTests.m @@ -20,6 +20,7 @@ * * @APPLE_LICENSE_HEADER_END@ */ +#if OCTAGON #import #import @@ -69,7 +70,7 @@ [expectation fulfill]; }); - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(150 * NSEC_PER_MSEC)), queue, ^{ + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(250 * NSEC_PER_MSEC)), queue, ^{ [c fulfill]; }); @@ -95,3 +96,5 @@ } @end + +#endif /* OCTAGON */ diff --git a/keychain/ckks/tests/CKKSDeviceStateUploadTests.m b/keychain/ckks/tests/CKKSDeviceStateUploadTests.m new file mode 100644 index 00000000..a7bfeb28 --- /dev/null +++ b/keychain/ckks/tests/CKKSDeviceStateUploadTests.m @@ -0,0 +1,622 @@ +/* + * Copyright (c) 2018 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import +#import +#import + +#import "keychain/ckks/tests/CloudKitMockXCTest.h" +#import "keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h" +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSViewManager.h" + +#import "keychain/ckks/tests/MockCloudKit.h" +#import "keychain/ckks/tests/CKKSTests.h" + +// break abstraction +@interface CKKSLockStateTracker () +@property (nullable) NSDate* lastUnlockedTime; +@end + + +@interface CloudKitKeychainSyncingDeviceStateUploadTests : CloudKitKeychainSyncingTestsBase +@end + +@implementation CloudKitKeychainSyncingDeviceStateUploadTests + +- (void)testDeviceStateUploadGood { + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + + [self startCKKSSubsystem]; + [self.keychainView waitForKeyHierarchyReadiness]; + + __weak __typeof(self) weakSelf = self; + [self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} + deletedRecordTypeCounts:nil + zoneID:self.keychainZoneID + checkModifiedRecord: ^BOOL (CKRecord* record){ + if([record.recordType isEqualToString: SecCKRecordDeviceStateType]) { + // Check that all the things matches + __strong __typeof(weakSelf) strongSelf = weakSelf; + XCTAssertNotNil(strongSelf, "self exists"); + + ZoneKeys* zoneKeys = strongSelf.keys[strongSelf.keychainZoneID]; + XCTAssertNotNil(zoneKeys, "Have zone keys for %@", strongSelf.keychainZoneID); + + XCTAssertEqualObjects(record[SecCKSRecordOSVersionKey], SecCKKSHostOSVersion(), "os version string should match current OS version"); + XCTAssertTrue([self.utcCalendar isDate:record[SecCKSRecordLastUnlockTime] equalToDate:[NSDate date] toUnitGranularity:NSCalendarUnitDay], + "last unlock date (%@) similar to Now (%@)", record[SecCKSRecordLastUnlockTime], [NSDate date]); + + XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); + XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); + XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateReady), "Device is in ready"); + + XCTAssertEqualObjects([record[SecCKRecordCurrentTLK] recordID].recordName, zoneKeys.tlk.uuid, "Correct TLK uuid"); + XCTAssertEqualObjects([record[SecCKRecordCurrentClassA] recordID].recordName, zoneKeys.classA.uuid, "Correct class A uuid"); + XCTAssertEqualObjects([record[SecCKRecordCurrentClassC] recordID].recordName, zoneKeys.classC.uuid, "Correct class C uuid"); + return YES; + } else { + return NO; + } + } + runAfterModification:nil]; + + [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + +- (void)testDeviceStateUploadRateLimited { + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + + [self startCKKSSubsystem]; + [self.keychainView waitForKeyHierarchyReadiness]; + + __weak __typeof(self) weakSelf = self; + [self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} + deletedRecordTypeCounts:nil + zoneID:self.keychainZoneID + checkModifiedRecord: ^BOOL (CKRecord* record){ + if([record.recordType isEqualToString: SecCKRecordDeviceStateType]) { + // Check that all the things matches + __strong __typeof(weakSelf) strongSelf = weakSelf; + XCTAssertNotNil(strongSelf, "self exists"); + + ZoneKeys* zoneKeys = strongSelf.keys[strongSelf.keychainZoneID]; + XCTAssertNotNil(zoneKeys, "Have zone keys for %@", strongSelf.keychainZoneID); + + XCTAssertEqualObjects(record[SecCKSRecordOSVersionKey], SecCKKSHostOSVersion(), "os version string should match current OS version"); + XCTAssertTrue([self.utcCalendar isDate:record[SecCKSRecordLastUnlockTime] equalToDate:[NSDate date] toUnitGranularity:NSCalendarUnitDay], + "last unlock date (%@) similar to Now (%@)", record[SecCKSRecordLastUnlockTime], [NSDate date]); + + XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); + XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); + XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateReady), "Device is in ready"); + + XCTAssertEqualObjects([record[SecCKRecordCurrentTLK] recordID].recordName, zoneKeys.tlk.uuid, "Correct TLK uuid"); + XCTAssertEqualObjects([record[SecCKRecordCurrentClassA] recordID].recordName, zoneKeys.classA.uuid, "Correct class A uuid"); + XCTAssertEqualObjects([record[SecCKRecordCurrentClassC] recordID].recordName, zoneKeys.classC.uuid, "Correct class C uuid"); + return YES; + } else { + return NO; + } + } + runAfterModification:nil]; + + CKKSUpdateDeviceStateOperation* op = [self.keychainView updateDeviceState:true waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [op waitUntilFinished]; + + // Check that an immediate rate-limited retry doesn't upload anything + op = [self.keychainView updateDeviceState:true waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; + [op waitUntilFinished]; + + // But not rate-limiting works just fine! + [self expectCKModifyRecords:@{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} + deletedRecordTypeCounts:nil + zoneID:self.keychainZoneID + checkModifiedRecord:nil + runAfterModification:nil]; + op = [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [op waitUntilFinished]; + + // And now, if the update is old enough, that'll work too + [self.keychainView dispatchSync:^bool { + NSError* error = nil; + CKKSDeviceStateEntry* cdse = [CKKSDeviceStateEntry fromDatabase:self.accountStateTracker.ckdeviceID zoneID:self.keychainZoneID error:&error]; + XCTAssertNil(error, "No error fetching device state entry"); + XCTAssertNotNil(cdse, "Fetched device state entry"); + + CKRecord* record = cdse.storedCKRecord; + + NSDate* m = record.modificationDate; + XCTAssertNotNil(m, "Have modification date"); + + // Four days ago! + NSDateComponents* offset = [[NSDateComponents alloc] init]; + [offset setHour:-4 * 24]; + NSDate* m2 = [[NSCalendar currentCalendar] dateByAddingComponents:offset toDate:m options:0]; + + XCTAssertNotNil(m2, "Made modification date"); + + record.modificationDate = m2; + [cdse setStoredCKRecord:record]; + + [cdse saveToDatabase:&error]; + XCTAssertNil(error, "No error saving device state entry"); + + return true; + }]; + + // And now the rate-limiting doesn't get in the way + [self expectCKModifyRecords:@{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} + deletedRecordTypeCounts:nil + zoneID:self.keychainZoneID + checkModifiedRecord:nil + runAfterModification:nil]; + op = [self.keychainView updateDeviceState:true waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; + OCMVerifyAllWithDelay(self.mockDatabase, 12); + [op waitUntilFinished]; +} + +- (void)testDeviceStateUploadRateLimitedAfterNormalUpload { + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + + [self startCKKSSubsystem]; + [self.keychainView waitForKeyHierarchyReadiness]; + + [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; + [self addGenericPassword:@"password" account:@"account-delete-me"]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + + // Check that an immediate rate-limited retry doesn't upload anything + CKKSUpdateDeviceStateOperation* op = [self.keychainView updateDeviceState:true waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; + [op waitUntilFinished]; +} + +- (void)testDeviceStateUploadWaitsForKeyHierarchyReady { + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + + // Ask to wait for quite a while if we don't become ready + [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:20*NSEC_PER_SEC ckoperationGroup:nil]; + + __weak __typeof(self) weakSelf = self; + // Expect a ready upload + [self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} + deletedRecordTypeCounts:nil + zoneID:self.keychainZoneID + checkModifiedRecord: ^BOOL (CKRecord* record){ + if([record.recordType isEqualToString: SecCKRecordDeviceStateType]) { + __strong __typeof(weakSelf) strongSelf = weakSelf; + XCTAssertNotNil(strongSelf, "self exists"); + + ZoneKeys* zoneKeys = strongSelf.keys[strongSelf.keychainZoneID]; + XCTAssertNotNil(zoneKeys, "Have zone keys for %@", strongSelf.keychainZoneID); + + XCTAssertEqualObjects(record[SecCKSRecordOSVersionKey], SecCKKSHostOSVersion(), "os version string should match current OS version"); + XCTAssertTrue([self.utcCalendar isDate:record[SecCKSRecordLastUnlockTime] equalToDate:[NSDate date] toUnitGranularity:NSCalendarUnitDay], + "last unlock date (%@) similar to Now (%@)", record[SecCKSRecordLastUnlockTime], [NSDate date]); + + XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); + XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); + XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateReady), "Device is in ready"); + + XCTAssertEqualObjects([record[SecCKRecordCurrentTLK] recordID].recordName, zoneKeys.tlk.uuid, "Correct TLK uuid"); + XCTAssertEqualObjects([record[SecCKRecordCurrentClassA] recordID].recordName, zoneKeys.classA.uuid, "Correct class A uuid"); + XCTAssertEqualObjects([record[SecCKRecordCurrentClassC] recordID].recordName, zoneKeys.classC.uuid, "Correct class C uuid"); + return YES; + } else { + return NO; + } + } + runAfterModification:nil]; + + // And allow the key state to progress + [self startCKKSSubsystem]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + +- (void)testDeviceStateUploadWaitsForKeyHierarchyWaitForTLK { + // This test has stuff in CloudKit, but no TLKs. It should become very sad. + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; + + // Ask to wait for the key state to enter a state if we don't become ready + [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:20*NSEC_PER_SEC ckoperationGroup:nil]; + + __weak __typeof(self) weakSelf = self; + // Expect a waitfortlk upload + [self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} + deletedRecordTypeCounts:nil + zoneID:self.keychainZoneID + checkModifiedRecord: ^BOOL (CKRecord* record){ + if([record.recordType isEqualToString: SecCKRecordDeviceStateType]) { + __strong __typeof(weakSelf) strongSelf = weakSelf; + XCTAssertNotNil(strongSelf, "self exists"); + + ZoneKeys* zoneKeys = strongSelf.keys[strongSelf.keychainZoneID]; + XCTAssertNotNil(zoneKeys, "Have zone keys for %@", strongSelf.keychainZoneID); + + XCTAssertEqualObjects(record[SecCKSRecordOSVersionKey], SecCKKSHostOSVersion(), "os version string should match current OS version"); + XCTAssertTrue([self.utcCalendar isDate:record[SecCKSRecordLastUnlockTime] equalToDate:[NSDate date] toUnitGranularity:NSCalendarUnitDay], + "last unlock date (%@) similar to Now (%@)", record[SecCKSRecordLastUnlockTime], [NSDate date]); + + XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID should matche what we gave it"); + XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device should be in circle"); + XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateWaitForTLK), "Device should be in waitfortlk"); + + XCTAssertNil([record[SecCKRecordCurrentTLK] recordID].recordName, "Should have no TLK uuid"); + XCTAssertNil([record[SecCKRecordCurrentClassA] recordID].recordName, "Should have no class A uuid"); + XCTAssertNil([record[SecCKRecordCurrentClassC] recordID].recordName, "Should have no class C uuid"); + return YES; + } else { + return NO; + } + } + runAfterModification:nil]; + + // And allow the key state to progress + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + +- (void)testDeviceStateReceive { + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + + ZoneKeys* zoneKeys = self.keys[self.keychainZoneID]; + XCTAssertNotNil(zoneKeys, "Have zone keys for %@", self.keychainZoneID); + + [self startCKKSSubsystem]; + [self.keychainView waitForKeyHierarchyReadiness]; + + NSDate* date = [[NSCalendar currentCalendar] startOfDayForDate:[NSDate date]]; + CKKSDeviceStateEntry* cdse = [[CKKSDeviceStateEntry alloc] initForDevice:@"otherdevice" + osVersion:@"fake-version" + lastUnlockTime:date + circlePeerID:@"asdfasdf" + circleStatus:kSOSCCInCircle + keyState:SecCKKSZoneKeyStateReady + currentTLKUUID:zoneKeys.tlk.uuid + currentClassAUUID:zoneKeys.classA.uuid + currentClassCUUID:zoneKeys.classC.uuid + zoneID:self.keychainZoneID + encodedCKRecord:nil]; + CKRecord* record = [cdse CKRecordWithZoneID:self.keychainZoneID]; + [self.keychainZone addToZone:record]; + + CKKSDeviceStateEntry* oldcdse = [[CKKSDeviceStateEntry alloc] initForDevice:@"olderotherdevice" + osVersion:nil // old-style, no OSVersion or lastUnlockTime + lastUnlockTime:nil + circlePeerID:@"olderasdfasdf" + circleStatus:kSOSCCInCircle + keyState:SecCKKSZoneKeyStateReady + currentTLKUUID:zoneKeys.tlk.uuid + currentClassAUUID:zoneKeys.classA.uuid + currentClassCUUID:zoneKeys.classC.uuid + zoneID:self.keychainZoneID + encodedCKRecord:nil]; + [self.keychainZone addToZone:[oldcdse CKRecordWithZoneID:self.keychainZoneID]]; + + // Trigger a notification (with hilariously fake data) + [self.keychainView notifyZoneChange:nil]; + [self.keychainView waitForFetchAndIncomingQueueProcessing]; + + [self.keychainView dispatchSync: ^bool { + NSError* error = nil; + NSArray* cdses = [CKKSDeviceStateEntry allInZone:self.keychainZoneID error:&error]; + XCTAssertNil(error, "No error fetching CDSEs"); + XCTAssertNotNil(cdses, "An array of CDSEs was returned"); + XCTAssert(cdses.count >= 1u, "At least one CDSE came back"); + + CKKSDeviceStateEntry* item = nil; + CKKSDeviceStateEntry* olderotherdevice = nil; + for(CKKSDeviceStateEntry* dbcdse in cdses) { + if([dbcdse.device isEqualToString:@"otherdevice"]) { + item = dbcdse; + } else if([dbcdse.device isEqualToString:@"olderotherdevice"]) { + olderotherdevice = dbcdse; + } + } + XCTAssertNotNil(item, "Found a cdse for otherdevice"); + + XCTAssertEqualObjects(cdse, item, "Saved item matches pre-cloudkit item"); + + XCTAssertEqualObjects(item.osVersion, @"fake-version", "correct osVersion"); + XCTAssertEqualObjects(item.lastUnlockTime, date, "correct date"); + XCTAssertEqualObjects(item.circlePeerID, @"asdfasdf", "correct peer id"); + XCTAssertEqualObjects(item.keyState, SecCKKSZoneKeyStateReady, "correct key state"); + XCTAssertEqualObjects(item.currentTLKUUID, zoneKeys.tlk.uuid, "correct tlk uuid"); + XCTAssertEqualObjects(item.currentClassAUUID, zoneKeys.classA.uuid, "correct classA uuid"); + XCTAssertEqualObjects(item.currentClassCUUID, zoneKeys.classC.uuid, "correct classC uuid"); + + + XCTAssertNotNil(olderotherdevice, "Should have found a cdse for olderotherdevice"); + XCTAssertEqualObjects(oldcdse, olderotherdevice, "Saved item should match pre-cloudkit item"); + + XCTAssertNil(olderotherdevice.osVersion, "osVersion should be nil"); + XCTAssertNil(olderotherdevice.lastUnlockTime, "lastUnlockTime should be nil"); + XCTAssertEqualObjects(olderotherdevice.circlePeerID, @"olderasdfasdf", "correct peer id"); + XCTAssertEqualObjects(olderotherdevice.keyState, SecCKKSZoneKeyStateReady, "correct key state"); + XCTAssertEqualObjects(olderotherdevice.currentTLKUUID, zoneKeys.tlk.uuid, "correct tlk uuid"); + XCTAssertEqualObjects(olderotherdevice.currentClassAUUID, zoneKeys.classA.uuid, "correct classA uuid"); + XCTAssertEqualObjects(olderotherdevice.currentClassCUUID, zoneKeys.classC.uuid, "correct classC uuid"); + + return false; + }]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + +- (void)testDeviceStateUploadBadKeyState { + // This test has stuff in CloudKit, but no TLKs. It should become very sad. + [self putFakeKeyHierarchyInCloudKit: self.keychainZoneID]; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; + + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); + XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateWaitForTLK, "CKKS entered waitfortlk"); + + __weak __typeof(self) weakSelf = self; + [self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} + deletedRecordTypeCounts:nil + zoneID:self.keychainZoneID + checkModifiedRecord: ^BOOL (CKRecord* record){ + if([record.recordType isEqualToString: SecCKRecordDeviceStateType]) { + // Check that all the things matches + __strong __typeof(weakSelf) strongSelf = weakSelf; + XCTAssertNotNil(strongSelf, "self exists"); + + XCTAssertEqualObjects(record[SecCKSRecordOSVersionKey], SecCKKSHostOSVersion(), "os version string should match current OS version"); + XCTAssertTrue([self.utcCalendar isDate:record[SecCKSRecordLastUnlockTime] equalToDate:[NSDate date] toUnitGranularity:NSCalendarUnitDay], + "last unlock date (%@) similar to Now (%@)", record[SecCKSRecordLastUnlockTime], [NSDate date]); + + XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); + XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); + XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateWaitForTLK), "Device is in waitfortlk"); + + XCTAssertNil(record[SecCKRecordCurrentTLK] , "No TLK"); + XCTAssertNil(record[SecCKRecordCurrentClassA], "No class A key"); + XCTAssertNil(record[SecCKRecordCurrentClassC], "No class C key"); + return YES; + } else { + return NO; + } + } + runAfterModification:nil]; + + [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:500*NSEC_PER_MSEC ckoperationGroup:nil]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + +- (void)testDeviceStateUploadWaitForUnlockKeyState { + // Starts with everything in keychain, but locked + [self putFakeKeyHierarchyInCloudKit: self.keychainZoneID]; + [self saveTLKMaterialToKeychain:self.keychainZoneID]; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; + + NSDateComponents *dateComponents = [[NSDateComponents alloc] init]; + [dateComponents setDay:-3]; + NSDate* threeDaysAgo = [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:[NSDate date] options:0]; + + self.aksLockState = true; + [self.lockStateTracker recheck]; + self.lockStateTracker.lastUnlockedTime = threeDaysAgo; + XCTAssertTrue([self.utcCalendar isDate:self.lockStateTracker.lastUnlockTime + equalToDate:threeDaysAgo + toUnitGranularity:NSCalendarUnitSecond], + "last unlock date (%@) similar to threeDaysAgo (%@)", self.lockStateTracker.lastUnlockTime, threeDaysAgo); + + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForUnlock] wait:8*NSEC_PER_SEC], "CKKS entered waitforunlock"); + + __weak __typeof(self) weakSelf = self; + [self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} + deletedRecordTypeCounts:nil + zoneID:self.keychainZoneID + checkModifiedRecord: ^BOOL (CKRecord* record){ + if([record.recordType isEqualToString: SecCKRecordDeviceStateType]) { + // Check that all the things matches + __strong __typeof(weakSelf) strongSelf = weakSelf; + XCTAssertNotNil(strongSelf, "self exists"); + + XCTAssertEqualObjects(record[SecCKSRecordOSVersionKey], SecCKKSHostOSVersion(), "os version string should match current OS version"); + XCTAssertTrue([self.utcCalendar isDate:record[SecCKSRecordLastUnlockTime] equalToDate:threeDaysAgo toUnitGranularity:NSCalendarUnitDay], + "last unlock date (%@) similar to three days ago (%@)", record[SecCKSRecordLastUnlockTime], threeDaysAgo); + + XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); + XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); + XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateWaitForUnlock), "Device is in waitforunlock"); + + XCTAssertNil(record[SecCKRecordCurrentTLK] , "No TLK"); + XCTAssertNil(record[SecCKRecordCurrentClassA], "No class A key"); + XCTAssertNil(record[SecCKRecordCurrentClassC], "No class C key"); + return YES; + } else { + return NO; + } + } + runAfterModification:nil]; + + [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:500*NSEC_PER_MSEC ckoperationGroup:nil]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + +- (void)testDeviceStateUploadBadKeyStateAfterRestart { + // This test has stuff in CloudKit, but no TLKs. It should become very sad. + [self putFakeKeyHierarchyInCloudKit: self.keychainZoneID]; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; + + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); + XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateWaitForTLK, "CKKS entered waitfortlk"); + + // And restart CKKS... + self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); + XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateWaitForTLK, "CKKS entered waitfortlk"); + + __weak __typeof(self) weakSelf = self; + [self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} + deletedRecordTypeCounts:nil + zoneID:self.keychainZoneID + checkModifiedRecord: ^BOOL (CKRecord* record){ + if([record.recordType isEqualToString: SecCKRecordDeviceStateType]) { + // Check that all the things matches + __strong __typeof(weakSelf) strongSelf = weakSelf; + XCTAssertNotNil(strongSelf, "self exists"); + + XCTAssertEqualObjects(record[SecCKSRecordOSVersionKey], SecCKKSHostOSVersion(), "os version string should match current OS version"); + XCTAssertTrue([self.utcCalendar isDate:record[SecCKSRecordLastUnlockTime] equalToDate:[NSDate date] toUnitGranularity:NSCalendarUnitDay], + "last unlock date (%@) similar to Now (%@)", record[SecCKSRecordLastUnlockTime], [NSDate date]); + + XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); + XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); + XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateWaitForTLK), "Device is in waitfortlk"); + + XCTAssertNil(record[SecCKRecordCurrentTLK] , "No TLK"); + XCTAssertNil(record[SecCKRecordCurrentClassA], "No class A key"); + XCTAssertNil(record[SecCKRecordCurrentClassC], "No class C key"); + return YES; + } else { + return NO; + } + } + runAfterModification:nil]; + + [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:500*NSEC_PER_MSEC ckoperationGroup:nil]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + + +- (void)testDeviceStateUploadBadCircleState { + self.circleStatus = kSOSCCNotInCircle; + [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + + // This test has stuff in CloudKit, but no TLKs. + [self putFakeKeyHierarchyInCloudKit: self.keychainZoneID]; + + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:8*NSEC_PER_SEC], "CKKS entered logged out"); + XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateLoggedOut, "CKKS thinks it's logged out"); + + __weak __typeof(self) weakSelf = self; + [self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} + deletedRecordTypeCounts:nil + zoneID:self.keychainZoneID + checkModifiedRecord: ^BOOL (CKRecord* record){ + if([record.recordType isEqualToString: SecCKRecordDeviceStateType]) { + // Check that all the things matches + __strong __typeof(weakSelf) strongSelf = weakSelf; + XCTAssertNotNil(strongSelf, "self exists"); + + XCTAssertEqualObjects(record[SecCKSRecordOSVersionKey], SecCKKSHostOSVersion(), "os version string should match current OS version"); + XCTAssertTrue([self.utcCalendar isDate:record[SecCKSRecordLastUnlockTime] equalToDate:[NSDate date] toUnitGranularity:NSCalendarUnitDay], + "last unlock date (%@) similar to Now (%@)", record[SecCKSRecordLastUnlockTime], [NSDate date]); + + XCTAssertNil(record[SecCKRecordCirclePeerID], "no peer ID if device is not in circle"); + XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCNotInCircle], "device is not in circle"); + XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateLoggedOut), "Device is in keystate:loggedout"); + + XCTAssertNil(record[SecCKRecordCurrentTLK] , "No TLK"); + XCTAssertNil(record[SecCKRecordCurrentClassA], "No class A key"); + XCTAssertNil(record[SecCKRecordCurrentClassC], "No class C key"); + return YES; + } else { + return NO; + } + } + runAfterModification:nil]; + + CKKSUpdateDeviceStateOperation* op = [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:500*NSEC_PER_MSEC ckoperationGroup:nil]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + + [op waitUntilFinished]; + XCTAssertNil(op.error, "No error uploading 'out of circle' device state"); +} + +- (void)testDeviceStateUploadWithTardyNetworkAfterRestart { + // Test starts with a key hierarchy in cloudkit and the TLK having arrived + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self saveTLKMaterialToKeychain:self.keychainZoneID]; + [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; + + [self holdCloudKitFetches]; + + [self startCKKSSubsystem]; + + // we should be stuck in fetch + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateFetch] wait:8*NSEC_PER_SEC], "Key state should become fetch"); + + __weak __typeof(self) weakSelf = self; + [self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} + deletedRecordTypeCounts:nil + zoneID:self.keychainZoneID + checkModifiedRecord: ^BOOL (CKRecord* record){ + if([record.recordType isEqualToString: SecCKRecordDeviceStateType]) { + // Check that all the things matches + __strong __typeof(weakSelf) strongSelf = weakSelf; + XCTAssertNotNil(strongSelf, "self exists"); + + ZoneKeys* zoneKeys = strongSelf.keys[strongSelf.keychainZoneID]; + XCTAssertNotNil(zoneKeys, "Have zone keys for %@", strongSelf.keychainZoneID); + + XCTAssertEqualObjects(record[SecCKSRecordOSVersionKey], SecCKKSHostOSVersion(), "os version string should match current OS version"); + XCTAssertTrue([self.utcCalendar isDate:record[SecCKSRecordLastUnlockTime] equalToDate:[NSDate date] toUnitGranularity:NSCalendarUnitDay], + "last unlock date (%@) similar to Now (%@)", record[SecCKSRecordLastUnlockTime], [NSDate date]); + + XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); + XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); + XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateReady), "Device is in ready"); + + XCTAssertEqualObjects([record[SecCKRecordCurrentTLK] recordID].recordName, zoneKeys.tlk.uuid, "Correct TLK uuid"); + XCTAssertEqualObjects([record[SecCKRecordCurrentClassA] recordID].recordName, zoneKeys.classA.uuid, "Correct class A uuid"); + XCTAssertEqualObjects([record[SecCKRecordCurrentClassC] recordID].recordName, zoneKeys.classC.uuid, "Correct class C uuid"); + return YES; + } else { + return NO; + } + } + runAfterModification:nil]; + + + [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:8*NSEC_PER_SEC ckoperationGroup:nil]; + + XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateFetch, "CKKS re-entered fetch"); + [self releaseCloudKitFetchHold]; + + OCMVerifyAllWithDelay(self.mockDatabase, 16); +} + + + +@end + +#endif // OCTAGON diff --git a/keychain/ckks/tests/CKKSLoggerTests.m b/keychain/ckks/tests/CKKSLoggerTests.m index 0ef3b1e5..4a83cc8d 100644 --- a/keychain/ckks/tests/CKKSLoggerTests.m +++ b/keychain/ckks/tests/CKKSLoggerTests.m @@ -21,13 +21,16 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if OCTAGON + #import "CKKSTests.h" -#import "keychain/ckks/CKKSAnalyticsLogger.h" +#import "keychain/ckks/CKKSAnalytics.h" #import #import +#import +#import #import - -#if OCTAGON +#import static NSString* tablePath = nil; @@ -120,8 +123,8 @@ static NSString* tablePath = nil; XCTAssertTrue([sqlTable openWithError:&error], @"failed to open database"); XCTAssertNil(error, "encountered error opening database: %@", error); - // delete the database to create havoc - [[NSFileManager defaultManager] removeItemAtPath:tablePath error:nil]; + // delete the table to create havoc + XCTAssertTrue([sqlTable executeSQL:@"drop table test;"], @"deleting test table should have worked"); XCTAssertNoThrow([sqlTable insertOrReplaceInto:@"test" values:@{@"test_column" : @(1)}], @"inserting into deleted table threw an exception"); } @@ -129,11 +132,31 @@ static NSString* tablePath = nil; @end @interface CKKSAnalyticsTests : CloudKitKeychainSyncingTestsBase +@property id mockCKKSAnalytics; @end @implementation CKKSAnalyticsTests -- (void)testLastSuccessfulSyncDate +- (void)setUp +{ + self.mockCKKSAnalytics = OCMClassMock([CKKSAnalytics class]); + OCMStub([self.mockCKKSAnalytics databasePath]).andCall(self, @selector(databasePath)); + [super setUp]; +} + +- (void)tearDown +{ + [self.mockCKKSAnalytics stopMocking]; + self.mockCKKSAnalytics = nil; + [super tearDown]; +} + +- (NSString*)databasePath +{ + return [NSTemporaryDirectory() stringByAppendingPathComponent:@"test_ckks_analytics_v2.db"]; +} + +- (void)testLastSuccessfulXDate { [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. [self startCKKSSubsystem]; @@ -144,12 +167,54 @@ static NSString* tablePath = nil; [self.keychainView notifyZoneChange:nil]; [[[self.keychainView waitForFetchAndIncomingQueueProcessing] completionHandlerDidRunCondition] wait:4 * NSEC_PER_SEC]; - - NSDate* syncDate = [[CKKSAnalyticsLogger logger] dateOfLastSuccessForEvent:CKKSEventProcessIncomingQueueClassC inView:self.keychainView]; - XCTAssertNotNil(syncDate, "Failed to get a last successful sync date"); - NSDate* nowDate = [NSDate dateWithTimeIntervalSinceNow:0]; - NSTimeInterval timeIntervalSinceSyncDate = [nowDate timeIntervalSinceDate:syncDate]; - XCTAssertTrue(timeIntervalSinceSyncDate >= 0.0 && timeIntervalSinceSyncDate <= 15.0, "Last sync date does not look like a reasonable one"); + + NSDate* nowDate = [NSDate date]; + NSTimeInterval timeInterval; + + /* + * Check last sync date for class A + */ + NSDate* syncADate = [[CKKSAnalytics logger] dateOfLastSuccessForEvent:CKKSEventProcessIncomingQueueClassA inView:self.keychainView]; + XCTAssertNotNil(syncADate, "Failed to get a last successful A sync date"); + timeInterval = [nowDate timeIntervalSinceDate:syncADate]; + XCTAssertTrue(timeInterval >= 0.0 && timeInterval <= 15.0, "Last sync date does not look like a reasonable one"); + + /* + * Check last sync date for class C + */ + NSDate *syncCDate = [[CKKSAnalytics logger] dateOfLastSuccessForEvent:CKKSEventProcessIncomingQueueClassC inView:self.keychainView]; + XCTAssertNotNil(syncCDate, "Failed to get a last successful C sync date"); + timeInterval = [nowDate timeIntervalSinceDate:syncCDate]; + XCTAssertTrue(timeInterval >= 0.0 && timeInterval <= 15.0, "Last sync date does not look like a reasonable one"); + + /* + * Check last unlock date + */ + NSDate* unlockDate = [[CKKSAnalytics logger] datePropertyForKey:CKKSAnalyticsLastUnlock]; + XCTAssertNotNil(unlockDate, "Failed to get a last unlock date"); + timeInterval = [nowDate timeIntervalSinceDate:unlockDate]; + NSLog(@"timeinterval: %f\n", timeInterval); + XCTAssertTrue(timeInterval >= 0.0 && timeInterval <= 15.0, "Last unlock date does not look like a reasonable one"); + + sleep(1); // wait to be a differnt second + + self.aksLockState = true; + [self.lockStateTracker recheck]; + + NSDate* newUnlockDate = [[CKKSAnalytics logger] datePropertyForKey:CKKSAnalyticsLastUnlock]; + XCTAssertNotNil(newUnlockDate, "Failed to get a last unlock date"); + XCTAssertEqualObjects(newUnlockDate, unlockDate, "unlock date not the same"); + + sleep(1); // wait to be a differnt second + + self.aksLockState = false; + [self.lockStateTracker recheck]; + + sleep(1); // wait for the completion block to have time to fire + + newUnlockDate = [[CKKSAnalytics logger] datePropertyForKey:CKKSAnalyticsLastUnlock]; + XCTAssertNotNil(newUnlockDate, "Failed to get a last unlock date"); + XCTAssertNotEqualObjects(newUnlockDate, unlockDate, "unlock date the same"); } - (void)testRaceToCreateLoggers @@ -157,7 +222,7 @@ static NSString* tablePath = nil; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); for (NSInteger i = 0; i < 5; i++) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - CKKSAnalyticsLogger* logger = [CKKSAnalyticsLogger logger]; + CKKSAnalytics* logger = [CKKSAnalytics logger]; [logger logSuccessForEvent:(CKKSAnalyticsFailableEvent*)@"test_event" inView:self.keychainView]; dispatch_semaphore_signal(semaphore); }); @@ -168,6 +233,76 @@ static NSString* tablePath = nil; } } +- (void)testUnderlayingError +{ + NSDictionary *errorString = nil; + NSError *error = nil; + + error = [NSError errorWithDomain:CKErrorDomain code:CKErrorPartialFailure userInfo:@{ + CKPartialErrorsByItemIDKey : @{ + @"recordid" : [NSError errorWithDomain:CKErrorDomain code:1 userInfo:nil], + } + }]; + + errorString = [[CKKSAnalytics logger] errorChain:error depth:0]; + + XCTAssertEqualObjects(errorString[@"domain"], CKErrorDomain, "error domain"); + XCTAssertEqual([errorString[@"code"] intValue], CKErrorPartialFailure, "error code"); + + XCTAssertEqualObjects(errorString[@"oneCloudKitPartialFailure"][@"domain"], CKErrorDomain, "error domain"); + XCTAssertEqual([errorString[@"oneCloudKitPartialFailure"][@"code"] intValue], 1, "error code"); + + /* interal partial error leaks out of CK */ + + error = [NSError errorWithDomain:CKErrorDomain code:CKErrorPartialFailure userInfo:@{ + CKPartialErrorsByItemIDKey : @{ + @"recordid1" : [NSError errorWithDomain:CKErrorDomain code:CKErrorBatchRequestFailed userInfo:nil], + @"recordid2" : [NSError errorWithDomain:CKErrorDomain code:CKErrorBatchRequestFailed userInfo:nil], + @"recordid3" : [NSError errorWithDomain:CKErrorDomain code:CKErrorBatchRequestFailed userInfo:nil], + @"recordid4" : [NSError errorWithDomain:CKErrorDomain code:CKErrorBatchRequestFailed userInfo:nil], + @"recordid5" : [NSError errorWithDomain:CKErrorDomain code:CKErrorBatchRequestFailed userInfo:nil], + @"recordid6" : [NSError errorWithDomain:CKErrorDomain code:CKErrorBatchRequestFailed userInfo:nil], + @"recordid7" : [NSError errorWithDomain:CKErrorDomain code:CKErrorBatchRequestFailed userInfo:nil], + @"recordid8" : [NSError errorWithDomain:CKErrorDomain code:CKErrorBatchRequestFailed userInfo:nil], + @"recordid9" : [NSError errorWithDomain:CKErrorDomain code:CKErrorBatchRequestFailed userInfo:nil], + @"recordid0" : [NSError errorWithDomain:CKErrorDomain code:1 userInfo:nil], + @"recordid10" : [NSError errorWithDomain:CKErrorDomain code:CKErrorBatchRequestFailed userInfo:nil], + @"recordid12" : [NSError errorWithDomain:CKErrorDomain code:CKErrorBatchRequestFailed userInfo:nil], + @"recordid13" : [NSError errorWithDomain:CKErrorDomain code:CKErrorBatchRequestFailed userInfo:nil], + @"recordid14" : [NSError errorWithDomain:CKErrorDomain code:CKErrorBatchRequestFailed userInfo:nil], + @"recordid15" : [NSError errorWithDomain:CKErrorDomain code:CKErrorBatchRequestFailed userInfo:nil], + @"recordid16" : [NSError errorWithDomain:CKErrorDomain code:CKErrorBatchRequestFailed userInfo:nil], + @"recordid17" : [NSError errorWithDomain:CKErrorDomain code:CKErrorBatchRequestFailed userInfo:nil], + @"recordid18" : [NSError errorWithDomain:CKErrorDomain code:CKErrorBatchRequestFailed userInfo:nil], + @"recordid19" : [NSError errorWithDomain:CKErrorDomain code:CKErrorBatchRequestFailed userInfo:nil], + } + }]; + + errorString = [[CKKSAnalytics logger] errorChain:error depth:0]; + + XCTAssertEqualObjects(errorString[@"domain"], CKErrorDomain, "error domain"); + XCTAssertEqual([errorString[@"code"] intValue], CKErrorPartialFailure, "error code"); + + XCTAssertEqualObjects(errorString[@"oneCloudKitPartialFailure"][@"domain"], CKErrorDomain, "error domain"); + XCTAssertEqualObjects(errorString[@"oneCloudKitPartialFailure"][@"code"], @1, "error code"); + + + + + error = [NSError errorWithDomain:@"domain" code:1 userInfo:@{ + NSUnderlyingErrorKey : [NSError errorWithDomain:CKErrorDomain code:1 userInfo:nil], + }]; + + errorString = [[CKKSAnalytics logger] errorChain:error depth:0]; + + XCTAssertEqualObjects(errorString[@"domain"], @"domain", "error domain"); + XCTAssertEqual([errorString[@"code"] intValue], 1, "error code"); + + XCTAssertEqualObjects(errorString[@"child"][@"domain"], CKErrorDomain, "error domain"); + XCTAssertEqual([errorString[@"child"][@"code"] intValue], 1, "error code"); +} + + @end #endif diff --git a/keychain/ckks/tests/CKKSManifestTests.m b/keychain/ckks/tests/CKKSManifestTests.m index 2728f7c6..e427957b 100644 --- a/keychain/ckks/tests/CKKSManifestTests.m +++ b/keychain/ckks/tests/CKKSManifestTests.m @@ -95,6 +95,7 @@ // Test starts with keys in CloudKit (so we can create items later) [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; [self saveTLKMaterialToKeychain:self.keychainZoneID]; [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; @@ -119,7 +120,8 @@ OCMVerifyAllWithDelay(self.mockDatabase, 8); [self waitForCKModifications]; int tlkshares = 1; - XCTAssertEqual(self.keychainZone.currentDatabase.count, SYSTEM_DB_RECORD_COUNT + passwordCount + tlkshares, "Have 6+passwordCount objects in cloudkit"); + int extraDeviceStates = 1; + XCTAssertEqual(self.keychainZone.currentDatabase.count, SYSTEM_DB_RECORD_COUNT + passwordCount + tlkshares + extraDeviceStates, "Have 6+passwordCount objects in cloudkit"); NSArray* items = [self mirrorItemsForExistingItems]; _egoManifest = [CKKSEgoManifest newManifestForZone:self.keychainZoneID.zoneName withItems:items peerManifestIDs:@[] currentItems:@{} error:&error]; diff --git a/keychain/ckks/tests/CKKSNearFutureSchedulerTests.m b/keychain/ckks/tests/CKKSNearFutureSchedulerTests.m index 84de78f7..107af38b 100644 --- a/keychain/ckks/tests/CKKSNearFutureSchedulerTests.m +++ b/keychain/ckks/tests/CKKSNearFutureSchedulerTests.m @@ -21,10 +21,13 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if OCTAGON + #include #import #import "keychain/ckks/CKKSNearFutureScheduler.h" #import "keychain/ckks/CKKSResultOperation.h" +#import "keychain/ckks/CKKS.h" @interface CKKSNearFutureSchedulerTests : XCTestCase @property NSOperationQueue* operationQueue; @@ -47,7 +50,9 @@ - (void)testBlockOneShot { XCTestExpectation *expectation = [self expectationWithDescription:@"FutureScheduler fired"]; - CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay:50*NSEC_PER_MSEC keepProcessAlive:true block:^{ + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay:50*NSEC_PER_MSEC keepProcessAlive:true + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{ [expectation fulfill]; }]; @@ -62,7 +67,9 @@ XCTestExpectation *expectation = [self expectationWithDescription:@"FutureScheduler fired"]; - CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 200*NSEC_PER_MSEC keepProcessAlive:false block:^{ + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 200*NSEC_PER_MSEC keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{ [toofastexpectation fulfill]; [expectation fulfill]; }]; @@ -83,7 +90,9 @@ XCTestExpectation *expectation = [self expectationWithDescription:@"FutureScheduler fired"]; expectation.assertForOverFulfill = YES; - CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 200*NSEC_PER_MSEC keepProcessAlive:true block:^{ + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 200*NSEC_PER_MSEC keepProcessAlive:true + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{ [toofastexpectation fulfill]; [expectation fulfill]; }]; @@ -118,7 +127,9 @@ second.expectedFulfillmentCount = 2; second.assertForOverFulfill = YES; - CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 100*NSEC_PER_MSEC keepProcessAlive:false block:^{ + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 100*NSEC_PER_MSEC keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{ [first fulfill]; [second fulfill]; }]; @@ -150,7 +161,9 @@ second.expectedFulfillmentCount = 2; second.assertForOverFulfill = YES; - CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" initialDelay: 50*NSEC_PER_MSEC continuingDelay:600*NSEC_PER_MSEC keepProcessAlive:false block:^{ + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" initialDelay: 50*NSEC_PER_MSEC continuingDelay:600*NSEC_PER_MSEC keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{ [first fulfill]; [longdelay fulfill]; [second fulfill]; @@ -179,7 +192,9 @@ XCTestExpectation *cancelexpectation = [self expectationWithDescription:@"FutureScheduler fired (after cancel)"]; cancelexpectation.inverted = YES; - CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 100*NSEC_PER_MSEC keepProcessAlive:true block:^{ + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 100*NSEC_PER_MSEC keepProcessAlive:true + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{ [cancelexpectation fulfill]; }]; @@ -194,7 +209,9 @@ XCTestExpectation *toofastexpectation = [self expectationWithDescription:@"FutureScheduler fired (too soon)"]; toofastexpectation.inverted = YES; - CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 10*NSEC_PER_MSEC keepProcessAlive:false block:^{ + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 10*NSEC_PER_MSEC keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{ [toofastexpectation fulfill]; }]; @@ -211,7 +228,9 @@ XCTestExpectation *toofastexpectation = [self expectationWithDescription:@"FutureScheduler fired (too soon)"]; toofastexpectation.inverted = YES; - CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 10*NSEC_PER_MSEC keepProcessAlive:false block:^{ + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 10*NSEC_PER_MSEC keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{ [first fulfill]; [toofastexpectation fulfill]; }]; @@ -235,7 +254,9 @@ second.expectedFulfillmentCount = 2; second.assertForOverFulfill = YES; - CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 10*NSEC_PER_MSEC keepProcessAlive:false block:^{ + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 10*NSEC_PER_MSEC keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{ [first fulfill]; [second fulfill]; [toofastexpectation fulfill]; @@ -272,7 +293,9 @@ - (void)testOperationOneShot { XCTestExpectation *expectation = [self expectationWithDescription:@"FutureScheduler fired"]; - CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay:50*NSEC_PER_MSEC keepProcessAlive:true block:^{}]; + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay:50*NSEC_PER_MSEC keepProcessAlive:true + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{}]; [self addOperationFulfillingExpectations:@[expectation] scheduler:scheduler]; [scheduler trigger]; @@ -286,7 +309,9 @@ XCTestExpectation *expectation = [self expectationWithDescription:@"FutureScheduler fired"]; - CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 200*NSEC_PER_MSEC keepProcessAlive:false block:^{}]; + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 200*NSEC_PER_MSEC keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{}]; [self addOperationFulfillingExpectations:@[expectation,toofastexpectation] scheduler:scheduler]; [scheduler trigger]; @@ -305,7 +330,9 @@ XCTestExpectation *expectation = [self expectationWithDescription:@"FutureScheduler fired"]; expectation.assertForOverFulfill = YES; - CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 200*NSEC_PER_MSEC keepProcessAlive:true block:^{}]; + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 200*NSEC_PER_MSEC keepProcessAlive:true + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{}]; [self addOperationFulfillingExpectations:@[expectation,toofastexpectation] scheduler:scheduler]; [scheduler trigger]; @@ -335,7 +362,9 @@ XCTestExpectation *second = [self expectationWithDescription:@"FutureScheduler fired (two)"]; - CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 100*NSEC_PER_MSEC keepProcessAlive:false block:^{}]; + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 100*NSEC_PER_MSEC keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{}]; [self addOperationFulfillingExpectations:@[first] scheduler:scheduler]; @@ -363,7 +392,9 @@ longdelay.inverted = YES; XCTestExpectation *second = [self expectationWithDescription:@"FutureScheduler fired (two)"]; - CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" initialDelay: 50*NSEC_PER_MSEC continuingDelay:300*NSEC_PER_MSEC keepProcessAlive:false block:^{}]; + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" initialDelay: 50*NSEC_PER_MSEC continuingDelay:300*NSEC_PER_MSEC keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{}]; [self addOperationFulfillingExpectations:@[first] scheduler:scheduler]; @@ -392,7 +423,9 @@ XCTestExpectation *cancelexpectation = [self expectationWithDescription:@"FutureScheduler fired (after cancel)"]; cancelexpectation.inverted = YES; - CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 100*NSEC_PER_MSEC keepProcessAlive:true block:^{}]; + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 100*NSEC_PER_MSEC keepProcessAlive:true + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{}]; [self addOperationFulfillingExpectations:@[cancelexpectation] scheduler:scheduler]; @@ -407,7 +440,9 @@ XCTestExpectation *toofastexpectation = [self expectationWithDescription:@"FutureScheduler fired (too soon)"]; toofastexpectation.inverted = YES; - CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 10*NSEC_PER_MSEC keepProcessAlive:false block:^{}]; + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 10*NSEC_PER_MSEC keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{}]; [self addOperationFulfillingExpectations:@[toofastexpectation] scheduler:scheduler]; // Tell the scheduler to wait, but don't trigger it. It shouldn't fire. @@ -423,7 +458,9 @@ XCTestExpectation *toofastexpectation = [self expectationWithDescription:@"FutureScheduler fired (too soon)"]; toofastexpectation.inverted = YES; - CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 10*NSEC_PER_MSEC keepProcessAlive:false block:^{}]; + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay: 10*NSEC_PER_MSEC keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{}]; [self addOperationFulfillingExpectations:@[first,toofastexpectation] scheduler:scheduler]; [scheduler waitUntil: 150*NSEC_PER_MSEC]; @@ -434,3 +471,5 @@ } @end + +#endif /* OCTAGON */ diff --git a/keychain/ckks/tests/CKKSOperationTests.m b/keychain/ckks/tests/CKKSOperationTests.m index 9ac3c81c..fd460dc5 100644 --- a/keychain/ckks/tests/CKKSOperationTests.m +++ b/keychain/ckks/tests/CKKSOperationTests.m @@ -21,6 +21,8 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if OCTAGON + #import #import "keychain/ckks/CKKSGroupOperation.h" @@ -223,8 +225,46 @@ XCTAssertTrue(second.cancelled, "Second operation cancelled"); XCTAssertNotNil(second.error, "Second operation has an error"); XCTAssertEqual(second.error.code, CKKSResultTimedOut, "Second operation error is good"); + NSError* underlying = second.error.userInfo[NSUnderlyingErrorKey]; + XCTAssertNil(underlying, "Second operation's error doesn't have an underlying explanation"); +} + +- (void)testResultTimeoutWithUnderlyingError { + __block bool firstRun = false; + __block bool secondRun = false; + + CKKSResultOperation* first = [[CKKSResultOperation alloc] init]; + [first addExecutionBlock:^{ + firstRun = true; + }]; + first.descriptionErrorCode = 604; + + CKKSResultOperation* second = [[CKKSResultOperation alloc] init]; + [second addExecutionBlock:^{ + XCTAssertTrue(firstRun); + secondRun = true; + }]; + [second addDependency: first]; + + [self.queue addOperation: [second timeout:(50)* NSEC_PER_MSEC]]; + [self.queue waitUntilAllOperationsAreFinished]; + + XCTAssertFalse(firstRun); + XCTAssertFalse(secondRun); + + XCTAssertFalse(first.finished, "First operation not finished"); + XCTAssertFalse(first.cancelled, "First operation not cancelled"); + XCTAssertTrue(second.finished, "Second operation finished"); + XCTAssertTrue(second.cancelled, "Second operation cancelled"); + XCTAssertNotNil(second.error, "Second operation has an error"); + XCTAssertEqual(second.error.code, CKKSResultTimedOut, "Second operation error is good"); + NSError* underlying = second.error.userInfo[NSUnderlyingErrorKey]; + XCTAssertNotNil(underlying, "second operation's error has an underlying reason"); + XCTAssertEqualObjects(underlying.domain, CKKSResultDescriptionErrorDomain, "second operation's underlying error's domain should be CKKSResultDescriptionErrorDomain"); + XCTAssertEqual(underlying.code, 604, "second operation's underlying error's domain should be first's description"); } + - (void)testResultNoTimeout { __block bool firstRun = false; __block bool secondRun = false; @@ -260,9 +300,7 @@ CKKSResultOperation* operation = [[CKKSResultOperation alloc] init]; XCTAssertNil(operation.finishDate, "Result operation does not have a finish date before it is run"); - [operation addExecutionBlock:^{ - NSLog(@"test execution block"); - }]; + [operation addExecutionBlock:^{}]; [self.queue addOperation:operation]; [self.queue waitUntilAllOperationsAreFinished]; @@ -298,6 +336,22 @@ XCTAssertNil(group.error, "Group operation: no error"); } +- (void)testGroupOperationRunBlock { + XCTestExpectation* operationRun = [self expectationWithDescription:@"operation run with named:withBlock:"]; + CKKSGroupOperation* group = [CKKSGroupOperation named:@"asdf" withBlock: ^{ + [operationRun fulfill]; + }]; + [self.queue addOperation:group]; + [self waitForExpectations: @[operationRun] timeout:5]; + + operationRun = [self expectationWithDescription:@"operation run with named:withBlockTakingSelf:"]; + group = [CKKSGroupOperation named:@"asdf" withBlockTakingSelf:^(CKKSGroupOperation *strongOp) { + [operationRun fulfill]; + }]; + [self.queue addOperation:group]; + [self waitForExpectations: @[operationRun] timeout:5]; +} + - (void)testGroupOperationSubOperationCancel { CKKSGroupOperation* group = [[CKKSGroupOperation alloc] init]; @@ -455,6 +509,10 @@ [self.queue waitUntilAllOperationsAreFinished]; + // Shouldn't be necessary, but I'm not sure the NSOperation's finished property vs. dependency triggering is thread-safe + [op1 waitUntilFinished]; + [op2 waitUntilFinished]; + XCTAssertEqual(op1.finished, YES, "First operation finished"); XCTAssertEqual(op2.finished, YES, "Second operation finished"); XCTAssertEqual(group.finished, YES, "Group operation finished"); @@ -559,3 +617,5 @@ @end + +#endif /* OCTAGON */ diff --git a/keychain/ckks/tests/CKKSRateLimiterTests.m b/keychain/ckks/tests/CKKSRateLimiterTests.m index acb9e697..e0472a47 100644 --- a/keychain/ckks/tests/CKKSRateLimiterTests.m +++ b/keychain/ckks/tests/CKKSRateLimiterTests.m @@ -24,6 +24,7 @@ #if OCTAGON #import +#import #import "keychain/ckks/CKKSOutgoingQueueEntry.h" #import "keychain/ckks/CKKSRateLimiter.h" @@ -272,15 +273,13 @@ NSDate* limit = nil; [self.rl judge:self.oqe at:date limitTime:&limit]; - NSMutableData* data = [[NSMutableData alloc] init]; - NSKeyedArchiver* encoder = [[NSKeyedArchiver alloc] initForWritingWithMutableData: data]; + NSKeyedArchiver* encoder = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; [encoder encodeObject: self.rl forKey:@"unneeded"]; - [encoder finishEncoding]; + NSData* data = encoder.encodedData; XCTAssertNotNil(data, "Still have our data object"); XCTAssertTrue(data.length > 0u, "Encoder produced some data"); - NSKeyedUnarchiver* decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData: data]; - decoder.requiresSecureCoding = YES; + NSKeyedUnarchiver* decoder = [[NSKeyedUnarchiver alloc] initForReadingFromData: data error:nil]; CKKSRateLimiter* rl = [decoder decodeObjectOfClass: [CKKSRateLimiter class] forKey:@"unneeded"]; XCTAssertNotNil(rl, "Decoded data into a CKKSRateLimiter"); diff --git a/keychain/ckks/tests/CKKSSOSTests.m b/keychain/ckks/tests/CKKSSOSTests.m index 819bbf44..c1032239 100644 --- a/keychain/ckks/tests/CKKSSOSTests.m +++ b/keychain/ckks/tests/CKKSSOSTests.m @@ -335,6 +335,7 @@ - (void)testFindPiggyTLKs { [self putFakeKeyHierachiesInCloudKit]; + [self putFakeDeviceStatusesInCloudKit]; [self saveTLKsToKeychain]; NSDictionary* piggyTLKs = [self SOSPiggyBackCopyFromKeychain]; @@ -526,6 +527,14 @@ }]; } +- (void)putFakeDeviceStatusesInCloudKit { + [self putFakeDeviceStatusInCloudKit: self.engramZoneID]; + [self putFakeDeviceStatusInCloudKit: self.manateeZoneID]; + [self putFakeDeviceStatusInCloudKit: self.autoUnlockZoneID]; + [self putFakeDeviceStatusInCloudKit: self.healthZoneID]; + [self putFakeDeviceStatusInCloudKit: self.applepayZoneID]; +} + -(void)putFakeKeyHierachiesInCloudKit{ [self putFakeKeyHierarchyInCloudKit: self.engramZoneID]; [self putFakeKeyHierarchyInCloudKit: self.manateeZoneID]; @@ -559,6 +568,7 @@ -(void)testAcceptExistingAndUsePiggyKeyHierarchy { // Test starts with nothing in database, but one in our fake CloudKit. [self putFakeKeyHierachiesInCloudKit]; + [self putFakeDeviceStatusesInCloudKit]; [self saveTLKsToKeychain]; NSDictionary* piggyData = [self SOSPiggyBackCopyFromKeychain]; [self deleteTLKMaterialsFromKeychain]; diff --git a/keychain/ckks/tests/CKKSSQLTests.m b/keychain/ckks/tests/CKKSSQLTests.m index 408c0772..7225246c 100644 --- a/keychain/ckks/tests/CKKSSQLTests.m +++ b/keychain/ckks/tests/CKKSSQLTests.m @@ -274,6 +274,8 @@ // Very simple test: can these objects roundtrip through the db? NSString* testUUID = @"157A3171-0677-451B-9EAE-0DDC4D4315B0"; CKKSDeviceStateEntry* cdse = [[CKKSDeviceStateEntry alloc] initForDevice:testUUID + osVersion:@"faux-version" + lastUnlockTime:nil circlePeerID:@"asdf" circleStatus:kSOSCCInCircle keyState:SecCKKSZoneKeyStateReady diff --git a/keychain/ckks/tests/CKKSTLKSharingTests.m b/keychain/ckks/tests/CKKSTLKSharingTests.m index 2639a5a9..3bda9247 100644 --- a/keychain/ckks/tests/CKKSTLKSharingTests.m +++ b/keychain/ckks/tests/CKKSTLKSharingTests.m @@ -26,6 +26,9 @@ #import #import #import +#import +#import +#import #import "keychain/ckks/tests/CloudKitMockXCTest.h" #import "keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h" @@ -34,9 +37,11 @@ #import "keychain/ckks/CKKSPeer.h" #import "keychain/ckks/CKKSTLKShare.h" #import "keychain/ckks/CKKSViewManager.h" +#import "keychain/ckks/CloudKitCategories.h" #import "keychain/ckks/tests/MockCloudKit.h" #import "keychain/ckks/tests/CKKSTests.h" +#import "keychain/ot/OTDefines.h" @interface CloudKitKeychainSyncingTLKSharingTests : CloudKitKeychainSyncingTestsBase @property CKKSSOSSelfPeer* remotePeer1; @@ -44,6 +49,11 @@ @property CKKSSOSSelfPeer* untrustedPeer; + +@property (nullable) NSMutableSet>* pastSelfPeers; + +// Used to test a single code path. If true, no past self peers will be valid +@property bool breakLoadSelfPeerEncryptionKey; @end @implementation CloudKitKeychainSyncingTLKSharingTests @@ -51,6 +61,13 @@ - (void)setUp { [super setUp]; + self.pastSelfPeers = [NSMutableSet set]; + + // Use the upsetting old-style mocks so we can ignore the enum + [[[[self.mockCKKSViewManager stub] andCall:@selector(fakeLoadRestoredBottledKeysOfType:error:) + onObject:self] ignoringNonObjectArgs] + loadRestoredBottledKeysOfType:0 error:[OCMArg anyObjectRef]]; + self.remotePeer1 = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"remote-peer1" encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; @@ -69,6 +86,7 @@ } - (void)tearDown { + self.pastSelfPeers = nil; self.remotePeer1 = nil; self.remotePeer2 = nil; self.untrustedPeer = nil; @@ -76,6 +94,53 @@ [super tearDown]; } + +- (NSArray* _Nullable)fakeLoadRestoredBottledKeysOfType:(OctagonKeyType)keyType error:(NSError**)error { + if(self.aksLockState) { + if(error) { + *error = [NSError errorWithDomain:(__bridge NSString*)kSecErrorDomain code:errSecInteractionNotAllowed userInfo:nil]; + } + return nil; + } else { + if(self.breakLoadSelfPeerEncryptionKey && keyType == OctagonEncryptionKey) { + if(error) { + *error = [NSError errorWithDomain:(__bridge NSString*)kSecErrorDomain code:errSecItemNotFound userInfo:nil]; + } + return nil; + } + + // Convert self.pastSelfPeers into an array of dictionaries + NSMutableArray* keys = [NSMutableArray array]; + + for(id peer in self.pastSelfPeers) { + SFECKeyPair* key = nil; + + switch(keyType) { + case OctagonSigningKey: + key = peer.signingKey; + break; + case OctagonEncryptionKey: + key = peer.encryptionKey; + break; + } + + XCTAssertNotNil(key, "Should have a key at this point"); + + NSData* signingPublicKeyHashBytes = [SFSHA384DigestOperation digest:peer.signingKey.publicKey.keyData]; + NSString* signingPublicKeyHash = [signingPublicKeyHashBytes base64EncodedStringWithOptions:0]; + + NSDictionary* dict = @{ + (id)kSecAttrAccount : peer.peerID, + (id)kSecAttrLabel : signingPublicKeyHash, + (id)kSecValueData : key.keyData, + }; + [keys addObject:dict]; + } + + return keys; + } +} + - (void)testAcceptExistingTLKSharedKeyHierarchy { // Test starts with no keys in CKKS database, but one in our fake CloudKit. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; @@ -110,6 +175,73 @@ }]; } +- (void)testAcceptExistingTLKSharedKeyHierarchyForPastSelf { + // Test starts with no keys in CKKS database, but one in our fake CloudKit. + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + + // Test also starts with the TLK shared to all trusted peers from peer1 + [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.remotePeer1 zoneID:self.keychainZoneID]; + + // Self rolls its keys and ID... + [self.pastSelfPeers addObject:self.currentSelfPeer]; + self.currentSelfPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"new-local-peer" + encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; + + // The CKKS subsystem should accept the keys, and share the TLK back to itself + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID + checkModifiedRecord:^BOOL(CKRecord* _Nonnull record) { + CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:record]; + XCTAssertEqualObjects(share.receiver.peerID, self.currentSelfPeer.peerID, "Receiver peerID on TLKShare should match current self"); + XCTAssertEqualObjects(share.receiver.publicEncryptionKey, self.currentSelfPeer.publicEncryptionKey, "Receiver encryption key on TLKShare should match current self"); + XCTAssertEqualObjects(share.senderPeerID, self.currentSelfPeer.peerID, "Sender of TLKShare should match current self"); + return TRUE; + }]; + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + + // Verify that there are three local keys, and three local current key records + __weak __typeof(self) weakSelf = self; + [self.keychainView dispatchSync: ^bool{ + __strong __typeof(weakSelf) strongSelf = weakSelf; + XCTAssertNotNil(strongSelf, "self exists"); + + NSError* error = nil; + + NSArray* keys = [CKKSKey localKeys:strongSelf.keychainZoneID error:&error]; + XCTAssertNil(error, "no error fetching keys"); + XCTAssertEqual(keys.count, 3u, "Three keys in local database"); + + NSArray* currentkeys = [CKKSCurrentKeyPointer all:&error]; + XCTAssertNil(error, "no error fetching current keys"); + XCTAssertEqual(currentkeys.count, 3u, "Three current key pointers in local database"); + + return false; + }]; +} + +- (void)testDontCrashOnHalfBottle { + self.breakLoadSelfPeerEncryptionKey = true; + + // Test starts with no keys in CKKS database, but one in our fake CloudKit. + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + + // Test also starts with the TLK shared to all trusted peers from peer1 + [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.remotePeer1 zoneID:self.keychainZoneID]; + + // Self rolls its keys and ID... + [self.pastSelfPeers addObject:self.currentSelfPeer]; + self.currentSelfPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"new-local-peer" + encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; + + // CKKS should enter 'waitfortlk' without crashing + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:10*NSEC_PER_SEC], "Key state should become waitfortlk"); +} + - (void)testAcceptExistingTLKSharedKeyHierarchyAndUse { // Test starts with nothing in database, but one in our fake CloudKit. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; @@ -248,6 +380,7 @@ - (void)testReceiveSharedTLKWhileInWaitForTLK { // Test starts with nothing in database, but one in our fake CloudKit. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; // Spin up CKKS subsystem. [self startCKKSSubsystem]; @@ -364,6 +497,7 @@ [self startCKKSSubsystem]; OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForCKModifications]; // Now the external peer rolls the TLK and updates the shares [self rollFakeKeyHierarchyInCloudKit:self.keychainZoneID]; @@ -470,11 +604,13 @@ - (void)testDontAcceptTLKFromUntrustedPeer { // Test starts with nothing in database, but key hierarchy in our fake CloudKit. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + // The remote peer should also have given the TLK to a non-TLKShare peer (which is also offline) + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; // Test also starts with the key hierarchy shared from a non-trusted peer [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.untrustedPeer zoneID:self.keychainZoneID]; - // The CKKS subsystem should go into waitfortlk, since it doesn't trust this peer + // The CKKS subsystem should go into waitfortlk, since it doesn't trust this peer, but the peer is active [self startCKKSSubsystem]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "Key state should become ready"); } @@ -482,13 +618,14 @@ - (void)testAcceptSharedTLKOnTrustSetAdditionOfSharer { // Test starts with nothing in database, but key hierarchy in our fake CloudKit. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; // Test also starts with the key hierarchy shared from a non-trusted peer // note that it would share it itself too [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.untrustedPeer zoneID:self.keychainZoneID]; [self putTLKShareInCloudKit:self.keychainZoneKeys.tlk from:self.untrustedPeer to:self.untrustedPeer zoneID:self.keychainZoneID]; - // The CKKS subsystem should go into waitfortlk, since it doesn't trust this peer + // The CKKS subsystem should go into waitfortlk, since it doesn't trust this peer, but the peer is active [self startCKKSSubsystem]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "Key state should become waitfortlk"); @@ -616,6 +753,399 @@ // Not implemented. Trust set removal demands a key roll, but let's not get ahead of ourselves... } +- (void)testWaitForTLKWithMissingKeys { + // Test starts with no keys in CKKS database, but one in our fake CloudKit. + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + + // Test also starts with the TLK shared to all trusted peers from peer1 + [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.remotePeer1 zoneID:self.keychainZoneID]; + + // self no longer has that key pair, but it does have a new one with the same peer ID.... + self.currentSelfPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:self.currentSelfPeer.peerID + encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; + self.pastSelfPeers = [NSMutableSet set]; + + // CKKS should become very upset, and enter waitfortlk. + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:4000*NSEC_PER_SEC], "Key state should become waitfortlk"); + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + +- (void)testSendNewTLKShareToPeerOnPeerEncryptionKeyChange { + // If a peer changes its keys, CKKS should send it a new TLK share with the right keys + // This recovers from the remote peer losing its Octagon keys and making new ones + + // step 1: add a new peer; we should share the TLK with them + // start with no trusted peers + [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:3 zoneID:self.keychainZoneID]; + [self startCKKSSubsystem]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:1000*NSEC_PER_SEC], "Key state should become ready"); + + // Remote peer rolls its encryption key... + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID + checkModifiedRecord:^BOOL(CKRecord* _Nonnull record) { + CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:record]; + XCTAssertEqualObjects(share.receiver.peerID, self.remotePeer1.peerID, "Receiver peerID on TLKShare should match remote peer"); + XCTAssertEqualObjects(share.receiver.publicEncryptionKey, self.remotePeer1.publicEncryptionKey, "Receiver encryption key on TLKShare should match remote peer"); + XCTAssertEqualObjects(share.senderPeerID, self.currentSelfPeer.peerID, "Sender of TLKShare should match current self"); + return TRUE; + }]; + + self.remotePeer1.encryptionKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + [self.injectedManager sendTrustedPeerSetChangedUpdate]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForCKModifications]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); +} + +- (void)testRecoverFromBrokenSignatureOnTLKShareDuetoSignatureKeyChange { + // If a peer changes its signature key, CKKS shouldn't necessarily enter 'error': it should enter 'waitfortlk'. + // The peer should then send us another TLKShare + // This recovers from the remote peer losing its Octagon keys and making new ones + + // For this test, only have one peer + self.currentPeers = [NSMutableSet setWithObject:self.remotePeer1]; + + // Test starts with nothing in database, but one in our fake CloudKit. + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + // Test also starts with the TLK shared to all trusted peers from remotePeer1 + [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.remotePeer1 zoneID:self.keychainZoneID]; + + // BUT, remotePeer1 has rolled its signing key + self.remotePeer1.signingKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + [self startCKKSSubsystem]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:10*NSEC_PER_SEC], "Key state should become waitfortlk"); + + // Remote peer discovers its error and sends a new TLKShare! CKKS should recover and share itself a TLKShare + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID + checkModifiedRecord:^BOOL(CKRecord* _Nonnull record) { + CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:record]; + XCTAssertEqualObjects(share.receiver.peerID, self.currentSelfPeer.peerID, "Receiver peerID on TLKShare should match self peer"); + XCTAssertEqualObjects(share.receiver.publicEncryptionKey, self.currentSelfPeer.publicEncryptionKey, "Receiver encryption key on TLKShare should match self peer"); + XCTAssertEqualObjects(share.senderPeerID, self.currentSelfPeer.peerID, "Sender of TLKShare should match current self"); + return TRUE; + }]; + + [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.remotePeer1 zoneID:self.keychainZoneID]; + [self.keychainView notifyZoneChange:nil]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForCKModifications]; +} + +- (void)testSendNewTLKShareToSelfOnPeerSigningKeyChange { + // If a CKKS peer rolls its own keys, but has the TLK, it should write a new TLK share to itself with its new Octagon keys + // This recovers from the local peer losing its Octagon keys and making new ones + + // For this test, only have one peer + self.currentPeers = [NSMutableSet setWithObject:self.remotePeer1]; + + // Test starts with nothing in database, but one in our fake CloudKit. + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + // Test also starts with the TLK shared to all trusted peers from peer1 + [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.remotePeer1 zoneID:self.keychainZoneID]; + // The CKKS subsystem should accept the keys, and share the TLK back to itself + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; + [self startCKKSSubsystem]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:100*NSEC_PER_SEC], "Key state should become ready"); + + // Remote peer rolls its signing key, but hasn't updated its TLKShare. We should send it one. + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID + checkModifiedRecord:^BOOL(CKRecord* _Nonnull record) { + CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:record]; + XCTAssertEqualObjects(share.receiver.peerID, self.remotePeer1.peerID, "Receiver peerID on TLKShare should match remote peer"); + XCTAssertEqualObjects(share.receiver.publicEncryptionKey, self.remotePeer1.publicEncryptionKey, "Receiver encryption key on TLKShare should match remote peer"); + XCTAssertEqualObjects(share.senderPeerID, self.currentSelfPeer.peerID, "Sender of TLKShare should match current self"); + return TRUE; + }]; + + self.remotePeer1.signingKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + [self.injectedManager sendTrustedPeerSetChangedUpdate]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForCKModifications]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); +} + +- (void)testSendNewTLKShareToPeerOnDisappearanceOfPeerKeys { + // If a CKKS peer deletes its own octagon keys (BUT WHY), local CKKS should be able to respond + + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + // Test also starts with the TLK shared to all trusted peers from peer1 + [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.remotePeer1 zoneID:self.keychainZoneID]; + // The CKKS subsystem should accept the keys, and share the TLK back to itself + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; + [self startCKKSSubsystem]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:100*NSEC_PER_SEC], "Key state should become ready"); + + // Now, peer 1 updates its keys (to be nil). Local peer should re-send TLKShares to peer2. + + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID + checkModifiedRecord:^BOOL(CKRecord* _Nonnull record) { + CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:record]; + XCTAssertEqualObjects(share.receiver.peerID, self.remotePeer2.peerID, "Receiver peerID on TLKShare should match remote peer"); + XCTAssertEqualObjects(share.receiver.publicEncryptionKey, self.remotePeer2.publicEncryptionKey, "Receiver encryption key on TLKShare should match remote peer"); + XCTAssertEqualObjects(share.senderPeerID, self.currentSelfPeer.peerID, "Sender of TLKShare should match current self"); + return TRUE; + }]; + + CKKSSOSPeer* brokenRemotePeer1 = [[CKKSSOSPeer alloc] initWithSOSPeerID:self.remotePeer1.peerID encryptionPublicKey:nil signingPublicKey:nil]; + [self.currentPeers removeObject:self.remotePeer1]; + [self.currentPeers addObject:brokenRemotePeer1]; + [self.injectedManager sendTrustedPeerSetChangedUpdate]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForCKModifications]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); +} + +- (void)testSendNewTLKShareToPeerOnDisappearanceOfPeerSigningKey { + // If a CKKS peer rolls its own keys, but has the TLK, it should write a new TLK share to itself with its new Octagon keys + // This recovers from the local peer losing its Octagon keys and making new ones + + // Test starts with nothing in database, but one in our fake CloudKit. + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + // Test also starts with the TLK shared to all trusted peers from peer1 + [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.remotePeer1 zoneID:self.keychainZoneID]; + // The CKKS subsystem should accept the keys, and share the TLK back to itself + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; + [self startCKKSSubsystem]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:100*NSEC_PER_SEC], "Key state should become ready"); + + // Now, peer 1 updates its signing key (to be nil). Local peer should re-send TLKShares to peer1 and peer2. + // Both should be sent because both peers don't have a signed TLKShare that gives them the TLK + + XCTestExpectation *peer1Share = [self expectationWithDescription:@"share uploaded for peer1"]; + XCTestExpectation *peer2Share = [self expectationWithDescription:@"share uploaded for peer2"]; + + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:2 zoneID:self.keychainZoneID + checkModifiedRecord:^BOOL(CKRecord* _Nonnull record) { + CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:record]; + if([share.receiver.peerID isEqualToString:self.remotePeer1.peerID]) { + [peer1Share fulfill]; + XCTAssertEqualObjects(share.receiver.publicEncryptionKey, self.remotePeer1.publicEncryptionKey, "Receiver encryption key on TLKShare should match remote peer1"); + } + if([share.receiver.peerID isEqualToString:self.remotePeer2.peerID]) { + [peer2Share fulfill]; + XCTAssertEqualObjects(share.receiver.publicEncryptionKey, self.remotePeer2.publicEncryptionKey, "Receiver encryption key on TLKShare should match remote peer2"); + } + + XCTAssertEqualObjects(share.senderPeerID, self.currentSelfPeer.peerID, "Sender of TLKShare should match current self"); + return TRUE; + }]; + + CKKSSOSPeer* brokenRemotePeer1 = [[CKKSSOSPeer alloc] initWithSOSPeerID:self.remotePeer1.peerID + encryptionPublicKey:self.remotePeer1.publicEncryptionKey + signingPublicKey:nil]; + [self.currentPeers removeObject:self.remotePeer1]; + [self.currentPeers addObject:brokenRemotePeer1]; + [self.injectedManager sendTrustedPeerSetChangedUpdate]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForCKModifications]; + [self waitForExpectations:@[peer1Share, peer2Share] timeout:5]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); +} + +- (void)testSendNewTLKShareToSelfOnSelfKeyChanges { + // If a CKKS peer rolls its own keys, but has the TLK, it should write a new TLK share to itself with its new Octagon keys + // This recovers from the local peer losing its Octagon keys and making new ones + + // Test starts with nothing in database, but one in our fake CloudKit. + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + // Test also starts with the TLK shared to all trusted peers from peer1 + [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.remotePeer1 zoneID:self.keychainZoneID]; + // The CKKS subsystem should accept the keys, and share the TLK back to itself + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; + [self startCKKSSubsystem]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); + + // Local peer rolls its encryption key (and loses the old ones) + [self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID + checkModifiedRecord:^BOOL(CKRecord* _Nonnull record) { + CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:record]; + XCTAssertEqualObjects(share.receiver.peerID, self.currentSelfPeer.peerID, "Receiver peerID on TLKShare should match current self"); + XCTAssertEqualObjects(share.receiver.publicEncryptionKey, self.currentSelfPeer.publicEncryptionKey, "Receiver encryption key on TLKShare should match current self"); + XCTAssertEqualObjects(share.senderPeerID, self.currentSelfPeer.peerID, "Sender of TLKShare should match current self"); + NSError* signatureVerifyError = nil; + XCTAssertTrue([share verifySignature:share.signature verifyingPeer:self.currentSelfPeer error:&signatureVerifyError], "New share's signature should verify"); + XCTAssertNil(signatureVerifyError, "Should be no error verifying signature on new TLKShare"); + return TRUE; + }]; + + self.currentSelfPeer.encryptionKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + self.pastSelfPeers = [NSMutableSet set]; + [self.injectedManager sendSelfPeerChangedUpdate]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); + + // Now, local peer loses and rolls its signing key (and loses the old one) + [self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID + checkModifiedRecord:^BOOL(CKRecord* _Nonnull record) { + CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:record]; + XCTAssertEqualObjects(share.receiver.peerID, self.currentSelfPeer.peerID, "Receiver peerID on TLKShare should match current self"); + XCTAssertEqualObjects(share.receiver.publicEncryptionKey, self.currentSelfPeer.publicEncryptionKey, "Receiver encryption key on TLKShare should match current self"); + XCTAssertEqualObjects(share.senderPeerID, self.currentSelfPeer.peerID, "Sender of TLKShare should match current self"); + NSError* signatureVerifyError = nil; + XCTAssertTrue([share verifySignature:share.signature verifyingPeer:self.currentSelfPeer error:&signatureVerifyError], "New share's signature should verify"); + XCTAssertNil(signatureVerifyError, "Should be no error verifying signature on new TLKShare"); + return TRUE; + }]; + + self.currentSelfPeer.signingKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + self.pastSelfPeers = [NSMutableSet set]; + [self.injectedManager sendSelfPeerChangedUpdate]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], "Key state should become ready"); +} + +- (void)testDoNotResetCloudKitZoneFromWaitForTLKDueToRecentTLKShare { + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + + // CKKS shouldn't reset this zone, due to a recent TLK Share from a trusted peer (indicating the presence of TLKs) + [self putTLKShareInCloudKit:self.keychainZoneKeys.tlk from:self.remotePeer1 to:self.remotePeer1 zoneID:self.keychainZoneID]; + + NSDateComponents* offset = [[NSDateComponents alloc] init]; + [offset setDay:-5]; + NSDate* updateTime = [[NSCalendar currentCalendar] dateByAddingComponents:offset toDate:[NSDate date] options:0]; + for(CKRecord* record in self.keychainZone.currentDatabase.allValues) { + if([record.recordType isEqualToString:SecCKRecordDeviceStateType] || [record.recordType isEqualToString:SecCKRecordTLKShareType]) { + record.creationDate = updateTime; + record.modificationDate = updateTime; + } + } + + self.keychainZone.flag = true; + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], @"Key state should become 'waitfortlk'"); + + XCTAssertTrue(self.keychainZone.flag, "Zone flag should not have been reset to false"); +} + +- (void)testDoNotResetCloudKitZoneFromWaitForTLKDueToVeryRecentUntrustedTLKShare { + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + + // CKKS shouldn't reset this zone, due to a very recent (but untrusted) TLK Share. You can hit this getting a circle reset; the device with the TLKs will have a CFU. + CKKSSOSSelfPeer* untrustedPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"untrusted-peer" + encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; + [self putTLKShareInCloudKit:self.keychainZoneKeys.tlk from:untrustedPeer to:untrustedPeer zoneID:self.keychainZoneID]; + + NSDateComponents* offset = [[NSDateComponents alloc] init]; + [offset setDay:-2]; + NSDate* updateTime = [[NSCalendar currentCalendar] dateByAddingComponents:offset toDate:[NSDate date] options:0]; + for(CKRecord* record in self.keychainZone.currentDatabase.allValues) { + if([record.recordType isEqualToString:SecCKRecordDeviceStateType] || [record.recordType isEqualToString:SecCKRecordTLKShareType]) { + record.creationDate = updateTime; + record.modificationDate = updateTime; + } + } + + self.keychainZone.flag = true; + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], @"Key state should become 'waitfortlk'"); + XCTAssertTrue(self.keychainZone.flag, "Zone flag should not have been reset to false"); + + // And ensure it doesn't go on to 'reset' + XCTAssertNotEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:100*NSEC_PER_MSEC], @"Key state should not become 'resetzone'"); +} + +- (void)testResetCloudKitZoneFromWaitForTLKDueToUntustedTLKShareNotRecentEnough { + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + + // CKKS shouldn't reset this zone, due to a recent TLK Share (indicating the presence of TLKs) + CKKSSOSSelfPeer* untrustedPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"untrusted-peer" + encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; + [self putTLKShareInCloudKit:self.keychainZoneKeys.tlk from:untrustedPeer to:untrustedPeer zoneID:self.keychainZoneID]; + + NSDateComponents* offset = [[NSDateComponents alloc] init]; + [offset setDay:-5]; + NSDate* updateTime = [[NSCalendar currentCalendar] dateByAddingComponents:offset toDate:[NSDate date] options:0]; + for(CKRecord* record in self.keychainZone.currentDatabase.allValues) { + if([record.recordType isEqualToString:SecCKRecordDeviceStateType] || [record.recordType isEqualToString:SecCKRecordTLKShareType]) { + record.creationDate = updateTime; + record.modificationDate = updateTime; + } + } + + self.silentZoneDeletesAllowed = true; + self.keychainZone.flag = true; + [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:3 zoneID:self.keychainZoneID]; + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:8*NSEC_PER_SEC], @"Key state should become 'resetzone'"); + + // Then we should reset. + OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + + // And the zone should have been cleared and re-made + XCTAssertFalse(self.keychainZone.flag, "Zone flag should have been reset to false"); +} + +- (void)testNoSelfEncryptionKeys { + // If you lose your local encryption keys, CKKS should do something reasonable + + // Test also starts with the TLK shared to all trusted peers from peer1 + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.remotePeer1 zoneID:self.keychainZoneID]; + [self saveTLKSharesInLocalDatabase:self.keychainZoneID]; + + // But, we lost our local keys :( + id oldSelfPeer = self.currentSelfPeer; + + self.currentSelfPeer = nil; + self.currentSelfPeerError = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecParam description:@"injected test failure"]; + + // CKKS subsystem should realize that it can't read the shares it has, and enter waitfortlk + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:10*NSEC_PER_SEC], "Key state should become 'waitfortlk'"); + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForCKModifications]; + + // Fetching status should be quick + XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; + [self.ckksControl rpcStatus:@"keychain" reply:^(NSArray* result, NSError* error) { + XCTAssertNil(error, "should be no error fetching status for keychain"); + [callbackOccurs fulfill]; + }]; + [self waitForExpectations:@[callbackOccurs] timeout:1.0]; + + // But, if by some miracle those keys come back, CKKS should be able to recover + // It'll also upload itself a TLK share + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; + + self.currentSelfPeer = oldSelfPeer; + self.currentSelfPeerError = nil; + + [self.injectedManager sendSelfPeerChangedUpdate]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:100*NSEC_PER_SEC], "Key state should become 'ready''"); + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForCKModifications]; +} @end diff --git a/keychain/ckks/tests/CKKSTests+API.h b/keychain/ckks/tests/CKKSTests+API.h index 42262a68..6e34aa02 100644 --- a/keychain/ckks/tests/CKKSTests+API.h +++ b/keychain/ckks/tests/CKKSTests+API.h @@ -27,7 +27,7 @@ NS_ASSUME_NONNULL_BEGIN -@interface CloudKitKeychainSyncingTests (APITests) +@interface CloudKitKeychainSyncingTestsBase (APITests) - (BOOL (^)(CKRecord*))checkPCSFieldsBlock:(CKRecordZoneID*)zoneID PCSServiceIdentifier:(NSNumber*)servIdentifier diff --git a/keychain/ckks/tests/CKKSTests+API.m b/keychain/ckks/tests/CKKSTests+API.m index 48af3b78..43e2160a 100644 --- a/keychain/ckks/tests/CKKSTests+API.m +++ b/keychain/ckks/tests/CKKSTests+API.m @@ -42,31 +42,13 @@ #import "keychain/ckks/CKKSZoneStateEntry.h" #import "keychain/ckks/CKKSControl.h" +#import "keychain/ckks/CloudKitCategories.h" #import "keychain/ckks/tests/MockCloudKit.h" #import "keychain/ckks/tests/CKKSTests.h" #import "keychain/ckks/tests/CKKSTests+API.h" -@implementation CloudKitKeychainSyncingTests (APITests) - -- (void)testSecuritydClientBringup { - CFErrorRef cferror = nil; - xpc_endpoint_t endpoint = SecCreateSecuritydXPCServerEndpoint(&cferror); - XCTAssertNil((__bridge id)cferror, "No error creating securityd endpoint"); - XCTAssertNotNil(endpoint, "Received securityd endpoint"); - - NSXPCInterface *interface = [NSXPCInterface interfaceWithProtocol:@protocol(SecuritydXPCProtocol)]; - [SecuritydXPCClient configureSecuritydXPCProtocol: interface]; - XCTAssertNotNil(interface, "Received a configured CKKS interface"); - - NSXPCListenerEndpoint *listenerEndpoint = [[NSXPCListenerEndpoint alloc] init]; - [listenerEndpoint _setEndpoint:endpoint]; - - NSXPCConnection* connection = [[NSXPCConnection alloc] initWithListenerEndpoint:listenerEndpoint]; - XCTAssertNotNil(connection , "Received an active connection"); - - connection.remoteObjectInterface = interface; -} +@implementation CloudKitKeychainSyncingTestsBase (APITests) -(NSMutableDictionary*)pcsAddItemQuery:(NSString*)account data:(NSData*)data @@ -126,6 +108,57 @@ return (NSDictionary*) CFBridgingRelease(result); } +- (BOOL (^) (CKRecord*)) checkPCSFieldsBlock: (CKRecordZoneID*) zoneID + PCSServiceIdentifier:(NSNumber*)servIdentifier + PCSPublicKey:(NSData*)publicKey + PCSPublicIdentity:(NSData*)publicIdentity +{ + __weak __typeof(self) weakSelf = self; + return ^BOOL(CKRecord* record) { + __strong __typeof(weakSelf) strongSelf = weakSelf; + XCTAssertNotNil(strongSelf, "self exists"); + + XCTAssert([record[SecCKRecordPCSServiceIdentifier] isEqual: servIdentifier], "PCS Service identifier matches input"); + XCTAssert([record[SecCKRecordPCSPublicKey] isEqual: publicKey], "PCS Public Key matches input"); + XCTAssert([record[SecCKRecordPCSPublicIdentity] isEqual: publicIdentity], "PCS Public Identity matches input"); + + if([record[SecCKRecordPCSServiceIdentifier] isEqual: servIdentifier] && + [record[SecCKRecordPCSPublicKey] isEqual: publicKey] && + [record[SecCKRecordPCSPublicIdentity] isEqual: publicIdentity]) { + return YES; + } else { + return NO; + } + }; +} +@end + +@interface CloudKitKeychainSyncingAPITests : CloudKitKeychainSyncingTestsBase +@end + +@implementation CloudKitKeychainSyncingAPITests +- (void)testSecuritydClientBringup { +#if 0 + CFErrorRef cferror = nil; + xpc_endpoint_t endpoint = SecCreateSecuritydXPCServerEndpoint(&cferror); + XCTAssertNil((__bridge id)cferror, "No error creating securityd endpoint"); + XCTAssertNotNil(endpoint, "Received securityd endpoint"); +#endif + + NSXPCInterface *interface = [NSXPCInterface interfaceWithProtocol:@protocol(SecuritydXPCProtocol)]; + [SecuritydXPCClient configureSecuritydXPCProtocol: interface]; + XCTAssertNotNil(interface, "Received a configured CKKS interface"); + +#if 0 + NSXPCListenerEndpoint *listenerEndpoint = [[NSXPCListenerEndpoint alloc] init]; + [listenerEndpoint _setEndpoint:endpoint]; + + NSXPCConnection* connection = [[NSXPCConnection alloc] initWithListenerEndpoint:listenerEndpoint]; + XCTAssertNotNil(connection , "Received an active connection"); + + connection.remoteObjectInterface = interface; +#endif +} - (void)testAddAndNotifyOnSync { [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. @@ -267,7 +300,7 @@ [self startCKKSSubsystem]; XCTAssertEqual(0, [self.keychainView.loggedIn wait:2*NSEC_PER_SEC], "CKKS should log in"); - [self.keychainView.viewSetupOperation waitUntilFinished]; + [self.keychainView.zoneSetupOperation waitUntilFinished]; NSMutableDictionary* query = [@{ (id)kSecClass : (id)kSecClassGenericPassword, @@ -288,8 +321,8 @@ [blockExpectation fulfill]; }), @"_SecItemAddAndNotifyOnSync succeeded"); - // We should be in the 'initialized' state, but no further - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateInitialized] wait:100*NSEC_PER_MSEC], @"Should have reached key state 'initialized', but no further"); + // We should be in the 'fetch' state, but no further + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateFetch] wait:100*NSEC_PER_MSEC], @"Should have reached key state 'fetch', but no further"); // When we release the fetch, the callback should still fire and the item should upload [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; @@ -302,30 +335,6 @@ [self waitForExpectationsWithTimeout:5.0 handler:nil]; } -- (BOOL (^) (CKRecord*)) checkPCSFieldsBlock: (CKRecordZoneID*) zoneID - PCSServiceIdentifier:(NSNumber*)servIdentifier - PCSPublicKey:(NSData*)publicKey - PCSPublicIdentity:(NSData*)publicIdentity -{ - __weak __typeof(self) weakSelf = self; - return ^BOOL(CKRecord* record) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - XCTAssertNotNil(strongSelf, "self exists"); - - XCTAssert([record[SecCKRecordPCSServiceIdentifier] isEqual: servIdentifier], "PCS Service identifier matches input"); - XCTAssert([record[SecCKRecordPCSPublicKey] isEqual: publicKey], "PCS Public Key matches input"); - XCTAssert([record[SecCKRecordPCSPublicIdentity] isEqual: publicIdentity], "PCS Public Identity matches input"); - - if([record[SecCKRecordPCSServiceIdentifier] isEqual: servIdentifier] && - [record[SecCKRecordPCSPublicKey] isEqual: publicKey] && - [record[SecCKRecordPCSPublicIdentity] isEqual: publicIdentity]) { - return YES; - } else { - return NO; - } - }; -} - - (void)testPCSUnencryptedFieldsAdd { [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. @@ -610,6 +619,7 @@ [self startCKKSSubsystem]; [self.keychainView waitForKeyHierarchyReadiness]; + [self.keychainView waitForOperationsOfClass:[CKKSIncomingQueueOperation class]]; NSNumber* servIdentifier = @3; NSData* publicKey = [@"asdfasdf" dataUsingEncoding:NSUTF8StringEncoding]; @@ -697,14 +707,12 @@ self.silentFetchesAllowed = false; [self expectCKFetch]; - dispatch_semaphore_t resetSemaphore = dispatch_semaphore_create(0); + XCTestExpectation* resetExpectation = [self expectationWithDescription: @"local reset callback occurs"]; [self.injectedManager rpcResetLocal:nil reply:^(NSError* result) { XCTAssertNil(result, "no error resetting local"); - secnotice("ckks", "Received a rpcResetLocal callback"); - dispatch_semaphore_signal(resetSemaphore); + [resetExpectation fulfill]; }]; - - XCTAssertEqual(0, dispatch_semaphore_wait(resetSemaphore, 4*NSEC_PER_SEC), "Semaphore wait did not time out"); + [self waitForExpectations:@[resetExpectation] timeout:8.0]; OCMVerifyAllWithDelay(self.mockDatabase, 8); @@ -742,20 +750,22 @@ NSError* error = nil; [ckse saveToDatabase:&error]; XCTAssertNil(error, "No error saving new zone state to database"); + return true; }]; - dispatch_semaphore_t resetSemaphore = dispatch_semaphore_create(0); + XCTestExpectation* resetExpectation = [self expectationWithDescription: @"local reset callback occurs"]; [self.injectedManager rpcResetLocal:nil reply:^(NSError* result) { XCTAssertNil(result, "no error resetting local"); secnotice("ckks", "Received a rpcResetLocal callback"); - dispatch_semaphore_signal(resetSemaphore); + [resetExpectation fulfill]; }]; - XCTAssertEqual(0, dispatch_semaphore_wait(resetSemaphore, 400*NSEC_PER_SEC), "Semaphore wait did not time out"); + [self waitForExpectations:@[resetExpectation] timeout:1.0]; [self.keychainView dispatchSync: ^bool{ CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state:self.keychainView.zoneName]; XCTAssertNotEqualObjects(changeToken, ckse.changeToken, "Change token is reset"); + return true; }]; // Now log in, and see what happens! It should re-fetch, pick up the old key hierarchy, and use it @@ -774,7 +784,66 @@ OCMVerifyAllWithDelay(self.mockDatabase, 8); } +-(void)testResetLocalMultipleTimes { + // Test starts with nothing in database, but one in our fake CloudKit. + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; + [self saveTLKMaterialToKeychainSimulatingSOS:self.keychainZoneID]; + + // Spin up CKKS subsystem. + [self startCKKSSubsystem]; + + // We expect a single record to be uploaded + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); + [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID + checkItem:[self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; + [self addGenericPassword: @"data" account: @"account-delete-me"]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForCKModifications]; + + // We're going to request a bunch of CloudKit resets, but hold them from finishing + [self holdCloudKitFetches]; + + XCTestExpectation* resetExpectation0 = [self expectationWithDescription: @"reset callback(0) occurs"]; + XCTestExpectation* resetExpectation1 = [self expectationWithDescription: @"reset callback(1) occurs"]; + XCTestExpectation* resetExpectation2 = [self expectationWithDescription: @"reset callback(2) occurs"]; + [self.injectedManager rpcResetLocal:nil reply:^(NSError* result) { + XCTAssertNil(result, "should receive no error resetting local"); + secnotice("ckksreset", "Received a rpcResetLocal(0) callback"); + [resetExpectation0 fulfill]; + }]; + [self.injectedManager rpcResetLocal:nil reply:^(NSError* result) { + XCTAssertNil(result, "should receive no error resetting local"); + secnotice("ckksreset", "Received a rpcResetLocal(1) callback"); + [resetExpectation1 fulfill]; + }]; + [self.injectedManager rpcResetLocal:nil reply:^(NSError* result) { + XCTAssertNil(result, "should receive no error resetting local"); + secnotice("ckksreset", "Received a rpcResetLocal(2) callback"); + [resetExpectation2 fulfill]; + }]; + + // After the reset(s), we expect no uploads. Let the resets flow! + [self releaseCloudKitFetchHold]; + [self waitForExpectations:@[resetExpectation0, resetExpectation1, resetExpectation2] timeout:20]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + + [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID + checkItem:[self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; + [self addGenericPassword:@"asdf" + account:@"account-class-A" + viewHint:nil + access:(id)kSecAttrAccessibleWhenUnlocked + expecting:errSecSuccess + message:@"Adding class A item"]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + -(void)testResetCloudKitZone { + self.silentZoneDeletesAllowed = true; + // Test starts with nothing in database, but one in our fake CloudKit. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; @@ -787,19 +856,19 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForCKModifications]; - // We expect a key hierarchy upload, and then the class C item upload + // After the reset, we expect a key hierarchy upload, and then the class C item upload [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; - dispatch_semaphore_t resetSemaphore = dispatch_semaphore_create(0); + XCTestExpectation* resetExpectation = [self expectationWithDescription: @"reset callback occurs"]; [self.injectedManager rpcResetCloudKit:nil reply:^(NSError* result) { XCTAssertNil(result, "no error resetting cloudkit"); secnotice("ckks", "Received a resetCloudKit callback"); - dispatch_semaphore_signal(resetSemaphore); + [resetExpectation fulfill]; }]; - - XCTAssertEqual(0, dispatch_semaphore_wait(resetSemaphore, 4*NSEC_PER_SEC), "Semaphore wait did not time out"); + [self waitForExpectations:@[resetExpectation] timeout:8.0]; OCMVerifyAllWithDelay(self.mockDatabase, 8); @@ -814,9 +883,12 @@ } - (void)testResetCloudKitZoneDuringWaitForTLK { + self.silentZoneDeletesAllowed = true; + // Test starts with nothing in database, but one in our fake CloudKit. // No TLK, though! [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; // Spin up CKKS subsystem. [self startCKKSSubsystem]; @@ -912,6 +984,8 @@ }*/ -(void)testResetCloudKitZoneWhileLoggedOut { + self.silentZoneDeletesAllowed = true; + // We're "logged in to" cloudkit but not in circle. self.circleStatus = kSOSCCNotInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; @@ -929,14 +1003,13 @@ XCTAssertNotNil(self.keychainZone.currentDatabase, "Zone exists"); XCTAssertNotNil(self.keychainZone.currentDatabase[ckr.recordID], "An item exists in the fake zone"); - dispatch_semaphore_t resetSemaphore = dispatch_semaphore_create(0); + XCTestExpectation* resetExpectation = [self expectationWithDescription: @"reset callback occurs"]; [self.injectedManager rpcResetCloudKit:nil reply:^(NSError* result) { XCTAssertNil(result, "no error resetting cloudkit"); secnotice("ckks", "Received a resetCloudKit callback"); - dispatch_semaphore_signal(resetSemaphore); + [resetExpectation fulfill]; }]; - - XCTAssertEqual(0, dispatch_semaphore_wait(resetSemaphore, 400*NSEC_PER_SEC), "Semaphore wait did not time out"); + [self waitForExpectations:@[resetExpectation] timeout:1.0]; XCTAssertNil(self.keychainZone.currentDatabase, "No zone anymore!"); OCMVerifyAllWithDelay(self.mockDatabase, 8); @@ -959,9 +1032,150 @@ OCMVerifyAllWithDelay(self.mockDatabase, 8); } +- (void)testResetCloudKitZoneMultipleTimes { + self.silentZoneDeletesAllowed = true; + + // Test starts with nothing in database, but one in our fake CloudKit. + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; + [self saveTLKMaterialToKeychainSimulatingSOS:self.keychainZoneID]; + + // Spin up CKKS subsystem. + [self startCKKSSubsystem]; + + // We expect a single record to be uploaded + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); + [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID + checkItem:[self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; + [self addGenericPassword: @"data" account: @"account-delete-me"]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForCKModifications]; + + // We're going to request a bunch of CloudKit resets, but hold them from finishing + [self holdCloudKitFetches]; + + XCTestExpectation* resetExpectation0 = [self expectationWithDescription: @"reset callback(0) occurs"]; + XCTestExpectation* resetExpectation1 = [self expectationWithDescription: @"reset callback(1) occurs"]; + XCTestExpectation* resetExpectation2 = [self expectationWithDescription: @"reset callback(2) occurs"]; + [self.injectedManager rpcResetCloudKit:nil reply:^(NSError* result) { + XCTAssertNil(result, "should receive no error resetting cloudkit"); + secnotice("ckksreset", "Received a resetCloudKit(0) callback"); + [resetExpectation0 fulfill]; + }]; + [self.injectedManager rpcResetCloudKit:nil reply:^(NSError* result) { + XCTAssertNil(result, "should receive no error resetting cloudkit"); + secnotice("ckksreset", "Received a resetCloudKit(1) callback"); + [resetExpectation1 fulfill]; + }]; + [self.injectedManager rpcResetCloudKit:nil reply:^(NSError* result) { + XCTAssertNil(result, "should receive no error resetting cloudkit"); + secnotice("ckksreset", "Received a resetCloudKit(2) callback"); + [resetExpectation2 fulfill]; + }]; + + // After the reset(s), we expect a key hierarchy upload, and then the class C item upload + [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; + [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID + checkItem:[self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; + + // And let the resets flow + [self releaseCloudKitFetchHold]; + [self waitForExpectations:@[resetExpectation0, resetExpectation1, resetExpectation2] timeout:20]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + + [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID + checkItem:[self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; + [self addGenericPassword:@"asdf" + account:@"account-class-A" + viewHint:nil + access:(id)kSecAttrAccessibleWhenUnlocked + expecting:errSecSuccess + message:@"Adding class A item"]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + +- (void)testRPCFetchAndProcessWhileCloudKitNotResponding { + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); + [self holdCloudKitFetches]; + + XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; + [self.ckksControl rpcFetchAndProcessChanges:nil reply:^(NSError * _Nullable error) { + // done! we should have an underlying error of "fetch isn't working" + XCTAssertNotNil(error, "Should have received an error attempting to fetch and process"); + NSError* underlying = error.userInfo[NSUnderlyingErrorKey]; + XCTAssertNotNil(underlying, "Should have received an underlying error"); + XCTAssertEqualObjects(underlying.domain, CKKSResultDescriptionErrorDomain, "Underlying error should be CKKSResultDescriptionErrorDomain"); + XCTAssertEqual(underlying.code, CKKSResultDescriptionPendingSuccessfulFetch, "Underlying error should be 'pending fetch'"); + [callbackOccurs fulfill]; + }]; + + [self waitForExpectations:@[callbackOccurs] timeout:20.0]; + [self releaseCloudKitFetchHold]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + +- (void)testRPCFetchAndProcessWhileCloudKitErroring { + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); + + [self.keychainZone failNextFetchWith:[[CKPrettyError alloc] initWithDomain:CKErrorDomain + code:CKErrorRequestRateLimited + userInfo:@{CKErrorRetryAfterKey : [NSNumber numberWithInt:30]}]]; + + XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; + [self.ckksControl rpcFetchAndProcessChanges:nil reply:^(NSError * _Nullable error) { + // done! we should have an underlying error of "fetch isn't working" + XCTAssertNotNil(error, "Should have received an error attempting to fetch and process"); + NSError* underlying = error.userInfo[NSUnderlyingErrorKey]; + XCTAssertNotNil(underlying, "Should have received an underlying error"); + XCTAssertEqualObjects(underlying.domain, CKKSResultDescriptionErrorDomain, "Underlying error should be CKKSResultDescriptionErrorDomain"); + XCTAssertEqual(underlying.code, CKKSResultDescriptionPendingSuccessfulFetch, "Underlying error should be 'pending fetch'"); + + NSError* underunderlying = underlying.userInfo[NSUnderlyingErrorKey]; + XCTAssertNotNil(underunderlying, "Should have received another layer of underlying error"); + XCTAssertEqualObjects(underunderlying.domain, CKErrorDomain, "Underlying error should be CKErrorDomain"); + XCTAssertEqual(underunderlying.code, CKErrorRequestRateLimited, "Underlying error should be 'rate limited'"); + + [callbackOccurs fulfill]; + }]; + + [self waitForExpectations:@[callbackOccurs] timeout:20.0]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + +- (void)testRPCFetchAndProcessWhileInWaitForTLK { + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); + + XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; + [self.ckksControl rpcFetchAndProcessChanges:nil reply:^(NSError * _Nullable error) { + // done! we should have an underlying error of "fetch isn't working" + XCTAssertNotNil(error, "Should have received an error attempting to fetch and process"); + NSError* underlying = error.userInfo[NSUnderlyingErrorKey]; + XCTAssertNotNil(underlying, "Should have received an underlying error"); + XCTAssertEqualObjects(underlying.domain, CKKSResultDescriptionErrorDomain, "Underlying error should be CKKSResultDescriptionErrorDomain"); + XCTAssertEqual(underlying.code, CKKSResultDescriptionPendingKeyReady, "Underlying error should be 'pending key ready'"); + [callbackOccurs fulfill]; + }]; + + [self waitForExpectations:@[callbackOccurs] timeout:20.0]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + - (void)testRPCTLKMissingWhenMissing { // Bring CKKS up in waitfortlk [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; [self startCKKSSubsystem]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); @@ -979,7 +1193,7 @@ } - (void)testRPCTLKMissingWhenFound { - // Bring CKKS up in waitfortlk + // Bring CKKS up in 'ready' [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; [self saveTLKMaterialToKeychain:self.keychainZoneID]; [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; @@ -999,6 +1213,150 @@ OCMVerifyAllWithDelay(self.mockDatabase, 8); } +- (void)testRPCKnownBadStateWhenTLKsMissing { + // Bring CKKS up in waitfortlk + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); + + XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; + + [self.ckksControl rpcKnownBadState:@"keychain" reply:^(CKKSKnownBadState result) { + XCTAssertEqual(result, CKKSKnownStateTLKsMissing, "TLKs should be missing"); + [callbackOccurs fulfill]; + }]; + + [self waitForExpectations:@[callbackOccurs] timeout:5.0]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + +- (void)testRPCKnownBadStateWhenInWaitForUnlock { + // Bring CKKS up in 'waitfortunlok' + self.aksLockState = true; + [self.lockStateTracker recheck]; + [self startCKKSSubsystem]; + + // Wait for the key hierarchy state machine to get stuck waiting for the unlock dependency. No uploads should occur. + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForUnlock] wait:8*NSEC_PER_SEC], @"Key state should get stuck in waitforunlock"); + + XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; + + [self.ckksControl rpcKnownBadState:@"keychain" reply:^(CKKSKnownBadState result) { + XCTAssertEqual(result, CKKSKnownStateWaitForUnlock, "known state should be wait for unlock"); + [callbackOccurs fulfill]; + }]; + + [self waitForExpectations:@[callbackOccurs] timeout:5.0]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + + +- (void)testRPCKnownBadStateWhenInGoodState { + // Bring CKKS up in 'ready' + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self saveTLKMaterialToKeychain:self.keychainZoneID]; + [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready''"); + + XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; + + [self.ckksControl rpcKnownBadState:@"keychain" reply:^(CKKSKnownBadState result) { + XCTAssertEqual(result, CKKSKnownStatePossiblyGood, "known state should not be possibly-good"); + [callbackOccurs fulfill]; + }]; + + [self waitForExpectations:@[callbackOccurs] timeout:5.0]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + +- (void)testRpcStatus { + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + + [self startCKKSSubsystem]; + + // Let things shake themselves out. + OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should return to 'ready'"); + [self waitForCKModifications]; + + XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; + [self.ckksControl rpcStatus:@"keychain" reply:^(NSArray* result, NSError* error) { + XCTAssertNil(error, "should be no error fetching status for keychain"); + + // Ugly "global" hack + XCTAssertEqual(result.count, 2u, "Should have received two result dictionaries back"); + NSDictionary* keychainStatus = result[1]; + + XCTAssertNotNil(keychainStatus, "Should have received at least one zone status back"); + XCTAssertEqualObjects(keychainStatus[@"view"], @"keychain", "Should have received status for the keychain view"); + XCTAssertEqualObjects(keychainStatus[@"keystate"], SecCKKSZoneKeyStateReady, "Should be in 'ready' status"); + [callbackOccurs fulfill]; + }]; + + [self waitForExpectations:@[callbackOccurs] timeout:5.0]; +} + +- (void)testRpcStatusWaitsForAccountDetermination { + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + + // Set up the account state callbacks to happen in one second + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (1 * NSEC_PER_SEC)), dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ + // Let CKKS come up (simulating daemon starting due to RPC) + [self startCKKSSubsystem]; + }); + + // Before CKKS figures out we're in an account, fire off the status RPC. + XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; + [self.ckksControl rpcStatus:@"keychain" reply:^(NSArray* result, NSError* error) { + XCTAssertNil(error, "should be no error fetching status for keychain"); + + // Ugly "global" hack + XCTAssertEqual(result.count, 2u, "Should have received two result dictionaries back"); + NSDictionary* keychainStatus = result[1]; + + XCTAssertNotNil(keychainStatus, "Should have received at least one zone status back"); + XCTAssertEqualObjects(keychainStatus[@"view"], @"keychain", "Should have received status for the keychain view"); + XCTAssertEqualObjects(keychainStatus[@"keystate"], SecCKKSZoneKeyStateReady, "Should be in 'ready' status"); + [callbackOccurs fulfill]; + }]; + + [self waitForExpectations:@[callbackOccurs] timeout:8.0]; +} + +- (void)testRpcStatusIsFastDuringError { + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + + self.keychainFetchError = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecInternalError description:@"injected keychain failure"]; + + // Let CKKS come up; it should enter 'error' + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateError] wait:8*NSEC_PER_SEC], "CKKS entered 'error'"); + + // Fire off the status RPC; it should return immediately + XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; + [self.ckksControl rpcStatus:@"keychain" reply:^(NSArray* result, NSError* error) { + XCTAssertNil(error, "should be no error fetching status for keychain"); + + // Ugly "global" hack + XCTAssertEqual(result.count, 2u, "Should have received two result dictionaries back"); + NSDictionary* keychainStatus = result[1]; + + XCTAssertNotNil(keychainStatus, "Should have received at least one zone status back"); + XCTAssertEqualObjects(keychainStatus[@"view"], @"keychain", "Should have received status for the keychain view"); + XCTAssertEqualObjects(keychainStatus[@"keystate"], SecCKKSZoneKeyStateError, "Should be in 'ready' status"); + [callbackOccurs fulfill]; + }]; + + [self waitForExpectations:@[callbackOccurs] timeout:1.0]; +} + @end #endif // OCTAGON diff --git a/keychain/ckks/tests/CKKSTests+CurrentPointerAPI.m b/keychain/ckks/tests/CKKSTests+CurrentPointerAPI.m index 4f2aff99..9d302e19 100644 --- a/keychain/ckks/tests/CKKSTests+CurrentPointerAPI.m +++ b/keychain/ckks/tests/CKKSTests+CurrentPointerAPI.m @@ -43,7 +43,10 @@ #import "keychain/ckks/tests/CKKSTests.h" #import "keychain/ckks/tests/CKKSTests+API.h" -@implementation CloudKitKeychainSyncingTests (CurrentPointerAPITests) +@interface CloudKitKeychainSyncingCurrentPointerAPITests : CloudKitKeychainSyncingTestsBase +@end + +@implementation CloudKitKeychainSyncingCurrentPointerAPITests -(void)fetchCurrentPointer:(bool)cached persistentRef:(NSData*)persistentRef { @@ -63,7 +66,7 @@ -(void)fetchCurrentPointerExpectingError:(bool)fetchCloudValue { XCTestExpectation* currentExpectation = [self expectationWithDescription: @"callback occurs"]; - //TEST_API_AUTORELEASE_BEFORE(SecItemFetchCurrentItemAcrossAllDevices); + TEST_API_AUTORELEASE_BEFORE(SecItemFetchCurrentItemAcrossAllDevices); SecItemFetchCurrentItemAcrossAllDevices((__bridge CFStringRef)@"com.apple.security.ckks", (__bridge CFStringRef)@"pcsservice", (__bridge CFStringRef)@"keychain", @@ -73,7 +76,7 @@ XCTAssertNotNil((__bridge id)cferror, "Error exists when there's a current item"); [currentExpectation fulfill]; }); - //TEST_API_AUTORELEASE_AFTER(SecItemFetchCurrentItemAcrossAllDevices); + TEST_API_AUTORELEASE_AFTER(SecItemFetchCurrentItemAcrossAllDevices); [self waitForExpectationsWithTimeout:8.0 handler:nil]; } @@ -134,7 +137,7 @@ publicIdentity:(NSData*)publicIdentity expectingSync:true]; XCTAssertNotNil(result, "Received result from adding item"); - [self waitForExpectations:@[keychainChanged] timeout:1]; + [self waitForExpectations:@[keychainChanged] timeout:8]; // Check that the record is where we expect it in CloudKit [self waitForCKModifications]; @@ -157,7 +160,7 @@ // Ensure that setting the current pointer sends a notification keychainChanged = [self expectChangeForView:self.keychainZoneID.zoneName]; - //TEST_API_AUTORELEASE_BEFORE(SecItemSetCurrentItemAcrossAllDevices); + TEST_API_AUTORELEASE_BEFORE(SecItemSetCurrentItemAcrossAllDevices); SecItemSetCurrentItemAcrossAllDevices((__bridge CFStringRef)@"com.apple.security.ckks", (__bridge CFStringRef)@"pcsservice", (__bridge CFStringRef)@"keychain", @@ -167,9 +170,9 @@ XCTAssertNil(error, "No error setting current item"); [setCurrentExpectation fulfill]; }); - //TEST_API_AUTORELEASE_AFTER(SecItemSetCurrentItemAcrossAllDevices); + TEST_API_AUTORELEASE_AFTER(SecItemSetCurrentItemAcrossAllDevices); OCMVerifyAllWithDelay(self.mockDatabase, 8); - [self waitForExpectations:@[keychainChanged] timeout:1]; + [self waitForExpectations:@[keychainChanged] timeout:8]; [self waitForCKModifications]; [self waitForExpectationsWithTimeout:8.0 handler:nil]; @@ -198,7 +201,7 @@ publicIdentity:(NSData*)publicIdentity expectingSync:true]; XCTAssertNotNil(result, "Received result from adding item"); - [self waitForExpectations:@[keychainChanged] timeout:1]; + [self waitForExpectations:@[keychainChanged] timeout:8]; // Check that the record is where we expect it [self waitForCKModifications]; @@ -250,7 +253,7 @@ [otherSetCurrentExpectation fulfill]; }); OCMVerifyAllWithDelay(self.mockDatabase, 8); - [self waitForExpectations:@[keychainChanged] timeout:1]; + [self waitForExpectations:@[keychainChanged] timeout:8]; [self waitForCKModifications]; [self waitForExpectationsWithTimeout:8.0 handler:nil]; @@ -267,6 +270,115 @@ SecResetLocalSecuritydXPCFakeEntitlements(); } +- (void)testPCSCurrentPointerAddMissingItem { + SecResetLocalSecuritydXPCFakeEntitlements(); + SecAddLocalSecuritydXPCFakeEntitlement(kSecEntitlementPrivateCKKSPlaintextFields, kCFBooleanTrue); + SecAddLocalSecuritydXPCFakeEntitlement(kSecEntitlementPrivateCKKSWriteCurrentItemPointers, kCFBooleanTrue); + SecAddLocalSecuritydXPCFakeEntitlement(kSecEntitlementPrivateCKKSReadCurrentItemPointers, kCFBooleanTrue); + + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + + [self fetchCurrentPointerExpectingError:false]; + + NSData* fakepersistentRef = [@"not a real pref" dataUsingEncoding:NSUTF8StringEncoding]; + NSData* fakesha1 = [@"not a real sha1" dataUsingEncoding:NSUTF8StringEncoding]; + + XCTestExpectation* setCurrentExpectation = [self expectationWithDescription: @"callback occurs"]; + + TEST_API_AUTORELEASE_BEFORE(SecItemSetCurrentItemAcrossAllDevices); + SecItemSetCurrentItemAcrossAllDevices((__bridge CFStringRef)@"com.apple.security.ckks", + (__bridge CFStringRef)@"pcsservice", + (__bridge CFStringRef)@"keychain", + (__bridge CFDataRef)fakepersistentRef, + (__bridge CFDataRef)fakesha1, NULL, NULL, ^ (CFErrorRef cferror) { + NSError* error = (__bridge NSError*)cferror; + XCTAssertNotNil(error, "Should error setting current item to a nonexistent item"); + [setCurrentExpectation fulfill]; + }); + TEST_API_AUTORELEASE_AFTER(SecItemSetCurrentItemAcrossAllDevices); + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForCKModifications]; + + [self waitForExpectationsWithTimeout:8.0 handler:nil]; + + SecResetLocalSecuritydXPCFakeEntitlements(); +} + +- (void)testPCSCurrentPointerAddMissingOldItem { + SecResetLocalSecuritydXPCFakeEntitlements(); + SecAddLocalSecuritydXPCFakeEntitlement(kSecEntitlementPrivateCKKSPlaintextFields, kCFBooleanTrue); + SecAddLocalSecuritydXPCFakeEntitlement(kSecEntitlementPrivateCKKSWriteCurrentItemPointers, kCFBooleanTrue); + SecAddLocalSecuritydXPCFakeEntitlement(kSecEntitlementPrivateCKKSReadCurrentItemPointers, kCFBooleanTrue); + + NSNumber* servIdentifier = @3; + NSData* publicKey = [@"asdfasdf" dataUsingEncoding:NSUTF8StringEncoding]; + NSData* publicIdentity = [@"somedata" dataUsingEncoding:NSUTF8StringEncoding]; + + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + + [self fetchCurrentPointerExpectingError:false]; + + XCTestExpectation* keychainChanged = [self expectChangeForView:self.keychainZoneID.zoneName]; + + [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID + checkItem: [self checkPCSFieldsBlock:self.keychainZoneID + PCSServiceIdentifier:(NSNumber *)servIdentifier + PCSPublicKey:publicKey + PCSPublicIdentity:publicIdentity]]; + + NSDictionary* result = [self pcsAddItem:@"testaccount" + data:[@"asdf" dataUsingEncoding:NSUTF8StringEncoding] + serviceIdentifier:(NSNumber*)servIdentifier + publicKey:(NSData*)publicKey + publicIdentity:(NSData*)publicIdentity + expectingSync:true]; + XCTAssertNotNil(result, "Received result from adding item"); + [self waitForExpectations:@[keychainChanged] timeout:8]; + + // Check that the record is where we expect it in CloudKit + [self waitForCKModifications]; + CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID]; + CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID]; + XCTAssertNotNil(record, "Found record in CloudKit at expected UUID"); + + NSData* persistentRef = result[(id)kSecValuePersistentRef]; + NSData* sha1 = result[(id)kSecAttrSHA1]; + + // Set the 'current' pointer. + XCTestExpectation* setCurrentExpectation = [self expectationWithDescription: @"callback occurs"]; + + NSData* fakepersistentRef = [@"not a real pref" dataUsingEncoding:NSUTF8StringEncoding]; + NSData* fakesha1 = [@"not a real sha1" dataUsingEncoding:NSUTF8StringEncoding]; + + TEST_API_AUTORELEASE_BEFORE(SecItemSetCurrentItemAcrossAllDevices); + SecItemSetCurrentItemAcrossAllDevices((__bridge CFStringRef)@"com.apple.security.ckks", + (__bridge CFStringRef)@"pcsservice", + (__bridge CFStringRef)@"keychain", + (__bridge CFDataRef)persistentRef, + (__bridge CFDataRef)sha1, + (__bridge CFDataRef)fakepersistentRef, + (__bridge CFDataRef)fakesha1, + ^(CFErrorRef cferror) { + NSError* error = (__bridge NSError*)cferror; + XCTAssertNotNil(error, "Should error setting current item when passing garbage for old item"); + [setCurrentExpectation fulfill]; + }); + TEST_API_AUTORELEASE_AFTER(SecItemSetCurrentItemAcrossAllDevices); + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectations:@[keychainChanged] timeout:8]; + [self waitForCKModifications]; + + [self waitForExpectationsWithTimeout:8.0 handler:nil]; + + SecResetLocalSecuritydXPCFakeEntitlements(); +} + - (void)testPCSCurrentPointerAddNoCloudKitAccount { SecResetLocalSecuritydXPCFakeEntitlements(); SecAddLocalSecuritydXPCFakeEntitlement(kSecEntitlementPrivateCKKSPlaintextFields, kCFBooleanTrue); @@ -414,7 +526,7 @@ XCTAssertNotNil(result, "Received result from adding item"); NSData* persistentRef = result[(id)kSecValuePersistentRef]; - [self waitForExpectations:@[keychainChanged] timeout:1]; + [self waitForExpectations:@[keychainChanged] timeout:8]; // And a second item [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID @@ -461,7 +573,7 @@ [self.keychainView notifyZoneChange:nil]; [self.keychainView waitForFetchAndIncomingQueueProcessing]; - [self waitForExpectations:@[keychainChanged] timeout:1]; + [self waitForExpectations:@[keychainChanged] timeout:8]; [self fetchCurrentPointer:false persistentRef:persistentRef]; // And again! @@ -480,7 +592,7 @@ [self.keychainView notifyZoneChange:nil]; [self.keychainView waitForFetchAndIncomingQueueProcessing]; - [self waitForExpectations:@[keychainChanged] timeout:1]; + [self waitForExpectations:@[keychainChanged] timeout:8]; [self fetchCurrentPointer:false persistentRef:persistentRef2]; SecResetLocalSecuritydXPCFakeEntitlements(); @@ -553,7 +665,7 @@ [self.keychainZone deleteCKRecordIDFromZone: currentPointerRecordID]; [self.keychainView notifyZoneChange:nil]; [self.keychainView waitForFetchAndIncomingQueueProcessing]; - [self waitForExpectations:@[keychainChanged] timeout:1]; + [self waitForExpectations:@[keychainChanged] timeout:8]; [self fetchCurrentPointerExpectingError:false]; @@ -929,7 +1041,6 @@ [self.keychainView waitUntilAllOperationsAreFinished]; // Before CKKS can add the item, shove a conflicting one into CloudKit - NSError* error = nil; NSString* account = @"testaccount"; @@ -947,9 +1058,15 @@ CKRecord* mismatchedRecord = [self newRecord:ckrid withNewItemData:item]; [self.keychainZone addToZone: mismatchedRecord]; + self.keychainView.holdIncomingQueueOperation = [CKKSResultOperation named:@"hold-incoming" withBlock:^{ + secnotice("ckks", "Releasing process incoming queue hold"); + }]; + + NSData* firstItemData = [@"asdf" dataUsingEncoding:NSUTF8StringEncoding]; + [self expectCKAtomicModifyItemRecordsUpdateFailure:self.keychainZoneID]; NSDictionary* result = [self pcsAddItem:account - data:[@"asdf" dataUsingEncoding:NSUTF8StringEncoding] + data:firstItemData serviceIdentifier:(NSNumber*)servIdentifier publicKey:(NSData*)publicKey publicIdentity:(NSData*)publicIdentity @@ -959,14 +1076,59 @@ NSData* persistentRef = result[(id)kSecValuePersistentRef]; NSData* sha1 = result[(id)kSecAttrSHA1]; + // Ensure that fetching the item without grabbing data returns the same SHA1 + NSDictionary* prefquery = @{(id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecReturnAttributes : @YES, + (id)kSecAttrSynchronizable : @YES, + (id)kSecAttrPersistentReference : persistentRef, + (id)kSecMatchLimit : (id)kSecMatchLimitOne, + }; + CFTypeRef prefresult = NULL; + XCTAssertEqual(errSecSuccess, SecItemCopyMatching((__bridge CFDictionaryRef)prefquery, &prefresult), "Should be able to find item by persistent ref"); + NSDictionary* newPersistentRefResult = (NSDictionary*) CFBridgingRelease(prefresult); + prefresult = NULL; + XCTAssertNotNil(newPersistentRefResult, "Should have received item attributes"); + XCTAssertEqualObjects(newPersistentRefResult[(id)kSecAttrSHA1], sha1, "SHA1 should match between Add and Find (with data)"); + XCTAssertNil(newPersistentRefResult[(id)kSecValueData], "Should have returned no data"); + + // Ensure that fetching the item and grabbing data returns the same SHA1 + prefquery = @{(id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecReturnAttributes : @YES, + (id)kSecReturnData : @YES, + (id)kSecAttrSynchronizable : @YES, + (id)kSecAttrPersistentReference : persistentRef, + (id)kSecMatchLimit : (id)kSecMatchLimitOne, + }; + XCTAssertEqual(errSecSuccess, SecItemCopyMatching((__bridge CFDictionaryRef)prefquery, &prefresult), "Should be able to find item by persistent ref"); + newPersistentRefResult = (NSDictionary*) CFBridgingRelease(prefresult); + XCTAssertNotNil(newPersistentRefResult, "Should have received item attributes"); + XCTAssertEqualObjects(newPersistentRefResult[(id)kSecAttrSHA1], sha1, "SHA1 should match between Add and Find (with data)"); + XCTAssertEqualObjects(newPersistentRefResult[(id)kSecValueData], firstItemData, "Should have returned data matching the item we put in"); + // Set the current pointer to the result of adding this item. This should fail. - XCTestExpectation* setCurrentExpectation = [self expectationWithDescription: @"callback occurs"]; + XCTestExpectation* setCurrentExpectation = [self expectationWithDescription: @"callback occurs before incoming queue operation"]; + SecItemSetCurrentItemAcrossAllDevices((__bridge CFStringRef)@"com.apple.security.ckks", + (__bridge CFStringRef)@"pcsservice", + (__bridge CFStringRef)@"keychain", + (__bridge CFDataRef)persistentRef, + (__bridge CFDataRef)sha1, NULL, NULL, ^ (CFErrorRef cferror) { + XCTAssertNotNil((__bridge NSError*)cferror, "Should error setting current item to hash of item which failed to sync (before incoming queue operation)"); + [setCurrentExpectation fulfill]; + }); + + [self waitForExpectations:@[setCurrentExpectation] timeout:8.0]; + + // Now, release the incoming queue processing and retry the failure + [self.operationQueue addOperation:self.keychainView.holdIncomingQueueOperation]; + [self.keychainView waitForOperationsOfClass:[CKKSIncomingQueueOperation class]]; + + setCurrentExpectation = [self expectationWithDescription: @"callback occurs after incoming queue operation"]; SecItemSetCurrentItemAcrossAllDevices((__bridge CFStringRef)@"com.apple.security.ckks", (__bridge CFStringRef)@"pcsservice", (__bridge CFStringRef)@"keychain", (__bridge CFDataRef)persistentRef, (__bridge CFDataRef)sha1, NULL, NULL, ^ (CFErrorRef cferror) { - XCTAssertNotNil((__bridge NSError*)cferror, "Should error setting current item to hash of item which failed to sync"); + XCTAssertNotNil((__bridge NSError*)cferror, "Should error setting current item to hash of item which failed to sync (after incoming queue operation)"); [setCurrentExpectation fulfill]; }); diff --git a/keychain/ckks/tests/CKKSTests.h b/keychain/ckks/tests/CKKSTests.h index 87f694b5..1fcb10a9 100644 --- a/keychain/ckks/tests/CKKSTests.h +++ b/keychain/ckks/tests/CKKSTests.h @@ -21,18 +21,15 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if OCTAGON + #import #import #import #include -#import "keychain/ckks/CKKS.h" -#import "keychain/ckks/CKKSKeychainView.h" -#import "keychain/ckks/CKKSManifest.h" -#import "keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h" -#import "keychain/ckks/tests/CloudKitMockXCTest.h" -#import "keychain/ckks/tests/MockCloudKit.h" +#import "keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.h" NS_ASSUME_NONNULL_BEGIN @@ -40,17 +37,9 @@ NS_ASSUME_NONNULL_BEGIN // 3 keys, 3 current keys, and 1 device state entry #define SYSTEM_DB_RECORD_COUNT (7 + ([CKKSManifest shouldSyncManifests] ? 73 : 0)) -@interface CloudKitKeychainSyncingTestsBase : CloudKitKeychainSyncingMockXCTest -@property (nullable) CKRecordZoneID* keychainZoneID; -@property (nullable) CKKSKeychainView* keychainView; -@property (nullable) FakeCKZone* keychainZone; - -@property (nullable, readonly) ZoneKeys* keychainZoneKeys; - -- (ZoneKeys*)keychainZoneKeys; -@end - @interface CloudKitKeychainSyncingTests : CloudKitKeychainSyncingTestsBase @end NS_ASSUME_NONNULL_END + +#endif /* OCTAGON */ diff --git a/keychain/ckks/tests/CKKSTests.m b/keychain/ckks/tests/CKKSTests.m index c1893a40..8644e903 100644 --- a/keychain/ckks/tests/CKKSTests.m +++ b/keychain/ckks/tests/CKKSTests.m @@ -32,6 +32,8 @@ #include #include #include +#include +#include #import "keychain/ckks/tests/CloudKitMockXCTest.h" #import "keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h" @@ -46,7 +48,7 @@ #import "keychain/ckks/CKKSViewManager.h" #import "keychain/ckks/CKKSZoneStateEntry.h" #import "keychain/ckks/CKKSManifest.h" -#import "keychain/ckks/CKKSAnalyticsLogger.h" +#import "keychain/ckks/CKKSAnalytics.h" #import "keychain/ckks/CKKSHealKeyHierarchyOperation.h" #import "keychain/ckks/CKKSZoneChangeFetcher.h" @@ -54,69 +56,9 @@ #import "keychain/ckks/tests/CKKSTests.h" -@implementation CloudKitKeychainSyncingTestsBase - -- (ZoneKeys*)keychainZoneKeys { - return self.keys[self.keychainZoneID]; -} - -// Override our base class --(NSSet*)managedViewList { - return [NSSet setWithObject:@"keychain"]; -} - -+ (void)setUp { - SecCKKSEnable(); - SecCKKSResetSyncing(); - [super setUp]; -} - -- (void)setUp { - [super setUp]; - - self.keychainZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"keychain" ownerName:CKCurrentUserDefaultName]; - self.keychainZone = [[FakeCKZone alloc] initZone: self.keychainZoneID]; - - [self.ckksZones addObject:self.keychainZoneID]; - - // Wait for the ViewManager to be brought up - XCTAssertEqual(0, [self.injectedManager.completedSecCKKSInitialize wait:4*NSEC_PER_SEC], "No timeout waiting for SecCKKSInitialize"); - - self.keychainView = [[CKKSViewManager manager] findView:@"keychain"]; - XCTAssertNotNil(self.keychainView, "CKKSViewManager created the keychain view"); - - // Check that your environment is set up correctly - XCTAssertFalse([CKKSManifest shouldSyncManifests], "Manifests syncing is disabled"); - XCTAssertFalse([CKKSManifest shouldEnforceManifests], "Manifests enforcement is disabled"); -} - -+ (void)tearDown { - [super tearDown]; - SecCKKSResetSyncing(); -} - -- (void)tearDown { - // Fetch status, to make sure we can - NSDictionary* status = [self.keychainView status]; - (void)status; - - [self.keychainView halt]; - [self.keychainView waitUntilAllOperationsAreFinished]; - - self.keychainView = nil; - self.keychainZoneID = nil; - - [super tearDown]; -} - -- (FakeCKZone*)keychainZone { - return self.zones[self.keychainZoneID]; -} - -- (void)setKeychainZone: (FakeCKZone*) zone { - self.zones[self.keychainZoneID] = zone; -} - +// break abstraction +@interface CKKSLockStateTracker () +@property (nullable) NSDate* lastUnlockedTime; @end @implementation CloudKitKeychainSyncingTests @@ -137,7 +79,7 @@ [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:4*NSEC_PER_SEC], @"Key state should have arrived at ready"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should have arrived at ready"); [self addGenericPassword: @"data" account: @"account-delete-me"]; @@ -408,6 +350,10 @@ return true; }]; + NSError *error = NULL; + XCTAssertEqual([CKKSOutgoingQueueEntry countByState:SecCKKSStateInFlight zone:self.keychainZoneID error:&error], 1, + "Expected on inflight entry in outgoing queue: %@", error); + // When CKKS restarts, it should find and re-upload this item [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem:[self checkPasswordBlock:self.keychainZoneID account:account password:@"data"]]; @@ -784,6 +730,62 @@ [self.keychainView waitUntilAllOperationsAreFinished]; } +- (void)testReceiveCloudKitConflictOnJustAddedItems { + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + [self startCKKSSubsystem]; + + [self.keychainView waitForKeyHierarchyReadiness]; + [self.keychainView waitUntilAllOperationsAreFinished]; + + // Place a hold on processing the outgoing queue. + self.keychainView.holdOutgoingQueueOperation = [CKKSResultOperation named:@"outgoing-queue-hold" withBlock:^{ + secnotice("ckks", "Outgoing queue hold released."); + }]; + + [self addGenericPassword:@"localchange" account:@"account-delete-me"]; + + // Pull out the new item's UUID. + __block NSString* itemUUID = nil; + [self.keychainView dispatchSync:^bool { + NSError* error = nil; + NSArray* uuids = [CKKSOutgoingQueueEntry allUUIDs:self.keychainZoneID ?: [[CKRecordZoneID alloc] initWithZoneName:@"keychain" + ownerName:CKCurrentUserDefaultName] + error:&error]; + XCTAssertNil(error, "no error fetching uuids"); + XCTAssertEqual(uuids.count, 1u, "There's exactly one outgoing queue entry"); + itemUUID = uuids[0]; + + XCTAssertNotNil(itemUUID, "Have a UUID for our new item"); + return false; + }]; + + // Add a second item: this item should be uploaded after the failure of the first item + [self addGenericPassword:@"localchange" account:@"account-delete-me-2"]; + + [self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName: itemUUID]]; + + // Also, this write will increment the class C current pointer's etag + CKRecordID* currentClassCID = [[CKRecordID alloc] initWithRecordName: @"classC" zoneID: self.keychainZoneID]; + CKRecord* currentClassC = self.keychainZone.currentDatabase[currentClassCID]; + XCTAssertNotNil(currentClassC, "Should have the class C current key pointer record"); + [self.keychainZone addCKRecordToZone:[currentClassC copy]]; + XCTAssertNotEqualObjects(currentClassC.etag, self.keychainZone.currentDatabase[currentClassCID].etag, "Etag should have changed"); + + [self expectCKAtomicModifyItemRecordsUpdateFailure: self.keychainZoneID]; + [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID + checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; + + // Allow the outgoing queue operation to proceed + [self.operationQueue addOperation:self.keychainView.holdOutgoingQueueOperation]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self.keychainView waitUntilAllOperationsAreFinished]; + + [self checkGenericPassword:@"data" account:@"account-delete-me"]; + [self checkGenericPassword:@"localchange" account:@"account-delete-me-2"]; +} + + -(void)testReceiveUnknownField { [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. @@ -994,7 +996,7 @@ [self startCKKSSubsystem]; // Should enter 'ready' - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:180*NSEC_PER_SEC], @"Key state should become 'ready'"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); OCMVerifyAllWithDelay(self.mockDatabase, 8); // Now, lock and allow fetches again @@ -1124,6 +1126,168 @@ OCMVerifyAllWithDelay(self.mockCKKSViewManager, 10); } +- (void)testResetCloudKitZoneFromNoTLK { + self.silentZoneDeletesAllowed = true; + + // If CKKS sees a zone it's never going to be able to read, it should reset that zone + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + // explicitly do not save a fake device status here + self.keychainZone.flag = true; + + // It'll eventually upload a new key hierarchy + [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; + + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:8*NSEC_PER_SEC], @"Key state should become 'resetzone'"); + + // But then, it'll fire off the reset and reach 'ready' + OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + + // And the zone should have been cleared and re-made + XCTAssertFalse(self.keychainZone.flag, "Zone flag should have been reset to false"); +} + +- (void)testResetCloudKitZoneFromNoTLKWithOtherWaitForTLKDevices { + self.silentZoneDeletesAllowed = true; + + // If CKKS sees a zone it's never going to be able to read, it should reset that zone + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + // Save a fake device status here, but modify its key state to be 'waitfortlk': it has no idea what the TLK is either + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; + + for(CKRecord* record in self.keychainZone.currentDatabase.allValues) { + if([record.recordType isEqualToString:SecCKRecordDeviceStateType]) { + record[SecCKRecordKeyState] = CKKSZoneKeyToNumber(SecCKKSZoneKeyStateWaitForTLK); + } + } + + self.keychainZone.flag = true; + + // It'll eventually upload a new key hierarchy + [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; + + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:8*NSEC_PER_SEC], @"Key state should become 'resetzone'"); + + // But then, it'll fire off the reset and reach 'ready' + OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + + // And the zone should have been cleared and re-made + XCTAssertFalse(self.keychainZone.flag, "Zone flag should have been reset to false"); +} + +- (void)testResetCloudKitZoneFromNoTLKIgnoringInactiveDevices { + self.silentZoneDeletesAllowed = true; + + // If CKKS sees a zone it's never going to be able to read, it should reset that zone + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + // Save a fake device status here, but modify its creation and modification times to be months ago + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; + + // Put a 'in-circle' TLKShare record, but also modify its creation and modification times + CKKSSOSSelfPeer* untrustedPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"untrusted-peer" + encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; + [self putTLKShareInCloudKit:self.keychainZoneKeys.tlk from:untrustedPeer to:untrustedPeer zoneID:self.keychainZoneID]; + + for(CKRecord* record in self.keychainZone.currentDatabase.allValues) { + if([record.recordType isEqualToString:SecCKRecordDeviceStateType] || [record.recordType isEqualToString:SecCKRecordTLKShareType]) { + record.creationDate = [NSDate distantPast]; + record.modificationDate = [NSDate distantPast]; + } + } + + self.keychainZone.flag = true; + + // It'll eventually upload a new key hierarchy + [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; + + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:8*NSEC_PER_SEC], @"Key state should become 'resetzone'"); + + // But then, it'll fire off the reset and reach 'ready' + OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + + // And the zone should have been cleared and re-made + XCTAssertFalse(self.keychainZone.flag, "Zone flag should have been reset to false"); +} + +- (void)testDoNotResetCloudKitZoneFromWaitForTLKDueToRecentDeviceState { + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + + // CKKS shouldn't reset this zone, due to a recent device status claiming to have TLKs + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; + + NSDateComponents* offset = [[NSDateComponents alloc] init]; + [offset setDay:-5]; + NSDate* updateTime = [[NSCalendar currentCalendar] dateByAddingComponents:offset toDate:[NSDate date] options:0]; + for(CKRecord* record in self.keychainZone.currentDatabase.allValues) { + if([record.recordType isEqualToString:SecCKRecordDeviceStateType] || [record.recordType isEqualToString:SecCKRecordTLKShareType]) { + record.creationDate = updateTime; + record.modificationDate = updateTime; + } + } + + self.keychainZone.flag = true; + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], @"Key state should become 'waitfortlk'"); + + XCTAssertTrue(self.keychainZone.flag, "Zone flag should not have been reset to false"); +} + +- (void)testDoNotCloudKitZoneFromWaitForTLKDueToRecentButUntrustedDeviceState { + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + + // CKKS should reset this zone, even though to a recent device status claiming to have TLKs. The device isn't trusted + self.silentZoneDeletesAllowed = true; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; + [self.currentPeers removeObject:self.remoteSOSOnlyPeer]; + + self.keychainZone.flag = true; + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], @"Key state should become 'waitfortlk'"); + XCTAssertTrue(self.keychainZone.flag, "Zone flag should not have been reset to false"); + + // And ensure it doesn't go on to 'reset' + XCTAssertNotEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:100*NSEC_PER_MSEC], @"Key state should not become 'resetzone'"); +} + +- (void)testResetCloudKitZoneFromWaitForTLKDueToLessRecentAndUntrustedDeviceState { + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + + // CKKS should reset this zone, even though to a recent device status claiming to have TLKs. The device isn't trusted + self.silentZoneDeletesAllowed = true; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; + [self.currentPeers removeObject:self.remoteSOSOnlyPeer]; + + NSDateComponents* offset = [[NSDateComponents alloc] init]; + [offset setDay:-5]; + NSDate* updateTime = [[NSCalendar currentCalendar] dateByAddingComponents:offset toDate:[NSDate date] options:0]; + for(CKRecord* record in self.keychainZone.currentDatabase.allValues) { + if([record.recordType isEqualToString:SecCKRecordDeviceStateType] || [record.recordType isEqualToString:SecCKRecordTLKShareType]) { + record.creationDate = updateTime; + record.modificationDate = updateTime; + } + } + + self.keychainZone.flag = true; + [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:8*NSEC_PER_SEC], @"Key state should become 'resetzone'"); + + // Then we should reset. + OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + + // And the zone should have been cleared and re-made + XCTAssertFalse(self.keychainZone.flag, "Zone flag should have been reset to false"); +} + - (void)testAcceptExistingKeyHierarchy { // Test starts with no keys in CKKS database, but one in our fake CloudKit. // Test also begins with the TLK having arrived in the local keychain (via SOS) @@ -1162,6 +1326,9 @@ - (void)testAcceptExistingAndUseKeyHierarchy { // Test starts with nothing in database, but one in our fake CloudKit. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; + // But, CKKS shouldn't ever reset the zone + self.keychainZone.flag = true; [self startCKKSSubsystem]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:5*NSEC_PER_SEC], "Key state should have become waitfortlk"); @@ -1187,6 +1354,7 @@ expecting:errSecSuccess message:@"Adding class A item"]; OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertTrue(self.keychainZone.flag, "Keychain zone shouldn't have been reset"); } - (void)testAcceptExistingKeyHierarchyDespiteLocked { @@ -1259,7 +1427,7 @@ XCTAssertNotNil(self.keychainZoneKeys.classA, "Have class A key for zone"); XCTAssertNotNil(self.keychainZoneKeys.classC, "Have class C key for zone"); - [self.keychainView dispatchSync: ^bool { + [self.keychainView dispatchSyncWithAccountKeys: ^bool { [self.keychainView _onqueueKeyStateMachineRequestProcess]; return true; }]; @@ -1342,6 +1510,14 @@ // Make life easy on this test; testAcceptKeyConflictAndUploadReencryptedItem will check the case when we don't receive the notification [self.keychainView waitForFetchAndIncomingQueueProcessing]; + // Just in extra case of threading issues, force a reexamination of the key hierarchy + [self.keychainView dispatchSyncWithAccountKeys: ^bool { + [self.keychainView _onqueueAdvanceKeyStateMachineToState: nil withError: nil]; + return true; + }]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); + // Verify that there are six local keys, and three local current key records [self.keychainView dispatchSync: ^bool{ __strong __typeof(weakSelf) strongSelf = weakSelf; @@ -1419,6 +1595,46 @@ OCMVerifyAllWithDelay(self.mockDatabase, 8); } +- (void)testAcceptKeyConflictAndUploadReencryptedItems { + // Test starts with no keys in database, a key hierarchy in our fake CloudKit, and the TLK safely in the local keychain. + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; + [self saveTLKMaterialToKeychain:self.keychainZoneID]; + + [self startCKKSSubsystem]; + [self.keychainView waitUntilAllOperationsAreFinished]; + + // We expect a single record to be uploaded. + [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID + checkItem:[self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; + + [self addGenericPassword: @"data" account: @"account-delete-me"]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForCKModifications]; + + [self rollFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + + // Do not trigger a notification here. This should cause a conflict updating the current key records + + // We expect a single record to be uploaded, but that the write will be rejected + // We then expect that item to be reuploaded with the current key + + [self expectCKAtomicModifyItemRecordsUpdateFailure: self.keychainZoneID]; + [self addGenericPassword: @"data" account: @"account-delete-me-rolled-key"]; + [self addGenericPassword: @"data" account: @"account-delete-me-rolled-key-2"]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + + [self expectCKModifyItemRecords:2 currentKeyPointerRecords:1 zoneID:self.keychainZoneID + checkItem:[self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under rolled class C key in hierarchy"]]; + + // New key arrives via SOS! + [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; + [self saveTLKMaterialToKeychainSimulatingSOS:self.keychainZoneID]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + - (void)testRecoverFromRequestKeyRefetchWithoutRolling { // Simply requesting a key state refetch shouldn't roll the key hierarchy. @@ -1439,7 +1655,7 @@ self.silentFetchesAllowed = false; [self expectCKFetch]; - [self.keychainView dispatchSync: ^bool { + [self.keychainView dispatchSyncWithAccountKeys: ^bool { [self.keychainView _onqueueKeyStateMachineRequestFetch]; return true; }]; @@ -1481,6 +1697,45 @@ OCMVerifyAllWithDelay(self.mockDatabase, 8); } +- (void)testRecoverMultipleItemsFromIncrementedCurrentKeyPointerEtag { + // CloudKit sometimes reports the current key pointers have changed (etag mismatch), but their content hasn't. + // In this case, CKKS shouldn't roll the TLK. + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + + // Spin up CKKS subsystem. + [self startCKKSSubsystem]; + [self.keychainView waitForFetchAndIncomingQueueProcessing]; // just to be sure it's fetched + + // Items should upload. + [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; + [self addGenericPassword: @"data" account: @"account-delete-me"]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + + [self waitForCKModifications]; + + // Bump the etag on the class C current key record, but don't change any data + CKRecordID* currentClassCID = [[CKRecordID alloc] initWithRecordName: @"classC" zoneID: self.keychainZoneID]; + CKRecord* currentClassC = self.keychainZone.currentDatabase[currentClassCID]; + XCTAssertNotNil(currentClassC, "Should have the class C current key pointer record"); + + [self.keychainZone addCKRecordToZone:[currentClassC copy]]; + XCTAssertNotEqualObjects(currentClassC.etag, self.keychainZone.currentDatabase[currentClassCID].etag, "Etag should have changed"); + + // Add another item. This write should fail, then CKKS should recover without rolling the key hierarchy or issuing a fetch. + self.keychainView.holdOutgoingQueueOperation = [CKKSGroupOperation named:@"outgoing-hold" withBlock: ^{ + secnotice("ckks", "releasing outgoing-queue hold"); + }]; + + self.silentFetchesAllowed = false; + [self expectCKAtomicModifyItemRecordsUpdateFailure:self.keychainZoneID]; + [self expectCKModifyItemRecords:2 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; + [self addGenericPassword: @"data" account: @"account-delete-me-2"]; + [self addGenericPassword: @"data" account: @"account-delete-me-3"]; + + [self.operationQueue addOperation: self.keychainView.holdOutgoingQueueOperation]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + - (void)testOnboardOldItemsCreatingKeyHierarchy { // In this test, we'll check if the CKKS subsystem will pick up a keychain item which existed before the key hierarchy, both with and without a UUID attached at item creation @@ -1541,6 +1796,8 @@ - (void)testOnboardOldItemsWithExistingKeyHierarchyLateTLK { // Test starts key hierarchy in our fake CloudKit, and CKKS blocked. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; + self.keychainZone.flag = true; // Add one item without a UUID... SecCKKSTestSetDisableAutomaticUUID(true); @@ -1564,6 +1821,7 @@ [self expectCKModifyItemRecords: 2 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertTrue(self.keychainZone.flag, "Keychain zone shouldn't have been reset"); } - (void)testResync { @@ -1595,7 +1853,7 @@ OCMVerifyAllWithDelay(self.mockDatabase, 8); [self waitForCKModifications]; // One TLK share record - XCTAssertEqual(self.keychainZone.currentDatabase.count, SYSTEM_DB_RECORD_COUNT+passwordCount+1, "Have 6+passwordCount objects in cloudkit"); + XCTAssertEqual(self.keychainZone.currentDatabase.count, SYSTEM_DB_RECORD_COUNT+passwordCount+1, "Have SYSTEM_DB_RECORD_COUNT+passwordCount+1 objects in cloudkit"); // Now, corrupt away! // Extract all passwordCount items for Corruption @@ -1724,34 +1982,120 @@ return true; }]; } -- (void)testResyncLocal { - [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; - [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; - [self saveTLKMaterialToKeychain:self.keychainZoneID]; +- (void)testResyncItemsMissingFromLocalKeychain { + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + + // We want: + // one password correctly synced between local keychain and CloudKit + // one password incorrectly disappeared from local keychain, but in mirror table + // one password sitting in the outgoing queue + // one password sitting in the incoming queue + + // Add and sync two passwords [self addGenericPassword: @"data" account: @"first"]; [self addGenericPassword: @"data" account: @"second"]; - NSUInteger passwordCount = 2u; - [self expectCKModifyItemRecords: passwordCount currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; - [self startCKKSSubsystem]; + [self checkGenericPassword: @"data" account: @"first"]; + [self checkGenericPassword: @"data" account: @"second"]; - // Wait for uploads to happen + [self expectCKModifyItemRecords:2 currentKeyPointerRecords:1 zoneID:self.keychainZoneID]; + [self startCKKSSubsystem]; OCMVerifyAllWithDelay(self.mockDatabase, 8); [self waitForCKModifications]; + [self.keychainView waitForFetchAndIncomingQueueProcessing]; - // Local resyncs shouldn't fetch clouds. - self.silentFetchesAllowed = false; - SecCKKSDisable(); - [self deleteGenericPassword:@"first"]; - [self deleteGenericPassword:@"second"]; - SecCKKSEnable(); + // Now, place an item in the outgoing queue - // And they're gone! - [self findGenericPassword:@"first" expecting:errSecItemNotFound]; - [self findGenericPassword:@"second" expecting:errSecItemNotFound]; + //[self addGenericPassword: @"data" account: @"third"]; + //[self checkGenericPassword: @"data" account: @"third"]; - CKKSLocalSynchronizeOperation* op = [self.keychainView resyncLocal]; + // Now, corrupt away! + // Extract all passwordCount items for Corruption + NSArray* items = [self.keychainZone.currentDatabase.allValues filteredArrayUsingPredicate: [NSPredicate predicateWithFormat:@"self.recordType like %@", SecCKRecordItemType]]; + XCTAssertEqual(items.count, 2u, "Have %lu Items in cloudkit", (unsigned long)2u); + + // For the first record, surreptitiously remove from local keychain + CKRecord* remove = items[0]; + NSString* removeAccount = [[self decryptRecord:remove] objectForKey:(__bridge id)kSecAttrAccount]; + XCTAssertNotNil(removeAccount, "received an account for the local delete object"); + + NSURL* kcpath = (__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"keychain-2-debug.db"); + sqlite3* db; + sqlite3_open([[kcpath path] UTF8String], &db); + NSString* query = [NSString stringWithFormat:@"DELETE FROM genp WHERE uuid=\"%@\"", remove.recordID.recordName]; + char* sqlerror = NULL; + XCTAssertEqual(SQLITE_OK, sqlite3_exec(db, [query UTF8String], NULL, NULL, &sqlerror), "SQL deletion shouldn't error"); + XCTAssertTrue(sqlerror == NULL, "No error string should have been returned: %s", sqlerror); + if(sqlerror) { + sqlite3_free(sqlerror); + sqlerror = NULL; + } + sqlite3_close(db); + + // The second record is kept in-sync + + // Now, add an in-flight change (for record 3) + [self holdCloudKitModifications]; + [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID]; + [self addGenericPassword:@"data" account:@"third"]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + + // For the fourth, add a new record but prevent incoming queue processing + self.keychainView.holdIncomingQueueOperation = [CKKSResultOperation named:@"hold-incoming" withBlock:^{}]; + + CKRecord* ckr = [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85" withAccount:@"fourth"]; + [self.keychainZone addToZone:ckr]; + [self.keychainView notifyZoneChange:nil]; + + // Now, where are we.... + CKKSScanLocalItemsOperation* scanLocal = [self.keychainView scanLocalItems:@"test-scan"]; + [scanLocal waitUntilFinished]; + + XCTAssertEqual(scanLocal.missingLocalItemsFound, 1u, "Should have found one missing item"); + + // Allow everything to proceed + [self releaseCloudKitModificationHold]; + [self.operationQueue addOperation:self.keychainView.holdIncomingQueueOperation]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self.keychainView waitForOperationsOfClass:[CKKSIncomingQueueOperation class]]; + + // And ensure that all four items are present again + [self findGenericPassword: @"first" expecting: errSecSuccess]; + [self findGenericPassword: @"second" expecting: errSecSuccess]; + [self findGenericPassword: @"third" expecting: errSecSuccess]; + [self findGenericPassword: @"fourth" expecting: errSecSuccess]; +} + +- (void)testResyncLocal { + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; + [self saveTLKMaterialToKeychain:self.keychainZoneID]; + + [self addGenericPassword: @"data" account: @"first"]; + [self addGenericPassword: @"data" account: @"second"]; + NSUInteger passwordCount = 2u; + + [self expectCKModifyItemRecords: passwordCount currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; + [self startCKKSSubsystem]; + + // Wait for uploads to happen + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForCKModifications]; + + // Local resyncs shouldn't fetch clouds. + self.silentFetchesAllowed = false; + SecCKKSDisable(); + [self deleteGenericPassword:@"first"]; + [self deleteGenericPassword:@"second"]; + SecCKKSEnable(); + + // And they're gone! + [self findGenericPassword:@"first" expecting:errSecItemNotFound]; + [self findGenericPassword:@"second" expecting:errSecItemNotFound]; + + CKKSLocalSynchronizeOperation* op = [self.keychainView resyncLocal]; [op waitUntilFinished]; XCTAssertNil(op.error, "Shouldn't be an error resyncing locally"); @@ -1792,7 +2136,7 @@ CFErrorRef cfcferror = NULL; bool ret = SecServerImportKeychainInPlist(dbt, SecSecurityClientGet(), KEYBAG_NONE, KEYBAG_NONE, - (__bridge CFDictionaryRef)@{}, kSecBackupableItemFilter, &cfcferror); + (__bridge CFDictionaryRef)@{}, kSecBackupableItemFilter, false, &cfcferror); XCTAssertNil(CFBridgingRelease(cfcferror), "Shouldn't error importing a 'backup'"); XCTAssert(ret, "Importing a 'backup' should have succeeded"); @@ -1800,15 +2144,15 @@ }); XCTAssertNil(CFBridgingRelease(cferror), "Shouldn't error mucking about in the db"); - // And they're gone! - [self findGenericPassword:@"first" expecting:errSecItemNotFound]; - [self findGenericPassword:@"second" expecting:errSecItemNotFound]; + // Restore is additive so original items stick around + [self findGenericPassword:@"first" expecting:errSecSuccess]; + [self findGenericPassword:@"second" expecting:errSecSuccess]; // Allow the local resync to continue... [self.operationQueue addOperation:self.keychainView.holdLocalSynchronizeOperation]; [self.keychainView waitForOperationsOfClass:[CKKSLocalSynchronizeOperation class]]; - // And they're back! + // Items are still here! [self checkGenericPassword: @"data" account: @"first"]; [self checkGenericPassword: @"data" account: @"second"]; } @@ -2268,16 +2612,17 @@ [self findGenericPassword: @"account0" expecting:errSecSuccess]; } -- (void)disabledtestRecoverDeletedTLKAndPause { - // If the TLK disappears halfway through, well, that's no good. But we should make it into waitfortlk. +- (void)testRecoverDeletedTLK { + // If the TLK disappears halfway through, well, that's no good. But we should recover using TLK sharing // Test starts with nothing in database. We expect some sort of TLK/key hierarchy upload. [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - [self.keychainView waitForKeyHierarchyReadiness]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should have returned to ready"); - [self.keychainView waitForFetchAndIncomingQueueProcessing]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForCKModifications]; CKRecord* ckr = [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85" withAccount:@"account0"]; [self.keychainView waitUntilAllOperationsAreFinished]; @@ -2288,14 +2633,8 @@ (id)kSecClass : (id)kSecClassInternetPassword, (id)kSecAttrNoLegacy : @YES, (id)kSecAttrAccessGroup : @"com.apple.security.ckks", - (id)kSecAttrSynchronizable : (id)kCFBooleanFalse, - }), @"Deleting local keys"); - XCTAssertEqual(errSecSuccess, SecItemDelete((__bridge CFDictionaryRef)@{ - (id)kSecClass : (id)kSecClassInternetPassword, - (id)kSecAttrNoLegacy : @YES, - (id)kSecAttrAccessGroup : @"com.apple.security.ckks", - (id)kSecAttrSynchronizable : (id)kCFBooleanTrue, - }), @"Deleting TLK"); + (id)kSecAttrSynchronizable : (id)kSecAttrSynchronizableAny, + }), @"Deleting CKKS keys"); SecCKKSTestSetDisableKeyNotifications(false); // Trigger a notification (with hilariously fake data) @@ -2303,9 +2642,107 @@ [self.keychainView notifyZoneChange:nil]; [self.keychainView waitForFetchAndIncomingQueueProcessing]; - [self.keychainView waitForOperationsOfClass:[CKKSHealKeyHierarchyOperation class]]; - XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateWaitForTLK, "CKKS re-entered waitfortlk"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should return to 'ready'"); + + [self.keychainView waitForFetchAndIncomingQueueProcessing]; // Do this again, to allow for non-atomic key state machinery switching + + [self findGenericPassword: @"account0" expecting:errSecSuccess]; +} + +- (void)testRecoverMissingRolledKey { + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + + NSString* accountShouldExist = @"under-rolled-key"; + NSString* accountWillExist = @"under-rolled-key-later"; + CKRecord* ckr = [self createFakeRecord:self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85" withAccount:accountShouldExist]; + [self.keychainZone addToZone: ckr]; + + CKRecord* ckrAddedLater = [self createFakeRecord:self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85" withAccount:accountWillExist]; + CKKSKey* pastClassCKey = self.keychainZoneKeys.classC; + + [self rollFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self saveTLKMaterialToKeychain:self.keychainZoneID]; + + [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; + + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should have returned to ready"); + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForCKModifications]; + + [self.keychainView waitForOperationsOfClass:[CKKSIncomingQueueOperation class]]; + [self findGenericPassword:accountShouldExist expecting:errSecSuccess]; + [self findGenericPassword:accountWillExist expecting:errSecItemNotFound]; + + // Now, find and delete the class C key that ckrAddedLater is under + NSError* error = nil; + XCTAssertTrue([pastClassCKey deleteKeyMaterialFromKeychain:&error], "Should be able to delete old key material from keychain"); + XCTAssertNil(error, "Should be no error deleting old key material from keychain"); + + [self.keychainZone addToZone:ckrAddedLater]; + [self.keychainView waitForFetchAndIncomingQueueProcessing]; + + [self findGenericPassword:accountShouldExist expecting:errSecSuccess]; + [self findGenericPassword:accountWillExist expecting:errSecSuccess]; + + XCTAssertTrue([pastClassCKey loadKeyMaterialFromKeychain:&error], "Class C key should be back in the keychain"); + XCTAssertNil(error, "Should be no error loading key from keychain"); +} + +- (void)testRecoverMissingRolledClassAKeyWhileLocked { + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + + NSString* accountShouldExist = @"under-rolled-key"; + NSString* accountWillExist = @"under-rolled-key-later"; + CKRecord* ckr = [self createFakeRecord:self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85" withAccount:accountShouldExist key:self.keychainZoneKeys.classA]; + [self.keychainZone addToZone: ckr]; + + CKRecord* ckrAddedLater = [self createFakeRecord:self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85" withAccount:accountWillExist key:self.keychainZoneKeys.classA]; + CKKSKey* pastClassAKey = self.keychainZoneKeys.classA; + + [self rollFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self saveTLKMaterialToKeychain:self.keychainZoneID]; + + [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; + + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "Key state should have returned to ready"); + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForCKModifications]; + + [self.keychainView waitForOperationsOfClass:[CKKSIncomingQueueOperation class]]; + [self findGenericPassword:accountShouldExist expecting:errSecSuccess]; + [self findGenericPassword:accountWillExist expecting:errSecItemNotFound]; + + // Now, find and delete the class C key that ckrAddedLater is under + NSError* error = nil; + XCTAssertTrue([pastClassAKey deleteKeyMaterialFromKeychain:&error], "Should be able to delete old key material from keychain"); + XCTAssertNil(error, "Should be no error deleting old key material from keychain"); + + // now, lock the keychain + self.aksLockState = true; + [self.lockStateTracker recheck]; + + [self.keychainZone addToZone:ckrAddedLater]; + [self.keychainView waitForFetchAndIncomingQueueProcessing]; + + // Item should still not exist due to the lock state.... + [self findGenericPassword:accountShouldExist expecting:errSecSuccess]; + [self findGenericPassword:accountWillExist expecting:errSecItemNotFound]; + + self.aksLockState = false; + [self.lockStateTracker recheck]; + + // And now it does + [self.keychainView waitUntilAllOperationsAreFinished]; + [self findGenericPassword:accountShouldExist expecting:errSecSuccess]; + [self findGenericPassword:accountWillExist expecting:errSecSuccess]; + + XCTAssertTrue([pastClassAKey loadKeyMaterialFromKeychain:&error], "Class A key should be back in the keychain"); + XCTAssertNil(error, "Should be no error loading key from keychain"); } - (void)testRecoverFromBadCurrentKeyPointer { @@ -2332,10 +2769,56 @@ OCMVerifyAllWithDelay(self.mockDatabase, 8); } +- (void)testRecoverFromIncorrectCurrentTLKPointer { + // The current key pointers in cloudkit shouldn't ever point to wrong entries. But, if they do, CKKS must recover. + + // Test starts with a rolled hierarchy, and CKPs pointing to the wrong items + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self saveTLKMaterialToKeychain:self.keychainZoneID]; + + CKKSCurrentKeyPointer* oldTLKCKP = self.keychainZoneKeys.currentTLKPointer; + CKRecord* oldTLKPointer = [self.keychainZone.currentDatabase[self.keychainZoneKeys.currentTLKPointer.storedCKRecord.recordID] copy]; + + [self rollFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self saveTLKMaterialToKeychain:self.keychainZoneID]; + + ZoneKeys* newZoneKeys = [self.keychainZoneKeys copy]; + + // And put the oldTLKPointer back + [self.zones[self.keychainZoneID] addToZone:oldTLKPointer]; + self.keychainZoneKeys.currentTLKPointer = oldTLKCKP; + + // Make sure it stuck: + XCTAssertNotEqualObjects(self.keychainZoneKeys.currentTLKPointer, + newZoneKeys.currentTLKPointer, + "current TLK pointer should now not point to proper TLK"); + + // Spin up CKKS subsystem. + [self startCKKSSubsystem]; + + // The CKKS subsystem should figure out the issue, and fix it (while uploading itself a TLK Share) + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:80*NSEC_PER_SEC], "Key state should have become ready"); + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForCKModifications]; + + XCTAssertEqualObjects(self.keychainZoneKeys.currentTLKPointer, + newZoneKeys.currentTLKPointer, + "current TLK pointer should now point to proper TLK"); + XCTAssertEqualObjects(self.keychainZoneKeys.currentClassAPointer, + newZoneKeys.currentClassAPointer, + "current Class A pointer should now point to proper Class A key"); + XCTAssertEqualObjects(self.keychainZoneKeys.currentClassCPointer, + newZoneKeys.currentClassCPointer, + "current Class C pointer should now point to proper Class C key"); +} - (void)testRecoverFromCloudKitFetchFail { // Test starts with nothing in database, but one in our fake CloudKit. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; // The first two CKRecordZoneChanges should fail with a 'network unavailable' error. [self.keychainZone failNextFetchWith:[[NSError alloc] initWithDomain:CKErrorDomain code:CKErrorNetworkUnavailable userInfo:@{}]]; @@ -2363,9 +2846,72 @@ OCMVerifyAllWithDelay(self.mockDatabase, 8); } +- (void)testRecoverFromCloudKitFetchNetworkFailAfterReady { + // Test starts with nothing in database, but one in our fake CloudKit. + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + + // Spin up CKKS subsystem. + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered ready"); + XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateReady, "CKKS entered ready"); + + // Network is unavailable + self.reachabilityFlags = 0; + [self.reachabilityTracker recheck]; + + CKRecord* ckr = [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85"]; + [self.keychainZone addToZone:ckr]; + + [self findGenericPassword:@"account-delete-me" expecting:errSecItemNotFound]; + + // Say network is available + self.reachabilityFlags = kSCNetworkReachabilityFlagsReachable; + [self.reachabilityTracker recheck]; + + [self.keychainView waitForFetchAndIncomingQueueProcessing]; + + [self findGenericPassword:@"account-delete-me" expecting:errSecSuccess]; +} + +- (void)testRecoverFromCloudKitFetchNetworkFailBeforeReady { + // Test starts with nothing in database, but one in our fake CloudKit. + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + + CKRecord* ckr = [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85"]; + [self.keychainZone addToZone:ckr]; + + // Network is unavailable + self.reachabilityFlags = 0; + [self.reachabilityTracker recheck]; + + // Spin up CKKS subsystem. + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateInitializing] wait:8*NSEC_PER_SEC], "CKKS entered initializing"); + XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateInitializing, "CKKS entered initializing"); + + // Now, save the TLK to the keychain (to simulate it coming in later via SOS). + [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; + [self saveTLKMaterialToKeychainSimulatingSOS:self.keychainZoneID]; + + [self findGenericPassword:@"account-delete-me" expecting:errSecItemNotFound]; + + // Say network is available + self.reachabilityFlags = kSCNetworkReachabilityFlagsReachable; + [self.reachabilityTracker recheck]; + + [self.keychainView waitUntilAllOperationsAreFinished]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + + [self findGenericPassword:@"account-delete-me" expecting:errSecSuccess]; +} + + - (void)testRecoverFromCloudKitFetchFailWithDelay { // Test starts with nothing in database, but one in our fake CloudKit. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; // The first CKRecordZoneChanges should fail with a 'delay' error. self.silentFetchesAllowed = false; @@ -2440,6 +2986,8 @@ // Save a new device state record with some fake etag [self.keychainView dispatchSync: ^bool { CKKSDeviceStateEntry* cdse = [[CKKSDeviceStateEntry alloc] initForDevice:self.ckDeviceID + osVersion:@"fake-record" + lastUnlockTime:[NSDate date] circlePeerID:self.circlePeerID circleStatus:kSOSCCInCircle keyState:SecCKKSZoneKeyStateWaitForTLK @@ -2521,10 +3069,11 @@ [self addGenericPassword: @"data" account: @"account-delete-me"]; OCMVerifyAllWithDelay(self.mockDatabase, 8); - // The first CKRecordZoneChanges should fail with a 'CKErrorUserDeletedZone' error. + // The first CKRecordZoneChanges should fail with a 'CKErrorUserDeletedZone' error. This will cause a local reset, ending up with zone re-creation. + self.zones[self.keychainZoneID] = nil; // delete the zone [self.keychainZone failNextFetchWith:[[NSError alloc] initWithDomain:CKErrorDomain code:CKErrorUserDeletedZone userInfo:@{}]]; - // We expect a key hierarchy upload, and then the class C item upload + // We expect CKKS to recreate the zone, then perform a key hierarchy upload, and then the class C item upload [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; @@ -2544,9 +3093,10 @@ OCMVerifyAllWithDelay(self.mockDatabase, 8); } -- (void)testRecoverFromCloudKitZoneNotFoundZoneDeletionSuccess { +- (void)testRecoverFromCloudKitZoneNotFoundWithoutZoneDeletion { // Test starts with nothing in database, but one in our fake CloudKit. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; // Spin up CKKS subsystem. [self startCKKSSubsystem]; @@ -2560,26 +3110,21 @@ [self addGenericPassword: @"data" account: @"account-delete-me"]; OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS should enter 'ready'"); + [self waitForCKModifications]; - self.zones[self.keychainZoneID] = nil; // delete the autocreated zone + [self.keychainView waitForOperationsOfClass:[CKKSScanLocalItemsOperation class]]; - // The next CKRecordZoneChanges should fail with a 'zone not found' error. - // BUT: when it goes to delete the zone as part of the reset, that should succeed. So, we won't delete the zone here. - NSError* zoneNotFoundError = [[CKPrettyError alloc] initWithDomain:CKErrorDomain - code:CKErrorZoneNotFound - userInfo:@{}]; - NSError* error = [[CKPrettyError alloc] initWithDomain:CKErrorDomain - code:CKErrorPartialFailure - userInfo:@{CKPartialErrorsByItemIDKey: @{self.keychainZoneID:zoneNotFoundError}}]; - [self.keychainZone failNextFetchWith:error]; + // The next CKRecordZoneChanges will fail with a 'zone not found' error. + self.zones[self.keychainZoneID] = nil; // delete the zone // We expect CKKS to reset itself and recover, then a key hierarchy upload, and then the class C item upload [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self.keychainView notifyZoneChange:nil]; - - OCMVerifyAllWithDelay(self.mockDatabase, 8); + OCMVerifyAllWithDelay(self.mockDatabase, 80); + [self waitForCKModifications]; // And check that a new upload occurs. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; @@ -2593,42 +3138,30 @@ OCMVerifyAllWithDelay(self.mockDatabase, 8); } -- (void)testRecoverFromCloudKitZoneNotFoundZoneDeletionFail { - // Test starts with nothing in database, but one in our fake CloudKit. - [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; +- (void)testRecoverFromCloudKitZoneNotFoundFetchBeforeSigninOccurs { + self.zones[self.keychainZoneID] = nil; // delete the autocreated zone - // Spin up CKKS subsystem. + // Before CKKS sign-in, it receives a fetch rpc + XCTestExpectation *fetchReturns = [self expectationWithDescription:@"fetch returned"]; + [self.injectedManager rpcFetchAndProcessChanges:nil reply:^(NSError *result) { + XCTAssertNil(result, "Should be no error fetching and processing changes"); + [fetchReturns fulfill]; + }]; + + // start 'login'. CKKS Should upload a key hierarchy + [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - // Now, save the TLK to the keychain (to simulate it coming in later via SOS). - [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; - [self saveTLKMaterialToKeychainSimulatingSOS:self.keychainZoneID]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS should enter 'ready'"); // We expect a single record to be uploaded - [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; + [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID + checkItem:[self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; [self addGenericPassword: @"data" account: @"account-delete-me"]; OCMVerifyAllWithDelay(self.mockDatabase, 8); - [self waitForCKModifications]; - self.zones[self.keychainZoneID] = nil; // delete the autocreated zone - - // We expect CKKS to reset itself and recover, then a key hierarchy upload, and then the class C item upload - [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; - [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; - - [self.keychainView notifyZoneChange:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); - - // And check that a new upload occurs. - [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; - - [self addGenericPassword:@"asdf" - account:@"account-class-A" - viewHint:nil - access:(id)kSecAttrAccessibleWhenUnlocked - expecting:errSecSuccess - message:@"Adding class A item"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + // The fetch should have come back by now + [self waitForExpectations: @[fetchReturns] timeout:5]; } - (void)testNoCloudKitAccount { @@ -2671,6 +3204,11 @@ self.silentFetchesAllowed = false; [self startCKKSSubsystem]; + [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + XCTAssertNotNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's no account"); + XCTAssertEqualObjects(self.accountStateTracker.currentAccountError.domain, CKKSErrorDomain, "Account tracker error should be in CKKSErrorDomain"); + XCTAssertEqual(self.accountStateTracker.currentAccountError.code, CKKSNotHSA2, "Account tracker error should be upset about HSA2"); + OCMVerifyAllWithDelay(self.mockDatabase, 8); // There should be no uploads, even when we save keychain items and enter/exit circle @@ -2702,6 +3240,11 @@ self.silentFetchesAllowed = false; [self startCKKSSubsystem]; + [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + XCTAssertNotNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's no account"); + XCTAssertEqualObjects(self.accountStateTracker.currentAccountError.domain, (__bridge NSString*)kSOSErrorDomain, "Account tracker error should be in SOSErrorDomain"); + XCTAssertEqual(self.accountStateTracker.currentAccountError.code, kSOSErrorNotInCircle, "Account tracker error should be upset about out-of-circle"); + OCMVerifyAllWithDelay(self.mockDatabase, 8); [self addGenericPassword: @"data" account: @"account-delete-me"]; @@ -2727,18 +3270,31 @@ self.accountStatus = CKAccountStatusNoAccount; self.circleStatus = kSOSCCNotInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + + // Before we inform CKKS of its account state.... + XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK shouldn't know the account state"); + [self startCKKSSubsystem]; XCTAssertEqual(0, [self.keychainView.loggedOut wait:500*NSEC_PER_MSEC], "Should have been told of a 'logout' event on startup"); XCTAssertNotEqual(0, [self.keychainView.loggedIn wait:100*NSEC_PER_MSEC], "'login' event shouldn't have happened"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); [self.keychainView waitUntilAllOperationsAreFinished]; OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertNotNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's no account"); + XCTAssertEqualObjects(self.accountStateTracker.currentAccountError.domain, CKKSErrorDomain, "Account tracker error should be in CKKSErrorDomain"); + XCTAssertEqual(self.accountStateTracker.currentAccountError.code, CKKSNotLoggedIn, "Account tracker error should just be 'no account'"); + // simulate a cloudkit login and NSNotification callback self.accountStatus = CKAccountStatusAvailable; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + XCTAssertNotNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's no account"); + XCTAssertEqualObjects(self.accountStateTracker.currentAccountError.domain, (__bridge NSString*)kSOSErrorDomain, "Account tracker error should be in SOSErrorDomain"); + XCTAssertEqual(self.accountStateTracker.currentAccountError.code, kSOSErrorNotInCircle, "Account tracker error should be upset about out-of-circle"); + // No writes yet, since we're not in circle [self.keychainView waitUntilAllOperationsAreFinished]; OCMVerifyAllWithDelay(self.mockDatabase, 8); @@ -2749,8 +3305,11 @@ self.circleStatus = kSOSCCInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + XCTAssertNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's an account"); + XCTAssertEqual(0, [self.keychainView.loggedIn wait:2000*NSEC_PER_MSEC], "Should have been told of a 'login'"); XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:100*NSEC_PER_MSEC], "'logout' event should be reset"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); OCMVerifyAllWithDelay(self.mockDatabase, 8); [self waitForCKModifications]; @@ -2767,9 +3326,11 @@ // Test starts with nothing in database. We expect some sort of TLK/key hierarchy upload. [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; + XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK shouldn't know the account state"); [self startCKKSSubsystem]; XCTAssertEqual(0, [self.keychainView.loggedIn wait:2000*NSEC_PER_MSEC], "Should have been told of a 'login'"); XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:100*NSEC_PER_MSEC], "'logout' event should be reset"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; @@ -2787,9 +3348,14 @@ self.circleStatus = kSOSCCNotInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + XCTAssertNotNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's no account"); + XCTAssertEqualObjects(self.accountStateTracker.currentAccountError.domain, CKKSErrorDomain, "Account tracker error should be in CKKSErrorDomain"); + XCTAssertEqual(self.accountStateTracker.currentAccountError.code, CKKSNotLoggedIn, "Account tracker error should just believe we're not logged in"); + // Test that there are no items in the database after logout XCTAssertEqual(0, [self.keychainView.loggedOut wait:2000*NSEC_PER_MSEC], "Should have been told of a 'logout'"); XCTAssertNotEqual(0, [self.keychainView.loggedIn wait:100*NSEC_PER_MSEC], "'login' event should be reset"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); [self checkNoCKKSData: self.keychainView]; // There should be no further uploads, even when we save keychain items @@ -2798,6 +3364,7 @@ [self.keychainView waitUntilAllOperationsAreFinished]; OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:8*NSEC_PER_SEC], "CKKS entered 'logged out'"); // simulate a cloudkit login // We should expect CKKS to re-find the key hierarchy it already uploaded, and then send up the two records we added during the pause @@ -2807,14 +3374,17 @@ [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; self.circleStatus = kSOSCCInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + XCTAssertNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's an account"); XCTAssertEqual(0, [self.keychainView.loggedIn wait:2000*NSEC_PER_MSEC], "Should have been told of a 'login'"); XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:100*NSEC_PER_MSEC], "'logout' event should be reset"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); OCMVerifyAllWithDelay(self.mockDatabase, 20); // Let everything settle... - [self.keychainView waitUntilAllOperationsAreFinished]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); + [self waitForCKModifications]; // Logout again self.accountStatus = CKAccountStatusNoAccount; @@ -2825,6 +3395,7 @@ // Test that there are no items in the database after logout XCTAssertEqual(0, [self.keychainView.loggedOut wait:2000*NSEC_PER_MSEC], "Should have been told of a 'logout'"); XCTAssertNotEqual(0, [self.keychainView.loggedIn wait:100*NSEC_PER_MSEC], "'login' event should be reset"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); [self checkNoCKKSData: self.keychainView]; // There should be no further uploads, even when we save keychain items @@ -2845,412 +3416,163 @@ XCTAssertEqual(0, [self.keychainView.loggedIn wait:2000*NSEC_PER_MSEC], "Should have been told of a 'login'"); XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:100*NSEC_PER_MSEC], "'logout' event should be reset"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); OCMVerifyAllWithDelay(self.mockDatabase, 20); -} - -- (void)testCloudKitLoginRace { - // Test starts with nothing in database, and 'in circle', but securityd hasn't received notification if we're logged into CloudKit. - // CKKS should not call handleLogout. - - id partialKVMock = OCMPartialMock(self.keychainView); - OCMReject([partialKVMock handleCKLogout]); - // note: don't unblock the ck account state object yet... - - self.circleStatus = kSOSCCInCircle; - [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; - - // Add a keychain item, but make sure it doesn't upload yet. - [self addGenericPassword: @"data" account: @"account-delete-me"]; + // Let everything settle... [self.keychainView waitUntilAllOperationsAreFinished]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); - // Now that we're here (and handleCKLogout hasn't been called), bring the account up + // Logout again + self.accountStatus = CKAccountStatusNoAccount; + [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + self.circleStatus = kSOSCCNotInCircle; + [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; - // We expect some sort of TLK/key hierarchy upload once we are notified of entering the circle. - [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; + // Test that there are no items in the database after logout + XCTAssertEqual(0, [self.keychainView.loggedOut wait:2000*NSEC_PER_MSEC], "Should have been told of a 'logout'"); + XCTAssertNotEqual(0, [self.keychainView.loggedIn wait:100*NSEC_PER_MSEC], "'login' event should be reset"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:8*NSEC_PER_SEC], "CKKS entered 'logged out'"); + [self checkNoCKKSData: self.keychainView]; - // We expect a single class C record to be uploaded. - [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; + // Force zone into error state + self.keychainView.keyHierarchyState = SecCKKSZoneKeyStateError; self.accountStatus = CKAccountStatusAvailable; - [self startCKAccountStatusMock]; - - // simulate another NSNotification callback [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + self.circleStatus = kSOSCCInCircle; + [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); - [self waitForCKModifications]; - - // Make sure new items upload too - [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; - [self addGenericPassword: @"data" account: @"account-delete-me-2"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); - - [self.keychainView waitUntilAllOperationsAreFinished]; - [self waitForCKModifications]; - [self.keychainView halt]; - - [partialKVMock stopMocking]; -} - -- (void)testDeviceStateUploadGood { - [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. - - [self startCKKSSubsystem]; - [self.keychainView waitForKeyHierarchyReadiness]; - - __weak __typeof(self) weakSelf = self; - [self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} - deletedRecordTypeCounts:nil - zoneID:self.keychainZoneID - checkModifiedRecord: ^BOOL (CKRecord* record){ - if([record.recordType isEqualToString: SecCKRecordDeviceStateType]) { - // Check that all the things matches - __strong __typeof(weakSelf) strongSelf = weakSelf; - XCTAssertNotNil(strongSelf, "self exists"); - - ZoneKeys* zoneKeys = strongSelf.keys[strongSelf.keychainZoneID]; - XCTAssertNotNil(zoneKeys, "Have zone keys for %@", strongSelf.keychainZoneID); - - XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); - XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); - XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateReady), "Device is in ready"); - - XCTAssertEqualObjects([record[SecCKRecordCurrentTLK] recordID].recordName, zoneKeys.tlk.uuid, "Correct TLK uuid"); - XCTAssertEqualObjects([record[SecCKRecordCurrentClassA] recordID].recordName, zoneKeys.classA.uuid, "Correct class A uuid"); - XCTAssertEqualObjects([record[SecCKRecordCurrentClassC] recordID].recordName, zoneKeys.classC.uuid, "Correct class C uuid"); - return YES; - } else { - return NO; - } - } - runAfterModification:nil]; - - [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; - - OCMVerifyAllWithDelay(self.mockDatabase, 8); -} - -- (void)testDeviceStateUploadRateLimited { - [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. - - [self startCKKSSubsystem]; - [self.keychainView waitForKeyHierarchyReadiness]; - - __weak __typeof(self) weakSelf = self; - [self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} - deletedRecordTypeCounts:nil - zoneID:self.keychainZoneID - checkModifiedRecord: ^BOOL (CKRecord* record){ - if([record.recordType isEqualToString: SecCKRecordDeviceStateType]) { - // Check that all the things matches - __strong __typeof(weakSelf) strongSelf = weakSelf; - XCTAssertNotNil(strongSelf, "self exists"); - - ZoneKeys* zoneKeys = strongSelf.keys[strongSelf.keychainZoneID]; - XCTAssertNotNil(zoneKeys, "Have zone keys for %@", strongSelf.keychainZoneID); - - XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); - XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); - XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateReady), "Device is in ready"); - - XCTAssertEqualObjects([record[SecCKRecordCurrentTLK] recordID].recordName, zoneKeys.tlk.uuid, "Correct TLK uuid"); - XCTAssertEqualObjects([record[SecCKRecordCurrentClassA] recordID].recordName, zoneKeys.classA.uuid, "Correct class A uuid"); - XCTAssertEqualObjects([record[SecCKRecordCurrentClassC] recordID].recordName, zoneKeys.classC.uuid, "Correct class C uuid"); - return YES; - } else { - return NO; - } - } - runAfterModification:nil]; - - CKKSUpdateDeviceStateOperation* op = [self.keychainView updateDeviceState:true waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); - [op waitUntilFinished]; - - // Check that an immediate rate-limited retry doesn't upload anything - op = [self.keychainView updateDeviceState:true waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; - [op waitUntilFinished]; - - // But not rate-limiting works just fine! - [self expectCKModifyRecords:@{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} - deletedRecordTypeCounts:nil - zoneID:self.keychainZoneID - checkModifiedRecord:nil - runAfterModification:nil]; - op = [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); - [op waitUntilFinished]; - - // And now, if the update is old enough, that'll work too - [self.keychainView dispatchSync:^bool { - NSError* error = nil; - CKKSDeviceStateEntry* cdse = [CKKSDeviceStateEntry fromDatabase:self.accountStateTracker.ckdeviceID zoneID:self.keychainZoneID error:&error]; - XCTAssertNil(error, "No error fetching device state entry"); - XCTAssertNotNil(cdse, "Fetched device state entry"); - - CKRecord* record = cdse.storedCKRecord; - - NSDate* m = record.modificationDate; - XCTAssertNotNil(m, "Have modification date"); - - // Four days ago! - NSDateComponents* offset = [[NSDateComponents alloc] init]; - [offset setHour:-4 * 24]; - NSDate* m2 = [[NSCalendar currentCalendar] dateByAddingComponents:offset toDate:m options:0]; - - XCTAssertNotNil(m2, "Made modification date"); - - record.modificationDate = m2; - [cdse setStoredCKRecord:record]; + XCTestExpectation *operationRun = [self expectationWithDescription:@"operation run"]; + NSOperation* op = [NSBlockOperation named:@"test" withBlock:^{ + [operationRun fulfill]; + }]; - [cdse saveToDatabase:&error]; - XCTAssertNil(error, "No error saving device state entry"); + [op addDependency:self.keychainView.keyStateReadyDependency]; + [self.operationQueue addOperation:op]; - return true; - }]; + XCTAssertEqual(0, [self.keychainView.loggedIn wait:2000*NSEC_PER_MSEC], "Should have been told of a 'login'"); + XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:100*NSEC_PER_MSEC], "'logout' event should be reset"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); - // And now the rate-limiting doesn't get in the way - [self expectCKModifyRecords:@{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} - deletedRecordTypeCounts:nil - zoneID:self.keychainZoneID - checkModifiedRecord:nil - runAfterModification:nil]; - op = [self.keychainView updateDeviceState:true waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; - OCMVerifyAllWithDelay(self.mockDatabase, 12); - [op waitUntilFinished]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForExpectations: @[operationRun] timeout:5]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); } -- (void)testDeviceStateUploadRateLimitedAfterNormalUpload { - [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. +- (void)testCloudKitLogoutDueToGreyMode { + // Test starts with nothing in database. We expect some sort of TLK/key hierarchy upload. + [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; + XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK shouldn't know the account state"); [self startCKKSSubsystem]; - [self.keychainView waitForKeyHierarchyReadiness]; + XCTAssertEqual(0, [self.keychainView.loggedIn wait:8*NSEC_PER_SEC], "Should have been told of a 'login'"); + XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:10*NSEC_PER_MSEC], "'logout' event should be reset"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); - [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; - [self addGenericPassword:@"password" account:@"account-delete-me"]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], @"Key state should become 'ready'"); - // Check that an immediate rate-limited retry doesn't upload anything - CKKSUpdateDeviceStateOperation* op = [self.keychainView updateDeviceState:true waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; - [op waitUntilFinished]; -} + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForCKModifications]; -- (void)testDeviceStateUploadWaitsForKeyHierarchy { - [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + // simulate a cloudkit grey mode switch and NSNotification callback. CKKS should treat this as a logout + self.iCloudHasValidCredentials = false; + [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - // Ask to wait for quite a while if we don't become ready - [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:20*NSEC_PER_SEC ckoperationGroup:nil]; + XCTAssertNotNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's no account"); + XCTAssertEqualObjects(self.accountStateTracker.currentAccountError.domain, CKKSErrorDomain, "Account tracker error should be in CKKSErrorDomain"); + XCTAssertEqual(self.accountStateTracker.currentAccountError.code, CKKSiCloudGreyMode, "Account tracker error should be upset about grey mode"); - __weak __typeof(self) weakSelf = self; - // Expect a ready upload - [self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} - deletedRecordTypeCounts:nil - zoneID:self.keychainZoneID - checkModifiedRecord: ^BOOL (CKRecord* record){ - if([record.recordType isEqualToString: SecCKRecordDeviceStateType]) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - XCTAssertNotNil(strongSelf, "self exists"); - - ZoneKeys* zoneKeys = strongSelf.keys[strongSelf.keychainZoneID]; - XCTAssertNotNil(zoneKeys, "Have zone keys for %@", strongSelf.keychainZoneID); - - XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); - XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); - XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateReady), "Device is in ready"); - - XCTAssertEqualObjects([record[SecCKRecordCurrentTLK] recordID].recordName, zoneKeys.tlk.uuid, "Correct TLK uuid"); - XCTAssertEqualObjects([record[SecCKRecordCurrentClassA] recordID].recordName, zoneKeys.classA.uuid, "Correct class A uuid"); - XCTAssertEqualObjects([record[SecCKRecordCurrentClassC] recordID].recordName, zoneKeys.classC.uuid, "Correct class C uuid"); - return YES; - } else { - return NO; - } - } - runAfterModification:nil]; + // Test that there are no items in the database after logout + XCTAssertEqual(0, [self.keychainView.loggedOut wait:8*NSEC_PER_SEC], "Should have been told of a 'logout'"); + XCTAssertNotEqual(0, [self.keychainView.loggedIn wait:10*NSEC_PER_MSEC], "'login' event should be reset"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); + [self checkNoCKKSData: self.keychainView]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:8*NSEC_PER_SEC], "CKKS entered 'logged out'"); - // And allow the key state to progress - [self startCKKSSubsystem]; - OCMVerifyAllWithDelay(self.mockDatabase, 8); -} + // There should be no further uploads, even when we save keychain items + [self addGenericPassword: @"data" account: @"account-delete-me-2"]; + [self addGenericPassword: @"data" account: @"account-delete-me-3"]; -- (void)testDeviceStateReceive { - [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + [self.keychainView waitUntilAllOperationsAreFinished]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); - ZoneKeys* zoneKeys = self.keys[self.keychainZoneID]; - XCTAssertNotNil(zoneKeys, "Have zone keys for %@", self.keychainZoneID); + // Also, fetches shouldn't occur + self.silentFetchesAllowed = false; + NSOperation* op = [self.keychainView.zoneChangeFetcher requestSuccessfulFetch:CKKSFetchBecauseTesting]; + CKKSResultOperation* timeoutOp = [CKKSResultOperation named:@"timeout" withBlock:^{}]; + [timeoutOp addDependency:op]; + [timeoutOp timeout:4*NSEC_PER_SEC]; + [self.operationQueue addOperation:timeoutOp]; + [timeoutOp waitUntilFinished]; + + // CloudKit figures its life out. We expect the two passwords from before to be uploaded + [self expectCKModifyItemRecords:2 currentKeyPointerRecords:1 zoneID:self.keychainZoneID]; + self.silentFetchesAllowed = true; + self.iCloudHasValidCredentials = true; + [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - [self startCKKSSubsystem]; - [self.keychainView waitForKeyHierarchyReadiness]; + XCTAssertNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's an account"); - CKKSDeviceStateEntry* cdse = [[CKKSDeviceStateEntry alloc] initForDevice:@"otherdevice" - circlePeerID:@"asdfasdf" - circleStatus:kSOSCCInCircle - keyState:SecCKKSZoneKeyStateReady - currentTLKUUID:zoneKeys.tlk.uuid - currentClassAUUID:zoneKeys.classA.uuid - currentClassCUUID:zoneKeys.classC.uuid - zoneID:self.keychainZoneID - encodedCKRecord:nil]; - CKRecord* record = [cdse CKRecordWithZoneID:self.keychainZoneID]; - [self.keychainZone addToZone:record]; + XCTAssertEqual(0, [self.keychainView.loggedIn wait:8*NSEC_PER_SEC], "Should have been told of a 'login'"); + XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:10*NSEC_PER_MSEC], "'logout' event should be reset"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:10*NSEC_PER_MSEC], "CKK should know the account state"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); - // Trigger a notification (with hilariously fake data) + // And fetching still works! + [self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D00" withAccount:@"account0"]]; [self.keychainView notifyZoneChange:nil]; [self.keychainView waitForFetchAndIncomingQueueProcessing]; - - [self.keychainView dispatchSync: ^bool { - NSError* error = nil; - NSArray* cdses = [CKKSDeviceStateEntry allInZone:self.keychainZoneID error:&error]; - XCTAssertNil(error, "No error fetching CDSEs"); - XCTAssertNotNil(cdses, "An array of CDSEs was returned"); - XCTAssert(cdses.count >= 1u, "At least one CDSE came back"); - - CKKSDeviceStateEntry* item = nil; - for(CKKSDeviceStateEntry* dbcdse in cdses) { - if([dbcdse.device isEqualToString:@"otherdevice"]) { - item = dbcdse; - } - } - XCTAssertNotNil(item, "Found a cdse for otherdevice"); - - XCTAssertEqualObjects(cdse, item, "Saved item matches pre-cloudkit item"); - - XCTAssertEqualObjects(item.circlePeerID, @"asdfasdf", "correct peer id"); - XCTAssertEqualObjects(item.keyState, SecCKKSZoneKeyStateReady, "correct key state"); - XCTAssertEqualObjects(item.currentTLKUUID, zoneKeys.tlk.uuid, "correct tlk uuid"); - XCTAssertEqualObjects(item.currentClassAUUID, zoneKeys.classA.uuid, "correct classA uuid"); - XCTAssertEqualObjects(item.currentClassCUUID, zoneKeys.classC.uuid, "correct classC uuid"); - - return false; - }]; - - OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self findGenericPassword: @"account0" expecting:errSecSuccess]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered 'ready'"); } -- (void)testDeviceStateUploadBadKeyState { - // This test has stuff in CloudKit, but no TLKs. It should become very sad. - [self putFakeKeyHierarchyInCloudKit: self.keychainZoneID]; +- (void)testCloudKitLoginRace { + // Test starts with nothing in database, and 'in circle', but securityd hasn't received notification if we're logged into CloudKit. + // CKKS should not call handleLogout. - [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); - XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateWaitForTLK, "CKKS entered waitfortlk"); + id partialKVMock = OCMPartialMock(self.keychainView); + OCMReject([partialKVMock handleCKLogout]); + // note: don't unblock the ck account state object yet... - __weak __typeof(self) weakSelf = self; - [self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} - deletedRecordTypeCounts:nil - zoneID:self.keychainZoneID - checkModifiedRecord: ^BOOL (CKRecord* record){ - if([record.recordType isEqualToString: SecCKRecordDeviceStateType]) { - // Check that all the things matches - __strong __typeof(weakSelf) strongSelf = weakSelf; - XCTAssertNotNil(strongSelf, "self exists"); - - XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); - XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); - XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateWaitForTLK), "Device is in waitfortlk"); - - XCTAssertNil(record[SecCKRecordCurrentTLK] , "No TLK"); - XCTAssertNil(record[SecCKRecordCurrentClassA], "No class A key"); - XCTAssertNil(record[SecCKRecordCurrentClassC], "No class C key"); - return YES; - } else { - return NO; - } - } - runAfterModification:nil]; + self.circleStatus = kSOSCCInCircle; + [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; - [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:500*NSEC_PER_MSEC ckoperationGroup:nil]; + // Add a keychain item, but make sure it doesn't upload yet. + [self addGenericPassword: @"data" account: @"account-delete-me"]; + [self.keychainView waitUntilAllOperationsAreFinished]; OCMVerifyAllWithDelay(self.mockDatabase, 8); -} -- (void)testDeviceStateUploadBadKeyStateAfterRestart { - // This test has stuff in CloudKit, but no TLKs. It should become very sad. - [self putFakeKeyHierarchyInCloudKit: self.keychainZoneID]; + // Now that we're here (and handleCKLogout hasn't been called), bring the account up - [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); - XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateWaitForTLK, "CKKS entered waitfortlk"); + // We expect some sort of TLK/key hierarchy upload once we are notified of entering the circle. + [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; - // And restart CKKS... - self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:8*NSEC_PER_SEC], "CKKS entered waitfortlk"); - XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateWaitForTLK, "CKKS entered waitfortlk"); + // We expect a single class C record to be uploaded. + [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; - __weak __typeof(self) weakSelf = self; - [self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} - deletedRecordTypeCounts:nil - zoneID:self.keychainZoneID - checkModifiedRecord: ^BOOL (CKRecord* record){ - if([record.recordType isEqualToString: SecCKRecordDeviceStateType]) { - // Check that all the things matches - __strong __typeof(weakSelf) strongSelf = weakSelf; - XCTAssertNotNil(strongSelf, "self exists"); - - XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); - XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); - XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateWaitForTLK), "Device is in waitfortlk"); - - XCTAssertNil(record[SecCKRecordCurrentTLK] , "No TLK"); - XCTAssertNil(record[SecCKRecordCurrentClassA], "No class A key"); - XCTAssertNil(record[SecCKRecordCurrentClassC], "No class C key"); - return YES; - } else { - return NO; - } - } - runAfterModification:nil]; + self.accountStatus = CKAccountStatusAvailable; + [self startCKAccountStatusMock]; - [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:500*NSEC_PER_MSEC ckoperationGroup:nil]; + // simulate another NSNotification callback + [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; OCMVerifyAllWithDelay(self.mockDatabase, 8); -} - - -- (void)testDeviceStateUploadBadCircleState { - self.circleStatus = kSOSCCNotInCircle; - [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; - - // This test has stuff in CloudKit, but no TLKs. - [self putFakeKeyHierarchyInCloudKit: self.keychainZoneID]; - - [self startCKKSSubsystem]; - - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateInitializing] wait:8*NSEC_PER_SEC], "CKKS entered initializing"); - XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateInitializing, "CKKS entered intializing"); - - __weak __typeof(self) weakSelf = self; - [self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} - deletedRecordTypeCounts:nil - zoneID:self.keychainZoneID - checkModifiedRecord: ^BOOL (CKRecord* record){ - if([record.recordType isEqualToString: SecCKRecordDeviceStateType]) { - // Check that all the things matches - __strong __typeof(weakSelf) strongSelf = weakSelf; - XCTAssertNotNil(strongSelf, "self exists"); - - XCTAssertNil(record[SecCKRecordCirclePeerID], "no peer ID if device is not in circle"); - XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCNotInCircle], "device is not in circle"); - XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateInitializing), "Device is in keystate:initializing"); - - XCTAssertNil(record[SecCKRecordCurrentTLK] , "No TLK"); - XCTAssertNil(record[SecCKRecordCurrentClassA], "No class A key"); - XCTAssertNil(record[SecCKRecordCurrentClassC], "No class C key"); - return YES; - } else { - return NO; - } - } - runAfterModification:nil]; + [self waitForCKModifications]; - CKKSUpdateDeviceStateOperation* op = [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:500*NSEC_PER_MSEC ckoperationGroup:nil]; + // Make sure new items upload too + [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; + [self addGenericPassword: @"data" account: @"account-delete-me-2"]; OCMVerifyAllWithDelay(self.mockDatabase, 8); - [op waitUntilFinished]; - XCTAssertNil(op.error, "No error uploading 'out of circle' device state"); + [self.keychainView waitUntilAllOperationsAreFinished]; + [self waitForCKModifications]; + [self.keychainView halt]; + + [partialKVMock stopMocking]; } - (void)testNotStuckAfterReset { @@ -3273,19 +3595,8 @@ } - (void)testCKKSControlBringup { - xpc_endpoint_t endpoint = SecServerCreateCKKSEndpoint(); - XCTAssertNotNil(endpoint, "Received endpoint"); - NSXPCInterface *interface = CKKSSetupControlProtocol([NSXPCInterface interfaceWithProtocol:@protocol(CKKSControlProtocol)]); XCTAssertNotNil(interface, "Received a configured CKKS interface"); - - NSXPCListenerEndpoint *listenerEndpoint = [[NSXPCListenerEndpoint alloc] init]; - [listenerEndpoint _setEndpoint:endpoint]; - - NSXPCConnection* connection = [[NSXPCConnection alloc] initWithListenerEndpoint:listenerEndpoint]; - XCTAssertNotNil(connection , "Received an active connection"); - - connection.remoteObjectInterface = interface; } @end diff --git a/keychain/ckks/tests/CloudKitKeychainSyncingFixupTests.m b/keychain/ckks/tests/CloudKitKeychainSyncingFixupTests.m index a8f82b94..88ff5a8a 100644 --- a/keychain/ckks/tests/CloudKitKeychainSyncingFixupTests.m +++ b/keychain/ckks/tests/CloudKitKeychainSyncingFixupTests.m @@ -26,6 +26,7 @@ #import #import #import +#import #import "keychain/ckks/tests/CloudKitMockXCTest.h" #import "keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h" @@ -315,11 +316,9 @@ CKKSMirrorEntry* ckme = [CKKSMirrorEntry fromDatabase:secondRecordID.recordName zoneID:self.keychainZoneID error:&error]; XCTAssertNil(error, "Should have no error pulling second CKKSMirrorEntry from database"); - NSMutableData* data = [NSMutableData data]; - NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; [ckme.item.storedCKRecord encodeSystemFieldsWithCoder:archiver]; - [archiver finishEncoding]; - ckme.item.encodedCKRecord = data; + ckme.item.encodedCKRecord = archiver.encodedData; [ckme saveToDatabase:&error]; XCTAssertNil(error, "No error saving system-fielded CKME back to database"); diff --git a/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h b/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h index b6992f58..d1559cc8 100644 --- a/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h +++ b/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h @@ -20,6 +20,9 @@ * * @APPLE_LICENSE_HEADER_END@ */ + +#if OCTAGON + #import "CloudKitMockXCTest.h" #import "keychain/ckks/CKKS.h" #import "keychain/ckks/CKKSControl.h" @@ -47,8 +50,15 @@ NS_ASSUME_NONNULL_BEGIN @property (nullable) id mockCKKSKey; -@property (nullable) id currentSelfPeer; +@property (nullable) CKKSSOSSelfPeer* currentSelfPeer; +@property (nullable) NSError* currentSelfPeerError; @property (nullable) NSMutableSet>* currentPeers; +@property (nullable) NSError* currentPeersError; + +@property (nullable) NSError* keychainFetchError; + +// A single trusted SOSPeer, but without any CKKS keys +@property CKKSSOSPeer* remoteSOSOnlyPeer; @property NSMutableSet* ckksZones; @property (nullable) NSMutableDictionary* keys; @@ -60,6 +70,10 @@ NS_ASSUME_NONNULL_BEGIN - (void)saveTLKMaterialToKeychain:(CKRecordZoneID*)zoneID; - (void)deleteTLKMaterialFromKeychain:(CKRecordZoneID*)zoneID; - (void)saveTLKMaterialToKeychainSimulatingSOS:(CKRecordZoneID*)zoneID; +- (void)putFakeDeviceStatusInCloudKit:(CKRecordZoneID*)zoneID; +- (void)putFakeDeviceStatusInCloudKit:(CKRecordZoneID*)zoneID + zonekeys:(ZoneKeys*)zonekeys; + - (void)SOSPiggyBackAddToKeychain:(NSDictionary*)piggydata; - (NSMutableDictionary*)SOSPiggyBackCopyFromKeychain; - (NSMutableArray*)SOSPiggyICloudIdentities; @@ -79,7 +93,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)rollFakeKeyHierarchyInCloudKit:(CKRecordZoneID*)zoneID; -- (NSDictionary*)fakeRecordDictionary:(NSString*)account zoneID:(CKRecordZoneID*)zoneID; +- (NSDictionary*)fakeRecordDictionary:(NSString* _Nullable)account zoneID:(CKRecordZoneID*)zoneID; - (CKRecord*)createFakeRecord:(CKRecordZoneID*)zoneID recordName:(NSString*)recordName; - (CKRecord*)createFakeRecord:(CKRecordZoneID*)zoneID recordName:(NSString*)recordName withAccount:(NSString* _Nullable)account; - (CKRecord*)createFakeRecord:(CKRecordZoneID*)zoneID @@ -135,3 +149,5 @@ NS_ASSUME_NONNULL_BEGIN @end NS_ASSUME_NONNULL_END + +#endif /* OCTAGON */ diff --git a/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.m b/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.m index 63ba5409..1515a7fe 100644 --- a/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.m +++ b/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.m @@ -44,6 +44,8 @@ #import "keychain/ckks/CKKSManifest.h" #import "keychain/ckks/CKKSPeer.h" +#import "keychain/ot/OTDefines.h" + #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" #import "Security/SecureObjectSync/SOSAccount.h" @@ -109,7 +111,7 @@ [description isEqualToString: [SecCKKSKeyClassTLK stringByAppendingString: @"-piggy"]]; bool isClassA = [description isEqualToString: SecCKKSKeyClassA]; - return (isTLK || isClassA) && strongSelf.aksLockState; + return ((isTLK || isClassA) && strongSelf.aksLockState) || self.keychainFetchError; }; OCMStub([self.mockCKKSKey setKeyMaterialInKeychain:[OCMArg checkWithBlock:shouldFailKeychainQuery] error:[OCMArg anyObjectRef]] @@ -123,10 +125,15 @@ encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; - // No trusted non-self peers by default. Your test can change this if it wants. + // One trusted non-self peer, but it doesn't have any Octagon keys. Your test can change this if it wants. + // However, note that [self putFakeDeviceStatusInCloudKit:] will likely not do what you want. + self.remoteSOSOnlyPeer = [[CKKSSOSPeer alloc] initWithSOSPeerID:@"remote-peer-with-no-keys" + encryptionPublicKey:nil + signingPublicKey:nil]; self.currentPeers = [NSMutableSet set]; + [self.currentPeers addObject:self.remoteSOSOnlyPeer]; - OCMStub([self.mockCKKSViewManager fetchSelfPeers:[OCMArg anyObjectRef]]).andCall(self, @selector(fetchSelfPeers:)); + OCMStub([self.mockCKKSViewManager currentSOSSelf:[OCMArg anyObjectRef]]).andCall(self, @selector(currentSOSSelf:)); OCMStub([self.mockCKKSViewManager fetchTrustedPeers:[OCMArg anyObjectRef]]).andCall(self, @selector(fetchTrustedPeers:)); // Bring up a fake CKKSControl object @@ -147,20 +154,30 @@ self.currentPeers = nil; } -- (CKKSSelves*)fetchSelfPeers:(NSError* __autoreleasing *)error { - // - if(self.aksLockState) { +- (id _Nullable)currentSOSSelf:(NSError**)error { + if(self.currentSelfPeerError) { + if(error) { + *error = self.currentSelfPeerError; + } + return nil; + } else if(self.aksLockState) { if(error) { *error = [NSError errorWithDomain:(__bridge NSString*)kSecErrorDomain code:errSecInteractionNotAllowed userInfo:nil]; } return nil; } else { - // Only supports a single self peer for now - return [[CKKSSelves alloc] initWithCurrent:self.currentSelfPeer allSelves:nil]; + return self.currentSelfPeer; } } - (NSSet>*)fetchTrustedPeers:(NSError* __autoreleasing *)error { + if(self.currentPeersError) { + if(error) { + *error = self.currentPeersError; + } + return nil; + } + // Trusted Peers include ourselves, but as a CKKSSOSPeer object instead of a self peer CKKSSOSPeer* s = [[CKKSSOSPeer alloc] initWithSOSPeerID:self.currentSelfPeer.peerID encryptionPublicKey:self.currentSelfPeer.publicEncryptionKey @@ -194,6 +211,13 @@ // Helpers to handle 'locked' keychain loading and saving -(bool)handleLockLoadKeyMaterialFromKeychain:(NSDictionary*)query error:(NSError * __autoreleasing *) error { + if(self.keychainFetchError) { + if(error) { + *error = self.keychainFetchError; + } + return false; + } + // I think the behavior is: errSecItemNotFound if the item doesn't exist, otherwise errSecInteractionNotAllowed. XCTAssertTrue(self.aksLockState, "Failing a read when keychain is locked"); @@ -211,6 +235,13 @@ } -(bool)handleLockSetKeyMaterialInKeychain:(NSDictionary*)query error:(NSError * __autoreleasing *) error { + if(self.keychainFetchError) { + if(error) { + *error = self.keychainFetchError; + } + return false; + } + XCTAssertTrue(self.aksLockState, "Failing a write only when keychain is locked"); if(error) { *error = [NSError errorWithDomain:@"securityd" code:errSecInteractionNotAllowed userInfo:nil]; @@ -282,6 +313,25 @@ XCTAssertNil(error, "Current Class C pointer saved to database successfully"); } +- (void)putFakeDeviceStatusInCloudKit:(CKRecordZoneID*)zoneID zonekeys:(ZoneKeys*)zonekeys { + CKKSDeviceStateEntry* dse = [[CKKSDeviceStateEntry alloc] initForDevice:self.remoteSOSOnlyPeer.peerID + osVersion:@"faux-version" + lastUnlockTime:nil + circlePeerID:self.remoteSOSOnlyPeer.peerID + circleStatus:kSOSCCInCircle + keyState:SecCKKSZoneKeyStateReady + currentTLKUUID:zonekeys.tlk.uuid + currentClassAUUID:zonekeys.classA.uuid + currentClassCUUID:zonekeys.classC.uuid + zoneID:zoneID + encodedCKRecord:nil]; + [self.zones[zoneID] addToZone:dse zoneID:zoneID]; +} + +- (void)putFakeDeviceStatusInCloudKit:(CKRecordZoneID*)zoneID { + [self putFakeDeviceStatusInCloudKit:zoneID zonekeys:self.keys[zoneID]]; +} + - (void)putFakeKeyHierarchyInCloudKit: (CKRecordZoneID*)zoneID { ZoneKeys* zonekeys = [self createFakeKeyHierarchy: zoneID oldTLK:nil]; @@ -365,6 +415,7 @@ static SOSFullPeerInfoRef SOSCreateFullPeerInfoFromName(CFStringRef name, SOSFullPeerInfoRef fpi = SOSCreateFullPeerInfoFromName(CFSTR("Test Peer"), &signingKey, &octagonSigningKey, &octagonEncryptionKey, NULL); NSData *data = CFBridgingRelease(SOSPeerInfoCopyData(SOSFullPeerInfoGetPeerInfo(fpi), NULL)); + CFReleaseNull(fpi); if (data) [icloudidentities addObject:data]; @@ -480,7 +531,10 @@ static CFDictionaryRef SOSCreatePeerGestaltFromName(CFStringRef name) NSSet* peers = [self.currentPeers setByAddingObject:self.currentSelfPeer]; for(id peer in peers) { - [self putTLKShareInCloudKit:key from:sharingPeer to:peer zoneID:zoneID]; + // Can only send to peers with encryption keys + if(peer.publicEncryptionKey) { + [self putTLKShareInCloudKit:key from:sharingPeer to:peer zoneID:zoneID]; + } } } @@ -512,7 +566,7 @@ static CFDictionaryRef SOSCreatePeerGestaltFromName(CFStringRef name) [self saveTLKSharesInLocalDatabase:zoneID]; } -// Override our base class here: +// Override our base class here, but only for Keychain Views - (void)expectCKModifyRecords:(NSDictionary*)expectedRecordTypeCounts deletedRecordTypeCounts:(NSDictionary*)expectedDeletedRecordTypeCounts @@ -520,70 +574,76 @@ static CFDictionaryRef SOSCreatePeerGestaltFromName(CFStringRef name) checkModifiedRecord:(BOOL (^)(CKRecord*))checkRecord runAfterModification:(void (^) ())afterModification { - __weak __typeof(self) weakSelf = self; + + void (^newAfterModification)() = afterModification; + if([self.ckksZones containsObject:zoneID]) { + __weak __typeof(self) weakSelf = self; + newAfterModification = ^{ + __strong __typeof(weakSelf) strongSelf = weakSelf; + XCTAssertNotNil(strongSelf, "self exists"); + + // Reach into our cloudkit database and extract the keys + CKRecordID* currentTLKPointerID = [[CKRecordID alloc] initWithRecordName:SecCKKSKeyClassTLK zoneID:zoneID]; + CKRecordID* currentClassAPointerID = [[CKRecordID alloc] initWithRecordName:SecCKKSKeyClassA zoneID:zoneID]; + CKRecordID* currentClassCPointerID = [[CKRecordID alloc] initWithRecordName:SecCKKSKeyClassC zoneID:zoneID]; + + ZoneKeys* zonekeys = strongSelf.keys[zoneID]; + if(!zonekeys) { + zonekeys = [[ZoneKeys alloc] init]; + strongSelf.keys[zoneID] = zonekeys; + } + + XCTAssertNotNil(strongSelf.zones[zoneID].currentDatabase[currentTLKPointerID], "Have a currentTLKPointer"); + XCTAssertNotNil(strongSelf.zones[zoneID].currentDatabase[currentClassAPointerID], "Have a currentClassAPointer"); + XCTAssertNotNil(strongSelf.zones[zoneID].currentDatabase[currentClassCPointerID], "Have a currentClassCPointer"); + XCTAssertNotNil(strongSelf.zones[zoneID].currentDatabase[currentTLKPointerID][SecCKRecordParentKeyRefKey], "Have a currentTLKPointer parent"); + XCTAssertNotNil(strongSelf.zones[zoneID].currentDatabase[currentClassAPointerID][SecCKRecordParentKeyRefKey], "Have a currentClassAPointer parent"); + XCTAssertNotNil(strongSelf.zones[zoneID].currentDatabase[currentClassCPointerID][SecCKRecordParentKeyRefKey], "Have a currentClassCPointer parent"); + XCTAssertNotNil([strongSelf.zones[zoneID].currentDatabase[currentTLKPointerID][SecCKRecordParentKeyRefKey] recordID].recordName, "Have a currentTLKPointer parent UUID"); + XCTAssertNotNil([strongSelf.zones[zoneID].currentDatabase[currentClassAPointerID][SecCKRecordParentKeyRefKey] recordID].recordName, "Have a currentClassAPointer parent UUID"); + XCTAssertNotNil([strongSelf.zones[zoneID].currentDatabase[currentClassCPointerID][SecCKRecordParentKeyRefKey] recordID].recordName, "Have a currentClassCPointer parent UUID"); + + zonekeys.currentTLKPointer = [[CKKSCurrentKeyPointer alloc] initWithCKRecord: strongSelf.zones[zoneID].currentDatabase[currentTLKPointerID]]; + zonekeys.currentClassAPointer = [[CKKSCurrentKeyPointer alloc] initWithCKRecord: strongSelf.zones[zoneID].currentDatabase[currentClassAPointerID]]; + zonekeys.currentClassCPointer = [[CKKSCurrentKeyPointer alloc] initWithCKRecord: strongSelf.zones[zoneID].currentDatabase[currentClassCPointerID]]; + + XCTAssertNotNil(zonekeys.currentTLKPointer.currentKeyUUID, "Have a currentTLKPointer current UUID"); + XCTAssertNotNil(zonekeys.currentClassAPointer.currentKeyUUID, "Have a currentClassAPointer current UUID"); + XCTAssertNotNil(zonekeys.currentClassCPointer.currentKeyUUID, "Have a currentClassCPointer current UUID"); + + CKRecordID* currentTLKID = [[CKRecordID alloc] initWithRecordName:zonekeys.currentTLKPointer.currentKeyUUID zoneID:zoneID]; + CKRecordID* currentClassAID = [[CKRecordID alloc] initWithRecordName:zonekeys.currentClassAPointer.currentKeyUUID zoneID:zoneID]; + CKRecordID* currentClassCID = [[CKRecordID alloc] initWithRecordName:zonekeys.currentClassCPointer.currentKeyUUID zoneID:zoneID]; + + zonekeys.tlk = [[CKKSKey alloc] initWithCKRecord: strongSelf.zones[zoneID].currentDatabase[currentTLKID]]; + zonekeys.classA = [[CKKSKey alloc] initWithCKRecord: strongSelf.zones[zoneID].currentDatabase[currentClassAID]]; + zonekeys.classC = [[CKKSKey alloc] initWithCKRecord: strongSelf.zones[zoneID].currentDatabase[currentClassCID]]; + + XCTAssertNotNil(zonekeys.tlk, "Have the current TLK"); + XCTAssertNotNil(zonekeys.classA, "Have the current Class A key"); + XCTAssertNotNil(zonekeys.classC, "Have the current Class C key"); + + NSMutableArray* shares = [NSMutableArray array]; + for(CKRecordID* recordID in strongSelf.zones[zoneID].currentDatabase.allKeys) { + if([recordID.recordName hasPrefix: [CKKSTLKShare ckrecordPrefix]]) { + CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:strongSelf.zones[zoneID].currentDatabase[recordID]]; + XCTAssertNotNil(share, "Should be able to parse a CKKSTLKShare CKRecord into a CKKSTLKShare"); + [shares addObject:share]; + } + } + zonekeys.tlkShares = shares; + + if(afterModification) { + afterModification(); + } + }; + } + [super expectCKModifyRecords:expectedRecordTypeCounts deletedRecordTypeCounts:expectedDeletedRecordTypeCounts zoneID:zoneID checkModifiedRecord:checkRecord - runAfterModification:^{ - __strong __typeof(weakSelf) strongSelf = weakSelf; - XCTAssertNotNil(strongSelf, "self exists"); - - // Reach into our cloudkit database and extract the keys - CKRecordID* currentTLKPointerID = [[CKRecordID alloc] initWithRecordName:SecCKKSKeyClassTLK zoneID:zoneID]; - CKRecordID* currentClassAPointerID = [[CKRecordID alloc] initWithRecordName:SecCKKSKeyClassA zoneID:zoneID]; - CKRecordID* currentClassCPointerID = [[CKRecordID alloc] initWithRecordName:SecCKKSKeyClassC zoneID:zoneID]; - - ZoneKeys* zonekeys = strongSelf.keys[zoneID]; - if(!zonekeys) { - zonekeys = [[ZoneKeys alloc] init]; - strongSelf.keys[zoneID] = zonekeys; - } - - XCTAssertNotNil(strongSelf.zones[zoneID].currentDatabase[currentTLKPointerID], "Have a currentTLKPointer"); - XCTAssertNotNil(strongSelf.zones[zoneID].currentDatabase[currentClassAPointerID], "Have a currentClassAPointer"); - XCTAssertNotNil(strongSelf.zones[zoneID].currentDatabase[currentClassCPointerID], "Have a currentClassCPointer"); - XCTAssertNotNil(strongSelf.zones[zoneID].currentDatabase[currentTLKPointerID][SecCKRecordParentKeyRefKey], "Have a currentTLKPointer parent"); - XCTAssertNotNil(strongSelf.zones[zoneID].currentDatabase[currentClassAPointerID][SecCKRecordParentKeyRefKey], "Have a currentClassAPointer parent"); - XCTAssertNotNil(strongSelf.zones[zoneID].currentDatabase[currentClassCPointerID][SecCKRecordParentKeyRefKey], "Have a currentClassCPointer parent"); - XCTAssertNotNil([strongSelf.zones[zoneID].currentDatabase[currentTLKPointerID][SecCKRecordParentKeyRefKey] recordID].recordName, "Have a currentTLKPointer parent UUID"); - XCTAssertNotNil([strongSelf.zones[zoneID].currentDatabase[currentClassAPointerID][SecCKRecordParentKeyRefKey] recordID].recordName, "Have a currentClassAPointer parent UUID"); - XCTAssertNotNil([strongSelf.zones[zoneID].currentDatabase[currentClassCPointerID][SecCKRecordParentKeyRefKey] recordID].recordName, "Have a currentClassCPointer parent UUID"); - - zonekeys.currentTLKPointer = [[CKKSCurrentKeyPointer alloc] initWithCKRecord: strongSelf.zones[zoneID].currentDatabase[currentTLKPointerID]]; - zonekeys.currentClassAPointer = [[CKKSCurrentKeyPointer alloc] initWithCKRecord: strongSelf.zones[zoneID].currentDatabase[currentClassAPointerID]]; - zonekeys.currentClassCPointer = [[CKKSCurrentKeyPointer alloc] initWithCKRecord: strongSelf.zones[zoneID].currentDatabase[currentClassCPointerID]]; - - XCTAssertNotNil(zonekeys.currentTLKPointer.currentKeyUUID, "Have a currentTLKPointer current UUID"); - XCTAssertNotNil(zonekeys.currentClassAPointer.currentKeyUUID, "Have a currentClassAPointer current UUID"); - XCTAssertNotNil(zonekeys.currentClassCPointer.currentKeyUUID, "Have a currentClassCPointer current UUID"); - - CKRecordID* currentTLKID = [[CKRecordID alloc] initWithRecordName:zonekeys.currentTLKPointer.currentKeyUUID zoneID:zoneID]; - CKRecordID* currentClassAID = [[CKRecordID alloc] initWithRecordName:zonekeys.currentClassAPointer.currentKeyUUID zoneID:zoneID]; - CKRecordID* currentClassCID = [[CKRecordID alloc] initWithRecordName:zonekeys.currentClassCPointer.currentKeyUUID zoneID:zoneID]; - - zonekeys.tlk = [[CKKSKey alloc] initWithCKRecord: strongSelf.zones[zoneID].currentDatabase[currentTLKID]]; - zonekeys.classA = [[CKKSKey alloc] initWithCKRecord: strongSelf.zones[zoneID].currentDatabase[currentClassAID]]; - zonekeys.classC = [[CKKSKey alloc] initWithCKRecord: strongSelf.zones[zoneID].currentDatabase[currentClassCID]]; - - XCTAssertNotNil(zonekeys.tlk, "Have the current TLK"); - XCTAssertNotNil(zonekeys.classA, "Have the current Class A key"); - XCTAssertNotNil(zonekeys.classC, "Have the current Class C key"); - - NSMutableArray* shares = [NSMutableArray array]; - for(CKRecordID* recordID in strongSelf.zones[zoneID].currentDatabase.allKeys) { - if([recordID.recordName hasPrefix: [CKKSTLKShare ckrecordPrefix]]) { - CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:strongSelf.zones[zoneID].currentDatabase[recordID]]; - XCTAssertNotNil(share, "Should be able to parse a CKKSTLKShare CKRecord into a CKKSTLKShare"); - [shares addObject:share]; - } - } - zonekeys.tlkShares = shares; - - if(afterModification) { - afterModification(); - } - }]; + runAfterModification:newAfterModification]; } - (void)expectCKReceiveSyncKeyHierarchyError:(CKRecordZoneID*)zoneID { @@ -947,13 +1007,13 @@ static CFDictionaryRef SOSCreatePeerGestaltFromName(CFStringRef name) }; CFTypeRef result = NULL; - XCTAssertEqual(errSecSuccess, SecItemCopyMatching((__bridge CFDictionaryRef) query, &result), "Finding item %@", account); - XCTAssertNotNil((__bridge id)result, "Received an item"); + XCTAssertEqual(errSecSuccess, SecItemCopyMatching((__bridge CFDictionaryRef) query, &result), "Item %@ should exist", account); + XCTAssertNotNil((__bridge id)result, "Should have received an item"); NSString* storedPassword = [[NSString alloc] initWithData: (__bridge NSData*) result encoding: NSUTF8StringEncoding]; - XCTAssertNotNil(storedPassword, "Password parsed as a password"); + XCTAssertNotNil(storedPassword, "Password should parse as a UTF8 password"); - XCTAssertEqualObjects(storedPassword, password, "Stored password matches received password"); + XCTAssertEqualObjects(storedPassword, password, "Stored password should match received password"); } -(XCTestExpectation*)expectChangeForView:(NSString*)view { diff --git a/keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.h b/keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.h new file mode 100644 index 00000000..97822f9f --- /dev/null +++ b/keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef CloudKitKeychainSyncingTestsBase_h +#define CloudKitKeychainSyncingTestsBase_h + +#import +#import +#import + +#include + +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSKeychainView.h" +#import "keychain/ckks/CKKSManifest.h" +#import "keychain/ckks/CKKSViewManager.h" + +#import "keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h" +#import "keychain/ckks/tests/CloudKitMockXCTest.h" +#import "keychain/ckks/tests/MockCloudKit.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface CloudKitKeychainSyncingTestsBase : CloudKitKeychainSyncingMockXCTest +@property (nullable) CKRecordZoneID* keychainZoneID; +@property (nullable) CKKSKeychainView* keychainView; +@property (nullable) FakeCKZone* keychainZone; + +@property (nullable, readonly) ZoneKeys* keychainZoneKeys; + +@property NSCalendar* utcCalendar; + +- (ZoneKeys*)keychainZoneKeys; +@end + +NS_ASSUME_NONNULL_END + +#endif /* CloudKitKeychainSyncingTestsBase_h */ diff --git a/keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.m b/keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.m new file mode 100644 index 00000000..1c109e32 --- /dev/null +++ b/keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.m @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2018 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import "CloudKitKeychainSyncingTestsBase.h" + +@implementation CloudKitKeychainSyncingTestsBase + +- (ZoneKeys*)keychainZoneKeys { + return self.keys[self.keychainZoneID]; +} + +// Override our base class +-(NSSet*)managedViewList { + return [NSSet setWithObject:@"keychain"]; +} + ++ (void)setUp { + SecCKKSEnable(); + SecCKKSResetSyncing(); + [super setUp]; +} + +- (void)setUp { + self.utcCalendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierISO8601]; + self.utcCalendar.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; + + [super setUp]; + + self.keychainZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"keychain" ownerName:CKCurrentUserDefaultName]; + self.keychainZone = [[FakeCKZone alloc] initZone: self.keychainZoneID]; + + [self.ckksZones addObject:self.keychainZoneID]; + + // Wait for the ViewManager to be brought up + XCTAssertEqual(0, [self.injectedManager.completedSecCKKSInitialize wait:4*NSEC_PER_SEC], "No timeout waiting for SecCKKSInitialize"); + + self.keychainView = [[CKKSViewManager manager] findView:@"keychain"]; + XCTAssertNotNil(self.keychainView, "CKKSViewManager created the keychain view"); + + // Check that your environment is set up correctly + XCTAssertFalse([CKKSManifest shouldSyncManifests], "Manifests syncing is disabled"); + XCTAssertFalse([CKKSManifest shouldEnforceManifests], "Manifests enforcement is disabled"); +} + ++ (void)tearDown { + [super tearDown]; + SecCKKSResetSyncing(); +} + +- (void)tearDown { + // Fetch status, to make sure we can + NSDictionary* status = [self.keychainView status]; + (void)status; + + [self.keychainView halt]; + [self.keychainView waitUntilAllOperationsAreFinished]; + + self.keychainView = nil; + self.keychainZoneID = nil; + + [super tearDown]; +} + +- (FakeCKZone*)keychainZone { + return self.zones[self.keychainZoneID]; +} + +- (void)setKeychainZone: (FakeCKZone*) zone { + self.zones[self.keychainZoneID] = zone; +} + +@end + +#endif /* OCTAGON */ diff --git a/keychain/ckks/tests/CloudKitMockXCTest.h b/keychain/ckks/tests/CloudKitMockXCTest.h index 59dba40a..8db293eb 100644 --- a/keychain/ckks/tests/CloudKitMockXCTest.h +++ b/keychain/ckks/tests/CloudKitMockXCTest.h @@ -21,11 +21,14 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if OCTAGON + #import #import #import #import +#import #import "keychain/ckks/CKKSCKAccountStateTracker.h" #import "keychain/ckks/tests/MockCloudKit.h" @@ -38,6 +41,7 @@ NS_ASSUME_NONNULL_BEGIN @class CKKSViewManager; @class FakeCKZone; @class CKKSLockStateTracker; +@class CKKSReachabilityTracker; @interface CloudKitMockXCTest : XCTestCase @@ -56,6 +60,7 @@ NS_ASSUME_NONNULL_BEGIN @property CKAccountStatus accountStatus; @property BOOL supportsDeviceToDeviceEncryption; +@property BOOL iCloudHasValidCredentials; @property SOSCCStatus circleStatus; @property (readonly) NSString* ckDeviceID; @property (readonly) CKKSCKAccountStateTracker* accountStateTracker; @@ -66,6 +71,10 @@ NS_ASSUME_NONNULL_BEGIN @property (readonly) CKKSLockStateTracker* lockStateTracker; @property (nullable) id mockLockStateTracker; +@property SCNetworkReachabilityFlags reachabilityFlags; // The current 'network reachability flags' +@property (readonly) CKKSReachabilityTracker *reachabilityTracker; +@property (nullable) id mockReachabilityTracker; + @property (nullable) NSMutableDictionary* zones; @property (nullable) NSOperationQueue* operationQueue; @@ -75,6 +84,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nullable) NSBlockOperation* ckFetchHoldOperation; @property bool silentFetchesAllowed; +@property bool silentZoneDeletesAllowed; @property (nullable) id mockCKKSViewManager; @property (nullable) CKKSViewManager* injectedManager; @@ -101,6 +111,11 @@ NS_ASSUME_NONNULL_BEGIN currentKeyPointerRecords:(NSUInteger)expectedCurrentKeyRecords tlkShareRecords:(NSUInteger)expectedTLKShareRecords zoneID:(CKRecordZoneID*)zoneID; +- (void)expectCKModifyKeyRecords:(NSUInteger)expectedNumberOfRecords + currentKeyPointerRecords:(NSUInteger)expectedCurrentKeyRecords + tlkShareRecords:(NSUInteger)expectedTLKShareRecords + zoneID:(CKRecordZoneID*)zoneID + checkModifiedRecord:(BOOL (^_Nullable)(CKRecord*))checkModifiedRecord; - (void)expectCKModifyRecords:(NSDictionary*)expectedRecordTypeCounts deletedRecordTypeCounts:(NSDictionary* _Nullable)expectedDeletedRecordTypeCounts @@ -164,3 +179,5 @@ NS_ASSUME_NONNULL_BEGIN @end NS_ASSUME_NONNULL_END + +#endif /* OCTAGON */ diff --git a/keychain/ckks/tests/CloudKitMockXCTest.m b/keychain/ckks/tests/CloudKitMockXCTest.m index 56a59241..82dea2e3 100644 --- a/keychain/ckks/tests/CloudKitMockXCTest.m +++ b/keychain/ckks/tests/CloudKitMockXCTest.m @@ -52,6 +52,7 @@ #include #include "keychain/ckks/CKKSGroupOperation.h" #include "keychain/ckks/CKKSLockStateTracker.h" +#include "keychain/ckks/CKKSReachabilityTracker.h" #import "MockCloudKit.h" @@ -73,6 +74,7 @@ + (void)setUp { // Turn on testing SecCKKSTestsEnable(); + SecCKKSSetReduceRateLimiting(true); [super setUp]; #if NO_SERVER @@ -92,6 +94,7 @@ SecCKKSTestSetDisableSOS(true); self.silentFetchesAllowed = true; + self.silentZoneDeletesAllowed = false; // Set to true if you want to do any deletes __weak __typeof(self) weakSelf = self; self.operationQueue = [[NSOperationQueue alloc] init]; @@ -119,6 +122,7 @@ self.accountStatus = CKAccountStatusAvailable; self.supportsDeviceToDeviceEncryption = YES; + self.iCloudHasValidCredentials = YES; // Inject a fake operation dependency so we won't respond with the CloudKit account status immediately // The CKKSCKAccountStateTracker won't send any login/logout calls without that information, so this blocks all CKKS setup @@ -153,6 +157,7 @@ CKAccountInfo* account = [[CKAccountInfo alloc] init]; account.accountStatus = blockStrongSelf.accountStatus; account.supportsDeviceToDeviceEncryption = blockStrongSelf.supportsDeviceToDeviceEncryption; + account.hasValidCredentials = blockStrongSelf.iCloudHasValidCredentials; account.accountPartition = CKAccountPartitionTypeProduction; passedBlock((CKAccountInfo*)account, nil); }]; @@ -190,8 +195,13 @@ self.mockLockStateTracker = OCMClassMock([CKKSLockStateTracker class]); OCMStub([self.mockLockStateTracker queryAKSLocked]).andCall(self, @selector(aksLockState)); + self.reachabilityFlags = kSCNetworkReachabilityFlagsReachable; // Lie and say network is available + self.mockReachabilityTracker = OCMClassMock([CKKSReachabilityTracker class]); + OCMStub([self.mockReachabilityTracker getReachabilityFlags:[OCMArg anyPointer]]).andCall(self, @selector(reachabilityFlags)); + self.mockFakeCKModifyRecordZonesOperation = OCMClassMock([FakeCKModifyRecordZonesOperation class]); OCMStub([self.mockFakeCKModifyRecordZonesOperation ckdb]).andReturn(self.zones); + OCMStub([self.mockFakeCKModifyRecordZonesOperation ensureZoneDeletionAllowed:[OCMArg any]]).andCall(self, @selector(ensureZoneDeletionAllowed:)); self.mockFakeCKModifySubscriptionsOperation = OCMClassMock([FakeCKModifySubscriptionsOperation class]); OCMStub([self.mockFakeCKModifySubscriptionsOperation ckdb]).andReturn(self.zones); @@ -293,6 +303,11 @@ } } + +- (void)ensureZoneDeletionAllowed:(FakeCKZone*)zone { + XCTAssertTrue(self.silentZoneDeletesAllowed, "Should be allowing zone deletes"); +} + -(CKKSCKAccountStateTracker*)accountStateTracker { return self.injectedManager.accountTracker; } @@ -301,6 +316,10 @@ return self.injectedManager.lockStateTracker; } +-(CKKSReachabilityTracker*)reachabilityTracker { + return self.injectedManager.reachabilityTracker; +} + -(NSSet*)managedViewList { return (NSSet*) CFBridgingRelease(SOSViewCopyViewSet(kViewSetCKKS)); } @@ -471,7 +490,21 @@ - (void)expectCKModifyKeyRecords:(NSUInteger)expectedNumberOfRecords currentKeyPointerRecords:(NSUInteger)expectedCurrentKeyRecords tlkShareRecords:(NSUInteger)expectedTLKShareRecords - zoneID:(CKRecordZoneID*)zoneID { + zoneID:(CKRecordZoneID*)zoneID +{ + return [self expectCKModifyKeyRecords:expectedNumberOfRecords + currentKeyPointerRecords:expectedCurrentKeyRecords + tlkShareRecords:expectedTLKShareRecords + zoneID:zoneID + checkModifiedRecord:nil]; +} + +- (void)expectCKModifyKeyRecords:(NSUInteger)expectedNumberOfRecords + currentKeyPointerRecords:(NSUInteger)expectedCurrentKeyRecords + tlkShareRecords:(NSUInteger)expectedTLKShareRecords + zoneID:(CKRecordZoneID*)zoneID + checkModifiedRecord:(BOOL (^_Nullable)(CKRecord*))checkModifiedRecord +{ NSNumber* nkeys = [NSNumber numberWithUnsignedInteger: expectedNumberOfRecords]; NSNumber* ncurrentkeys = [NSNumber numberWithUnsignedInteger: expectedCurrentKeyRecords]; NSNumber* ntlkshares = [NSNumber numberWithUnsignedInteger: expectedTLKShareRecords]; @@ -482,7 +515,7 @@ } deletedRecordTypeCounts:nil zoneID:zoneID - checkModifiedRecord:nil + checkModifiedRecord:checkModifiedRecord runAfterModification:nil]; } @@ -737,14 +770,18 @@ if ([obj isKindOfClass:[CKModifyRecordsOperation class]]) { CKModifyRecordsOperation *op = (CKModifyRecordsOperation *)obj; + secnotice("fakecloudkit", "checking for expectCKAtomicModifyItemRecordsUpdateFailure"); + if(!op.atomic) { // We only care about atomic operations + secnotice("fakecloudkit", "expectCKAtomicModifyItemRecordsUpdateFailure: update not atomic"); return NO; } // We want to only match zone updates pertaining to this zone for(CKRecord* record in op.recordsToSave) { if(![record.recordID.zoneID isEqual: zoneID]) { + secnotice("fakecloudkit", "expectCKAtomicModifyItemRecordsUpdateFailure: %@ is not %@", record.recordID.zoneID, zoneID); return NO; } } @@ -767,6 +804,8 @@ if(rejected) { [strongSelf rejectWrite: op failedRecords:failedRecords]; + } else { + secnotice("fakecloudkit", "expectCKAtomicModifyItemRecordsUpdateFailure: doesn't seem like an error to us"); } } return rejected ? YES : NO; @@ -811,7 +850,7 @@ // We're updating the device state type on every update, so add it in here NSMutableDictionary* expectedRecords = [@{ - SecCKRecordDeviceStateType: [NSNumber numberWithUnsignedInt: 1], + SecCKRecordDeviceStateType: [NSNumber numberWithUnsignedInteger:expectedNumberOfRecords], } mutableCopy]; if(SecCKKSSyncManifests()) { // TODO: this really shouldn't be 2. @@ -840,6 +879,8 @@ if(SecCKKSIsEnabled()) { self.accountStatus = CKAccountStatusCouldNotDetermine; + // If the test never initialized the account state, don't call status later + bool callStatus = [self.ckaccountHoldOperation isFinished]; [self.ckaccountHoldOperation cancel]; self.ckaccountHoldOperation = nil; @@ -850,6 +891,16 @@ XCTAssertEqual(0, [self.injectedManager.completedSecCKKSInitialize wait:2*NSEC_PER_SEC], "Timeout did not occur waiting for SecCKKSInitialize"); + // Ensure that we can fetch zone status for all zones + if(callStatus) { + XCTestExpectation *statusReturned = [self expectationWithDescription:@"status returned"]; + [self.injectedManager rpcStatus:nil reply:^(NSArray *result, NSError *error) { + XCTAssertNil(error, "Should be no error fetching status"); + [statusReturned fulfill]; + }]; + [self waitForExpectations: @[statusReturned] timeout:5]; + } + // Make sure this happens before teardown. XCTAssertEqual(0, [self.accountStateTracker.finishedInitialDispatches wait:1*NSEC_PER_SEC], "Account state tracker initialized itself"); @@ -871,6 +922,9 @@ [self.mockLockStateTracker stopMocking]; self.mockLockStateTracker = nil; + [self.mockReachabilityTracker stopMocking]; + self.mockReachabilityTracker = nil; + [self.mockFakeCKModifyRecordZonesOperation stopMocking]; self.mockFakeCKModifyRecordZonesOperation = nil; diff --git a/keychain/ckks/tests/MockCloudKit.h b/keychain/ckks/tests/MockCloudKit.h index 5bc654fd..11ef4eb1 100644 --- a/keychain/ckks/tests/MockCloudKit.h +++ b/keychain/ckks/tests/MockCloudKit.h @@ -21,6 +21,7 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if OCTAGON #import #import @@ -41,6 +42,7 @@ typedef NSMutableDictionary FakeCKDatabase; @property (nonatomic, nullable) NSMutableArray* recordZonesSaved; @property (nonatomic, nullable) NSMutableArray* recordZoneIDsDeleted; + (FakeCKDatabase*)ckdb; ++(void)ensureZoneDeletionAllowed:(FakeCKZone*)zone; @end @interface FakeCKModifySubscriptionsOperation : NSBlockOperation @@ -116,3 +118,5 @@ typedef NSMutableDictionary FakeCKDatabase; @end NS_ASSUME_NONNULL_END + +#endif /* OCTAGON */ diff --git a/keychain/ckks/tests/MockCloudKit.m b/keychain/ckks/tests/MockCloudKit.m index abaada93..556ab2ab 100644 --- a/keychain/ckks/tests/MockCloudKit.m +++ b/keychain/ckks/tests/MockCloudKit.m @@ -26,6 +26,7 @@ #import "keychain/ckks/tests/MockCloudKit.h" #import "keychain/ckks/CKKS.h" #import "keychain/ckks/CKKSRecordHolder.h" +#import "keychain/ckks/CKKSReachabilityTracker.h" #import #import @@ -38,6 +39,7 @@ @synthesize recordZonesToSave = _recordZonesToSave; @synthesize recordZoneIDsToDelete = _recordZoneIDsToDelete; @synthesize modifyRecordZonesCompletionBlock = _modifyRecordZonesCompletionBlock; +@synthesize group = _group; - (instancetype)initWithRecordZonesToSave:(nullable NSArray *)recordZonesToSave recordZoneIDsToDelete:(nullable NSArray *)recordZoneIDsToDelete { if(self = [super init]) { @@ -107,6 +109,7 @@ if(zone) { // The zone exists. Its deletion will succeed. + [FakeCKModifyRecordZonesOperation ensureZoneDeletionAllowed:zone]; ckdb[zoneID] = nil; if(!self.recordZoneIDsDeleted) { @@ -137,6 +140,11 @@ reason:[NSString stringWithFormat:@"+ckdb[] must be mocked out for use"] userInfo:nil]; } + ++(void)ensureZoneDeletionAllowed:(FakeCKZone*)zone { + // Shouldn't ever be called; will be mocked out + (void)zone; +} @end @implementation FakeCKModifySubscriptionsOperation @@ -257,6 +265,13 @@ return; } + SCNetworkReachabilityFlags reachabilityFlags = [CKKSReachabilityTracker getReachabilityFlags:NULL]; + if ((reachabilityFlags & kSCNetworkReachabilityFlagsReachable) == 0) { + NSError *networkError = [NSError errorWithDomain:CKErrorDomain code:CKErrorNetworkFailure userInfo:NULL]; + self.fetchRecordZoneChangesCompletionBlock(networkError); + return; + } + // Not precisely correct in the case of multiple zone fetches. However, we don't currently do that, so it'll work for now. NSError* mockError = [zone popFetchChangesError]; if(mockError) { @@ -324,6 +339,7 @@ @implementation FakeCKFetchRecordsOperation @synthesize recordIDs = _recordIDs; @synthesize desiredKeys = _desiredKeys; +@synthesize configuration = _configuration; @synthesize perRecordProgressBlock = _perRecordProgressBlock; @synthesize perRecordCompletionBlock = _perRecordCompletionBlock; @@ -343,7 +359,6 @@ return self; } - - (void)main { FakeCKDatabase* ckdb = [FakeCKFetchRecordsOperation ckdb]; diff --git a/keychain/ckks/tests/RateLimiterTests.m b/keychain/ckks/tests/RateLimiterTests.m index 91bd6bf3..00ceb9ee 100644 --- a/keychain/ckks/tests/RateLimiterTests.m +++ b/keychain/ckks/tests/RateLimiterTests.m @@ -22,6 +22,7 @@ */ #import +#import #import #import "keychain/ckks/RateLimiter.h" @@ -163,16 +164,14 @@ NSDate* limit = nil; [self.RL judge:self.obj at:date limitTime:&limit]; - NSMutableData *data = [NSMutableData new]; - NSKeyedArchiver *encoder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; - encoder.requiresSecureCoding = YES; + NSKeyedArchiver *encoder = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; [self.RL encodeWithCoder:encoder]; - [encoder finishEncoding]; + NSData* data = encoder.encodedData; + XCTAssertEqualObjects(self.config, self.RL.config, @"config unmodified after encoding"); XCTAssertNil(self.RL.assetType, @"assetType still nil after encoding"); - NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; - decoder.requiresSecureCoding = YES; + NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:nil]; RateLimiter *RL2 = [[RateLimiter alloc] initWithCoder:decoder]; XCTAssertNotNil(RL2, @"Received an object from initWithCoder"); XCTAssertEqualObjects(self.RL.config, RL2.config, @"config is the same after encoding and decoding"); diff --git a/keychain/ckksctl/ckksctl.m b/keychain/ckksctl/ckksctl.m index 9bb556b6..cc9e4ac6 100644 --- a/keychain/ckksctl/ckksctl.m +++ b/keychain/ckksctl/ckksctl.m @@ -33,13 +33,44 @@ static void nsprintf(NSString *fmt, ...) #endif } +static NSDictionary* flattenNSErrorsInDictionary(NSDictionary* dict) { + if(!dict) { + return nil; + } + NSMutableDictionary* mutDict = [dict mutableCopy]; + for(id key in mutDict.allKeys) { + id obj = mutDict[key]; + if([obj isKindOfClass:[NSError class]]) { + NSError* obje = (NSError*) obj; + NSMutableDictionary* newErrorDict = [@{@"code": @(obje.code), @"domain": obje.domain} mutableCopy]; + newErrorDict[@"userInfo"] = flattenNSErrorsInDictionary(obje.userInfo); + mutDict[key] = newErrorDict; + } else if(![NSJSONSerialization isValidJSONObject:obj]) { + mutDict[key] = [obj description]; + } + } + return mutDict; +} + static void print_result(NSDictionary *dict, bool json_flag) { if (json_flag) { NSError *err; + + // NSErrors don't know how to JSON-ify themselves, for some reason + // This will flatten a single layer of them + if(![NSJSONSerialization isValidJSONObject:dict]) { + dict = flattenNSErrorsInDictionary(dict); + } + + if(![NSJSONSerialization isValidJSONObject:dict]) { + printf("Still unsure how to JSONify the following object:\n"); + print_dict(dict, 0); + } + NSData *json = [NSJSONSerialization dataWithJSONObject:dict - options:(NSJSONWritingPrettyPrinted | NSJSONWritingSortedKeys) - error:&err]; + options:(NSJSONWritingPrettyPrinted | NSJSONWritingSortedKeys) + error:&err]; if (!json) { NSLog(@"error: %@", err.localizedDescription); } else { @@ -128,7 +159,8 @@ static void print_entry(id k, id v, int ind) return perfDict; } -- (void)resetLocal: (NSString*)view { +- (long)resetLocal:(NSString*)view { + __block long ret = 0; #if OCTAGON printf("Beginning local reset for %s...\n", view ? [[view description] UTF8String] : "all zones"); dispatch_semaphore_t sema = dispatch_semaphore_create(0); @@ -137,19 +169,24 @@ static void print_entry(id k, id v, int ind) reply:^(NSError *error) { if(error == NULL) { printf("reset complete.\n"); + ret = 0; } else { nsprintf(@"reset error: %@\n", error); + ret = error.code; } dispatch_semaphore_signal(sema); }]; - if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60)) != 0) { + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60 * 2)) != 0) { printf("\n\nError: timed out waiting for response\n"); + return -1; } #endif // OCTAGON + return ret; } -- (void)resetCloudKit: (NSString*)view { +- (long)resetCloudKit:(NSString*)view { + __block long ret = 0; #if OCTAGON printf("Beginning CloudKit reset for %s...\n", view ? [[view description] UTF8String] : "all zones"); dispatch_semaphore_t sema = dispatch_semaphore_create(0); @@ -157,19 +194,24 @@ static void print_entry(id k, id v, int ind) [self.control rpcResetCloudKit:view reply:^(NSError* error){ if(error == NULL) { printf("CloudKit Reset complete.\n"); + ret = 0; } else { nsprintf(@"Reset error: %@\n", error); + ret = error.code; } dispatch_semaphore_signal(sema); }]; - if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60)) != 0) { + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60 * 5)) != 0) { printf("\n\nError: timed out waiting for response\n"); + return -1; } #endif // OCTAON + return ret; } -- (void)resync: (NSString*)view { +- (long)resync:(NSString*)view { + __block long ret = 0; #if OCTAGON printf("Beginning resync for %s...\n", view ? [[view description] UTF8String] : "all zones"); dispatch_semaphore_t sema = dispatch_semaphore_create(0); @@ -177,79 +219,20 @@ static void print_entry(id k, id v, int ind) [self.control rpcResync:view reply:^(NSError* error){ if(error == NULL) { printf("resync success.\n"); + ret = 0; } else { nsprintf(@"resync errored: %@\n", error); + ret = error.code; } dispatch_semaphore_signal(sema); }]; - if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60)) != 0) { + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60 * 2)) != 0) { printf("\n\nError: timed out waiting for response\n"); + return -1; } #endif // OCTAGON -} - -- (void)getAnalyticsSysdiagnose -{ - printf("Getting analytics sysdiagnose....\n"); - dispatch_semaphore_t sema = dispatch_semaphore_create(0); - - [self.control rpcGetAnalyticsSysdiagnoseWithReply:^(NSString* sysdiagnose, NSError* error) { - if (sysdiagnose && !error) { - nsprintf(@"Analytics sysdiagnose:\n\n%@", sysdiagnose); - } - else { - nsprintf(@"error retrieving sysdiagnose: %@", error); - } - - dispatch_semaphore_signal(sema); - }]; - - if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60)) != 0) { - printf("\n\nError: timed out waiting for response\n"); - } -} - -- (void)getAnalyticsJSON -{ - printf("Getting analytics json....\n"); - dispatch_semaphore_t sema = dispatch_semaphore_create(0); - - [self.control rpcGetAnalyticsJSONWithReply:^(NSData* json, NSError* error) { - if (json && !error) { - nsprintf(@"Analytics JSON:\n\n%@", [[NSString alloc] initWithData:json encoding:NSUTF8StringEncoding]); - } - else { - nsprintf(@"error retrieving JSON: %@", error); - } - - dispatch_semaphore_signal(sema); - }]; - - if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60)) != 0) { - printf("\n\nError: timed out waiting for response\n"); - } -} - -- (void)forceAnalyticsUpload -{ - printf("Uploading....\n"); - dispatch_semaphore_t sema = dispatch_semaphore_create(0); - - [self.control rpcForceUploadAnalyticsWithReply:^(BOOL success, NSError* error) { - if (success) { - nsprintf(@"successfully uploaded analytics data"); - } - else { - nsprintf(@"error uploading analytics: %@", error); - } - - dispatch_semaphore_signal(sema); - }]; - - if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60)) != 0) { - printf("\n\nError: timed out waiting for response\n"); - } + return ret; } - (NSDictionary *)fetchStatus: (NSString*) view { @@ -273,7 +256,7 @@ static void print_entry(id k, id v, int ind) dispatch_semaphore_signal(sema); }]; - if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 5)) != 0) { + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 30)) != 0) { status[@"error"] = @"timed out"; } #endif // OCTAGON @@ -300,6 +283,9 @@ static void print_entry(id k, id v, int ind) NSString* selfPeersError = pop(global, @"selfPeersError"); NSArray* trustedPeers = pop(global, @"trustedPeers"); NSString* trustedPeersError = pop(global, @"trustedPeersError"); + NSString* reachability = pop(global, @"reachability"); + NSString* ckdeviceID = pop(global, @"ckdeviceID"); + NSString* ckdeviceIDError = pop(global, @"ckdeviceIDError"); printf("================================================================================\n\n"); printf("Global state:\n\n"); @@ -311,6 +297,10 @@ static void print_entry(id k, id v, int ind) if(![trustedPeersError isEqual: [NSNull null]]) { printf("Trusted Peers Error: %s\n", [[trustedPeersError description] UTF8String]); } + printf("Reachability: %s\n", [[reachability description] UTF8String]); + printf("CK DeviceID: %s\n", [[ckdeviceID description] UTF8String]); + printf("CK DeviceID Error: %s\n", [[ckdeviceIDError description] UTF8String]); + printf("\n"); } @@ -328,7 +318,6 @@ static void print_entry(id k, id v, int ind) NSString* lockStateTracker = pop(status,@"lockstatetracker"); NSString* accountTracker = pop(status,@"accounttracker"); NSString* fetcher = pop(status,@"fetcher"); - NSString* setup = pop(status,@"setup"); NSString* zoneCreated = pop(status,@"zoneCreated"); NSString* zoneCreatedError = pop(status,@"zoneCreatedError"); NSString* zoneSubscribed = pop(status,@"zoneSubscribed"); @@ -340,6 +329,9 @@ static void print_entry(id k, id v, int ind) NSString* currentTLK = pop(status,@"currentTLK"); NSString* currentClassA = pop(status,@"currentClassA"); NSString* currentClassC = pop(status,@"currentClassC"); + NSString* currentTLKPtr = pop(status,@"currentTLKPtr"); + NSString* currentClassAPtr = pop(status,@"currentClassAPtr"); + NSString* currentClassCPtr = pop(status,@"currentClassCPtr"); NSString* currentManifestGeneration = pop(status,@"currentManifestGen"); NSDictionary* oqe = pop(status,@"oqe"); @@ -351,7 +343,6 @@ static void print_entry(id k, id v, int ind) NSString* zoneSetupOperation = pop(status,@"zoneSetupOperation"); - NSString* viewSetupOperation = pop(status,@"viewSetupOperation"); NSString* keyStateOperation = pop(status,@"keyStateOperation"); NSString* lastIncomingQueueOperation = pop(status,@"lastIncomingQueueOperation"); NSString* lastNewTLKOperation = pop(status,@"lastNewTLKOperation"); @@ -371,7 +362,6 @@ static void print_entry(id k, id v, int ind) printf("CloudKit account: %s\n", [accountStatus UTF8String]); printf("Account tracker: %s\n", [accountTracker UTF8String]); - printf("Ran setup operation: %s\n", [setup UTF8String]); if(!([zoneCreated isEqualToString:@"yes"] && [zoneSubscribed isEqualToString:@"yes"])) { printf("CK Zone Created: %s\n", [[zoneCreated description] UTF8String]); @@ -389,9 +379,15 @@ static void print_entry(id k, id v, int ind) } printf("Lock state: %s\n", [lockStateTracker UTF8String]); - printf("Current TLK: %s\n", [currentTLK isEqual: [NSNull null]] ? "null" : [currentTLK UTF8String]); - printf("Current ClassA: %s\n", [currentClassA isEqual: [NSNull null]] ? "null" : [currentClassA UTF8String]); - printf("Current ClassC: %s\n", [currentClassC isEqual: [NSNull null]] ? "null" : [currentClassC UTF8String]); + printf("Current TLK: %s\n", ![currentTLK isEqual: [NSNull null]] + ? [currentTLK UTF8String] + : [[NSString stringWithFormat:@"missing; pointer is %@", currentTLKPtr] UTF8String]); + printf("Current ClassA: %s\n", ![currentClassA isEqual: [NSNull null]] + ? [currentClassA UTF8String] + : [[NSString stringWithFormat:@"missing; pointer is %@", currentClassAPtr] UTF8String]); + printf("Current ClassC: %s\n", ![currentClassC isEqual: [NSNull null]] + ? [currentClassC UTF8String] + : [[NSString stringWithFormat:@"missing; pointer is %@", currentClassCPtr] UTF8String]); printf("TLK shares: %s\n", [[tlkshares description] UTF8String]); @@ -405,7 +401,6 @@ static void print_entry(id k, id v, int ind) printf("zone change fetcher: %s\n", [[fetcher description] UTF8String]); printf("zoneSetupOperation: %s\n", [zoneSetupOperation isEqual: [NSNull null]] ? "never" : [zoneSetupOperation UTF8String]); - printf("viewSetupOperation: %s\n", [viewSetupOperation isEqual: [NSNull null]] ? "never" : [viewSetupOperation UTF8String]); printf("keyStateOperation: %s\n", [keyStateOperation isEqual: [NSNull null]] ? "never" : [keyStateOperation UTF8String]); printf("lastIncomingQueueOperation: %s\n", [lastIncomingQueueOperation isEqual: [NSNull null]] ? "never" : [lastIncomingQueueOperation UTF8String]); printf("lastNewTLKOperation: %s\n", [lastNewTLKOperation isEqual: [NSNull null]] ? "never" : [lastNewTLKOperation UTF8String]); @@ -423,21 +418,24 @@ static void print_entry(id k, id v, int ind) dispatch_semaphore_signal(sema); }]; - if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 5)) != 0) { + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 30)) != 0) { printf("\n\nError: timed out waiting for response\n"); } #endif // OCTAGON } -- (void)fetch: (NSString*) view { +- (long)fetch:(NSString*)view { + __block long ret = 0; #if OCTAGON dispatch_semaphore_t sema = dispatch_semaphore_create(0); [self.control rpcFetchAndProcessChanges:view reply:^(NSError* error) { if(error) { printf("Error fetching: %s\n", [[error description] UTF8String]); + ret = (error.code == 0 ? -1 : error.code); } else { printf("Complete.\n"); + ret = 0; } dispatch_semaphore_signal(sema); @@ -445,19 +443,24 @@ static void print_entry(id k, id v, int ind) if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { printf("\n\nError: timed out waiting for response\n"); + return -1; } #endif // OCTAGON + return ret; } -- (void)push: (NSString*) view { +- (long)push:(NSString*)view { + __block long ret = 0; #if OCTAGON dispatch_semaphore_t sema = dispatch_semaphore_create(0); [self.control rpcPushOutgoingChanges:view reply:^(NSError* error) { if(error) { printf("Error pushing: %s\n", [[error description] UTF8String]); + ret = (error.code == 0 ? -1 : error.code); } else { printf("Complete.\n"); + ret = 0; } dispatch_semaphore_signal(sema); @@ -465,8 +468,10 @@ static void print_entry(id k, id v, int ind) if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { printf("\n\nError: timed out waiting for response\n"); + return -1; } #endif // OCTAGON + return ret; } @end @@ -480,9 +485,6 @@ static int resetCloudKit = false; static int fetch = false; static int push = false; static int json = false; -static int getAnalyticsSysdiagnose = false; -static int getAnalyticsJSON = false; -static int uploadAnalytics = false; static char* viewArg = NULL; @@ -499,9 +501,6 @@ int main(int argc, char **argv) { .command="resync", .flag=&resync, .flagval=true, .description="Resync all data with what's in CloudKit"}, { .command="reset", .flag=&reset, .flagval=true, .description="All local data will be wiped, and data refetched from CloudKit"}, { .command="reset-cloudkit", .flag=&resetCloudKit, .flagval=true, .description="All data in CloudKit will be removed and replaced with what's local"}, - { .command="get-analytics-sysdiagnose", .flag=&getAnalyticsSysdiagnose, .flagval=true, .description="Retrieve the current sysdiagnose dump for CKKS analytics"}, - { .command="get-analytics", .flag=&getAnalyticsJSON, .flagval=true, .description="Retrieve the current JSON blob that would be uploaded to the logging server if an upload occurred now"}, - { .command="upload-analytics", .flag=&uploadAnalytics, .flagval=true, .description="Force an upload of analytics data to cloud server"}, {} }; @@ -546,27 +545,22 @@ int main(int argc, char **argv) if(!json) { [ctl printHumanReadableStatus:view]; } + return 0; } else if(perfCounters) { NSMutableDictionary *statusDict = [[NSMutableDictionary alloc] init]; statusDict[@"performance"] = [ctl fetchPerformanceCounters]; print_result(statusDict, false); } else if(fetch) { - [ctl fetch:view]; + return (int)[ctl fetch:view]; } else if(push) { - [ctl push:view]; + return (int)[ctl push:view]; } else if(reset) { - [ctl resetLocal:view]; + return (int)[ctl resetLocal:view]; } else if(resetCloudKit) { - [ctl resetCloudKit:view]; + return (int)[ctl resetCloudKit:view]; } else if(resync) { - [ctl resync:view]; - } else if(getAnalyticsSysdiagnose) { - [ctl getAnalyticsSysdiagnose]; - } else if(getAnalyticsJSON) { - [ctl getAnalyticsJSON]; - } else if(uploadAnalytics) { - [ctl forceAnalyticsUpload]; + return (int)[ctl resync:view]; } else { print_usage(&args); return -1; diff --git a/keychain/ot/OT.h b/keychain/ot/OT.h new file mode 100644 index 00000000..939ebfe8 --- /dev/null +++ b/keychain/ot/OT.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef OT_h +#define OT_h + +#ifdef __OBJC__ +#import +NS_ASSUME_NONNULL_BEGIN +#else +CF_ASSUME_NONNULL_BEGIN +#endif + +bool SecOTIsEnabled(void); + +CF_ASSUME_NONNULL_END +#endif /* OT_h */ diff --git a/keychain/ot/OT.m b/keychain/ot/OT.m new file mode 100644 index 00000000..e0e8bf85 --- /dev/null +++ b/keychain/ot/OT.m @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import "OT.h" +#import +#import + +bool SecOTIsEnabled(void) { + + bool userDefaultsShouldBottledPeer = true; + CFBooleanRef enabled = (CFBooleanRef)CFPreferencesCopyValue(CFSTR("EnableOTRestore"), + CFSTR("com.apple.security"), + kCFPreferencesAnyUser, kCFPreferencesAnyHost); + if(enabled && CFGetTypeID(enabled) == CFBooleanGetTypeID()){ + if(enabled == kCFBooleanFalse){ + secnotice("octagon", "Octagon Restore Disabled"); + userDefaultsShouldBottledPeer = false; + } + if(enabled == kCFBooleanTrue){ + secnotice("octagon", "Octagon Restore Enabled"); + userDefaultsShouldBottledPeer = true; + } + } + + CFReleaseNull(enabled); + return userDefaultsShouldBottledPeer; +} diff --git a/keychain/ot/OTAuthenticatedCiphertext+SF.h b/keychain/ot/OTAuthenticatedCiphertext+SF.h new file mode 100644 index 00000000..799dac23 --- /dev/null +++ b/keychain/ot/OTAuthenticatedCiphertext+SF.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import +#import + +#import "OTAuthenticatedCiphertext.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTAuthenticatedCiphertext (SecurityFoundation) + ++ (instancetype)fromSFAuthenticatedCiphertext:(SFAuthenticatedCiphertext *)cipher; + +- (SFAuthenticatedCiphertext *)asSFAuthenticatedCiphertext; + +@end + +NS_ASSUME_NONNULL_END +#endif diff --git a/keychain/ot/OTAuthenticatedCiphertext+SF.m b/keychain/ot/OTAuthenticatedCiphertext+SF.m new file mode 100644 index 00000000..10ee1063 --- /dev/null +++ b/keychain/ot/OTAuthenticatedCiphertext+SF.m @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import "OTAuthenticatedCiphertext+SF.h" + +@implementation OTAuthenticatedCiphertext (SecurityFoundation) + ++ (instancetype)fromSFAuthenticatedCiphertext:(SFAuthenticatedCiphertext *)cipher +{ + OTAuthenticatedCiphertext *obj = [OTAuthenticatedCiphertext new]; + obj.ciphertext = cipher.ciphertext; + obj.authenticationCode = cipher.authenticationCode; + obj.initializationVector = cipher.initializationVector; + return obj; +} + +- (SFAuthenticatedCiphertext *)asSFAuthenticatedCiphertext +{ + return [[SFAuthenticatedCiphertext alloc] initWithCiphertext:self.ciphertext + authenticationCode:self.authenticationCode + initializationVector:self.initializationVector]; +} + +@end + +#endif diff --git a/keychain/ot/OTBottledPeer.h b/keychain/ot/OTBottledPeer.h new file mode 100644 index 00000000..3d84714c --- /dev/null +++ b/keychain/ot/OTBottledPeer.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON +#import +#import + +#import "OTEscrowKeys.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTBottledPeer : NSObject + +@property (nonatomic, readonly) NSString* peerID; +@property (nonatomic, readonly) NSString* spID; +@property (nonatomic, readonly) SFECKeyPair* peerSigningKey; +@property (nonatomic, readonly) SFECKeyPair* peerEncryptionKey; +@property (nonatomic, readonly) NSData* data; + +// Given a peer's details including private key material, and +// the keys generated from the escrow secret, encrypt the peer private keys, +// make a bottled peer object and serialize it into data. +- (nullable instancetype) initWithPeerID:(NSString * _Nullable)peerID + spID:(NSString * _Nullable)spID + peerSigningKey:(SFECKeyPair *)peerSigningKey + peerEncryptionKey:(SFECKeyPair *)peerEncryptionKey + escrowKeys:(OTEscrowKeys *)escrowKeys + error:(NSError**)error; + +// Deserialize a bottle and decrypt the contents (peer keys) +// using the keys generated from the escrow secret. +- (nullable instancetype) initWithData:(NSData *)data + escrowKeys:(OTEscrowKeys *)escrowKeys + error:(NSError**)error; + +@end +NS_ASSUME_NONNULL_END + +#endif diff --git a/keychain/ot/OTBottledPeer.m b/keychain/ot/OTBottledPeer.m new file mode 100644 index 00000000..0d3992d5 --- /dev/null +++ b/keychain/ot/OTBottledPeer.m @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import "OTBottledPeer.h" + +#if OCTAGON +#import +#import +#import +#import +#import + +#import + +#import +#import +#import + +#import + +#import + +#import "OTBottle.h" +#import "OTBottleContents.h" +#import "OTDefines.h" +#import "OTPrivateKey.h" +#import "OTPrivateKey+SF.h" +#import "OTAuthenticatedCiphertext.h" +#import "OTAuthenticatedCiphertext+SF.h" +#import "SFPublicKey+SPKI.h" + +@interface OTBottledPeer () + +@property (nonatomic, strong) NSString* peerID; +@property (nonatomic, strong) NSString* spID; +@property (nonatomic, strong) SFECKeyPair* peerSigningKey; +@property (nonatomic, strong) SFECKeyPair* peerEncryptionKey; +@property (nonatomic, strong) NSData* data; + +@end + +@implementation OTBottledPeer + ++ (SFAuthenticatedEncryptionOperation *) encryptionOperation +{ + SFAESKeySpecifier *keySpecifier = [[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256]; + return [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:keySpecifier]; +} + +// Given a peer's details including private key material, and +// the keys generated from the escrow secret, encrypt the peer private keys, +// make a bottled peer object and serialize it into data. +- (nullable instancetype) initWithPeerID:(NSString * _Nullable)peerID + spID:(NSString * _Nullable)spID + peerSigningKey:(SFECKeyPair *)peerSigningKey + peerEncryptionKey:(SFECKeyPair *)peerEncryptionKey + escrowKeys:(OTEscrowKeys *)escrowKeys + error:(NSError**)error +{ + self = [super init]; + if (self) { + // Serialize the peer private keys into "contents" + OTBottleContents *contentsObj = [[OTBottleContents alloc] init]; + contentsObj.peerSigningPrivKey = [OTPrivateKey fromECKeyPair:peerSigningKey]; + contentsObj.peerEncryptionPrivKey = [OTPrivateKey fromECKeyPair:peerEncryptionKey]; + NSData *clearContentsData = contentsObj.data; + + // Encrypt the contents + SFAuthenticatedEncryptionOperation *op = [OTBottledPeer encryptionOperation]; + SFAuthenticatedCiphertext* cipher = [op encrypt:clearContentsData withKey:escrowKeys.symmetricKey error:error]; + if (!cipher) { + return nil; + } + + // Serialize the whole thing + OTBottle *obj = [[OTBottle alloc] init]; + obj.peerID = peerID; + obj.spID = spID; + obj.escrowedSigningSPKI = [escrowKeys.signingKey.publicKey asSPKI]; + obj.escrowedEncryptionSPKI = [escrowKeys.encryptionKey.publicKey asSPKI]; + obj.peerSigningSPKI = [peerSigningKey.publicKey asSPKI]; + obj.peerEncryptionSPKI = [peerEncryptionKey.publicKey asSPKI]; + obj.contents = [OTAuthenticatedCiphertext fromSFAuthenticatedCiphertext:cipher]; + + _peerID = [peerID copy]; + _spID = [spID copy]; + _peerSigningKey = peerSigningKey; + _peerEncryptionKey = peerEncryptionKey; + _data = obj.data; + } + return self; +} + +// Deserialize a bottle and decrypt the contents (peer keys) +// using the keys generated from the escrow secret. +- (nullable instancetype) initWithData:(NSData *)data + escrowKeys:(OTEscrowKeys *)escrowKeys + error:(NSError**)error +{ + self = [super init]; + if (self) { + NSError* localError =nil; + + // Deserialize the whole thing + OTBottle *obj = [[OTBottle alloc] initWithData:data]; + if (!obj) { + secerror("octagon: failed to deserialize data into OTBottle"); + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorDeserializationFailure userInfo:@{NSLocalizedDescriptionKey: @"Failed to deserialize bottle peer"}]; + } + return nil; + } + + // Decrypt contents + SFAuthenticatedEncryptionOperation *op = [OTBottledPeer encryptionOperation]; + SFAuthenticatedCiphertext* ciphertext = [obj.contents asSFAuthenticatedCiphertext]; + NSData* clearContentsData = [op decrypt:ciphertext withKey:escrowKeys.symmetricKey error:&localError]; + if (!clearContentsData || clearContentsData.length == 0) { + secerror("octagon: could not decrypt bottle contents: %@", localError); + if(error){ + *error = localError; + } + return nil; + } + + // Deserialize contents into private peer keys + OTBottleContents *contentsObj = [[OTBottleContents alloc] initWithData:clearContentsData]; + if (!contentsObj) { + secerror("octagon: could not deserialize bottle contents"); + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorDeserializationFailure userInfo:@{NSLocalizedDescriptionKey: @"Failed to deserialize bottle contents"}]; + } + return nil; + } + + _peerID = obj.peerID; + _spID = obj.spID; + _peerSigningKey = [contentsObj.peerSigningPrivKey asECKeyPair]; + _peerEncryptionKey = [contentsObj.peerEncryptionPrivKey asECKeyPair]; + if (!_peerSigningKey || !_peerEncryptionKey) { + secerror("octagon: could not get private EC keys from bottle contents"); + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorPrivateKeyFailure userInfo:@{NSLocalizedDescriptionKey: @"Failed to instantiate octagon peer keys"}]; + } + return nil; + } + _data = [data copy]; + + SFECPublicKey *peerSigningPubKey = [SFECPublicKey fromSPKI:obj.peerSigningSPKI]; + SFECPublicKey *peerEncryptionPubKey = [SFECPublicKey fromSPKI:obj.peerEncryptionSPKI]; + + // Check the private keys match the public keys + if (![_peerSigningKey.publicKey isEqual:peerSigningPubKey]) { + secerror("octagon: public and private peer signing keys do not match"); + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorPrivateKeyFailure userInfo:@{NSLocalizedDescriptionKey: @"public and private peer signing keys do not match"}]; + } + return nil; + } + if (![_peerEncryptionKey.publicKey isEqual:peerEncryptionPubKey]) { + secerror("octagon: public and private peer encryption keys do not match"); + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorPrivateKeyFailure userInfo:@{NSLocalizedDescriptionKey: @"public and private peer encryption keys do not match"}]; + } + return nil; + } + + } + return self; +} + +@end + +#endif + + diff --git a/keychain/ot/OTBottledPeerRecord.h b/keychain/ot/OTBottledPeerRecord.h new file mode 100644 index 00000000..43c7802d --- /dev/null +++ b/keychain/ot/OTBottledPeerRecord.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import + +@interface OTBottledPeerRecord : NSObject + +@property (nonatomic, strong) NSString* peerID; +@property (nonatomic, strong) NSString* spID; +@property (nonatomic, strong) NSData* bottle; +@property (nonatomic, strong) NSString* escrowRecordID; +@property (nonatomic, strong) NSData* escrowedSigningSPKI; +@property (nonatomic, strong) NSData* peerSigningSPKI; +@property (nonatomic, strong) NSData* signatureUsingEscrowKey; +@property (nonatomic, strong) NSData* signatureUsingPeerKey; +@property (nonatomic, strong) NSData* encodedRecord; +@property (nonatomic, readonly) NSString* recordName; +@property (nonatomic, strong) NSString* launched; + ++ (NSString*) constructRecordID:(NSString*)escrowRecordID escrowSigningSPKI:(NSData*)escrowSigningSPKI; + +@end + diff --git a/keychain/ot/OTBottledPeerRecord.m b/keychain/ot/OTBottledPeerRecord.m new file mode 100644 index 00000000..b7646eef --- /dev/null +++ b/keychain/ot/OTBottledPeerRecord.m @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +#import "OTBottledPeerRecord.h" +#import +#import +#import + +static NSString* OTCKRecordName = @"bp-"; + +@implementation OTBottledPeerRecord + +-(NSString*) recordName +{ + return [OTBottledPeerRecord constructRecordID:self.escrowRecordID escrowSigningSPKI:self.escrowedSigningSPKI]; +} + ++ (NSString*) constructRecordID:(NSString*)escrowRecordID escrowSigningSPKI:(NSData*)escrowSigningSPKI +{ + const struct ccdigest_info *di = ccsha384_di(); + NSMutableData* result = [[NSMutableData alloc] initWithLength:ccsha384_di()->output_size]; + + ccdigest(di, [escrowSigningSPKI length], [escrowSigningSPKI bytes], [result mutableBytes]); + + NSString* hash = [result base64EncodedStringWithOptions:0]; + + return [NSString stringWithFormat:@"%@-spid:%@-%@", OTCKRecordName, escrowRecordID, hash]; +} + +@end diff --git a/keychain/ot/OTBottledPeerSigned.h b/keychain/ot/OTBottledPeerSigned.h new file mode 100644 index 00000000..c21599e2 --- /dev/null +++ b/keychain/ot/OTBottledPeerSigned.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON +#import +#import "OTBottledPeer.h" +#import "OTBottledPeerRecord.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTBottledPeerSigned : NSObject +@property (nonatomic, readonly) OTBottledPeer* bp; +@property (nonatomic, readonly) NSData* signatureUsingEscrowKey; +@property (nonatomic, readonly) NSData* signatureUsingPeerKey; +@property (nonatomic, readonly) NSData* escrowSigningSPKI; + +- (instancetype) init NS_UNAVAILABLE; + +// Create signatures +- (nullable instancetype) initWithBottledPeer:(OTBottledPeer*)bp + escrowedSigningKey:(SFECKeyPair *)escrowedSigningKey + peerSigningKey:(SFECKeyPair *)peerSigningKey + error:(NSError**)error; + +// Verify signatures, or return nil +- (nullable instancetype) initWithBottledPeer:(OTBottledPeer*)bp + signatureUsingEscrow:(NSData*)signatureUsingEscrow + signatureUsingPeerKey:(NSData*)signatureUsingPeerKey + escrowedSigningPubKey:(SFECPublicKey *)escrowedSigningPubKey + error:(NSError**)error; + +// Convenience wrapper, verifies signatures +- (nullable instancetype) initWithBottledPeerRecord:(OTBottledPeerRecord *)record + escrowKeys:(OTEscrowKeys *)escrowKeys + error:(NSError**)error; + +- (OTBottledPeerRecord *)asRecord:(NSString*)escrowRecordID; ++ (BOOL) verifyBottleSignature:(NSData*)data signature:(NSData*)signature key:(_SFECPublicKey*) pubKey error:(NSError**)error; + +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/keychain/ot/OTBottledPeerSigned.m b/keychain/ot/OTBottledPeerSigned.m new file mode 100644 index 00000000..a639fe73 --- /dev/null +++ b/keychain/ot/OTBottledPeerSigned.m @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON +#import +#import "OTBottledPeer.h" +#import "OTBottledPeerSigned.h" +#import "SFPublicKey+SPKI.h" +#import "OTIdentity.h" + +#import +#import +#import +#import +#import + +#import +#import +#import + +#include + +@interface OTBottledPeerSigned () +@property (nonatomic, strong) OTBottledPeer* bp; +@property (nonatomic, strong) NSData* signatureUsingEscrowKey; +@property (nonatomic, strong) NSData* signatureUsingPeerKey; +@property (nonatomic, strong) NSData* escrowSigningPublicKey; +@end + +@implementation OTBottledPeerSigned + +// Create signatures +- (nullable instancetype) initWithBottledPeer:(OTBottledPeer*)bp + escrowedSigningKey:(SFECKeyPair *)escrowedSigningKey + peerSigningKey:(SFECKeyPair *)peerSigningKey + error:(NSError**)error +{ + self = [super init]; + if (self) { + _bp = bp; + _escrowSigningSPKI = [escrowedSigningKey.publicKey asSPKI]; + SFEC_X962SigningOperation* xso = [OTBottledPeerSigned signingOperation]; + _signatureUsingEscrowKey = [xso sign:bp.data withKey:escrowedSigningKey error:error].signature; + if (!_signatureUsingEscrowKey) { + return nil; + } + _signatureUsingPeerKey = [xso sign:bp.data withKey:peerSigningKey error:error].signature; + if (!_signatureUsingPeerKey) { + return nil; + } + } + return self; +} + +-(NSString*) escrowSigningPublicKeyHash +{ + const struct ccdigest_info *di = ccsha384_di(); + NSMutableData* result = [[NSMutableData alloc] initWithLength:ccsha384_di()->output_size]; + + ccdigest(di, [self.escrowSigningPublicKey length], [self.escrowSigningPublicKey bytes], [result mutableBytes]); + + return [result base64EncodedStringWithOptions:0]; +} + +// Verify signatures, or return nil +- (nullable instancetype) initWithBottledPeer:(OTBottledPeer*)bp + signatureUsingEscrow:(NSData*)signatureUsingEscrow + signatureUsingPeerKey:(NSData*)signatureUsingPeerKey + escrowedSigningPubKey:(SFECPublicKey *)escrowedSigningPubKey + error:(NSError**)error +{ + self = [super init]; + if (self) { + _bp = bp; + _escrowSigningSPKI = [escrowedSigningPubKey asSPKI]; + _signatureUsingPeerKey = signatureUsingPeerKey; + _signatureUsingEscrowKey = signatureUsingEscrow; + _escrowSigningPublicKey = [escrowedSigningPubKey keyData]; + + SFEC_X962SigningOperation* xso = [OTBottledPeerSigned signingOperation]; + + SFSignedData *escrowSigned = [[SFSignedData alloc] initWithData:bp.data signature:signatureUsingEscrow]; + if (![xso verify:escrowSigned withKey:escrowedSigningPubKey error:error]) { + return nil; + } + SFSignedData *peerSigned = [[SFSignedData alloc] initWithData:bp.data signature:signatureUsingPeerKey]; + if (![xso verify:peerSigned withKey:bp.peerSigningKey.publicKey error:error]) { + return nil; + } + //stuff restored keys in the keychain + [OTIdentity storeOctagonIdentityIntoKeychain:self.bp.peerSigningKey restoredEncryptionKey:self.bp.peerEncryptionKey escrowSigningPubKeyHash:self.escrowSigningPublicKeyHash restoredPeerID:self.bp.spID error:error]; + } + return self; +} + ++ (SFEC_X962SigningOperation*) signingOperation +{ + SFECKeySpecifier *keySpecifier = [[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]; + id digestOperation = [[SFSHA384DigestOperation alloc] init]; + return [[SFEC_X962SigningOperation alloc] initWithKeySpecifier:keySpecifier digestOperation:digestOperation]; +} + ++ (BOOL) verifyBottleSignature:(NSData*)data signature:(NSData*)signature key:(_SFECPublicKey*) pubKey error:(NSError**)error +{ + SFEC_X962SigningOperation* xso = [OTBottledPeerSigned signingOperation]; + + SFSignedData *peerSigned = [[SFSignedData alloc] initWithData:data signature:signature]; + + return ([xso verify:peerSigned withKey:pubKey error:error] != nil); + +} + +- (nullable instancetype) initWithBottledPeerRecord:(OTBottledPeerRecord *)record + escrowKeys:(OTEscrowKeys *)escrowKeys + error:(NSError**)error +{ + OTBottledPeer *bp = [[OTBottledPeer alloc] initWithData:record.bottle + escrowKeys:escrowKeys + error:error]; + if (!bp) { + return nil; + } + return [self initWithBottledPeer:bp + signatureUsingEscrow:record.signatureUsingEscrowKey + signatureUsingPeerKey:record.signatureUsingPeerKey + escrowedSigningPubKey:escrowKeys.signingKey.publicKey + error:error]; +} + +- (OTBottledPeerRecord *)asRecord:(NSString*)escrowRecordID +{ + OTBottledPeerRecord *rec = [[OTBottledPeerRecord alloc] init]; + rec.spID = self.bp.spID; + rec.escrowRecordID = [escrowRecordID copy]; + rec.peerSigningSPKI = [self.bp.peerSigningKey.publicKey asSPKI]; + rec.escrowedSigningSPKI = self.escrowSigningSPKI; + rec.bottle = self.bp.data; + rec.signatureUsingPeerKey = self.signatureUsingPeerKey; + rec.signatureUsingEscrowKey = self.signatureUsingEscrowKey; + rec.launched = @"NO"; + return rec; +} + +@end +#endif + diff --git a/keychain/ot/OTCloudStore.h b/keychain/ot/OTCloudStore.h new file mode 100644 index 00000000..0670aa8b --- /dev/null +++ b/keychain/ot/OTCloudStore.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#ifndef OTCloudStore_h +#define OTCloudStore_h + +#if OCTAGON +#import "keychain/ot/OTLocalStore.h" + +#import +#import + +#import "keychain/ckks/CKKSZone.h" +#import "keychain/ckks/CloudKitDependencies.h" +#import "keychain/ckks/CKKSCondition.h" +#import "keychain/ckks/CKKSZoneChangeFetcher.h" +#import "keychain/ckks/CKKSNotifier.h" +#import "keychain/ckks/CKKSSQLDatabaseObject.h" +#import "keychain/ckks/CKKSRecordHolder.h" +#import "OTBottledPeerRecord.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTCloudStore : CKKSZone + +@property (nonatomic, readonly) NSString* contextID; +@property (nonatomic, readonly) NSString* dsid; +@property (nonatomic, readonly) NSString* containerName; +@property (nonatomic, readonly) CKRecordID* recordID; +@property (nonatomic, readonly) CKKSResultOperation* viewSetupOperation; +@property CKKSCondition* loggedIn; +@property CKKSCondition* loggedOut; + + +- (instancetype) initWithContainer:(CKContainer*) container + zoneName:(NSString*)zoneName + accountTracker:(nullable CKKSCKAccountStateTracker*)tracker + reachabilityTracker:(nullable CKKSReachabilityTracker*)reachabilityTracker + localStore:(OTLocalStore*)localStore + contextID:(NSString*)contextID + dsid:(NSString*)dsid +fetchRecordZoneChangesOperationClass:(Class) fetchRecordZoneChangesOperationClass + fetchRecordsOperationClass:(Class)fetchRecordsOperationClass + queryOperationClass:(Class)queryOperationClass + modifySubscriptionsOperationClass:(Class) modifySubscriptionsOperationClass + modifyRecordZonesOperationClass:(Class) modifyRecordZonesOperationClass + apsConnectionClass:(Class) apsConnectionClass + operationQueue:(nullable NSOperationQueue *)operationQueue; + + +- (BOOL) uploadBottledPeerRecord:(OTBottledPeerRecord *)bprecord + escrowRecordID:(NSString *)escrowRecordID + error:(NSError**)error; +- (BOOL) downloadBottledPeerRecord:(NSError**)error; +- (BOOL) removeBottledPeerRecordID:(CKRecordID*)recordID error:(NSError**)error; +- (nullable NSArray*) retrieveListOfEligibleEscrowRecordIDs:(NSError**)error; + +- (void)notifyZoneChange:(CKRecordZoneNotification* _Nullable)notification; +- (void)handleCKLogin; +- (BOOL) performReset:(NSError**)error; + +@end + +NS_ASSUME_NONNULL_END +#endif +#endif /* OTCloudStore_h */ diff --git a/keychain/ot/OTCloudStore.m b/keychain/ot/OTCloudStore.m new file mode 100644 index 00000000..ccecbaca --- /dev/null +++ b/keychain/ot/OTCloudStore.m @@ -0,0 +1,763 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#if OCTAGON + +#import +#import + +#import "keychain/ot/OTCloudStore.h" +#import "keychain/ot/OTCloudStoreState.h" +#import "keychain/ckks/CKKSZoneStateEntry.h" +#import "keychain/ckks/CKKS.h" +#import "keychain/ot/OTDefines.h" +#import "keychain/ckks/CKKSReachabilityTracker.h" +#import + + +NS_ASSUME_NONNULL_BEGIN + +/* Octagon Trust Local Context Record Constants */ +static NSString* OTCKRecordContextID = @"contextID"; +static NSString* OTCKRecordDSID = @"accountDSID"; +static NSString* OTCKRecordContextName = @"contextName"; +static NSString* OTCKRecordZoneCreated = @"zoneCreated"; +static NSString* OTCKRecordSubscribedToChanges = @"subscribedToChanges"; +static NSString* OTCKRecordChangeToken = @"changeToken"; +static NSString* OTCKRecordEgoPeerID = @"egoPeerID"; +static NSString* OTCKRecordEgoPeerCreationDate = @"egoPeerCreationDate"; +static NSString* OTCKRecordRecoverySigningSPKI = @"recoverySigningSPKI"; +static NSString* OTCKRecordRecoveryEncryptionSPKI = @"recoveryEncryptionSPKI"; +static NSString* OTCKRecordBottledPeerTableEntry = @"bottledPeer"; + +/* Octagon Trust Local Peer Record */ +static NSString* OTCKRecordPeerID = @"peerID"; +static NSString* OTCKRecordPermanentInfo = @"permanentInfo"; +static NSString* OTCKRecordStableInfo = @"stableInfo"; +static NSString* OTCKRecordDynamicInfo = @"dynamicInfo"; +static NSString* OTCKRecordRecoveryVoucher = @"recoveryVoucher"; +static NSString* OTCKRecordIsEgoPeer = @"isEgoPeer"; + +/* Octagon Trust BottledPeerSchema */ +static NSString* OTCKRecordEscrowRecordID = @"escrowRecordID"; +static NSString* OTCKRecordBottle = @"bottle"; +static NSString* OTCKRecordSPID = @"spID"; +static NSString* OTCKRecordEscrowSigningSPKI = @"escrowSigningSPKI"; +static NSString* OTCKRecordPeerSigningSPKI = @"peerSigningSPKI"; +static NSString* OTCKRecordSignatureFromEscrow = @"signatureUsingEscrow"; +static NSString* OTCKRecordSignatureFromPeerKey = @"signatureUsingPeerKey"; +static NSString* OTCKRecordEncodedRecord = @"encodedRecord"; + +/* Octagon Table Names */ +static NSString* const contextTable = @"context"; +static NSString* const peerTable = @"peer"; +static NSString* const bottledPeerTable = @"bp"; + +/* Octagon Trust Schemas */ +static NSString* const octagonZoneName = @"OctagonTrustZone"; + +/* Octagon Cloud Kit defines */ +static NSString* OTCKContainerName = @"com.apple.security.keychain"; +static NSString* OTCKZoneName = @"OctagonTrust"; +static NSString* OTCKRecordName = @"bp-"; +static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; + +@interface OTCloudStore () +@property (nonatomic, strong) NSString* dsid; +@property (nonatomic, strong) NSString* containerName; +@property (nonatomic, strong) CKModifyRecordsOperation* modifyRecordsOperation; +@property (nonatomic, strong) CKDatabaseOperation* fetchRecordZoneChangesOperation; +@property (nonatomic, strong) NSOperationQueue *operationQueue; +@property (nonatomic, strong) OTLocalStore* localStore; +@property (nonatomic, strong) CKKSResultOperation* viewSetupOperation; +@property (nonatomic, strong) NSError* error; +@end + +@class CKKSAPSReceiver; + +@interface OTCloudStore() + +@property CKDatabaseOperation* zoneCreationOperation; +@property CKDatabaseOperation* zoneDeletionOperation; +@property CKDatabaseOperation* zoneSubscriptionOperation; + +@property NSOperation* accountLoggedInDependency; + +@property NSHashTable* accountOperations; +@end + +@implementation OTCloudStore + +- (instancetype) initWithContainer:(CKContainer*) container + zoneName:(NSString*)zoneName + accountTracker:(nullable CKKSCKAccountStateTracker*)accountTracker + reachabilityTracker:(nullable CKKSReachabilityTracker*)reachabilityTracker + localStore:(OTLocalStore*)localStore + contextID:(NSString*)contextID + dsid:(NSString*)dsid +fetchRecordZoneChangesOperationClass:(Class) fetchRecordZoneChangesOperationClass + fetchRecordsOperationClass:(Class)fetchRecordsOperationClass + queryOperationClass:(Class)queryOperationClass + modifySubscriptionsOperationClass:(Class) modifySubscriptionsOperationClass + modifyRecordZonesOperationClass:(Class) modifyRecordZonesOperationClass + apsConnectionClass:(Class) apsConnectionClass + operationQueue:(nullable NSOperationQueue *)operationQueue +{ + + self = [super initWithContainer:container + zoneName:zoneName + accountTracker:accountTracker + reachabilityTracker:reachabilityTracker +fetchRecordZoneChangesOperationClass:fetchRecordZoneChangesOperationClass + fetchRecordsOperationClass:fetchRecordsOperationClass + queryOperationClass:queryOperationClass + modifySubscriptionsOperationClass:modifySubscriptionsOperationClass + modifyRecordZonesOperationClass:modifyRecordZonesOperationClass + apsConnectionClass:apsConnectionClass]; + + if(self){ + if (!operationQueue) { + operationQueue = [[NSOperationQueue alloc] init]; + } + _contextID = [contextID copy]; + _localStore = localStore; + _containerName = OTCKContainerName; + _dsid = [dsid copy]; + _operationQueue = operationQueue; + self.queue = dispatch_queue_create([[NSString stringWithFormat:@"OctagonTrustQueue.%@.zone.%@", container.containerIdentifier, zoneName] UTF8String], DISPATCH_QUEUE_SERIAL); + [self initializeZone]; + } + return self; + +} + +-(CKKSResultOperation*) otFetchAndProcessUpdates +{ + CKKSResultOperation* fetchOp = [CKKSResultOperation named:@"fetch-and-process-updates-watcher" withBlock:^{}]; + + __weak __typeof(self) weakSelf = self; + + [self dispatchSync: ^bool{ + + OTCloudStoreState* state = [OTCloudStoreState state: self.zoneName]; + + CKFetchRecordZoneChangesOptions* options = [[CKFetchRecordZoneChangesOptions alloc] init]; + options.previousServerChangeToken = state.changeToken; + + self.fetchRecordZoneChangesOperation = [[[self.fetchRecordZoneChangesOperationClass class] alloc] initWithRecordZoneIDs:@[self.zoneID] optionsByRecordZoneID:@{self.zoneID : options}]; + + self.fetchRecordZoneChangesOperation.recordChangedBlock = ^(CKRecord *record) { + secinfo("octagon", "CloudKit notification: record changed(%@): %@", [record recordType], record); + __strong __typeof(weakSelf) strongSelf = weakSelf; + + if(!strongSelf) { + secnotice("octagon", "received callback for released object"); + fetchOp.error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTCloudStore userInfo:@{NSLocalizedDescriptionKey: @"received callback for released object"}]; + + fetchOp.descriptionErrorCode = CKKSResultDescriptionPendingBottledPeerFetchRecords; + + return; + } + if ([record.recordType isEqualToString:OTCKRecordBottledPeerType]) { + NSError* localError = nil; + + //write to localStore + OTBottledPeerRecord *rec = [[OTBottledPeerRecord alloc] init]; + rec.bottle = record[OTCKRecordBottle]; + rec.spID = record[OTCKRecordSPID]; + rec.escrowRecordID = record[OTCKRecordEscrowRecordID]; + rec.escrowedSigningSPKI = record[OTCKRecordEscrowSigningSPKI]; + rec.peerSigningSPKI = record[OTCKRecordPeerSigningSPKI]; + rec.signatureUsingEscrowKey = record[OTCKRecordSignatureFromEscrow]; + rec.signatureUsingPeerKey = record[OTCKRecordSignatureFromPeerKey]; + rec.encodedRecord = [strongSelf recordToData:record]; + rec.launched = @"YES"; + BOOL result = [strongSelf.localStore insertBottledPeerRecord:rec escrowRecordID:record[OTCKRecordEscrowRecordID] error:&localError]; + if(!result || localError){ + secerror("Could not write bottled peer record:%@ to database: %@", record.recordID.recordName, localError); + fetchOp.error = localError; + fetchOp.descriptionErrorCode = CKKSResultDescriptionPendingBottledPeerFetchRecords; + + } + secnotice("octagon", "fetched changes: %@", record); + } + }; + + self.fetchRecordZoneChangesOperation.recordWithIDWasDeletedBlock = ^(CKRecordID *RecordID, NSString *recordType) { + secinfo("octagon", "CloudKit notification: deleted record(%@): %@", recordType, RecordID); + }; + + self.fetchRecordZoneChangesOperation.recordZoneChangeTokensUpdatedBlock = ^(CKRecordZoneID *recordZoneID, CKServerChangeToken *serverChangeToken, NSData *clientChangeTokenData) { + __strong __typeof(weakSelf) strongSelf = weakSelf; + NSError* error = nil; + OTCloudStoreState* state = [OTCloudStoreState state: strongSelf.zoneName]; + secdebug("octagon", "Received a new server change token: %@ %@", serverChangeToken, clientChangeTokenData); + state.changeToken = serverChangeToken; + + if(error) { + secerror("octagon: Couldn't save new server change token: %@", error); + fetchOp.error = error; + fetchOp.descriptionErrorCode = CKKSResultDescriptionPendingBottledPeerFetchRecords; + } + }; + + // Completion blocks don't count for dependencies. Use this intermediate operation hack instead. + NSBlockOperation* recordZoneChangesCompletedOperation = [[NSBlockOperation alloc] init]; + self.fetchRecordZoneChangesOperation.recordZoneFetchCompletionBlock = ^(CKRecordZoneID *recordZoneID, CKServerChangeToken *serverChangeToken, NSData *clientChangeTokenData, BOOL moreComing, NSError * recordZoneError) { + __strong __typeof(weakSelf) strongSelf = weakSelf; + if(!strongSelf) { + secnotice("octagon", "received callback for released object"); + return; + } + if(recordZoneError) { + secerror("octagon: FetchRecordZoneChanges(%@) error: %@", strongSelf.zoneName, recordZoneError); + fetchOp.error = recordZoneError; + fetchOp.descriptionErrorCode = CKKSResultDescriptionPendingBottledPeerFetchRecords; + } + + // TODO: fetch state here + if(serverChangeToken) { + NSError* error = nil; + secdebug("octagon", "Zone change fetch complete: received a new server change token: %@ %@", serverChangeToken, clientChangeTokenData); + state.changeToken = serverChangeToken; + if(error) { + secerror("octagon: Couldn't save new server change token: %@", error); + fetchOp.error = error; + fetchOp.descriptionErrorCode = CKKSResultDescriptionPendingBottledPeerFetchRecords; + } + } + secdebug("octagon", "Record zone fetch complete: changeToken=%@ error=%@", serverChangeToken, recordZoneError); + + [strongSelf.operationQueue addOperation: recordZoneChangesCompletedOperation]; + [strongSelf.operationQueue addOperation: fetchOp]; + + }; + self.fetchRecordZoneChangesOperation.fetchRecordZoneChangesCompletionBlock = ^(NSError * _Nullable operationError) { + __strong __typeof(weakSelf) strongSelf = weakSelf; + if(!strongSelf) { + secnotice("octagon", "received callback for released object"); + fetchOp.error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTCloudStore userInfo:@{NSLocalizedDescriptionKey: @"received callback for released object"}]; + fetchOp.descriptionErrorCode = CKKSResultDescriptionPendingBottledPeerFetchRecords; + return; + } + secnotice("octagon", "Record zone changes fetch complete: error=%@", operationError); + }; + return true; + }]; + [self.database addOperation: self.fetchRecordZoneChangesOperation]; + + return fetchOp; +} + + +- (void)notifyZoneChange:(CKRecordZoneNotification* _Nullable)notification +{ + secnotice("octagon", "received notify zone change. notification: %@", notification); + + CKKSResultOperation* op = [CKKSResultOperation named:@"cloudkit-fetch-and-process-changes" withBlock:^{}]; + + [op addSuccessDependency: [self otFetchAndProcessUpdates]]; + + [op timeout:(SecCKKSTestsEnabled() ? 2*NSEC_PER_SEC : 120*NSEC_PER_SEC)]; + [self.operationQueue addOperation: op]; + + [op waitUntilFinished]; + if(op.error != nil) { + secerror("octagon: failed to fetch changes error:%@", op.error); + } + else{ + secnotice("octagon", "downloaded bottled peer records"); + } +} + +-(BOOL) downloadBottledPeerRecord:(NSError**)error +{ + secnotice("octagon", "downloadBottledPeerRecord"); + BOOL result = NO; + CKKSResultOperation* op = [CKKSResultOperation named:@"cloudkit-fetch-and-process-changes" withBlock:^{}]; + + [op addSuccessDependency: [self otFetchAndProcessUpdates]]; + + [op timeout:(SecCKKSTestsEnabled() ? 2*NSEC_PER_SEC : 120*NSEC_PER_SEC)]; + [self.operationQueue addOperation: op]; + + [op waitUntilFinished]; + if(op.error != nil) { + secerror("octagon: failed to fetch changes error:%@", op.error); + if(error){ + *error = op.error; + } + } + else{ + result = YES; + secnotice("octagon", "downloaded bottled peer records"); + } + return result; +} + +- (nullable NSArray*) retrieveListOfEligibleEscrowRecordIDs:(NSError**)error +{ + NSError* localError = nil; + + NSMutableArray* recordIDs = [NSMutableArray array]; + + //fetch any recent changes first before gathering escrow record ids + CKKSResultOperation* op = [CKKSResultOperation named:@"cloudkit-fetch-and-process-changes" withBlock:^{}]; + + secnotice("octagon", "Beginning CloudKit fetch"); + [op addSuccessDependency: [self otFetchAndProcessUpdates]]; + + [op timeout:(SecCKKSTestsEnabled() ? 2*NSEC_PER_SEC : 120*NSEC_PER_SEC)]; + [self.operationQueue addOperation: op]; + + [op waitUntilFinished]; + if(op.error != nil) { + secerror("octagon: failed to fetch changes error:%@", op.error); + if(error){ + *error = op.error; + } + return nil; + } + NSArray* localStoreBottledPeerRecords = [self.localStore readAllLocalBottledPeerRecords:&localError]; + if(!localStoreBottledPeerRecords) + { + secerror("octagon: local store contains no bottled peer entries: %@", localError); + if(error){ + *error = localError; + } + return nil; + } + for(OTBottledPeerRecord* entry in localStoreBottledPeerRecords){ + NSString* escrowID = entry.escrowRecordID; + if(escrowID && ![recordIDs containsObject:escrowID]){ + [recordIDs addObject:escrowID]; + } + } + + return recordIDs; +} + +-(CKRecord*) dataToRecord:(NSData*)encodedRecord +{ + NSKeyedUnarchiver *coder = [[NSKeyedUnarchiver alloc] initForReadingFromData:encodedRecord error:nil]; + CKRecord* record = [[CKRecord alloc] initWithCoder:coder]; + [coder finishDecoding]; + return record; +} + +-(NSData*) recordToData:(CKRecord*)record +{ + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; + [record encodeWithCoder:archiver]; + [archiver finishEncoding]; + + return archiver.encodedData; +} + +-( CKRecord* _Nullable ) CKRecordFromMirror:(CKRecordID*)recordID bpRecord:(OTBottledPeerRecord*)bprecord escrowRecordID:(NSString*)escrowRecordID error:(NSError**)error +{ + CKRecord* record = nil; + + OTBottledPeerRecord* recordFromDB = [self.localStore readLocalBottledPeerRecordWithRecordID:recordID.recordName error:error]; + if(recordFromDB && recordFromDB.encodedRecord != nil){ + record = [self dataToRecord:recordFromDB.encodedRecord]; + } + else{ + record = [[CKRecord alloc] initWithRecordType:OTCKRecordBottledPeerType recordID:recordID]; + } + + if(record == nil){ + secerror("octagon: failed to create cloud kit record"); + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTCloudStore userInfo:@{NSLocalizedDescriptionKey: @"failed to create cloud kit record"}]; + } + return nil; + } + record[OTCKRecordPeerID] = bprecord.peerID; + record[OTCKRecordSPID] = bprecord.spID; + record[OTCKRecordEscrowSigningSPKI] = bprecord.escrowedSigningSPKI; + record[OTCKRecordPeerSigningSPKI] = bprecord.peerSigningSPKI; + record[OTCKRecordEscrowRecordID] = escrowRecordID; + record[OTCKRecordBottle] = bprecord.bottle; + record[OTCKRecordSignatureFromEscrow] = bprecord.signatureUsingEscrowKey; + record[OTCKRecordSignatureFromPeerKey] = bprecord.signatureUsingPeerKey; + + return record; +} + +-(CKKSResultOperation*) modifyRecords:(NSArray*) recordsToSave deleteRecordIDs:(NSArray*) recordIDsToDelete +{ + __weak __typeof(self) weakSelf = self; + CKKSResultOperation* modifyOp = [CKKSResultOperation named:@"modify-records-watcher" withBlock:^{}]; + + [self dispatchSync: ^bool{ + self.modifyRecordsOperation = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:recordsToSave recordIDsToDelete:recordIDsToDelete]; + + self.modifyRecordsOperation.atomic = YES; + self.modifyRecordsOperation.longLived = NO; // The keys are only in memory; mark this explicitly not long-lived + self.modifyRecordsOperation.qualityOfService = NSQualityOfServiceUserInitiated; // Currently done during buddy. User is waiting. + self.modifyRecordsOperation.savePolicy = CKRecordSaveIfServerRecordUnchanged; + + self.modifyRecordsOperation.perRecordCompletionBlock = ^(CKRecord *record, NSError * _Nullable error) { + // These should all fail or succeed as one. Do the hard work in the records completion block. + if(!error) { + secnotice("octagon", "Successfully completed upload for %@", record.recordID.recordName); + + } else { + secerror("octagon: error on row: %@ %@", record.recordID.recordName, error); + modifyOp.error = error; + modifyOp.descriptionErrorCode = CKKSResultDescriptionPendingBottledPeerModifyRecords; + [weakSelf.operationQueue addOperation:modifyOp]; + } + }; + self.modifyRecordsOperation.modifyRecordsCompletionBlock = ^(NSArray *savedRecords, NSArray *deletedRecordIDs, NSError *error) { + secnotice("octagon", "Completed trust update"); + __strong __typeof(weakSelf) strongSelf = weakSelf; + + if(error){ + modifyOp.error = error; + modifyOp.descriptionErrorCode = CKKSResultDescriptionPendingBottledPeerModifyRecords; + secerror("octagon: received error from cloudkit: %@", error); + if([error.domain isEqualToString:CKErrorDomain] && (error.code == CKErrorPartialFailure)) { + NSMutableDictionary* failedRecords = error.userInfo[CKPartialErrorsByItemIDKey]; + ckksnotice("octagon", strongSelf, "failed records %@", failedRecords); + } + return; + } + if(!strongSelf) { + secerror("octagon: received callback for released object"); + modifyOp.error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTCloudStore userInfo:@{NSLocalizedDescriptionKey: @"received callback for released object"}]; + modifyOp.descriptionErrorCode = CKKSResultDescriptionPendingBottledPeerModifyRecords; + [strongSelf.operationQueue addOperation:modifyOp]; + return; + } + + if(savedRecords && [savedRecords count] > 0){ + for(CKRecord* record in savedRecords){ + NSError* localError = nil; + secnotice("octagon", "saving recordID: %@ changeToken:%@", record.recordID.recordName, record.recordChangeTag); + + //write to localStore + OTBottledPeerRecord *rec = [[OTBottledPeerRecord alloc] init]; + rec.bottle = record[OTCKRecordBottle]; + rec.spID = record[OTCKRecordSPID]; + rec.escrowRecordID = record[OTCKRecordEscrowRecordID]; + rec.signatureUsingEscrowKey = record[OTCKRecordSignatureFromEscrow]; + rec.signatureUsingPeerKey = record[OTCKRecordSignatureFromPeerKey]; + rec.encodedRecord = [strongSelf recordToData:record]; + rec.launched = @"YES"; + rec.escrowedSigningSPKI = record[OTCKRecordEscrowSigningSPKI]; + rec.peerSigningSPKI = record[OTCKRecordPeerSigningSPKI]; + + BOOL result = [strongSelf.localStore insertBottledPeerRecord:rec escrowRecordID:record[OTCKRecordEscrowRecordID] error:&localError]; + + if(!result || localError){ + secerror("Could not write bottled peer record:%@ to database: %@", record.recordID.recordName, localError); + } + + if(localError){ + secerror("octagon: could not save to database: %@", localError); + modifyOp.error = localError; + modifyOp.descriptionErrorCode = CKKSResultDescriptionPendingBottledPeerModifyRecords; + } + } + } + else if(deletedRecordIDs && [deletedRecordIDs count] >0){ + for(CKRecordID* recordID in deletedRecordIDs){ + secnotice("octagon", "removed recordID: %@", recordID); + NSError* localError = nil; + BOOL result = [strongSelf.localStore deleteBottledPeer:recordID.recordName error:&localError]; + if(!result){ + secerror("octagon: could not remove record id: %@, error:%@", recordID, localError); + modifyOp.error = localError; + modifyOp.descriptionErrorCode = CKKSResultDescriptionPendingBottledPeerModifyRecords; + } + } + } + [strongSelf.operationQueue addOperation:modifyOp]; + }; + return true; + }]; + + [self.database addOperation: self.modifyRecordsOperation]; + return modifyOp; +} + +- (BOOL) uploadBottledPeerRecord:(OTBottledPeerRecord *)bprecord + escrowRecordID:(NSString *)escrowRecordID + error:(NSError**)error +{ + secnotice("octagon", "sending bottled peer to cloudkit"); + BOOL result = YES; + + CKRecordID* recordID = [[CKRecordID alloc] initWithRecordName:bprecord.recordName zoneID:self.zoneID]; + CKRecord *record = [self CKRecordFromMirror:recordID bpRecord:bprecord escrowRecordID:escrowRecordID error:error]; + + if(!record){ + return NO; + } + CKKSResultOperation* op = [CKKSResultOperation named:@"cloudkit-modify-changes" withBlock:^{}]; + + secnotice("octagon", "Beginning CloudKit ModifyRecords"); + [op addSuccessDependency: [self modifyRecords:@[ record ] deleteRecordIDs:@[]]]; + + [op timeout:(SecCKKSTestsEnabled() ? 2*NSEC_PER_SEC : 120*NSEC_PER_SEC)]; + [self.operationQueue addOperation: op]; + + [op waitUntilFinished]; + if(op.error != nil) { + secerror("octagon: failed to commit record changes error:%@", op.error); + if(error){ + *error = op.error; + } + return NO; + } + secnotice("octagon", "successfully uploaded record: %@", bprecord.recordName); + return result; +} + +-(BOOL) removeBottledPeerRecordID:(CKRecordID*)recordID error:(NSError**)error +{ + secnotice("octagon", "removing bottled peer from cloudkit"); + BOOL result = YES; + + NSMutableArray* recordIDsToRemove = [[NSMutableArray alloc] init]; + [recordIDsToRemove addObject:recordID]; + + CKKSResultOperation* op = [CKKSResultOperation named:@"cloudkit-modify-changes" withBlock:^{}]; + + secnotice("octagon", "Beginning CloudKit ModifyRecords"); + [op addSuccessDependency: [self modifyRecords:[NSMutableArray array] deleteRecordIDs:recordIDsToRemove]]; + + [op timeout:(SecCKKSTestsEnabled() ? 2*NSEC_PER_SEC : 120*NSEC_PER_SEC)]; + [self.operationQueue addOperation: op]; + + [op waitUntilFinished]; + if(op.error != nil) { + secerror("octagon: ailed to commit record changes error:%@", op.error); + if(error){ + *error = op.error; + } + return NO; + } + + return result; +} + +- (void)_onqueueHandleCKLogin { + if(!SecCKKSIsEnabled()) { + ckksnotice("ckks", self, "Skipping CloudKit initialization due to disabled CKKS"); + return; + } + + dispatch_assert_queue(self.queue); + + __weak __typeof(self) weakSelf = self; + + CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state: self.zoneName]; + [self handleCKLogin:ckse.ckzonecreated zoneSubscribed:ckse.ckzonesubscribed]; + + self.viewSetupOperation = [CKKSResultOperation operationWithBlock: ^{ + __strong __typeof(weakSelf) strongSelf = weakSelf; + if(!strongSelf) { + ckkserror("ckks", strongSelf, "received callback for released object"); + return; + } + + __block bool quit = false; + + [strongSelf dispatchSync: ^bool { + ckksnotice("octagon", strongSelf, "Zone setup progress: %@ %d %@ %d %@", + [CKKSCKAccountStateTracker stringFromAccountStatus:strongSelf.accountStatus], + strongSelf.zoneCreated, strongSelf.zoneCreatedError, strongSelf.zoneSubscribed, strongSelf.zoneSubscribedError); + + NSError* error = nil; + CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state: strongSelf.zoneName]; + ckse.ckzonecreated = strongSelf.zoneCreated; + ckse.ckzonesubscribed = strongSelf.zoneSubscribed; + + // Although, if the zone subscribed error says there's no zone, mark down that there's no zone + if(strongSelf.zoneSubscribedError && + [strongSelf.zoneSubscribedError.domain isEqualToString:CKErrorDomain] && strongSelf.zoneSubscribedError.code == CKErrorPartialFailure) { + NSError* subscriptionError = strongSelf.zoneSubscribedError.userInfo[CKPartialErrorsByItemIDKey][strongSelf.zoneID]; + if(subscriptionError && [subscriptionError.domain isEqualToString:CKErrorDomain] && subscriptionError.code == CKErrorZoneNotFound) { + + ckkserror("octagon", strongSelf, "zone subscription error appears to say the zone doesn't exist, fixing status: %@", strongSelf.zoneSubscribedError); + ckse.ckzonecreated = false; + } + } + + [ckse saveToDatabase: &error]; + if(error) { + ckkserror("octagon", strongSelf, "couldn't save zone creation status for %@: %@", strongSelf.zoneName, error); + } + + if(!strongSelf.zoneCreated || !strongSelf.zoneSubscribed || strongSelf.accountStatus != CKAccountStatusAvailable) { + // Something has gone very wrong. Error out and maybe retry. + quit = true; + + // Note that CKKSZone has probably called [handleLogout]; which means we have a key hierarchy reset queued up. Error here anyway. + NSError* realReason = strongSelf.zoneCreatedError ? strongSelf.zoneCreatedError : strongSelf.zoneSubscribedError; + strongSelf.viewSetupOperation.error = realReason; + + + return true; + } + + return true; + }]; + + if(quit) { + ckkserror("octagon", strongSelf, "Quitting setup."); + return; + } + }]; + self.viewSetupOperation.name = @"zone-setup"; + + [self.viewSetupOperation addNullableDependency: self.zoneSetupOperation]; + [self scheduleAccountStatusOperation: self.viewSetupOperation]; +} + +- (void)handleCKLogin +{ + ckksinfo("octagon", self, "received a notification of CK login"); + + __weak __typeof(self) weakSelf = self; + CKKSResultOperation* login = [CKKSResultOperation named:@"octagon-login" withBlock:^{ + __strong __typeof(self) strongSelf = weakSelf; + + [strongSelf dispatchSync:^bool{ + strongSelf.accountStatus = CKKSAccountStatusAvailable; + [strongSelf _onqueueHandleCKLogin]; + return true; + }]; + }]; + + [self scheduleAccountStatusOperation:login]; +} + +- (bool)_onqueueResetLocalData: (NSError * __autoreleasing *) error { + dispatch_assert_queue(self.queue); + + NSError* localerror = nil; + bool setError = false; + + CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state: self.zoneName]; + ckse.ckzonecreated = false; + ckse.ckzonesubscribed = false; + ckse.changeToken = NULL; + [ckse saveToDatabase: &localerror]; + if(localerror) { + ckkserror("ckks", self, "couldn't reset zone status for %@: %@", self.zoneName, localerror); + if(error && !setError) { + *error = localerror; setError = true; + } + } + + BOOL result = [_localStore removeAllBottledPeerRecords:&localerror]; + if(!result){ + *error = localerror; + secerror("octagon: failed to move all bottled peer entries for context: %@ error: %@", self.contextID, localerror); + } + return (localerror == nil && !setError); +} + +-(CKKSResultOperation*) resetOctagonTrustZone:(NSError**)error +{ + // On a reset, we should cancel all existing operations + [self cancelAllOperations]; + CKKSResultOperation* reset = [super deleteCloudKitZoneOperation:nil]; + [self scheduleOperationWithoutDependencies:reset]; + + __weak __typeof(self) weakSelf = self; + CKKSGroupOperation* resetFollowUp = [[CKKSGroupOperation alloc] init]; + resetFollowUp.name = @"cloudkit-reset-follow-up-group"; + + [resetFollowUp runBeforeGroupFinished: [CKKSResultOperation named:@"cloudkit-reset-follow-up" withBlock: ^{ + __strong __typeof(weakSelf) strongSelf = weakSelf; + if(!strongSelf) { + ckkserror("octagon", strongSelf, "received callback for released object"); + return; + } + + if(!reset.error) { + ckksnotice("octagon", strongSelf, "Successfully deleted zone %@", strongSelf.zoneName); + __block NSError* error = nil; + + [strongSelf dispatchSync: ^bool{ + [strongSelf _onqueueResetLocalData: &error]; + return true; + }]; + } else { + // Shouldn't ever happen, since reset is a successDependency + ckkserror("ckks", strongSelf, "Couldn't reset zone %@: %@", strongSelf.zoneName, reset.error); + } + }]]; + + [resetFollowUp addSuccessDependency:reset]; + [self scheduleOperationWithoutDependencies:resetFollowUp]; + + return reset; +} + +-(BOOL) performReset:(NSError**)error +{ + BOOL result = NO; + CKKSResultOperation* op = [CKKSResultOperation named:@"cloudkit-reset-zones-waiter" withBlock:^{}]; + + secnotice("octagon", "Beginning CloudKit reset for Octagon Trust"); + [op addSuccessDependency:[self resetOctagonTrustZone:error]]; + + [op timeout:(SecCKKSTestsEnabled() ? 2*NSEC_PER_SEC : 120*NSEC_PER_SEC)]; + [self.operationQueue addOperation: op]; + + [op waitUntilFinished]; + if(!op.error) { + secnotice("octagon", "Completed rpcResetCloudKit"); + __weak __typeof(self) weakSelf = self; + CKKSResultOperation* login = [CKKSResultOperation named:@"octagon-login" withBlock:^{ + __strong __typeof(self) strongSelf = weakSelf; + + [strongSelf dispatchSync:^bool{ + strongSelf.accountStatus = CKKSAccountStatusAvailable; + [strongSelf handleCKLogin:false zoneSubscribed:false]; + return true; + }]; + }]; + + [self.operationQueue addOperation:login]; + result = YES; + } else { + secnotice("octagon", "Completed rpcResetCloudKit with error: %@", op.error); + if(error){ + *error = op.error; + } + } + + return result; +} + +@end + +NS_ASSUME_NONNULL_END +#endif + diff --git a/keychain/ot/OTCloudStoreState.h b/keychain/ot/OTCloudStoreState.h new file mode 100644 index 00000000..915a3200 --- /dev/null +++ b/keychain/ot/OTCloudStoreState.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef OTCloudStoreState_h +#define OTCloudStoreState_h + +#if OCTAGON +#import "keychain/ckks/CKKSSQLDatabaseObject.h" + +@interface OTCloudStoreState : CKKSSQLDatabaseObject + +@property NSString* ckzone; +@property bool ckzonecreated; +@property bool ckzonesubscribed; +@property (getter=getChangeToken, setter=setChangeToken:) CKServerChangeToken* changeToken; +@property NSData* encodedChangeToken; +@property NSDate* lastFetchTime; + ++ (instancetype)state:(NSString*)ckzone; + ++ (instancetype)fromDatabase:(NSString*)ckzone error:(NSError* __autoreleasing*)error; ++ (instancetype)tryFromDatabase:(NSString*)ckzone error:(NSError* __autoreleasing*)error; + +- (instancetype)initWithCKZone:(NSString*)ckzone + zoneCreated:(bool)ckzonecreated + zoneSubscribed:(bool)ckzonesubscribed + changeToken:(NSData*)changetoken + lastFetch:(NSDate*)lastFetch; + +- (CKServerChangeToken*)getChangeToken; +- (void)setChangeToken:(CKServerChangeToken*)token; + +- (BOOL)isEqual:(id)object; +@end + +#endif +#endif /* OTCloudStoreState_h */ diff --git a/keychain/ot/OTCloudStoreState.m b/keychain/ot/OTCloudStoreState.m new file mode 100644 index 00000000..3c119dc7 --- /dev/null +++ b/keychain/ot/OTCloudStoreState.m @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2016 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include + +#import +#import + +#import "CKKSKeychainView.h" + +#include +#include +#include + +#if OCTAGON + +#import +#import "OTCloudStoreState.h" + +@implementation OTCloudStoreState + +- (instancetype)initWithCKZone:(NSString*)ckzone + zoneCreated:(bool)ckzonecreated + zoneSubscribed:(bool)ckzonesubscribed + changeToken:(NSData*)changetoken + lastFetch:(NSDate*)lastFetch +{ + if(self = [super init]) { + _ckzone = [ckzone copy]; + _ckzonecreated = ckzonecreated; + _ckzonesubscribed = ckzonesubscribed; + _encodedChangeToken = [changetoken copy]; + _lastFetchTime = [lastFetch copy]; + } + return self; +} + +- (BOOL)isEqual: (id) object { + if(![object isKindOfClass:[OTCloudStoreState class]]) { + return NO; + } + + OTCloudStoreState* obj = (OTCloudStoreState*) object; + + return ([self.ckzone isEqualToString: obj.ckzone] && + self.ckzonecreated == obj.ckzonecreated && + self.ckzonesubscribed == obj.ckzonesubscribed && + ((self.encodedChangeToken == nil && obj.encodedChangeToken == nil) || [self.encodedChangeToken isEqual: obj.encodedChangeToken]) && + ((self.lastFetchTime == nil && obj.lastFetchTime == nil) || [self.lastFetchTime isEqualToDate: obj.lastFetchTime]) && + true) ? YES : NO; +} + ++ (instancetype) state: (NSString*) ckzone { + NSError* error = nil; + OTCloudStoreState* ret = [OTCloudStoreState tryFromDatabase:ckzone error:&error]; + + if(error) { + secerror("octagon: error fetching CKState(%@): %@", ckzone, error); + } + + if(!ret) { + ret = [[OTCloudStoreState alloc] initWithCKZone:ckzone + zoneCreated:false + zoneSubscribed:false + changeToken:nil + lastFetch:nil]; + } + return ret; +} + +- (CKServerChangeToken*) getChangeToken { + if(self.encodedChangeToken) { + NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:self.encodedChangeToken error:nil]; + return [unarchiver decodeObjectOfClass:[CKServerChangeToken class] forKey:NSKeyedArchiveRootObjectKey]; + } else { + return nil; + } +} + +- (void) setChangeToken: (CKServerChangeToken*) token { + self.encodedChangeToken = token ? [NSKeyedArchiver archivedDataWithRootObject:token requiringSecureCoding:YES error:nil] : nil; +} + +#pragma mark - Database Operations + ++ (instancetype) fromDatabase: (NSString*) ckzone error: (NSError * __autoreleasing *) error { + return [self fromDatabaseWhere: @{@"ckzone": CKKSNilToNSNull(ckzone)} error: error]; +} + ++ (instancetype) tryFromDatabase: (NSString*) ckzone error: (NSError * __autoreleasing *) error { + return [self tryFromDatabaseWhere: @{@"ckzone": CKKSNilToNSNull(ckzone)} error: error]; +} + +#pragma mark - CKKSSQLDatabaseObject methods + ++ (NSString*) sqlTable { + return @"ckstate"; +} + ++ (NSArray*) sqlColumns { + return @[@"ckzone", @"ckzonecreated", @"ckzonesubscribed", @"changetoken", @"lastfetch", @"ratelimiter", @"lastFixup"]; +} + +- (NSDictionary*) whereClauseToFindSelf { + return @{@"ckzone": self.ckzone}; +} + +- (NSDictionary*) sqlValues { + NSISO8601DateFormatter* dateFormat = [[NSISO8601DateFormatter alloc] init]; + + return @{@"ckzone": self.ckzone, + @"ckzonecreated": [NSNumber numberWithBool:self.ckzonecreated], + @"ckzonesubscribed": [NSNumber numberWithBool:self.ckzonesubscribed], + @"changetoken": CKKSNilToNSNull([self.encodedChangeToken base64EncodedStringWithOptions:0]), + @"lastfetch": CKKSNilToNSNull(self.lastFetchTime ? [dateFormat stringFromDate: self.lastFetchTime] : nil), + }; +} + ++ (instancetype) fromDatabaseRow: (NSDictionary*) row { + NSISO8601DateFormatter* dateFormat = [[NSISO8601DateFormatter alloc] init]; + + return [[OTCloudStoreState alloc] initWithCKZone: row[@"ckzone"] + zoneCreated: [row[@"ckzonecreated"] boolValue] + zoneSubscribed: [row[@"ckzonesubscribed"] boolValue] + changeToken: ![row[@"changetoken"] isEqual: [NSNull null]] ? + [[NSData alloc] initWithBase64EncodedString: row[@"changetoken"] options:0] : + nil + lastFetch: [row[@"lastfetch"] isEqual: [NSNull null]] ? nil : [dateFormat dateFromString: row[@"lastfetch"]] + ]; +} + +@end + +#endif //OTCloudStoreState + diff --git a/keychain/ot/OTConstants.h b/keychain/ot/OTConstants.h new file mode 100644 index 00000000..5b3010c3 --- /dev/null +++ b/keychain/ot/OTConstants.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef OTConstants_h +#define OTConstants_h + +#import + +extern NSString* OTDefaultContext; + +#endif /* OTConstants_h */ diff --git a/keychain/ot/OTConstants.m b/keychain/ot/OTConstants.m new file mode 100644 index 00000000..5e2e40f2 --- /dev/null +++ b/keychain/ot/OTConstants.m @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import "OTConstants.h" + +NSString* OTDefaultContext = @"defaultContext"; + + diff --git a/keychain/ot/OTContext.h b/keychain/ot/OTContext.h new file mode 100644 index 00000000..52b33e7b --- /dev/null +++ b/keychain/ot/OTContext.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON +#import +#import "OTLocalStore.h" +#import "OTCloudStore.h" +#import "OTEscrowKeys.h" +#import "OTIdentity.h" +#import "OTBottledPeer.h" +#import "OTBottledPeerSigned.h" +#import "OTRamping.h" +#import "OTDefines.h" +#import "OTPreflightInfo.h" +#import "keychain/ckks/CKKSLockStateTracker.h" + +NS_ASSUME_NONNULL_BEGIN + +@protocol OTContextIdentityProvider +- (nullable OTIdentity *) currentIdentity:(NSError**) error; +@end + + +@interface OTContext : NSObject + +@property (nonatomic, readonly) NSString* contextID; +@property (nonatomic, readonly) NSString* dsid; +@property (nonatomic, readonly) OTCloudStore* cloudStore; + +@property (nonatomic, readonly) CKKSLockStateTracker* lockStateTracker; +@property (nonatomic, readonly) CKKSCKAccountStateTracker* accountTracker; +@property (nonatomic, readonly) CKKSReachabilityTracker *reachabilityTracker; + +- (nullable instancetype) initWithContextID:(NSString*)contextID + dsid:(NSString*)dsid + localStore:(OTLocalStore*)localStore + cloudStore:(nullable OTCloudStore*)cloudStore + identityProvider:(id )identityProvider + error:(NSError**)error; + +- (nullable OTBottledPeerSigned *) restoreFromEscrowRecordID:(NSString*)escrowRecordID + secret:(NSData*)secret + error:(NSError**)error; + +- (NSData* _Nullable) makeMeSomeEntropy:(int)requiredLength; +- (nullable OTPreflightInfo*) preflightBottledPeer:(NSString*)contextID + entropy:(NSData*)entropy + error:(NSError**)error; +- (BOOL)scrubBottledPeer:(NSString*)contextID + bottleID:(NSString*)bottleID + error:(NSError**)error; + +-(OctagonBottleCheckState)doesThisDeviceHaveABottle:(NSError**)error; +-(void) postFollowUp; + +@end +NS_ASSUME_NONNULL_END +#endif + diff --git a/keychain/ot/OTContext.m b/keychain/ot/OTContext.m new file mode 100644 index 00000000..479d8878 --- /dev/null +++ b/keychain/ot/OTContext.m @@ -0,0 +1,557 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#if OCTAGON + +#import "OTContext.h" +#import "SFPublicKey+SPKI.h" + +#include +#include + +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSViewManager.h" +#import "keychain/ckks/CKKSAnalytics.h" + +#import "CoreCDP/CDPFollowUpController.h" +#import "CoreCDP/CDPFollowUpContext.h" +#import + +NSString* OTCKContainerName = @"com.apple.security.keychain"; +NSString* OTCKZoneName = @"OctagonTrust"; +static NSString* const kOTRampZoneName = @"metadata_zone"; + +@interface OTContext (lockstateTracker) +@end + +@interface OTContext () + +@property (nonatomic, strong) NSString* contextID; +@property (nonatomic, strong) NSString* contextName; +@property (nonatomic, strong) NSString* dsid; + +@property (nonatomic, strong) OTLocalStore* localStore; +@property (nonatomic, strong) OTCloudStore* cloudStore; +@property (nonatomic, strong) NSData* changeToken; +@property (nonatomic, strong) NSString* egoPeerID; +@property (nonatomic, strong) NSDate* egoPeerCreationDate; +@property (nonatomic, strong) dispatch_queue_t queue; +@property (nonatomic, weak) id identityProvider; + +@property (nonatomic, strong) CKKSCKAccountStateTracker* accountTracker; +@property (nonatomic, strong) CKKSLockStateTracker* lockStateTracker; +@property (nonatomic, strong) CKKSReachabilityTracker *reachabilityTracker; + +@end + +@implementation OTContext + +-(CKContainer*)makeCKContainer:(NSString*)containerName { + CKContainer* container = [CKContainer containerWithIdentifier:containerName]; + container = [[CKContainer alloc] initWithContainerID: container.containerID]; + return container; +} + +-(BOOL) isPrequeliteEnabled +{ + BOOL result = YES; + if([PQLConnection class] == nil) { + secerror("OT: prequelite appears to not be linked. Can't create OT objects."); + result = NO; + } + return result; +} + +- (nullable instancetype) initWithContextID:(NSString*)contextID + dsid:(NSString*)dsid + localStore:(OTLocalStore*)localStore + cloudStore:(nullable OTCloudStore*)cloudStore + identityProvider:(id )identityProvider + error:(NSError**)error +{ + if(![self isPrequeliteEnabled]){ + // We're running in the base build environment, which lacks a bunch of libraries. + // We don't support doing anything in this environment. Bye. + return nil; + } + + self = [super init]; + if (self) { + NSError* localError = nil; + _contextID = contextID; + _dsid = dsid; + _identityProvider = identityProvider; + _localStore = localStore; + + NSString* contextAndDSID = [NSString stringWithFormat:@"%@-%@", contextID, dsid]; + + CKContainer* container = [self makeCKContainer:OTCKContainerName]; + + _accountTracker = [CKKSViewManager manager].accountTracker; + _lockStateTracker = [CKKSViewManager manager].lockStateTracker; + _reachabilityTracker = [CKKSViewManager manager].reachabilityTracker; + + if(!cloudStore) { + _cloudStore = [[OTCloudStore alloc]initWithContainer:container + zoneName:OTCKZoneName + accountTracker:_accountTracker + reachabilityTracker:_reachabilityTracker + localStore:_localStore + contextID:contextID + dsid:dsid + fetchRecordZoneChangesOperationClass:[CKFetchRecordZoneChangesOperation class] + fetchRecordsOperationClass:[CKFetchRecordsOperation class] + queryOperationClass:[CKQueryOperation class] + modifySubscriptionsOperationClass:[CKModifySubscriptionsOperation class] + modifyRecordZonesOperationClass:[CKModifyRecordZonesOperation class] + apsConnectionClass:[APSConnection class] + operationQueue:nil]; + } else{ + _cloudStore = cloudStore; + } + + OTContextRecord* localContextRecord = [_localStore readLocalContextRecordForContextIDAndDSID:contextAndDSID error:&localError]; + + if(localContextRecord == nil || localContextRecord.contextID == nil){ + localError = nil; + BOOL result = [_localStore initializeContextTable:contextID dsid:dsid error:&localError]; + if(!result || localError != nil){ + secerror("octagon: reading from database failed with error: %@", localError); + if (error) { + *error = localError; + } + return nil; + } + localContextRecord = [_localStore readLocalContextRecordForContextIDAndDSID:contextAndDSID error:&localError]; + if(localContextRecord == nil || localError !=nil){ + secerror("octagon: reading from database failed with error: %@", localError); + if (error) { + *error = localError; + } + return nil; + } + } + + _contextID = localContextRecord.contextID; + _contextName = localContextRecord.contextName; + _changeToken = localContextRecord.changeToken; + _egoPeerID = localContextRecord.egoPeerID; + _egoPeerCreationDate = localContextRecord.egoPeerCreationDate; + + _queue = dispatch_queue_create("com.apple.security.otcontext", DISPATCH_QUEUE_SERIAL); + } + return self; +} + +- (nullable OTBottledPeerSigned *) createBottledPeerRecordForIdentity:(OTIdentity *)identity + secret:(NSData*)secret + error:(NSError**)error +{ + NSError* localError = nil; + if(self.lockStateTracker.isLocked){ + secnotice("octagon", "device is locked"); + if(error){ + *error = [NSError errorWithDomain:(__bridge NSString*)kSecErrorDomain code:errSecInteractionNotAllowed userInfo:nil]; + } + return nil; + } + + OTEscrowKeys *escrowKeys = [[OTEscrowKeys alloc] initWithSecret:secret dsid:self.dsid error:&localError]; + if (!escrowKeys || localError != nil) { + secerror("octagon: unable to derive escrow keys: %@", localError); + if (error) { + *error = localError; + } + return nil; + } + + OTBottledPeer *bp = [[OTBottledPeer alloc] initWithPeerID:identity.peerID + spID:identity.spID + peerSigningKey:identity.peerSigningKey + peerEncryptionKey:identity.peerEncryptionKey + escrowKeys:escrowKeys + error:&localError]; + if (!bp || localError !=nil) { + secerror("octagon: unable to create a bottled peer: %@", localError); + if (error) { + *error = localError; + } + return nil; + } + return [[OTBottledPeerSigned alloc] initWithBottledPeer:bp + escrowedSigningKey:escrowKeys.signingKey + peerSigningKey:identity.peerSigningKey + error:error]; +} + +- (NSData* _Nullable) makeMeSomeEntropy:(int)requiredLength +{ + NSMutableData* salt = [NSMutableData dataWithLength:requiredLength]; + if (salt == nil){ + return nil; + } + if (SecRandomCopyBytes(kSecRandomDefault, [salt length], [salt mutableBytes]) != 0){ + return nil; + } + return salt; +} + +- (nullable OTPreflightInfo*) preflightBottledPeer:(NSString*)contextID + entropy:(NSData*)entropy + error:(NSError**)error +{ + NSError* localError = nil; + if(self.lockStateTracker.isLocked){ + secnotice("octagon", "device is locked"); + if(error){ + *error = [NSError errorWithDomain:(__bridge NSString*)kSecErrorDomain code:errSecInteractionNotAllowed userInfo:nil]; + } + return nil; + } + + OTIdentity *identity = [self.identityProvider currentIdentity:&localError]; + if (!identity || localError != nil) { + secerror("octagon: unable to get current identity:%@", localError); + if (error) { + *error = localError; + } + return nil; + } + + OTBottledPeerSigned* bps = [self createBottledPeerRecordForIdentity:identity + secret:entropy + error:&localError]; + if (!bps || localError != nil) { + secerror("octagon: failed to create bottled peer record: %@", localError); + if (error) { + *error = localError; + } + return nil; + } + secnotice("octagon", "created bottled peer:%@", bps); + + OTBottledPeerRecord *bprec = [bps asRecord:identity.spID]; + + if (!identity.spID) { + secerror("octagon: cannot enroll without a spID"); + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorNoIdentity userInfo:@{NSLocalizedDescriptionKey: @"OTIdentity does not have an SOS peer id"}]; + } + return nil; + } + + OTPreflightInfo* info = [[OTPreflightInfo alloc]init]; + info.escrowedSigningSPKI = bprec.escrowedSigningSPKI; + + if(!info.escrowedSigningSPKI){ + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorEscrowSigningSPKI userInfo:@{NSLocalizedDescriptionKey: @"Escrowed spinging SPKI is nil"}]; + } + secerror("octagon: Escrowed spinging SPKI is nil"); + return nil; + } + + info.bottleID = bprec.recordName; + if(!info.bottleID){ + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorBottleID userInfo:@{NSLocalizedDescriptionKey: @"BottleID is nil"}]; + } + secerror("octagon: BottleID is nil"); + return nil; + } + + //store record in localStore + BOOL result = [self.localStore insertBottledPeerRecord:bprec escrowRecordID:identity.spID error:&localError]; + if(!result || localError){ + secerror("octagon: could not persist the bottle record: %@", localError); + if (error) { + *error = localError; + } + return nil; + } + + return info; +} + +- (BOOL)scrubBottledPeer:(NSString*)contextID + bottleID:(NSString*)bottleID + error:(NSError**)error +{ + secnotice("octagon", "scrubBottledPeer"); + NSError* localError = nil; + if(self.lockStateTracker.isLocked){ + secnotice("octagon", "device is locked"); + if(error){ + *error = [NSError errorWithDomain:(__bridge NSString*)kSecErrorDomain code:errSecInteractionNotAllowed userInfo:nil]; + } + return YES; + } + + BOOL result = [self.localStore deleteBottledPeer:bottleID error:&localError]; + if(!result || localError != nil){ + secerror("octagon: could not remove record for bottleID %@, error:%@", bottleID, localError); + if (error) { + *error = localError; + } + } + return result; +} + +- (OTBottledPeerSigned *) restoreFromEscrowRecordID:(NSString*)escrowRecordID + secret:(NSData*)secret + error:(NSError**)error +{ + NSError *localError = nil; + + if(self.lockStateTracker.isLocked){ + if(error){ + *error = [NSError errorWithDomain:(__bridge NSString*)kSecErrorDomain code:errSecInteractionNotAllowed userInfo:nil]; + } + return nil; + } + + OTEscrowKeys *escrowKeys = [[OTEscrowKeys alloc] initWithSecret:secret dsid:self.dsid error:&localError]; + if (!escrowKeys || localError != nil) { + secerror("unable to derive escrow keys: %@", localError); + if (error) { + *error = localError; + } + return nil; + } + + BOOL result = [self.cloudStore downloadBottledPeerRecord:&localError]; + if(!result || localError){ + secerror("octagon: could not download bottled peer record:%@", localError); + if(error){ + *error = localError; + } + } + NSString* recordName = [OTBottledPeerRecord constructRecordID:escrowRecordID + escrowSigningSPKI:[escrowKeys.signingKey.publicKey asSPKI]]; + OTBottledPeerRecord* rec = [self.localStore readLocalBottledPeerRecordWithRecordID:recordName error:&localError]; + + if (!rec) { + secerror("octagon: could not read bottled peer record:%@", localError); + if (error) { + *error = localError; + } + return nil; + } + + OTBottledPeerSigned *bps = [[OTBottledPeerSigned alloc] initWithBottledPeerRecord:rec + escrowKeys:escrowKeys + error:&localError]; + if (!bps) { + secerror("octagon: could not unpack bottled peer:%@", localError); + if (error) { + *error = localError; + } + return nil; + } + + return bps; +} + +-(BOOL)bottleExistsLocallyForIdentity:(OTIdentity*)identity logger:(CKKSAnalytics*)logger error:(NSError**)error +{ + NSError* localError = nil; + //read all the local bp records + NSArray* bottles = [self.localStore readLocalBottledPeerRecordsWithMatchingPeerID:identity.spID error:&localError]; + if(!bottles || [bottles count] == 0 || localError != nil){ + secerror("octagon: there are no eligible bottle peer records: %@", localError); + [logger logRecoverableError:localError + forEvent:OctagonEventBottleCheck + zoneName:kOTRampZoneName + withAttributes:NULL]; + if(error){ + *error = localError; + } + return NO; + } + + BOOL hasBottle = NO; + //if check all the records if the peer signing public key matches the bottled one! + for(OTBottledPeerRecord* bottle in bottles){ + NSData* bottledSigningSPKIData = [[SFECPublicKey fromSPKI:bottle.peerSigningSPKI] keyData]; + NSData* currentIdentitySPKIData = [identity.peerSigningKey.publicKey keyData]; + + //spIDs are the same AND check bottle signature + if([currentIdentitySPKIData isEqualToData:bottledSigningSPKIData] && + [OTBottledPeerSigned verifyBottleSignature:bottle.bottle + signature:bottle.signatureUsingPeerKey + key:identity.peerSigningKey.publicKey + error:error]){ + hasBottle = YES; + } + } + + + + return hasBottle; +} + +-(BOOL)queryCloudKitForBottle:(OTIdentity*)identity logger:(CKKSAnalytics*)logger error:(NSError**)error +{ + NSError* localError = nil; + BOOL hasBottle = NO; + //attempt to pull down all the records, but continue checking local store even if this fails. + BOOL fetched = [self.cloudStore downloadBottledPeerRecord:&localError]; + if(fetched == NO || localError != nil){ //couldn't download bottles + secerror("octagon: 0 bottled peers downloaded: %@", localError); + [logger logRecoverableError:localError + forEvent:OctagonEventBottleCheck + zoneName:kOTRampZoneName + withAttributes:NULL]; + if(error){ + *error = localError; + } + return NO; + }else{ //downloaded bottles, let's check local store + hasBottle = [self bottleExistsLocallyForIdentity:identity logger:logger error:&localError]; + } + + if(error){ + *error = localError; + } + return hasBottle; +} + +-(OctagonBottleCheckState) doesThisDeviceHaveABottle:(NSError**)error +{ + secnotice("octagon", "checking if device has enrolled a bottle"); + + if(self.lockStateTracker.isLocked){ + secnotice("octagon", "device locked, not checking for bottle"); + if(error){ + *error = [NSError errorWithDomain:(__bridge NSString*)kSecErrorDomain code:errSecInteractionNotAllowed userInfo:nil]; + } + return UNCLEAR; + } + + if(self.accountTracker.currentCKAccountInfo.accountStatus != CKAccountStatusAvailable){ + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain + code:OTErrorNotSignedIn + userInfo:@{NSLocalizedDescriptionKey: @"iCloud account is logged out"}]; + } + secnotice("octagon", "not logged into an account"); + return UNCLEAR; + } + + NSError* localError = nil; + OctagonBottleCheckState bottleStatus = NOBOTTLE; + CKKSAnalytics* logger = [CKKSAnalytics logger]; + SFAnalyticsActivityTracker *tracker = [logger logSystemMetricsForActivityNamed:CKKSActivityBottleCheck withAction:nil]; + [tracker start]; + + //get our current identity + OTIdentity* identity = [self.identityProvider currentIdentity:&localError]; + + //if we get the locked error, return true so we don't prompt the user + if(localError && [_lockStateTracker isLockedError:localError]){ + secnotice("octagon", "attempting to perform bottle check while locked: %@", localError); + return UNCLEAR; + } + + if(!identity && localError != nil){ + secerror("octagon: do not have an identity: %@", localError); + [logger logRecoverableError:localError + forEvent:OctagonEventBottleCheck + zoneName:kOTRampZoneName + withAttributes:NULL]; + [tracker stop]; + if(error){ + *error = localError; + } + return NOBOTTLE; + } + + //check locally first + BOOL bottleExistsLocally = [self bottleExistsLocallyForIdentity:identity logger:logger error:&localError]; + + //no bottle and we have no network + if(!bottleExistsLocally && !self.reachabilityTracker.currentReachability){ + secnotice("octagon", "no network, can't query"); + localError = [NSError errorWithDomain:octagonErrorDomain + code:OTErrorNoNetwork + userInfo:@{NSLocalizedDescriptionKey: @"no network"}]; + [tracker stop]; + if(error){ + *error = localError; + } + return UNCLEAR; + } + else if(!bottleExistsLocally){ + if([self queryCloudKitForBottle:identity logger:logger error:&localError]){ + bottleStatus = BOTTLE; + } + }else if(bottleExistsLocally){ + bottleStatus = BOTTLE; + } + + if(bottleStatus == NOBOTTLE){ + localError = [NSError errorWithDomain:octagonErrorDomain code:OTErrorNoBottlePeerRecords userInfo:@{NSLocalizedDescriptionKey: @"Peer %@ does not have any bottled records"}]; + secerror("octagon: this device does not have any bottled peers: %@", localError); + [logger logRecoverableError:localError + forEvent:OctagonEventBottleCheck + zoneName:kOTRampZoneName + withAttributes:@{ OctagonEventAttributeFailureReason : @"does not have bottle"}]; + if(error){ + *error = localError; + } + } + else{ + [logger logSuccessForEventNamed:OctagonEventBottleCheck]; + } + + [tracker stop]; + + return bottleStatus; +} + +-(void) postFollowUp +{ + NSError* error = nil; + + CKKSAnalytics* logger = [CKKSAnalytics logger]; + SFAnalyticsActivityTracker *tracker = [logger logSystemMetricsForActivityNamed:CKKSActivityBottleCheck withAction:nil]; + + [tracker start]; + CDPFollowUpController *cdpd = [[CDPFollowUpController alloc] init]; + CDPFollowUpContext *context = [CDPFollowUpContext contextForOfflinePasscodeChange]; + + [cdpd postFollowUpWithContext:context error:&error]; + if(error){ + [logger logUnrecoverableError:error forEvent:OctagonEventCoreFollowUp withAttributes:@{ + OctagonEventAttributeFailureReason : @"core follow up failed"}]; + + secerror("request to CoreCDP to follow up failed: %@", error); + } + else{ + [logger logSuccessForEventNamed:OctagonEventCoreFollowUp]; + } + [tracker stop]; +} + + +@end +#endif diff --git a/keychain/ot/OTContextRecord.h b/keychain/ot/OTContextRecord.h new file mode 100644 index 00000000..9fe05570 --- /dev/null +++ b/keychain/ot/OTContextRecord.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +#ifndef OTContextRecord_h +#define OTContextRecord_h + +#if OCTAGON + +#import + +NS_ASSUME_NONNULL_BEGIN + + +@interface OTContextRecord : NSObject + +@property (nonatomic, strong) NSString* contextID; +@property (nonatomic, strong) NSString* dsid; +@property (nonatomic, strong) NSString* contextName; +@property (nonatomic) BOOL zoneCreated; +@property (nonatomic) BOOL subscribedToChanges; +@property (nonatomic, strong) NSData* changeToken; +@property (nonatomic, strong) NSString* egoPeerID; +@property (nonatomic, strong) NSDate* egoPeerCreationDate; +@property (nonatomic, strong) NSData* recoverySigningSPKI; +@property (nonatomic, strong) NSData* recoveryEncryptionSPKI; + + +-(BOOL)isEqual:(OTContextRecord*)record; + +@end + +NS_ASSUME_NONNULL_END + +#endif /* OCTAGON */ +#endif /* OTContextRecord_h */ diff --git a/keychain/ot/OTContextRecord.m b/keychain/ot/OTContextRecord.m new file mode 100644 index 00000000..09e9e371 --- /dev/null +++ b/keychain/ot/OTContextRecord.m @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON +#import "OTContextRecord.h" + +@implementation OTContextRecord + +-(BOOL)isEqual:(OTContextRecord*)record +{ + return [self.contextID isEqualToString:record.contextID] && + [self.contextName isEqualToString:record.contextName] && + [self.dsid isEqualToString:record.dsid] && + [self.egoPeerID isEqualToString:record.egoPeerID] && + [self.recoverySigningSPKI isEqual:record.recoverySigningSPKI] && + [self.recoveryEncryptionSPKI isEqual:record.recoveryEncryptionSPKI]; +} +@end + +#endif /* OCTAGON */ diff --git a/keychain/ot/OTControl.h b/keychain/ot/OTControl.h new file mode 100644 index 00000000..428c905b --- /dev/null +++ b/keychain/ot/OTControl.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +// You must be 64-bit to use this class. +#if __OBJC2__ + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface OTControl : NSObject ++ (OTControl* _Nullable)controlObject:(NSError* _Nullable __autoreleasing* _Nullable)error; +- (instancetype)initWithConnection:(NSXPCConnection*)connection; + +- (void)restore:(NSString *)contextID dsid:(NSString *)dsid secret:(NSData*)secret escrowRecordID:(NSString*)escrowRecordID + reply:(void (^)(NSData* signingKeyData, NSData* encryptionKeyData, NSError* _Nullable error))reply; +- (void)encryptionKey:(void (^)(NSData* result, NSError* _Nullable error))reply; +- (void)signingKey:(void (^)(NSData* result, NSError* _Nullable error))reply; +- (void)listOfRecords:(void (^)(NSArray* list, NSError* _Nullable error))reply; +- (void)signOut:(void (^)(BOOL result, NSError * _Nullable error))reply; +- (void)signIn:(NSString*)dsid reply:(void (^)(BOOL result, NSError * _Nullable error))reply; +- (void)reset:(void (^)(BOOL result, NSError* _Nullable error))reply; + +// Call this to 'preflight' a bottled peer entry. This will create sufficient entropy, derive and save all relevant keys, +// then return the entropy to the caller. If something goes wrong during this process, do not store the returned entropy. +- (void)preflightBottledPeer:(NSString*)contextID + dsid:(NSString*)dsid + reply:(void (^)(NSData* _Nullable entropy, + NSString* _Nullable bottleID, + NSData* _Nullable signingPublicKey, + NSError* _Nullable error))reply; + +// Call this to 'launch' a preflighted bottled peer entry. This indicates that you've successfully stored the entropy, +// and we should save the bottled peer entry off-device for later retrieval. +- (void)launchBottledPeer:(NSString*)contextID + bottleID:(NSString*)bottleID + reply:(void (^ _Nullable)(NSError* _Nullable error))reply; + +// Call this to scrub the launch of a preflighted bottled peer entry. This indicates you've terminally failed to store the +// preflighted entropy, and this bottled peer will never be used again and can be deleted. +- (void)scrubBottledPeer:(NSString*)contextID + bottleID:(NSString*)bottleID + reply:(void (^ _Nullable)(NSError* _Nullable error))reply; + +@end + +NS_ASSUME_NONNULL_END +#endif // __OBJC__ diff --git a/keychain/ot/OTControl.m b/keychain/ot/OTControl.m new file mode 100644 index 00000000..41cc74af --- /dev/null +++ b/keychain/ot/OTControl.m @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if __OBJC2__ + +#import +#import + +#import + +#import "keychain/ot/OTControl.h" +#import "keychain/ot/OTControlProtocol.h" +#import "keychain/ot/OctagonControlServer.h" + +#include + +@interface OTControl () +@property NSXPCConnection *connection; +@end + +@implementation OTControl + +- (instancetype)initWithConnection:(NSXPCConnection*)connection { + if(self = [super init]) { + _connection = connection; + } + return self; +} + +- (void)restore:(NSString *)contextID dsid:(NSString *)dsid secret:(NSData*)secret escrowRecordID:(NSString*)escrowRecordID + reply:(void (^)(NSData* signingKeyData, NSData* encryptionKeyData, NSError* _Nullable error))reply +{ + [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + reply(nil, nil, error); + }] restore:contextID dsid:dsid secret:secret escrowRecordID:escrowRecordID reply:^(NSData* signingKeyData, NSData* encryptionKeyData, NSError *error) { + reply(signingKeyData, encryptionKeyData, error); + }]; + +} + +-(void)reset:(void (^)(BOOL result, NSError* _Nullable error))reply +{ + [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + reply(NO, error); + }] reset:^(BOOL result, NSError * _Nullable error) { + reply(result, error); + }]; +} + +- (void)signingKey:(void (^)(NSData* result, NSError* _Nullable error))reply +{ + [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + reply(nil, error); + }] octagonSigningPublicKey:^(NSData *signingKey, NSError * _Nullable error) { + reply(signingKey, error); + }]; + +} + +- (void)encryptionKey:(void (^)(NSData* result, NSError* _Nullable error))reply +{ + [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + reply(nil, error); + }] octagonEncryptionPublicKey:^(NSData *encryptionKey, NSError * _Nullable error) { + reply(encryptionKey, error); + }]; + +} + +- (void)listOfRecords:(void (^)(NSArray* list, NSError* _Nullable error))reply +{ + [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + reply(nil, error); + }] listOfEligibleBottledPeerRecords:^(NSArray *list, NSError * _Nullable error) { + reply(list, error); + }]; + +} + +- (void)signIn:(NSString*)dsid reply:(void (^)(BOOL result, NSError * _Nullable error))reply{ + [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + reply(NO, error); + }] signIn:dsid reply:^(BOOL result, NSError * _Nullable error) { + reply(result, error); + }]; +} + +- (void)signOut:(void (^)(BOOL result, NSError * _Nullable error))reply +{ + [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + reply(NO, error); + }] signOut:^(BOOL result, NSError * _Nullable error) { + reply(result, error); + }]; + +} + + +- (void)preflightBottledPeer:(NSString*)contextID + dsid:(NSString*)dsid + reply:(void (^)(NSData* _Nullable entropy, + NSString* _Nullable bottleID, + NSData* _Nullable signingPublicKey, + NSError* _Nullable error))reply +{ + [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + reply(nil, nil, nil, error); + }] preflightBottledPeer:contextID dsid:dsid reply:^(NSData* _Nullable entropy, + NSString* _Nullable bottleID, + NSData* _Nullable signingPublicKey, + NSError* _Nullable error) { + reply(entropy, bottleID, signingPublicKey, error); + }]; +} + +- (void)launchBottledPeer:(NSString*)contextID + bottleID:(NSString*)bottleID + reply:(void (^ _Nullable)(NSError* _Nullable))reply +{ + [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + reply(error); + }] launchBottledPeer:contextID bottleID:bottleID reply:^(NSError * _Nullable error) { + reply(error); + }]; +} + +- (void)scrubBottledPeer:(NSString*)contextID + bottleID:(NSString*)bottleID + reply:(void (^ _Nullable)(NSError* _Nullable))reply +{ + [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + reply(error); + }] scrubBottledPeer:contextID bottleID:bottleID reply:reply]; +} + ++ (OTControl*)controlObject:(NSError* __autoreleasing *)error { + + NSXPCConnection* connection = [[NSXPCConnection alloc] initWithMachServiceName:@(kSecuritydOctagonServiceName) options:0]; + + if (connection == nil) { + if(error) { + *error = [NSError errorWithDomain:@"securityd" code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Couldn't create connection (no reason given)"}]; + } + return nil; + } + + NSXPCInterface *interface = OTSetupControlProtocol([NSXPCInterface interfaceWithProtocol:@protocol(OTControlProtocol)]); + connection.remoteObjectInterface = interface; + [connection resume]; + + OTControl* c = [[OTControl alloc] initWithConnection:connection]; + return c; +} + +@end + +#endif // __OBJC2__ diff --git a/keychain/ot/OTControlProtocol.h b/keychain/ot/OTControlProtocol.h new file mode 100644 index 00000000..6caa8dc9 --- /dev/null +++ b/keychain/ot/OTControlProtocol.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import +NS_ASSUME_NONNULL_BEGIN + +@protocol OTControlProtocol +- (void)restore:(NSString *)contextID dsid:(NSString *)dsid secret:(NSData*)secret escrowRecordID:(NSString*)escrowRecordID reply:(void (^)(NSData* _Nullable signingKeyData, NSData* _Nullable encryptionKeyData, NSError * _Nullable error))reply; +- (void)octagonEncryptionPublicKey:(void (^)(NSData* _Nullable encryptionKey, NSError * _Nullable))reply;; +- (void)octagonSigningPublicKey:(void (^)(NSData* _Nullable signingKey, NSError * _Nullable))reply;; +- (void)listOfEligibleBottledPeerRecords:(void (^)(NSArray* listOfRecords, NSError *))reply; +- (void)signOut:(void (^)(BOOL result, NSError * _Nullable signedOutError))reply; +- (void)signIn:(NSString*)dsid reply:(void (^)(BOOL result, NSError * _Nullable signedInError))reply; +- (void)reset:(void (^)(BOOL result, NSError * _Nullable error))reply; +- (void)scheduleCFUForFuture; + +- (void)preflightBottledPeer:(NSString*)contextID + dsid:(NSString*)dsid + reply:(void (^)(NSData* _Nullable entropy, + NSString* _Nullable bottleID, + NSData* _Nullable signingPublicKey, + NSError* _Nullable error))reply; +- (void)launchBottledPeer:(NSString*)contextID + bottleID:(NSString*)bottleID + reply:(void (^ _Nullable)(NSError* _Nullable error))reply; +- (void)scrubBottledPeer:(NSString*)contextID + bottleID:(NSString*)bottleID + reply:(void (^ _Nullable)(NSError* _Nullable error))reply; +@end + +NSXPCInterface* OTSetupControlProtocol(NSXPCInterface* interface); + +NS_ASSUME_NONNULL_END diff --git a/keychain/ot/OTControlProtocol.m b/keychain/ot/OTControlProtocol.m new file mode 100644 index 00000000..fde2ded8 --- /dev/null +++ b/keychain/ot/OTControlProtocol.m @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import + +#import "keychain/ot/OTControlProtocol.h" + +#if OCTAGON +#import +#import +#import +#include +#endif // OCTAGON + +NSXPCInterface* OTSetupControlProtocol(NSXPCInterface* interface) { +#if OCTAGON + static NSMutableSet *errClasses; + + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + errClasses = [NSMutableSet set]; + char *classes[] = { + "NSArray", + "NSData", + "NSDate", + "NSDictionary", + "NSError", + "NSNull", + "NSNumber", + "NSOrderedSet", + "NSSet", + "NSString", + "NSURL", + }; + + for (unsigned n = 0; n < sizeof(classes)/sizeof(classes[0]); n++) { + Class cls = objc_getClass(classes[n]); + if (cls) { + [errClasses addObject:cls]; + } + } + }); + + @try { + [interface setClasses:errClasses forSelector:@selector(restore:dsid:secret:escrowRecordID:reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errClasses forSelector:@selector(octagonEncryptionPublicKey:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errClasses forSelector:@selector(octagonSigningPublicKey:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errClasses forSelector:@selector(listOfEligibleBottledPeerRecords:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errClasses forSelector:@selector(signOut:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errClasses forSelector:@selector(signIn:reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errClasses forSelector:@selector(reset:) argumentIndex:0 ofReply:YES]; + + [interface setClasses:errClasses forSelector:@selector(preflightBottledPeer:dsid:reply:) argumentIndex:3 ofReply:YES]; + [interface setClasses:errClasses forSelector:@selector(launchBottledPeer:bottleID:reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errClasses forSelector:@selector(scrubBottledPeer:bottleID:reply:) argumentIndex:0 ofReply:YES]; + } + @catch(NSException* e) { + secerror("OTSetupControlProtocol failed, continuing, but you might crash later: %@", e); +#if DEBUG + @throw e; +#endif + } +#endif + + return interface; +} + + diff --git a/keychain/ot/OTDefines.h b/keychain/ot/OTDefines.h new file mode 100644 index 00000000..c5f36bff --- /dev/null +++ b/keychain/ot/OTDefines.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef OTDefines_h +#define OTDefines_h +#if OCTAGON +#include +#include +NS_ASSUME_NONNULL_BEGIN + +static NSString* const octagonErrorDomain = @"com.apple.security.octagon"; +static NSString* const OctagonEventAttributeZoneName = @"OTBottledPeer"; +static NSString* const OctagonEventAttributeFailureReason = @"OTFailureReason"; +static NSString* const OctagonEventAttributeTimeSinceLastPostedFollowUp = @"TimeSinceLastPostedFollowUp"; + + +/* Octagon Errors */ +#define OTErrorNoColumn 1 +#define OTErrorKeyGeneration 2 +#define OTErrorEmptySecret 3 +#define OTErrorEmptyDSID 4 +#define OTErrorNoIdentity 5 +#define OTErrorRestoreFailed 6 +#define OTErrorRestoredPeerEncryptionKeyFailure 7 +#define OTErrorRestoredPeerSigningKeyFailure 8 +#define OTErrorEntropyCreationFailure 9 +#define OTErrorDeserializationFailure 10 +#define OTErrorDecryptFailure 11 +#define OTErrorPrivateKeyFailure 12 +#define OTErrorEscrowSigningSPKI 13 +#define OTErrorBottleID 14 +#define OTErrorOTLocalStore 15 +#define OTErrorOTCloudStore 16 +#define OTErrorEmptyEscrowRecordID 17 +#define OTErrorNoBottlePeerRecords 18 +#define OTErrorCoreFollowUp 19 +#define OTErrorFeatureNotEnabled 20 +#define OTErrorCKCallback 21 +#define OTErrorRampInit 22 +#define OTErrorCKTimeOut 23 +#define OTErrorNoNetwork 24 +#define OTErrorNotSignedIn 25 +#define OTErrorRecordNotFound 26 + +#define OTMasterSecretLength 72 + +typedef enum { + OctagonSigningKey = 1, + OctagonEncryptionKey = 2 +} OctagonKeyType; + +typedef enum { + UNCLEAR = 0, + BOTTLE = 1, + NOBOTTLE = 2 +} OctagonBottleCheckState; + +NS_ASSUME_NONNULL_END +#endif +#endif /* OTDefines_h */ diff --git a/keychain/ot/OTEscrowKeys.h b/keychain/ot/OTEscrowKeys.h new file mode 100644 index 00000000..d2d7975f --- /dev/null +++ b/keychain/ot/OTEscrowKeys.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef OTEscrow_h +#define OTEscrow_h +#if OCTAGON + +#import +#import +NS_ASSUME_NONNULL_BEGIN + +typedef enum { + kOTEscrowKeySigning = 1, + kOTEscrowKeyEncryption = 2, + kOTEscrowKeySymmetric = 3, +} escrowKeyType; + +@interface OTEscrowKeys : NSObject + +@property (nonatomic, readonly) SFECKeyPair* encryptionKey; +@property (nonatomic, readonly) SFECKeyPair* signingKey; +@property (nonatomic, readonly) SFAESKey* symmetricKey; + +@property (nonatomic, readonly) NSData* secret; +@property (nonatomic, readonly) NSString* dsid; + +-(instancetype) init NS_UNAVAILABLE; + +- (nullable instancetype) initWithSecret:(NSData*)secret + dsid:(NSString*)dsid + error:(NSError* __autoreleasing *)error; + ++ (SecKeyRef) createSecKey:(NSData*)keyData; ++ (BOOL) setKeyMaterialInKeychain:(NSDictionary*)query error:(NSError* __autoreleasing *)error; + ++ (NSData* _Nullable) generateEscrowKey:(escrowKeyType)keyType + masterSecret:(NSData*)masterSecret + dsid:(NSString *)dsid + error:(NSError**)error; + +@end +NS_ASSUME_NONNULL_END +#endif +#endif /* OTEscrow_h */ diff --git a/keychain/ot/OTEscrowKeys.m b/keychain/ot/OTEscrowKeys.m new file mode 100644 index 00000000..1779714a --- /dev/null +++ b/keychain/ot/OTEscrowKeys.m @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#if OCTAGON + +#import "OTEscrowKeys.h" + +#import +#include +#include +#import +#import +#import + +#import +#import +#import +#import +#import + +#import "keychain/ot/OTDefines.h" + +#import +#import +#import + +#import +#import +#import + +static uint8_t escrowedSigningPrivKey[] = {'E', 's', 'c', 'r', 'o', 'w', ' ', 'S', 'i', 'g', 'n', 'i', 'n', 'g', ' ', 'P', 'r', 'i', 'v', 'a', 't', 'e', ' ', 'K', 'e', 'y'}; +static uint8_t escrowedEncryptionPrivKey[] = { 'E', 's', 'c', 'r', 'o', 'w', ' ','E', 'n', 'c', 'r', 'y', 'p', 't', 'i', 'o', 'n', ' ', 'P', 'r', 'v', 'a', 't', 'e', ' ', 'K', 'e', 'y' }; +static uint8_t escrowedSymmetric[] = {'E', 's', 'c', 'r', 'o', 'w', ' ', 'S', 'y', 'm', 'm', 'e', 't', 'r', 'i','c',' ', 'K', 'e', 'y' }; + +#define OT_ESCROW_SIGNING_HKDF_SIZE 56 +#define OT_ESCROW_ENCRYPTION_HKDF_SIZE 56 +#define OT_ESCROW_SYMMETRIC_HKDF_SIZE 32 + +@interface OTEscrowKeys () +@property (nonatomic, strong) SFECKeyPair* encryptionKey; +@property (nonatomic, strong) SFECKeyPair* signingKey; +@property (nonatomic, strong) SFAESKey* symmetricKey; +@property (nonatomic, strong) NSData* secret; +@property (nonatomic, strong) NSString* dsid; +@end + +@implementation OTEscrowKeys + +- (nullable instancetype) initWithSecret:(NSData*)secret + dsid:(NSString*)dsid + error:(NSError* __autoreleasing *)error +{ + self = [super init]; + if (self) { + NSError* localError = nil; + + if([secret length] == 0){ + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorEmptySecret userInfo:@{NSLocalizedDescriptionKey: @"entropy/secret is nil"}]; + } + return nil; + } + _secret = [secret copy]; + + if([dsid length] == 0){ + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorEmptyDSID userInfo:@{NSLocalizedDescriptionKey: @"dsid is nil"}]; + } + return nil; + } + _dsid = [dsid copy]; + + NSData *data = [OTEscrowKeys generateEscrowKey:kOTEscrowKeySigning masterSecret:secret dsid:self.dsid error:&localError]; + if (!data) { + if(error){ + *error = localError; + } + return nil; + } + _signingKey = [[SFECKeyPair alloc] initWithSecKey:[OTEscrowKeys createSecKey:data]]; + if(!_signingKey){ + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorKeyGeneration userInfo:@{NSLocalizedDescriptionKey: @"failed to create EC signing key"}]; + } + return nil; + } + data = [OTEscrowKeys generateEscrowKey:kOTEscrowKeyEncryption masterSecret:secret dsid:self.dsid error:&localError]; + if (!data) { + if(error){ + *error = localError; + } + return nil; + } + _encryptionKey = [[SFECKeyPair alloc] initWithSecKey:[OTEscrowKeys createSecKey:data]]; + if(!_encryptionKey){ + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorKeyGeneration userInfo:@{NSLocalizedDescriptionKey: @"failed to create EC encryption key"}]; + } + return nil; + } + data = [OTEscrowKeys generateEscrowKey:kOTEscrowKeySymmetric masterSecret:secret dsid:self.dsid error:&localError]; + if (!data) { + if(error){ + *error = localError; + } + return nil; + } + _symmetricKey = [[SFAESKey alloc] initWithData:data specifier:[[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256] error:&localError]; + if (!_symmetricKey) { + if(error){ + *error = localError; + } + return nil; + } + + BOOL result = [OTEscrowKeys storeEscrowedSigningKeyPair:[_signingKey keyData] error:&localError]; + if(!result || localError){ + secerror("octagon: could not store escrowed signing SPKI in keychain: %@", localError); + if(error){ + *error = localError; + } + return nil; + } + result = [OTEscrowKeys storeEscrowedEncryptionKeyPair:[_encryptionKey keyData] error:error]; + if(!result || localError){ + secerror("octagon: could not store escrowed signing SPKI in keychain: %@", localError); + if(error){ + *error = localError; + } + return nil; + } + result = [OTEscrowKeys storeEscrowedSymmetricKey:[_symmetricKey keyData] error:error]; + if(!result || localError){ + secerror("octagon: could not store escrowed signing SPKI in keychain: %@", localError); + if(error){ + *error = localError; + } + return nil; + } + } + return self; +} + ++ (NSData* _Nullable) generateEscrowKey:(escrowKeyType)keyType + masterSecret:(NSData*)masterSecret + dsid:(NSString *)dsid + error:(NSError**)error +{ + NSUInteger keyLength = 0; + const void *info = nil; + size_t infoLength = 0; + NSMutableData* derivedKey = NULL; + + switch(keyType) + { + case kOTEscrowKeySymmetric: + keyLength = OT_ESCROW_SYMMETRIC_HKDF_SIZE; + info = escrowedSymmetric; + infoLength = sizeof(escrowedSymmetric); + break; + case kOTEscrowKeyEncryption: + keyLength = OT_ESCROW_ENCRYPTION_HKDF_SIZE; + info = escrowedEncryptionPrivKey; + infoLength = sizeof(escrowedEncryptionPrivKey); + break; + case kOTEscrowKeySigning: + keyLength = OT_ESCROW_SIGNING_HKDF_SIZE; + info = escrowedSigningPrivKey; + infoLength = sizeof(escrowedSigningPrivKey); + break; + default: + break; + } + + ccec_const_cp_t cp = ccec_cp_384(); + int status = 0; + + ccec_full_ctx_decl_cp(cp, fullKey); + + derivedKey = [NSMutableData dataWithLength:keyLength]; + status = cchkdf(ccsha384_di(), + [masterSecret length], [masterSecret bytes], + strlen([dsid UTF8String]),[dsid UTF8String], + infoLength, info, + keyLength, [derivedKey mutableBytes]); + + + if (status != 0) { + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorKeyGeneration userInfo:nil]; + } + secerror("octagon: could not generate seed for signing keys"); + return nil; + } + if(keyType == kOTEscrowKeySymmetric){ + return derivedKey; + } + else if(keyType == kOTEscrowKeyEncryption || keyType == kOTEscrowKeySigning){ + + status = ccec_generate_key_deterministic(cp, + [derivedKey length], [derivedKey mutableBytes], + ccDRBGGetRngState(), + CCEC_GENKEY_DETERMINISTIC_FIPS, + fullKey); + if(status != 0){ + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorKeyGeneration userInfo:nil]; + } + secerror("octagon: could not generate signing keys"); + return nil; + } + + size_t space = ccec_x963_export_size(true, ccec_ctx_pub(fullKey)); + NSMutableData* key = [[NSMutableData alloc]initWithLength:space]; + ccec_x963_export(true, [key mutableBytes], fullKey); + derivedKey = key; + } + return derivedKey; +} + ++ (SecKeyRef) createSecKey:(NSData*)keyData +{ + NSDictionary *keyAttributes = @{ + (__bridge id)kSecAttrKeyClass : (__bridge id)kSecAttrKeyClassPrivate, + (__bridge id)kSecAttrKeyType : (__bridge id)kSecAttrKeyTypeEC, + }; + + SecKeyRef key = SecKeyCreateWithData((__bridge CFDataRef)keyData, (__bridge CFDictionaryRef)keyAttributes, NULL); + return key; +} + ++ (BOOL) setKeyMaterialInKeychain:(NSDictionary*)query error:(NSError* __autoreleasing *)error +{ + BOOL result = NO; + + CFTypeRef results = NULL; + OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, &results); + + NSError* localerror = nil; + + if(status == errSecDuplicateItem || status == errSecSuccess) { + result = YES; + } else { + localerror = [NSError errorWithDomain:@"securityd" + code:status + userInfo:nil]; + } + if(status != errSecSuccess) { + CFReleaseNull(results); + + if(error) { + *error = localerror; + } + } + + return result; +} + ++(NSString*) hashIt:(NSData*)keyData +{ + const struct ccdigest_info *di = ccsha384_di(); + NSMutableData* result = [[NSMutableData alloc] initWithLength:ccsha384_di()->output_size]; + + ccdigest(di, [keyData length], [keyData bytes], [result mutableBytes]); + + NSString* hash = [result base64EncodedStringWithOptions:0]; + return hash; +} + ++ (BOOL)storeEscrowedEncryptionKeyPair:(NSData*)keyData error:(NSError**)error +{ + NSDictionary* query = @{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecAttrAccessible: (id)kSecAttrAccessibleWhenUnlocked, + (id)kSecAttrNoLegacy : @YES, + (id)kSecAttrAccessGroup: @"com.apple.security.ckks", + (id)kSecAttrSynchronizable : (id)kCFBooleanFalse, + (id)kSecAttrServer : [self hashIt:keyData], + (id)kSecAttrLabel : @"Escrowed Encryption Key", + (id)kSecValueData : keyData, + }; + return [OTEscrowKeys setKeyMaterialInKeychain:query error:error]; +} + ++ (BOOL)storeEscrowedSigningKeyPair:(NSData*)keyData error:(NSError**)error +{ + NSDictionary* query = @{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecAttrAccessible: (id)kSecAttrAccessibleWhenUnlocked, + (id)kSecAttrNoLegacy : @YES, + (id)kSecAttrAccessGroup: @"com.apple.security.ckks", + (id)kSecAttrSynchronizable : (id)kCFBooleanFalse, + (id)kSecAttrLabel : @"Escrowed Signing Key", + (id)kSecAttrServer : [self hashIt:keyData], + (id)kSecValueData : keyData, + }; + return [OTEscrowKeys setKeyMaterialInKeychain:query error:error]; +} + ++ (BOOL)storeEscrowedSymmetricKey:(NSData*)keyData error:(NSError**)error +{ + NSDictionary* query = @{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecAttrAccessible: (id)kSecAttrAccessibleWhenUnlocked, + (id)kSecAttrNoLegacy : @YES, + (id)kSecAttrAccessGroup: @"com.apple.security.ckks", + (id)kSecAttrSynchronizable : (id)kCFBooleanFalse, + (id)kSecAttrLabel : @"Escrowed Symmetric Key", + (id)kSecAttrServer : [self hashIt:keyData], + (id)kSecValueData : keyData, + }; + return [OTEscrowKeys setKeyMaterialInKeychain:query error:error]; +} + +@end +#endif diff --git a/keychain/ot/OTIdentity.h b/keychain/ot/OTIdentity.h new file mode 100644 index 00000000..35ba3476 --- /dev/null +++ b/keychain/ot/OTIdentity.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#include +NS_ASSUME_NONNULL_BEGIN + +@interface OTIdentity : NSObject + +@property (nonatomic, readonly) NSString* peerID; +@property (nonatomic, readonly) NSString* spID; +@property (nonatomic, readonly) SFECKeyPair* peerSigningKey; +@property (nonatomic, readonly) SFECKeyPair* peerEncryptionKey; + + +- (instancetype) initWithPeerID:(nullable NSString*)peerID + spID:(nullable NSString*)spID + peerSigningKey:(SFECKeyPair*)peerSigningKey + peerEncryptionkey:(SFECKeyPair*)peerEncryptionKey + error:(NSError**)error; + ++ (nullable instancetype) currentIdentityFromSOS:(NSError**)error; + +-(BOOL)isEqual:(OTIdentity*)identity; + + ++(BOOL) storeOctagonIdentityIntoKeychain:(_SFECKeyPair *)restoredSigningKey + restoredEncryptionKey:(_SFECKeyPair *)restoredEncryptionKey + escrowSigningPubKeyHash:(NSString *)escrowSigningPubKeyHash + restoredPeerID:(NSString *)peerID + error:(NSError**)error; + +@end + +NS_ASSUME_NONNULL_END +#endif + diff --git a/keychain/ot/OTIdentity.m b/keychain/ot/OTIdentity.m new file mode 100644 index 00000000..a26c0eaf --- /dev/null +++ b/keychain/ot/OTIdentity.m @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#if OCTAGON + +#import "OTIdentity.h" + +#import +#import +#import "keychain/ot/OTDefines.h" + +#import +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#import +#pragma clang diagnostic pop + +@interface OTIdentity () + +@property (nonatomic, strong) NSString* peerID; +@property (nonatomic, strong) NSString* spID; +@property (nonatomic, strong) SFECKeyPair* peerSigningKey; +@property (nonatomic, strong) SFECKeyPair* peerEncryptionKey; + +@end + +@implementation OTIdentity + +- (instancetype) initWithPeerID:(nullable NSString*)peerID + spID:(nullable NSString*)spID + peerSigningKey:(SFECKeyPair*)peerSigningKey + peerEncryptionkey:(SFECKeyPair*)peerEncryptionKey + error:(NSError**)error +{ + self = [super init]; + if (self) { + _peerID = peerID; + _spID = spID; + _peerSigningKey = peerSigningKey; + _peerEncryptionKey = peerEncryptionKey; + } + return self; +} + ++ (nullable instancetype) currentIdentityFromSOS:(NSError**)error +{ + CFErrorRef circleCheckError = NULL; + SOSCCStatus circleStatus = SOSCCThisDeviceIsInCircle(&circleCheckError); + if(circleStatus != kSOSCCInCircle){ + if(circleCheckError){ + secerror("octagon: cannot retrieve octagon keys from SOS, not in circle, error: %@", circleCheckError); + if(error){ + *error = (__bridge NSError*)circleCheckError; + } + } + secerror("octagon: current circle status: %d",circleStatus); + return nil; + } + __block NSString* sosPeerID = nil; + __block NSError* sosPeerIDError = nil; + + SOSCCPerformWithPeerID(^(CFStringRef peerID, CFErrorRef error) { + sosPeerID = (__bridge NSString *)(peerID); + if(error){ + secerror("octagon: retrieving sos peer id error: %@", error); + sosPeerIDError = CFBridgingRelease(error); + } + }); + + if(sosPeerID == nil || sosPeerIDError != nil){ + secerror("octagon: cannot retrieve peer id from SOS, error: %@", sosPeerIDError); + if(error){ + *error = sosPeerIDError; + } + return nil; + } + + __block SFECKeyPair *peerEncryptionKey; + __block SFECKeyPair *peerSigningKey; + __block NSError* localError = nil; + + SOSCCPerformWithAllOctagonKeys(^(SecKeyRef octagonEncryptionKey, SecKeyRef octagonSigningKey, CFErrorRef cferror) { + if(cferror) { + localError = (__bridge NSError*)cferror; + return; + } + if (!cferror && octagonEncryptionKey && octagonSigningKey) { + peerSigningKey = [[SFECKeyPair alloc] initWithSecKey:octagonSigningKey]; + peerEncryptionKey = [[SFECKeyPair alloc] initWithSecKey:octagonEncryptionKey]; + + } + }); + + if(!peerEncryptionKey || !peerSigningKey || localError != nil){ + secerror("octagon: failed to retrieve octagon keys from sos: %@", localError); + if(error){ + *error = localError; + } + return nil; + } + return [[OTIdentity alloc] initWithPeerID:nil + spID:sosPeerID + peerSigningKey:peerSigningKey + peerEncryptionkey:peerEncryptionKey + error:error]; +} + +-(BOOL)isEqual:(OTIdentity*)identity +{ + return [self.peerID isEqualToString:identity.peerID] && + [self.spID isEqualToString:identity.spID] && + [self.peerSigningKey isEqual:identity.peerSigningKey] && + [self.peerEncryptionKey isEqual:identity.peerEncryptionKey]; +} + ++ (BOOL) setKeyMaterialInKeychain:(NSDictionary*)query error:(NSError* __autoreleasing *)error +{ + BOOL result = NO; + + CFTypeRef results = NULL; + OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, &results); + + NSError* localerror = nil; + + if(status == errSecDuplicateItem || status == errSecSuccess) { + result = YES; + } else { + localerror = [NSError errorWithDomain:@"securityd" + code:status + userInfo:nil]; + } + if(status != errSecSuccess) { + CFReleaseNull(results); + + if(error) { + *error = localerror; + } + } + + return result; +} + ++ (BOOL)storeOtagonKey:(NSData*)keyData + octagonKeyType:(OctagonKeyType)octagonKeyType + restoredPeerID:(NSString*)restoredPeerID + escrowSigningPubKeyHash:(NSString*)escrowSigningPubKeyHash + error:(NSError**)error +{ + NSNumber *keyType = [[NSNumber alloc]initWithInt:octagonKeyType]; + + NSDictionary* query = @{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecAttrAccessible: (id)kSecAttrAccessibleWhenUnlocked, + (id)kSecAttrNoLegacy : @YES, + (id)kSecAttrLabel : escrowSigningPubKeyHash, + (id)kSecAttrAccount : restoredPeerID, + (id)kSecAttrType : keyType, + (id)kSecAttrServer : (octagonKeyType == 1) ? @"Octagon Signing Key" : @"Octagon Encryption Key", + (id)kSecAttrAccessGroup: @"com.apple.security.ckks", + (id)kSecAttrSynchronizable : (id)kCFBooleanFalse, + (id)kSecValueData : keyData, + }; + return [OTIdentity setKeyMaterialInKeychain:query error:error]; + +} + ++(BOOL) storeOctagonIdentityIntoKeychain:(_SFECKeyPair *)restoredSigningKey + restoredEncryptionKey:(_SFECKeyPair *)restoredEncryptionKey + escrowSigningPubKeyHash:(NSString *)escrowSigningPubKeyHash + restoredPeerID:(NSString *)peerID + error:(NSError**)error +{ + NSError* localError = nil; + + BOOL result = [OTIdentity storeOtagonKey:[restoredSigningKey keyData] octagonKeyType:OctagonSigningKey restoredPeerID:peerID escrowSigningPubKeyHash:escrowSigningPubKeyHash error:&localError]; + if(!result || localError){ + secerror("octagon: could not store octagon signing key in keychain:%@", localError); + if(error){ + *error = localError; + } + return NO; + } + result = [OTIdentity storeOtagonKey:[restoredEncryptionKey keyData] octagonKeyType:OctagonEncryptionKey restoredPeerID:peerID escrowSigningPubKeyHash:escrowSigningPubKeyHash error:&localError]; + if(!result || localError){ + secerror("octagon: could not store octagon encryption key in keychain:%@", localError); + if(error){ + *error = localError; + } + return NO; + } + return result; +} + +@end +#endif diff --git a/keychain/ot/OTLocalStore.h b/keychain/ot/OTLocalStore.h new file mode 100644 index 00000000..74c4fa09 --- /dev/null +++ b/keychain/ot/OTLocalStore.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef OTLocalStore_h +#define OTLocalStore_h +#if OCTAGON + +#import +#import +#import +#import "keychain/ot/OTBottledPeerRecord.h" +#import "keychain/ot/OTContextRecord.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTLocalStore : NSObject + +@property (nonatomic, readonly) NSString* dbPath; +@property (nonatomic, readonly) PQLConnection* pDB; +@property (nonatomic, readonly) dispatch_queue_t serialQ; +@property (nonatomic, readonly) NSString* contextID; +@property (nonatomic, readonly) NSString* dsid; +@property (nonatomic, readonly) sqlite3* _db; + +-(instancetype) initWithContextID:(NSString*)contextID dsid:(NSString*)dsid path:(nullable NSString*)path error:(NSError**)error; + +-(BOOL)isProposedColumnNameInTable:(NSString*)proposedColumnName tableName:(NSString*)tableName; + +// OT Context Record routines +-(BOOL)initializeContextTable:(NSString*)contextID dsid:(NSString*)dsid error:(NSError**)error; +-(OTContextRecord* _Nullable)readLocalContextRecordForContextIDAndDSID:(NSString*)contextAndDSID error:(NSError**)error; +-(BOOL)insertLocalContextRecord:(NSDictionary*)attributes error:(NSError**)error; +-(BOOL)updateLocalContextRecordRowWithContextID:(NSString*)contextIDAndDSID columnName:(NSString*)columnName newValue:(void*)newValue error:(NSError**)error; +-(BOOL)deleteLocalContext:(NSString*)contextIDAndDSID error:(NSError**)error; +-(BOOL) deleteAllContexts:(NSError**)error; + +//OT Bottled Peer routines +- (nullable OTBottledPeerRecord *)readLocalBottledPeerRecordWithRecordID:(NSString *)recordID + error:(NSError**)error; +- (nullable NSArray*) readAllLocalBottledPeerRecords:(NSError**)error; +-(BOOL)deleteBottledPeer:(NSString*) recordID error:(NSError**)error; +-(BOOL) deleteBottledPeersForContextAndDSID:(NSString*)contextIDAndDSID + error:(NSError**)error; +-(BOOL)removeAllBottledPeerRecords:(NSError**)error; +-(BOOL)insertBottledPeerRecord:(OTBottledPeerRecord *)bp + escrowRecordID:(NSString *)escrowRecordID + error:(NSError**)error; +- (nullable NSArray*) readLocalBottledPeerRecordsWithMatchingPeerID:(NSString*)peerID error:(NSError**)error; + +// generic DB routines +-(BOOL)openDBWithError:(NSError**)error; +-(BOOL)closeDBWithError:(NSError**)error;; +-(BOOL)createDirectoryAtPath:(NSString*)path error:(NSError **)error; +@end +NS_ASSUME_NONNULL_END +#endif +#endif /* OTLocalStore_h */ diff --git a/keychain/ot/OTLocalStore.m b/keychain/ot/OTLocalStore.m new file mode 100644 index 00000000..8e4c3e7a --- /dev/null +++ b/keychain/ot/OTLocalStore.m @@ -0,0 +1,684 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#if OCTAGON + +#import +#import +#import +#import +#include +#import "keychain/ot/OTDefines.h" +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR +#include +#else +#include +#endif + +#import "OTLocalStore.h" +#import "OTBottledPeerSigned.h" + +static NSString* const contextSchema = @"create table if not exists context (contextIDAndDSID text primary key, contextID text, accountDSID text, contextName text, zoneCreated boolean, subscribedToChanges boolean, changeToken blob, egoPeerID text, egoPeerCreationDate date, recoverySigningSPKI text, recoveryEncryptionSPKI text);"; + +static NSString* const bottledPeerSchema = @"create table if not exists bp (bottledPeerRecordID text primary key, contextIDAndDSID text, escrowRecordID text, peerID text, spID text, bottle text, escrowSigningSPKI text, peerSigningSPKI text, signatureUsingEscrow text, signatureUsingPeerKey text, encodedRecord text, launched text);"; + +static const NSInteger user_version = 0; + +/* Octagon Trust Local Context Record Constants */ +static NSString* OTCKRecordContextAndDSID = @"contextIDAndDSID"; +static NSString* OTCKRecordContextID = @"contextID"; +static NSString* OTCKRecordDSID = @"accountDSID"; +static NSString* OTCKRecordContextName = @"contextName"; +static NSString* OTCKRecordZoneCreated = @"zoneCreated"; +static NSString* OTCKRecordSubscribedToChanges = @"subscribedToChanges"; +static NSString* OTCKRecordChangeToken = @"changeToken"; +static NSString* OTCKRecordEgoPeerID = @"egoPeerID"; +static NSString* OTCKRecordEgoPeerCreationDate = @"egoPeerCreationDate"; +static NSString* OTCKRecordRecoverySigningSPKI = @"recoverySigningSPKI"; +static NSString* OTCKRecordRecoveryEncryptionSPKI = @"recoveryEncryptionSPKI"; +static NSString* OTCKRecordBottledPeerTableEntry = @"bottledPeer"; + +/* Octagon Trust Local Peer Record */ +static NSString* OTCKRecordPeerID = @"peerID"; +static NSString* OTCKRecordPermanentInfo = @"permanentInfo"; +static NSString* OTCKRecordStableInfo = @"stableInfo"; +static NSString* OTCKRecordDynamicInfo = @"dynamicInfo"; +static NSString* OTCKRecordRecoveryVoucher = @"recoveryVoucher"; +static NSString* OTCKRecordIsEgoPeer = @"isEgoPeer"; + +/* Octagon Trust BottledPeerSchema */ +static NSString* OTCKRecordEscrowRecordID = @"escrowRecordID"; +static NSString* OTCKRecordRecordID = @"bottledPeerRecordID"; +static NSString* OTCKRecordSPID = @"spID"; +static NSString* OTCKRecordBottle = @"bottle"; +static NSString* OTCKRecordEscrowSigningSPKI = @"escrowSigningSPKI"; +static NSString* OTCKRecordPeerSigningSPKI = @"peerSigningSPKI"; +static NSString* OTCKRecordSignatureFromEscrow = @"signatureUsingEscrow"; +static NSString* OTCKRecordSignatureFromPeerKey = @"signatureUsingPeerKey"; +static NSString* OTCKRecordEncodedRecord = @"encodedRecord"; +static NSString* OTCKRecordLaunched = @"launched"; + +/* Octagon Table Names */ +static NSString* const contextTable = @"context"; +static NSString* const peerTable = @"peer"; +static NSString* const bottledPeerTable = @"bp"; + +/* Octagon Trust Schemas */ +static NSString* const octagonZoctagonErrorDomainoneName = @"OctagonTrustZone"; + +/* Octagon Cloud Kit defines */ +static NSString* OTCKContainerName = @"com.apple.security.keychain"; +static NSString* OTCKZoneName = @"OctagonTrust"; +static NSString* OTCKRecordName = @"bp-"; +static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; + +static NSArray* _Nullable selectAll(PQLResultSet *rs, Class class) +{ + NSMutableArray *arr = [NSMutableArray array]; + for (id o in [rs enumerateObjectsOfClass:class]) { + [arr addObject:o]; + } + if (rs.error) { + return nil; + } + return arr; +} +#define selectArrays(db, sql, ...) \ +selectAll([db fetch:sql, ##__VA_ARGS__], [NSArray class]) + +#define selectDictionaries(db, sql, ...) \ +selectAll([db fetch:sql, ##__VA_ARGS__], [NSDictionary class]) + + +@interface NSDictionary (PQLResultSetInitializer) +@end +@implementation NSDictionary (PQLResultSetInitializer) +- (instancetype)initFromPQLResultSet:(PQLResultSet *)rs + error:(NSError **)error +{ + NSUInteger cols = rs.columns; + NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:cols]; + + for (NSUInteger i = 0; i < cols; i++) { + id obj = rs[i]; + if (obj) { + dict[[rs columnNameAtIndex:(int)i]] = obj; + } + } + + return [self initWithDictionary:dict]; +} +@end + + +@implementation OTLocalStore + +-(instancetype) initWithContextID:(NSString*)contextID dsid:(NSString*)dsid path:(nullable NSString*)path error:(NSError**)error +{ + self = [super init]; + if(self){ + if (!path) { + NSURL* urlPath = (__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"otdb.db"); + path = [urlPath path]; + } + _dbPath = [path copy]; + _pDB = [[PQLConnection alloc] init]; + _contextID = [contextID copy]; + _dsid = [dsid copy]; + _serialQ = dispatch_queue_create("com.apple.security.ot.db", DISPATCH_QUEUE_SERIAL); + + NSError* localError = nil; + if(![self openDBWithError:&localError]) + { + secerror("octagon: could not open db: %@", localError); + if(error){ + *error = localError; + } + return nil; + } + } + return self; +} + +- (BOOL) createDirectoryAtPath:(NSString*)path error:(NSError **)error +{ + BOOL success = YES; + NSError *localError; + NSFileManager *fileManager = [NSFileManager defaultManager]; + + if (![fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&localError]) { + if (![localError.domain isEqualToString:NSCocoaErrorDomain] || localError.code != NSFileWriteFileExistsError) { + success = NO; + if(error){ + *error = localError; + } + } + } + +#if TARGET_OS_IPHONE + if (success) { + NSDictionary *attributes = [fileManager attributesOfItemAtPath:path error:&localError]; + if (![attributes[NSFileProtectionKey] isEqualToString:NSFileProtectionCompleteUntilFirstUserAuthentication]) { + [fileManager setAttributes:@{ NSFileProtectionKey: NSFileProtectionCompleteUntilFirstUserAuthentication } + ofItemAtPath:path error:&localError]; + } + } +#endif + if (!success) { + if (error) *error = localError; + } + return success; +} + +-(BOOL)openDBWithError:(NSError**)error +{ + BOOL result = NO; + NSError *localError = nil; + + if(!(result = [_pDB openAtURL:[NSURL URLWithString:_dbPath] sharedCache:NO error:&localError])){ + secerror("octagon: could not open db: %@", localError); + if(error){ + *error = localError; + } + return NO; + } + if(![_pDB execute:bottledPeerSchema]){ + secerror("octagon: could not create bottled peer schema"); + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorEntropyCreationFailure userInfo:@{NSLocalizedDescriptionKey: @"could not create bottled peer schema"}]; + } + result = NO; + } + if(![_pDB execute:contextSchema]){ + secerror("octagon: could not create contextschema"); + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"could not create context schema"}]; + } + result = NO; + } + if(![_pDB setupPragmas]){ + secerror("octagon: could not set up db pragmas"); + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"could not set up db pragmas"}]; + } + result = NO; + } + if(![_pDB setUserVersion:user_version]){ + secerror("octagon: could not set version"); + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"could not set version"}]; + } + result = NO; + } + return result; +} + +-(BOOL)closeDBWithError:(NSError**)error +{ + BOOL result = NO; + NSError *localError = nil; + + if(!(result =[_pDB close:&localError])){ + secerror("octagon: could not close db: %@", localError); + if(error){ + *error = localError; + } + } + return result; +} + +-(BOOL)isProposedColumnNameInTable:(NSString*)proposedColumnName tableName:(NSString*)tableName +{ + BOOL result = NO; + + if([tableName isEqualToString:contextTable]) + { + if([proposedColumnName isEqualToString:OTCKRecordContextAndDSID]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordContextID]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordDSID]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordContextName]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordZoneCreated]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordSubscribedToChanges]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordChangeToken]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordEgoPeerID]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordEgoPeerCreationDate]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordRecoverySigningSPKI]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordRecoveryEncryptionSPKI]){ + result = YES; + } + else{ + secerror("octagon: column name unknown: %@", proposedColumnName); + } + } + else if([tableName isEqualToString:peerTable]){ //not using yet! + result = NO; + secerror("octagon: not using this table yet!"); + } + else if([tableName isEqualToString:bottledPeerTable]) + { + if([proposedColumnName isEqualToString:OTCKRecordContextAndDSID]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordRecordID]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordEscrowRecordID]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordSPID]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordPeerID]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordBottle]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordSignatureFromEscrow]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordSignatureFromPeerKey]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordEncodedRecord]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordLaunched]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordPeerSigningSPKI]){ + result = YES; + } + else if([proposedColumnName isEqualToString:OTCKRecordEscrowSigningSPKI]){ + result = YES; + } + else{ + secerror("octagon: column name unknown: %@", proposedColumnName); + } + } + else{ + secerror("octagon: table name unknown: %@", tableName); + } + return result; +} + +///// +// Local Context Record +///// +-(OTContextRecord* _Nullable)readLocalContextRecordForContextIDAndDSID:(NSString*)contextAndDSID error:(NSError**)error +{ + OTContextRecord* record = [[OTContextRecord alloc]init]; + NSDictionary* attributes = nil; + NSArray *selectArray = nil; + + selectArray = selectDictionaries(_pDB, @"SELECT * from context WHERE contextIDAndDSID == %@;", PQLName(contextAndDSID)); + if(selectArray && [selectArray count] > 0){ + attributes = [selectArray objectAtIndex:0]; + } + if(attributes && [attributes count] > 0){ + record.contextID = attributes[OTCKRecordContextID]; + record.dsid = attributes[OTCKRecordDSID]; + record.contextName = attributes[OTCKRecordContextName]; + record.zoneCreated = (BOOL)attributes[OTCKRecordZoneCreated]; + record.subscribedToChanges = (BOOL)attributes[OTCKRecordSubscribedToChanges]; + record.changeToken = attributes[OTCKRecordChangeToken]; + record.egoPeerID = attributes[OTCKRecordEgoPeerID]; + record.egoPeerCreationDate = attributes[OTCKRecordEgoPeerCreationDate]; + record.recoverySigningSPKI = dataFromBase64(attributes[OTCKRecordRecoverySigningSPKI]); + record.recoveryEncryptionSPKI = dataFromBase64(attributes[OTCKRecordRecoveryEncryptionSPKI]); + } + else{ + secerror("octagon: no context attributes found"); + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"no context attributes found"}]; + } + } + + return record; +} + +-(BOOL)initializeContextTable:(NSString*)contextID dsid:(NSString*)dsid error:(NSError**)error +{ + BOOL result = NO; + NSError* localError = nil; + NSString* contextName = nil; +#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR + contextName = (__bridge_transfer NSString *)MGCopyAnswer(kMGQUserAssignedDeviceName, NULL); +#else + contextName = (__bridge_transfer NSString *)SCDynamicStoreCopyComputerName(NULL, NULL); +#endif + + NSDictionary *contextAttributes = @{ + OTCKRecordContextAndDSID : [NSString stringWithFormat:@"%@-%@", contextID, dsid], + OTCKRecordContextID : contextID, + OTCKRecordDSID : dsid, + OTCKRecordContextName : contextName, + OTCKRecordZoneCreated : @(NO), + OTCKRecordSubscribedToChanges : @(NO), + OTCKRecordChangeToken : [NSData data], + OTCKRecordEgoPeerID : @"ego peer id", + OTCKRecordEgoPeerCreationDate : [NSDate date], + OTCKRecordRecoverySigningSPKI : [NSData data], + OTCKRecordRecoveryEncryptionSPKI : [NSData data]}; + + result = [self insertLocalContextRecord:contextAttributes error:&localError]; + if(!result || localError != nil){ + secerror("octagon: context table init failed: %@", localError); + if(error){ + *error = localError; + } + } + return result; +} + +-(BOOL)insertLocalContextRecord:(NSDictionary*)attributes error:(NSError**)error +{ + BOOL result = NO; + + NSString* dsidAndContext = [NSString stringWithFormat:@"%@-%@", attributes[OTCKRecordContextID], attributes[OTCKRecordDSID]]; + result = [_pDB execute:@"insert into context (contextIDAndDSID, contextID, accountDSID, contextName, zoneCreated, subscribedToChanges, changeToken, egoPeerID, egoPeerCreationDate, recoverySigningSPKI, recoveryEncryptionSPKI) values (%@,%@,%@,%@,%@,%@,%@,%@,%@,%@,%@)", + dsidAndContext, attributes[OTCKRecordContextID], attributes[OTCKRecordDSID], attributes[OTCKRecordContextName], attributes[OTCKRecordZoneCreated], + attributes[OTCKRecordSubscribedToChanges], attributes[OTCKRecordChangeToken], + attributes[OTCKRecordEgoPeerID], attributes[OTCKRecordEgoPeerCreationDate], + [attributes[OTCKRecordRecoverySigningSPKI] base64EncodedStringWithOptions:0], [attributes[OTCKRecordRecoveryEncryptionSPKI] base64EncodedStringWithOptions:0]]; + + + if(_pDB.lastError){ + secerror("octagon: failed to insert local context: %@", _pDB.lastError); + if(error){ + *error = _pDB.lastError; + } + } + return result; +} + +-(BOOL)updateLocalContextRecordRowWithContextID:(NSString*)contextIDAndDSID columnName:(NSString*)columnName newValue:(void*)newValue error:(NSError**)error +{ + BOOL result = NO; + if([self isProposedColumnNameInTable:columnName tableName:contextTable]){ + result = [_pDB execute:@"update context set %@ = %@ where contextIDAndDSID == %@", + PQLName(columnName), newValue, PQLName(_contextID)]; + if(!result && error){ + secerror("octagon: error updating table: %@", _pDB.lastError); + *error = _pDB.lastError; + } + } + else{ + secerror("octagon: failed to update local context record: %@", _pDB.lastError); + + if(error != nil){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorNoColumn userInfo:nil]; + } + } + return result; +} + +-(BOOL) deleteLocalContext:(NSString*)contextIDAndDSID error:(NSError**)error +{ + BOOL result = NO; + secnotice("octagon", "deleting local context: %@", contextIDAndDSID); + + result = [_pDB execute:@"delete from context where contextIDAndDSID == %@", + PQLName(contextIDAndDSID)]; + + if(!result){ + secerror("octagon: error updating table: %@", _pDB.lastError); + if(error){ + *error = _pDB.lastError; + } + } + return result; +} + +-(BOOL) deleteAllContexts:(NSError**)error +{ + BOOL result = NO; + secnotice("octagon", "deleting all local context"); + + result = [_pDB execute:@"delete from context"]; + + if(!result){ + secerror("octagon: error updating table: %@", _pDB.lastError); + if(error){ + *error = _pDB.lastError; + } + } + return result; +} + +///// +// Local Bottled Peer Record +///// + +- (BOOL) insertBottledPeerRecord:(OTBottledPeerRecord *)rec + escrowRecordID:(NSString *)escrowRecordID + error:(NSError**)error +{ + BOOL result; + + result = [_pDB execute:@"insert or replace into bp (bottledPeerRecordID, contextIDAndDSID, escrowRecordID, peerID, spID, bottle, escrowSigningSPKI, peerSigningSPKI, signatureUsingEscrow, signatureUsingPeerKey, encodedRecord, launched) values (%@,%@,%@,%@,%@,%@,%@,%@,%@,%@,%@,%@)", + rec.recordName, + [NSString stringWithFormat:@"%@-%@", self.contextID, self.dsid], + escrowRecordID, + rec.peerID, + rec.spID, + [rec.bottle base64EncodedStringWithOptions:0], + [rec.escrowedSigningSPKI base64EncodedStringWithOptions:0], + [rec.peerSigningSPKI base64EncodedStringWithOptions:0], + [rec.signatureUsingEscrowKey base64EncodedStringWithOptions:0], + [rec.signatureUsingPeerKey base64EncodedStringWithOptions:0], + [rec.encodedRecord base64EncodedStringWithOptions:0], + rec.launched]; + + if (!result) { + secerror("octagon: error inserting bottled peer record: %@", _pDB.lastError); + if(error){ + *error = _pDB.lastError; + } + } + return result; +} + +-(BOOL) removeAllBottledPeerRecords:(NSError**)error +{ + BOOL result = NO; + + result = [_pDB execute:@"DELETE from bp WHERE contextIDAndDSID == %@;", [NSString stringWithFormat:@"%@-%@", self.contextID, self.dsid]]; + + if (!result) { + secerror("octagon: error removing bottled peer records: %@", _pDB.lastError); + if(error){ + *error = _pDB.lastError; + } + } + return result; +} + +-(BOOL) deleteBottledPeer:(NSString*) recordID + error:(NSError**)error +{ + BOOL result = NO; + + result = [_pDB execute:@"DELETE from bp WHERE contextIDAndDSID == %@ AND bottledPeerRecordID == %@;", [NSString stringWithFormat:@"%@-%@", self.contextID, self.dsid], recordID]; + + if (!result) { + secerror("octagon: error removing bottled peer record:%@, error: %@", recordID, _pDB.lastError); + if(error){ + *error = _pDB.lastError; + } + } + return result; +} + +-(BOOL) deleteBottledPeersForContextAndDSID:(NSString*) contextIDAndDSID + error:(NSError**)error +{ + BOOL result = NO; + + result = [_pDB execute:@"DELETE from bp WHERE contextIDAndDSID == %@;", contextIDAndDSID]; + + if (!result) { + secerror("octagon: error removing bottled peer record:%@, error: %@", contextIDAndDSID, _pDB.lastError); + if(error){ + *error = _pDB.lastError; + } + } + return result; +} + +- (nullable OTBottledPeerRecord *)readLocalBottledPeerRecordWithRecordID:(NSString *)recordID + error:(NSError**)error +{ + NSArray *selectArray; + + selectArray = selectDictionaries(_pDB, @"SELECT * from bp WHERE contextIDAndDSID == %@ AND bottledPeerRecordID == %@;", [NSString stringWithFormat:@"%@-%@", self.contextID, self.dsid], recordID); + if (!selectArray) { + if (error) { + secerror("octagon: failed to read local store entry for %@", recordID); + *error = self.pDB.lastError; + } + return nil; + } + if ([selectArray count] > 1) { + secerror("octagon: error multiple records exist in local store for %@", recordID); + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"error multiple records exist in local store"}]; + } + return nil; + } + else if([selectArray count] == 0){ + secerror("octagon: record does not exist: %@", recordID); + return nil; + } + NSDictionary *attributes = [selectArray objectAtIndex:0]; + + OTBottledPeerRecord *rec = [[OTBottledPeerRecord alloc] init]; + rec.escrowRecordID = attributes[OTCKRecordEscrowRecordID]; + rec.peerID = attributes[OTCKRecordPeerID]; + rec.spID = attributes[OTCKRecordSPID]; + rec.bottle = dataFromBase64(attributes[OTCKRecordBottle]); + rec.escrowedSigningSPKI = dataFromBase64(attributes[OTCKRecordEscrowSigningSPKI]); + rec.peerSigningSPKI = dataFromBase64(attributes[OTCKRecordPeerSigningSPKI]); + rec.signatureUsingEscrowKey = dataFromBase64(attributes[OTCKRecordSignatureFromEscrow]); + rec.signatureUsingPeerKey = dataFromBase64(attributes[OTCKRecordSignatureFromPeerKey]); + rec.encodedRecord = dataFromBase64(attributes[OTCKRecordEncodedRecord]); + rec.launched = attributes[OTCKRecordLaunched]; + return rec; +} + +- (NSMutableArray*) convertResultsToBottles:(NSArray*) selectArray +{ + NSMutableArray *arrayOfBottleRecords = [NSMutableArray array]; + for(NSDictionary* bottle in selectArray){ + OTBottledPeerRecord *rec = [[OTBottledPeerRecord alloc] init]; + rec.escrowRecordID = bottle[OTCKRecordEscrowRecordID]; + rec.peerID = bottle[OTCKRecordPeerID]; + rec.spID = bottle[OTCKRecordSPID]; + rec.bottle = dataFromBase64(bottle[OTCKRecordBottle]); + rec.escrowedSigningSPKI = dataFromBase64(bottle[OTCKRecordEscrowSigningSPKI]); + rec.peerSigningSPKI = dataFromBase64(bottle[OTCKRecordPeerSigningSPKI]); + rec.signatureUsingEscrowKey = dataFromBase64(bottle[OTCKRecordSignatureFromEscrow]); + rec.signatureUsingPeerKey = dataFromBase64(bottle[OTCKRecordSignatureFromPeerKey]); + rec.encodedRecord = dataFromBase64(bottle[OTCKRecordEncodedRecord]); + rec.launched = bottle[OTCKRecordLaunched]; + + [arrayOfBottleRecords addObject:rec]; + } + return arrayOfBottleRecords; +} + +- (nullable NSArray*) readAllLocalBottledPeerRecords:(NSError**)error +{ + NSArray *selectArray; + + selectArray = selectDictionaries(_pDB, @"SELECT * from bp where contextIDAndDSID == %@;", [NSString stringWithFormat:@"%@-%@", self.contextID, self.dsid]); + if (!selectArray) { + if (error) { + secerror("octagon: failed to read local store entries"); + *error = self.pDB.lastError; + } + return nil; + } + if ([selectArray count] == 0) { + secerror("octagon: there are no bottled peer entries in local store"); + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"there are no bottled peer entries in local store"}]; + } + return nil; + } + + return [self convertResultsToBottles:selectArray]; +} + +- (nullable NSArray*) readLocalBottledPeerRecordsWithMatchingPeerID:(NSString*)peerID error:(NSError**)error +{ + NSArray *selectArray; + + selectArray = selectDictionaries(_pDB, @"SELECT * from bp where spID == %@;", peerID); + if (!selectArray) { + if (error) { + secerror("octagon: failed to read local store entries"); + *error = self.pDB.lastError; + } + return nil; + } + if ([selectArray count] == 0) { + secerror("octagon: there are no bottled peer entries in local store"); + if(error){ + *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"there are no bottled peer entries in local store"}]; + } + return nil; + } + + return [self convertResultsToBottles:selectArray]; +} + +static NSData * _Nullable dataFromBase64(NSString * _Nullable base64) +{ + if (base64 && [base64 length] > 0) { + return [[NSData alloc] initWithBase64EncodedString:base64 options:0]; + } + return nil; +} + +@end +#endif diff --git a/keychain/ot/OTManager.h b/keychain/ot/OTManager.h new file mode 100644 index 00000000..5c3aba0d --- /dev/null +++ b/keychain/ot/OTManager.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +#import + +#if OCTAGON +#import "keychain/ot/OTManager.h" +#import "keychain/ot/OTContext.h" +#import "keychain/ot/OTControlProtocol.h" +#include + +NS_ASSUME_NONNULL_BEGIN + +@class OTContext; + +@interface OTManager : NSObject + +@property (nonatomic, readonly) NSDate *lastPostedCoreFollowUp; + +-(instancetype)init; + +-(instancetype) initWithContext:(OTContext* __nullable)context + localStore:(OTLocalStore* __nullable)localStore + enroll:(OTRamp*)enroll + restore:(OTRamp*)restore + cfu:(OTRamp*)cfu + cfuScheduler:(CKKSNearFutureScheduler*)cfuScheduler; + ++ (instancetype _Nullable)manager; +-(BOOL)scheduledCloudKitRampCheck:(NSError**)error; +@end +NS_ASSUME_NONNULL_END + +#endif // OCTAGON + diff --git a/keychain/ot/OTManager.m b/keychain/ot/OTManager.m new file mode 100644 index 00000000..cef912b2 --- /dev/null +++ b/keychain/ot/OTManager.m @@ -0,0 +1,888 @@ +/* + * Copyright (c) 2016 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +#import "SecEntitlements.h" +#import +#import + + +#if OCTAGON +#import "keychain/ot/OTControlProtocol.h" +#import "keychain/ot/OTControl.h" +#import "keychain/ot/OTContext.h" +#import "keychain/ot/OTManager.h" +#import "keychain/ot/OTDefines.h" +#import "keychain/ot/OTRamping.h" +#import "keychain/ot/SFPublicKey+SPKI.h" +#import "keychain/ot/OT.h" +#import "keychain/ot/OTConstants.h" + +#import "keychain/ckks/CloudKitCategories.h" +#import "keychain/ckks/CKKSAnalytics.h" +#import "keychain/ckks/CKKSNearFutureScheduler.h" +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSViewManager.h" +#import "keychain/ckks/CKKSLockStateTracker.h" + +#import +#import + +#import +#import + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR +#import +#import +#import +#import +#import +#import +#else +#import +#import +#import +#import +#import +#import +#endif + +#import +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#import +#pragma clang diagnostic pop + +static NSString* const kOTRampForEnrollmentRecordName = @"metadata_rampstate_enroll"; +static NSString* const kOTRampForRestoreRecordName = @"metadata_rampstate_restore"; +static NSString* const kOTRampForCFURecordName = @"metadata_rampstate_cfu"; +static NSString* const kOTRampZoneName = @"metadata_zone"; +#define NUM_NSECS_IN_24_HRS (86400 * NSEC_PER_SEC) + +@interface OTManager () +@property NSXPCListener *listener; +@property (nonatomic, strong) OTContext* context; +@property (nonatomic, strong) OTLocalStore *localStore; +@property (nonatomic, strong) OTRamp *enrollRamp; +@property (nonatomic, strong) OTRamp *restoreRamp; +@property (nonatomic, strong) OTRamp *cfuRamp; +@property (nonatomic, strong) CKKSNearFutureScheduler *cfuScheduler; +@property (nonatomic, strong) NSDate *lastPostedCoreFollowUp; +@end + +@implementation OTManager + +-(instancetype)init +{ + OTLocalStore* localStore = nil; + OTContext* context = nil; + + NSString* dsid = [self askAccountsForDSID]; + if(dsid){ + localStore = [[OTLocalStore alloc]initWithContextID:OTDefaultContext dsid:dsid path:nil error:nil]; + context = [[OTContext alloc]initWithContextID:OTDefaultContext dsid:dsid localStore:self.localStore cloudStore:nil identityProvider:self error:nil]; + } + //initialize our scheduler + CKKSNearFutureScheduler *cfuScheduler = [[CKKSNearFutureScheduler alloc] initWithName:@"scheduling-cfu" initialDelay:NUM_NSECS_IN_24_HRS continuingDelay:NUM_NSECS_IN_24_HRS keepProcessAlive:true dependencyDescriptionCode:CKKSResultDescriptionNone block:^{ + secnotice("octagon", "running scheduled cfu block"); + NSError* error = nil; + [self scheduledCloudKitRampCheck:&error]; + }]; + + //initialize our ramp objects + [self initRamps]; + + return [self initWithContext:context + localStore:localStore + enroll:self.enrollRamp + restore:self.restoreRamp + cfu:self.cfuRamp + cfuScheduler:cfuScheduler]; +} + +-(instancetype) initWithContext:(OTContext*)context + localStore:(OTLocalStore*)localStore + enroll:(OTRamp*)enroll + restore:(OTRamp*)restore + cfu:(OTRamp*)cfu + cfuScheduler:(CKKSNearFutureScheduler*)cfuScheduler +{ + self = [super init]; + if(self){ + self.context = context; + self.localStore = localStore; + self.cfuRamp = cfu; + self.enrollRamp = enroll; + self.restoreRamp = restore; + self.cfuScheduler = cfuScheduler; + + secnotice("octagon", "otmanager init"); + } + return self; +} + +-(NSString*) askAccountsForDSID +{ + NSString *dsid = nil; + ACAccountStore *accountStore = [[ACAccountStore alloc] init]; + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + ACAccount *account = [accountStore aa_primaryAppleAccount]; + dsid = [account aa_personID]; +#else + ACAccount *primaryiCloudAccount = nil; + if ([accountStore respondsToSelector:@selector(icaPrimaryAppleAccount)]){ + primaryiCloudAccount = [accountStore icaPrimaryAppleAccount]; + } + dsid = [primaryiCloudAccount icaPersonID]; +#endif + return dsid; +} + ++ (instancetype _Nullable)manager { + static OTManager* manager = nil; + + if(!SecOTIsEnabled()) { + secerror("octagon: Attempt to fetch a manager while Octagon is disabled"); + return nil; + } + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + manager = [[OTManager alloc]init]; + }); + + return manager; +} + + +-(BOOL) initRamps +{ + BOOL initResult = NO; + + CKContainer* container = [CKKSViewManager manager].container; + CKDatabase* database = [container privateCloudDatabase]; + CKRecordZoneID* zoneID = [[CKRecordZoneID alloc] initWithZoneName:kOTRampZoneName ownerName:CKCurrentUserDefaultName]; + + CKKSCKAccountStateTracker *accountTracker = [CKKSViewManager manager].accountTracker; + CKKSReachabilityTracker *reachabilityTracker = [CKKSViewManager manager].reachabilityTracker; + CKKSLockStateTracker *lockStateTracker = [CKKSViewManager manager].lockStateTracker; + + self.cfuRamp = [[OTRamp alloc]initWithRecordName:kOTRampForCFURecordName + featureName:@"cfu" + container:container + database:database + zoneID:zoneID + accountTracker:accountTracker + lockStateTracker:lockStateTracker + reachabilityTracker:reachabilityTracker + fetchRecordRecordsOperationClass:[CKFetchRecordsOperation class]]; + + self.enrollRamp = [[OTRamp alloc]initWithRecordName:kOTRampForEnrollmentRecordName + featureName:@"enroll" + container:container + database:database + zoneID:zoneID + accountTracker:accountTracker + lockStateTracker:lockStateTracker + reachabilityTracker:reachabilityTracker + fetchRecordRecordsOperationClass:[CKFetchRecordsOperation class]]; + + + self.restoreRamp = [[OTRamp alloc]initWithRecordName:kOTRampForRestoreRecordName + featureName:@"restore" + container:container + database:database + zoneID:zoneID + accountTracker:accountTracker + lockStateTracker:lockStateTracker + reachabilityTracker:reachabilityTracker + fetchRecordRecordsOperationClass:[CKFetchRecordsOperation class]]; + + if(self.cfuRamp && self.enrollRamp && self.restoreRamp){ + initResult = YES; + } + return initResult; +} + +-(BOOL) initializeManagerPropertiesForContext:(NSString*)dsid error:(NSError**)error +{ + CKKSAnalytics* logger = [CKKSAnalytics logger]; + NSError *localError = nil; + BOOL initialized = YES; + + if(dsid == nil){ + dsid = [self askAccountsForDSID]; + } + + //create local store + self.localStore = [[OTLocalStore alloc] initWithContextID:OTDefaultContext dsid:dsid path:nil error:&localError]; + if(!self.localStore){ + secerror("octagon: could not create localStore: %@", localError); + [logger logUnrecoverableError:localError forEvent:OctagonEventSignIn withAttributes:@{ + OctagonEventAttributeFailureReason : @"creating local store", + }]; + initialized = NO; + } + + //create context + self.context = [[OTContext alloc]initWithContextID:OTDefaultContext dsid:dsid localStore:self.localStore cloudStore:nil identityProvider:self error:&localError]; + if(!self.context){ + secerror("octagon: could not create context: %@", localError); + [logger logUnrecoverableError:localError forEvent:OctagonEventSignIn withAttributes:@{ + OctagonEventAttributeFailureReason : @"creating context", + }]; + self.localStore = nil; + initialized = NO; + } + + //just in case, init the ramp objects + [self initRamps]; + + if(localError && error){ + *error = localError; + } + return initialized; +} + +/* + * SPI routines + */ + +- (void)signIn:(NSString*)dsid reply:(void (^)(BOOL result, NSError * _Nullable signedInError))reply +{ + CKKSAnalytics* logger = [CKKSAnalytics logger]; + SFAnalyticsActivityTracker *tracker = [logger logSystemMetricsForActivityNamed:CKKSActivityOctagonSignIn withAction:nil]; + [tracker start]; + + NSError *error = nil; + if(![self initializeManagerPropertiesForContext:dsid error:&error]){ + [tracker cancel]; + reply(NO, error); + return; + } + + [tracker stop]; + [logger logSuccessForEventNamed:OctagonEventSignIn]; + + secnotice("octagon","created context and local store on manager for:%@", dsid); + + reply(YES, error); +} + +- (void)signOut:(void (^)(BOOL result, NSError * _Nullable signedOutError))reply +{ + CKKSAnalytics* logger = [CKKSAnalytics logger]; + + NSError* error = nil; + NSError *bottledPeerError = nil; + NSError *localContextError = nil; + + secnotice("octagon", "signing out of octagon trust: dsid: %@ contextID: %@", + self.context.dsid, + self.context.contextID); + + NSString* contextAndDSID = [NSString stringWithFormat:@"%@-%@", self.context.contextID, self.context.dsid]; + + //remove all locally stored context + BOOL result1 = [self.localStore deleteLocalContext:contextAndDSID error:&localContextError]; + if(!result1){ + secerror("octagon: could not delete local context: %@: %@", self.context.contextID, localContextError); + [logger logUnrecoverableError:localContextError forEvent:OctagonEventSignOut withAttributes:@{ + OctagonEventAttributeFailureReason : @"deleting local context", + }]; + error = localContextError; + } + + BOOL result2 = [self.localStore deleteBottledPeersForContextAndDSID:contextAndDSID error:&bottledPeerError]; + if(!result2){ + secerror("octagon: could not delete bottle peer records: %@: %@", self.context.contextID, bottledPeerError); + [logger logUnrecoverableError:bottledPeerError forEvent:OctagonEventSignOut withAttributes:@{ + OctagonEventAttributeFailureReason : @"deleting local bottled peers", + }]; + error = bottledPeerError; + } + + //free context & local store + self.context = nil; + self.localStore = nil; + + BOOL result = (result1 && result2); + if (result) { + [logger logSuccessForEventNamed:OctagonEventSignOut]; + } + + reply(result, error); +} +- (void)preflightBottledPeer:(NSString*)contextID + dsid:(NSString*)dsid + reply:(void (^)(NSData* _Nullable entropy, + NSString* _Nullable bottleID, + NSData* _Nullable signingPublicKey, + NSError* _Nullable error))reply +{ + secnotice("octagon", "preflightBottledPeer: %@ %@", contextID, dsid); + NSError* error = nil; + CKKSAnalytics* logger = [CKKSAnalytics logger]; + SFAnalyticsActivityTracker *tracker = [logger logSystemMetricsForActivityNamed:CKKSActivityOctagonPreflightBottle withAction:nil]; + + [tracker start]; + + if(!self.context || !self.localStore){ + if(![self initializeManagerPropertiesForContext:dsid error:&error]){ + secerror("octagon: could not init manager obejcts: %@", error); + reply(nil,nil,nil,error); + [tracker cancel]; + return; + } + } + + NSInteger retryDelayInSeconds = 0; + BOOL isFeatureOn = [self.enrollRamp checkRampState:&retryDelayInSeconds qos:NSQualityOfServiceUserInitiated error:&error]; + + //got an error from ramp check, we should log it + if(error){ + [logger logRecoverableError:error + forEvent:OctagonEventRamp + zoneName:kOTRampZoneName + withAttributes:@{ + OctagonEventAttributeFailureReason : @"ramp check for preflight bottle" + }]; + } + + if(!isFeatureOn){ //cloud kit has not asked us to come back and the feature is off for this device + secnotice("octagon", "bottled peers is not on"); + if(!error){ + error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorFeatureNotEnabled userInfo:@{NSLocalizedDescriptionKey: @"Feature not enabled"}]; + } + reply(nil, nil, nil, error); + return; + } + + NSData* entropy = [self.context makeMeSomeEntropy:OTMasterSecretLength]; + if(!entropy){ + secerror("octagon: entropy creation failed: %@", error); + error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorEntropyCreationFailure userInfo:@{NSLocalizedDescriptionKey: @"Failed to create entropy"}]; + [logger logUnrecoverableError:error forEvent:OctagonEventPreflightBottle withAttributes:@{ + OctagonEventAttributeFailureReason : @"preflight bottle, entropy failure"} + ]; + [tracker stop]; + reply(nil, nil, nil, error); + return; + } + + OTPreflightInfo* result = [self.context preflightBottledPeer:contextID entropy:entropy error:&error]; + if(!result || error){ + secerror("octagon: preflight failed: %@", error); + [logger logUnrecoverableError:error forEvent:OctagonEventPreflightBottle withAttributes:@{ OctagonEventAttributeFailureReason : @"preflight bottle"}]; + reply(nil, nil, nil, error); + [tracker stop]; + return; + } + + [tracker stop]; + [logger logSuccessForEventNamed:OctagonEventPreflightBottle]; + + secnotice("octagon", "preflightBottledPeer completed, created: %@", result.bottleID); + + reply(entropy, result.bottleID, result.escrowedSigningSPKI, error); +} + +- (void)launchBottledPeer:(NSString*)contextID + bottleID:(NSString*)bottleID + reply:(void (^ _Nullable)(NSError* _Nullable error))reply +{ + secnotice("octagon", "launchBottledPeer"); + NSError* error = nil; + CKKSAnalytics* logger = [CKKSAnalytics logger]; + SFAnalyticsActivityTracker *tracker = [logger logSystemMetricsForActivityNamed:CKKSActivityOctagonLaunchBottle withAction:nil]; + + [tracker start]; + + if(!self.context || !self.localStore){ + if(![self initializeManagerPropertiesForContext:nil error:&error]){ + [tracker cancel]; + reply(error); + return; + } + } + + NSInteger retryDelayInSeconds = 0; + BOOL isFeatureOn = [self.enrollRamp checkRampState:&retryDelayInSeconds qos:NSQualityOfServiceUserInitiated error:&error]; + + //got an error from ramp check, we should log it + if(error){ + [logger logRecoverableError:error + forEvent:OctagonEventRamp + zoneName:kOTRampZoneName + withAttributes:@{ + OctagonEventAttributeFailureReason : @"ramp state check for launch bottle" + }]; + } + + if(!isFeatureOn){ + secnotice("octagon", "bottled peers is not on"); + if(!error){ + error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorFeatureNotEnabled userInfo:@{NSLocalizedDescriptionKey: @"Feature not enabled"}]; + } + reply(error); + return; + } + + OTBottledPeerRecord* bprecord = [self.localStore readLocalBottledPeerRecordWithRecordID:bottleID error:&error]; + if(!bprecord || error){ + secerror("octagon: could not retrieve record for: %@, error: %@", bottleID, error); + [logger logUnrecoverableError:error forEvent:OctagonEventLaunchBottle withAttributes:@{ + OctagonEventAttributeFailureReason : @"reading bottle from local store" + }]; + [tracker stop]; + reply(error); + return; + } + BOOL result = [self.context.cloudStore uploadBottledPeerRecord:bprecord escrowRecordID:bprecord.escrowRecordID error:&error]; + if(!result || error){ + secerror("octagon: could not upload record for bottleID %@, error: %@", bottleID, error); + [logger logUnrecoverableError:error forEvent:OctagonEventLaunchBottle withAttributes:@{ + OctagonEventAttributeFailureReason : @"upload bottle to cloud kit" + }]; + [tracker stop]; + reply(error); + return; + } + + [tracker stop]; + [logger logSuccessForEventNamed:OctagonEventLaunchBottle]; + + secnotice("octagon", "successfully launched: %@", bprecord.recordName); + + reply(error); +} + +- (void)restore:(NSString *)contextID dsid:(NSString *)dsid secret:(NSData*)secret escrowRecordID:(NSString*)escrowRecordID reply:(void (^)(NSData* signingKeyData, NSData* encryptionKeyData, NSError *))reply +{ + //check if configuration zone allows restore + NSError* error = nil; + CKKSAnalytics* logger = [CKKSAnalytics logger]; + SFAnalyticsActivityTracker *tracker = [logger logSystemMetricsForActivityNamed:CKKSActivityOctagonRestore withAction:nil]; + + [tracker start]; + + if(!self.context || !self.localStore){ + if(![self initializeManagerPropertiesForContext:dsid error:&error]){ + secerror("octagon: could not init manager obejcts: %@", error); + reply(nil,nil,error); + [tracker cancel]; + return; + } + } + + NSInteger retryDelayInSeconds = 0; + BOOL isFeatureOn = [self.restoreRamp checkRampState:&retryDelayInSeconds qos:NSQualityOfServiceUserInitiated error:&error]; + + //got an error from ramp check, we should log it + if(error){ + [logger logRecoverableError:error + forEvent:OctagonEventRamp + zoneName:kOTRampZoneName + withAttributes:@{ + OctagonEventAttributeFailureReason : @"checking ramp state for restore" + }]; + } + + if(!isFeatureOn){ + secnotice("octagon", "bottled peers is not on"); + if(!error){ + error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorFeatureNotEnabled userInfo:@{NSLocalizedDescriptionKey: @"Feature not enabled"}]; + } + [tracker stop]; + reply(nil, nil, error); + return; + } + + if(!escrowRecordID || [escrowRecordID length] == 0){ + secerror("octagon: missing escrowRecordID"); + error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorEmptyEscrowRecordID userInfo:@{NSLocalizedDescriptionKey: @"Escrow Record ID is empty or missing"}]; + + [logger logUnrecoverableError:error forEvent:OctagonEventRestoreBottle withAttributes:@{ + OctagonEventAttributeFailureReason : @"escrow record id missing", + }]; + + [tracker stop]; + reply(nil, nil, error); + return; + } + if(!dsid || [dsid length] == 0){ + secerror("octagon: missing dsid"); + error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorEmptyDSID userInfo:@{NSLocalizedDescriptionKey: @"DSID is empty or missing"}]; + + [logger logUnrecoverableError:error forEvent:OctagonEventRestoreBottle withAttributes:@{ + OctagonEventAttributeFailureReason : @"dsid missing", + }]; + [tracker stop]; + reply(nil, nil, error); + return; + } + if(!secret || [secret length] == 0){ + secerror("octagon: missing secret"); + error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorEmptySecret userInfo:@{NSLocalizedDescriptionKey: @"Secret is empty or missing"}]; + + + [logger logUnrecoverableError:error forEvent:OctagonEventRestoreBottle withAttributes:@{ + OctagonEventAttributeFailureReason : @"secret missing", + }]; + + [tracker stop]; + reply(nil, nil, error); + return; + } + + OTBottledPeerSigned *bps = [_context restoreFromEscrowRecordID:escrowRecordID secret:secret error:&error]; + if(!bps || error != nil){ + secerror("octagon: failed to restore bottled peer: %@", error); + + [logger logUnrecoverableError:error forEvent:OctagonEventRestoreBottle withAttributes:@{ + OctagonEventAttributeFailureReason : @"restore failed", + }]; + [tracker stop]; + reply(nil, nil, error); + return; + } + + NSData *encryptionKeyData = bps.bp.peerEncryptionKey.publicKey.keyData; // FIXME + if(!encryptionKeyData){ + secerror("octagon: restored octagon encryption key is nil: %@", error); + error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorRestoredPeerEncryptionKeyFailure userInfo:@{NSLocalizedDescriptionKey: @"Failed to retrieve restored Octagon Peer Encryption Key"}]; + + [logger logUnrecoverableError:error forEvent:OctagonEventRestoreBottle withAttributes:@{ + OctagonEventAttributeFailureReason : @"restored octagon encryption key" + }]; + [tracker stop]; + reply(nil,nil,error); + return; + } + + NSData *signingKeyData = bps.bp.peerSigningKey.publicKey.keyData; // FIXME + if(!signingKeyData){ + secerror("octagon: restored octagon signing key is nil: %@", error); + error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorRestoredPeerSigningKeyFailure userInfo:@{NSLocalizedDescriptionKey: @"Failed to retrieve restored Octagon Peer Signing Key"}]; + + [logger logUnrecoverableError:error forEvent:OctagonEventRestoreBottle withAttributes:@{ + OctagonEventAttributeFailureReason : @"restored octagon signing key" + }]; + [tracker stop]; + reply(nil,nil,error); + return; + } + [tracker stop]; + + [logger logSuccessForEventNamed:OctagonEventRestoreBottle]; + + secnotice("octagon", "restored bottled peer: %@", escrowRecordID); + + reply(signingKeyData, encryptionKeyData, error); +} + +- (void)scrubBottledPeer:(NSString*)contextID + bottleID:(NSString*)bottleID + reply:(void (^ _Nullable)(NSError* _Nullable error))reply +{ + NSError* error = nil; + + CKKSAnalytics* logger = [CKKSAnalytics logger]; + SFAnalyticsActivityTracker *tracker = [logger logSystemMetricsForActivityNamed:CKKSActivityScrubBottle withAction:nil]; + + if(!self.context || !self.localStore){ + if(![self initializeManagerPropertiesForContext:nil error:&error]){ + [tracker cancel]; + reply(error); + return; + } + } + [tracker start]; + + NSInteger retryDelayInSeconds = 0; + BOOL isFeatureOn = [self.enrollRamp checkRampState:&retryDelayInSeconds qos:NSQualityOfServiceUserInitiated error:&error]; + + //got an error from ramp check, we should log it + if(error){ + [logger logRecoverableError:error + forEvent:OctagonEventRamp + zoneName:kOTRampZoneName + withAttributes:@{ + OctagonEventAttributeFailureReason : @"ramp check for scrubbing bottled peer" + }]; + } + + if(!isFeatureOn){ + secnotice("octagon", "bottled peers is not on"); + if(!error){ + error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorFeatureNotEnabled userInfo:@{NSLocalizedDescriptionKey: @"Feature not enabled"}]; + } + [tracker stop]; + reply(error); + return; + } + + BOOL result = [self.context scrubBottledPeer:contextID bottleID:bottleID error:&error]; + if(!result || error){ + secerror("octagon: could not scrub record for bottleID %@, error: %@", bottleID, error); + [logger logUnrecoverableError:error forEvent:OctagonEventScrubBottle withAttributes:@{ + OctagonEventAttributeFailureReason : @"could not scrub bottle", + }]; + [tracker stop]; + reply(error); + return; + } + [logger logSuccessForEventNamed:OctagonEventScrubBottle]; + + secnotice("octagon", "scrubbed bottled peer: %@", bottleID); + + reply(error); +} + +/* + * OTCTL tool routines + */ + +-(void) reset:(void (^)(BOOL result, NSError *))reply +{ + NSError* error = nil; + + if(self.context.lockStateTracker.isLocked){ + secnotice("octagon","device is locked! can't check ramp state"); + error = [NSError errorWithDomain:(__bridge NSString*)kSecErrorDomain + code:errSecInteractionNotAllowed + userInfo:@{NSLocalizedDescriptionKey: @"device is locked"}]; + + reply(NO,error); + return; + } + if(self.context.accountTracker.currentCKAccountInfo.accountStatus != CKAccountStatusAvailable){ + secnotice("octagon","not signed in! can't check ramp state"); + error = [NSError errorWithDomain:octagonErrorDomain + code:OTErrorNotSignedIn + userInfo:@{NSLocalizedDescriptionKey: @"not signed in"}]; + reply(NO,error); + return; + + } + if(!self.context.reachabilityTracker.currentReachability){ + secnotice("octagon","no network! can't check ramp state"); + error = [NSError errorWithDomain:octagonErrorDomain + code:OTErrorNoNetwork + userInfo:@{NSLocalizedDescriptionKey: @"no network"}]; + reply(NO,error); + return; + } + + NSError* bottledPeerError = nil; + + BOOL result = [_context.cloudStore performReset:&bottledPeerError]; + if(!result || bottledPeerError != nil){ + secerror("octagon: resetting octagon trust zone failed: %@", bottledPeerError); + } + + NSString* contextAndDSID = [NSString stringWithFormat:@"%@-%@", self.context.contextID, self.context.dsid]; + + result = [self.localStore deleteBottledPeersForContextAndDSID:contextAndDSID error:&bottledPeerError]; + if(!result){ + secerror("octagon: could not delete bottle peer records: %@: %@", self.context.contextID, bottledPeerError); + } + + reply(result, bottledPeerError); +} + +- (void)listOfEligibleBottledPeerRecords:(void (^)(NSArray* listOfRecords, NSError *))reply +{ + NSError* error = nil; + + if(self.context.lockStateTracker.isLocked){ + secnotice("octagon","device is locked! can't check ramp state"); + error = [NSError errorWithDomain:(__bridge NSString*)kSecErrorDomain + code:errSecInteractionNotAllowed + userInfo:@{NSLocalizedDescriptionKey: @"device is locked"}]; + + reply(nil,error); + return; + } + if(self.context.accountTracker.currentCKAccountInfo.accountStatus != CKAccountStatusAvailable){ + secnotice("octagon","not signed in! can't check ramp state"); + error = [NSError errorWithDomain:octagonErrorDomain + code:OTErrorNotSignedIn + userInfo:@{NSLocalizedDescriptionKey: @"not signed in"}]; + reply(nil,error); + return; + } + if(!self.context.reachabilityTracker.currentReachability){ + secnotice("octagon","no network! can't check ramp state"); + error = [NSError errorWithDomain:octagonErrorDomain + code:OTErrorNoNetwork + userInfo:@{NSLocalizedDescriptionKey: @"no network"}]; + reply(nil,error); + return; + } + + NSArray* list = [_context.cloudStore retrieveListOfEligibleEscrowRecordIDs:&error]; + if(!list || error !=nil){ + secerror("octagon: there are not eligible bottle peer records: %@", error); + reply(nil,error); + return; + } + reply(list, error); +} + +- (void)octagonEncryptionPublicKey:(void (^)(NSData* encryptionKey, NSError *))reply +{ + __block NSData *encryptionKey = NULL; + __block NSError* localError = nil; + + SOSCCPerformWithOctagonEncryptionPublicKey(^(SecKeyRef octagonPrivKey, CFErrorRef error) { + CFDataRef key; + SecKeyCopyPublicBytes(octagonPrivKey, &key); + encryptionKey = CFBridgingRelease(key); + if(error){ + localError = (__bridge NSError*)error; + } + }); + if(!encryptionKey || localError != nil){ + reply(nil, localError); + secerror("octagon: retrieving the octagon encryption public key failed: %@", localError); + return; + } + reply(encryptionKey, localError); +} + +-(void)octagonSigningPublicKey:(void (^)(NSData* encryptionKey, NSError *))reply +{ + __block NSData *signingKey = NULL; + __block NSError* localError = nil; + + SOSCCPerformWithOctagonSigningPublicKey(^(SecKeyRef octagonPrivKey, CFErrorRef error) { + CFDataRef key; + SecKeyCopyPublicBytes(octagonPrivKey, &key); + signingKey = CFBridgingRelease(key); + if(error){ + localError = (__bridge NSError*)error; + } + }); + if(!signingKey || localError != nil){ + reply(nil, localError); + secerror("octagon: retrieving the octagon signing public key failed: %@", localError); + return; + } + reply(signingKey, localError); +} + +/* + * OT Helpers + */ + +-(BOOL)scheduledCloudKitRampCheck:(NSError**)error +{ + secnotice("octagon", "scheduling a CloudKit ramping check"); + NSInteger retryAfterInSeconds = 0; + NSError* localError = nil; + BOOL cancelScheduler = YES; + + CKKSAnalytics* logger = [CKKSAnalytics logger]; + + if(self.cfuRamp){ + BOOL canCFU = [self.cfuRamp checkRampState:&retryAfterInSeconds qos:NSQualityOfServiceUserInitiated error:&localError]; + + if(localError){ + secerror("octagon: checking ramp state for CFU error'd: %@", localError); + [logger logUnrecoverableError:localError forEvent:OctagonEventRamp withAttributes:@{ + OctagonEventAttributeFailureReason : @"ramp check failed", + }]; + } + + if(canCFU){ + secnotice("octagon", "CFU is enabled, checking if this device has a bottle"); + OctagonBottleCheckState bottleStatus = [self.context doesThisDeviceHaveABottle:&localError]; + + if(bottleStatus == NOBOTTLE){ + //time to post a follow up! + secnotice("octagon", "device does not have a bottle, posting a follow up"); + if(!SecCKKSTestsEnabled()){ + [self.context postFollowUp]; + } + NSInteger timeDiff = -1; + + NSDate *currentDate = [NSDate date]; + if(self.lastPostedCoreFollowUp){ + timeDiff = [currentDate timeIntervalSinceDate:self.lastPostedCoreFollowUp]; + } + + //log how long we last posted a followup, if any + [logger logRecoverableError:localError + forEvent:OctagonEventCoreFollowUp + zoneName:kOTRampZoneName + withAttributes:@{ + OctagonEventAttributeFailureReason : @"No bottle for peer", + OctagonEventAttributeTimeSinceLastPostedFollowUp: [NSNumber numberWithInteger:timeDiff], + }]; + + self.lastPostedCoreFollowUp = currentDate; + //if the followup failed or succeeded, we should continue the scheduler until we have a bottle. + cancelScheduler = NO; + }else if(bottleStatus == BOTTLE){ + secnotice("octagon", "device has a bottle"); + [logger logSuccessForEventNamed:OctagonEventBottleCheck]; + } + + if(localError){ + [logger logRecoverableError:localError + forEvent:OctagonEventBottleCheck + zoneName:kOTRampZoneName + withAttributes:@{ + OctagonEventAttributeFailureReason : @"bottle check", + }]; + } + } + } + if(cancelScheduler == NO){ + secnotice("octagon", "requesting bottle check again"); + [self.cfuScheduler trigger]; + } + + if(error && localError){ + *error = localError; + } + return cancelScheduler; +} + +-(void)scheduleCFUForFuture +{ + secnotice("octagon", "scheduling a query to cloudkit to see if this device can post a core follow up"); + + [self.cfuScheduler trigger]; +} + +- (nullable OTIdentity *) currentIdentity:(NSError**)error +{ + return [OTIdentity currentIdentityFromSOS:error]; +} + +@end + +#endif diff --git a/keychain/ot/OTPreflightInfo.h b/keychain/ot/OTPreflightInfo.h new file mode 100644 index 00000000..c39b0bf4 --- /dev/null +++ b/keychain/ot/OTPreflightInfo.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#ifndef OTPreflightInfo_h +#define OTPreflightInfo_h + +#import + +@interface OTPreflightInfo : NSObject + +@property (nonatomic, strong) NSData* escrowedSigningSPKI; +@property (nonatomic, strong) NSString* bottleID; + +@end + + +#endif /* OTPreflightInfo_h */ +#endif /* OCTAGON */ diff --git a/keychain/ot/OTPreflightInfo.m b/keychain/ot/OTPreflightInfo.m new file mode 100644 index 00000000..539856d4 --- /dev/null +++ b/keychain/ot/OTPreflightInfo.m @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import "OTPreflightInfo.h" + +@implementation OTPreflightInfo + +@end + +#endif diff --git a/keychain/ot/OTPrivateKey+SF.h b/keychain/ot/OTPrivateKey+SF.h new file mode 100644 index 00000000..7b281409 --- /dev/null +++ b/keychain/ot/OTPrivateKey+SF.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import +#import + +#import "OTPrivateKey.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTPrivateKey (SecurityFoundation) + ++ (instancetype)fromECKeyPair:(SFECKeyPair *)keyPair; + +- (nullable SFECKeyPair *)asECKeyPair; + +@end + +NS_ASSUME_NONNULL_END +#endif diff --git a/keychain/ot/OTPrivateKey+SF.m b/keychain/ot/OTPrivateKey+SF.m new file mode 100644 index 00000000..f12ab72d --- /dev/null +++ b/keychain/ot/OTPrivateKey+SF.m @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import "OTPrivateKey+SF.h" + +#import "OTEscrowKeys.h" +#import + +@implementation OTPrivateKey (SecurityFoundation) + ++ (instancetype)fromECKeyPair:(SFECKeyPair *)keyPair +{ + OTPrivateKey *pk = [OTPrivateKey new]; + pk.keyType = OTPrivateKey_KeyType_EC_NIST_CURVES; + pk.keyData = keyPair.keyData; + return pk; +} + +- (nullable SFECKeyPair *)asECKeyPair +{ + if (self.keyType != OTPrivateKey_KeyType_EC_NIST_CURVES) { + return nil; + } + return [[SFECKeyPair alloc] initWithSecKey:[OTEscrowKeys createSecKey:self.keyData]]; +} + +@end + +#endif diff --git a/keychain/ot/OTRamping.h b/keychain/ot/OTRamping.h new file mode 100644 index 00000000..184ee8ac --- /dev/null +++ b/keychain/ot/OTRamping.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2018 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef OTRamping_h +#define OTRamping_h +#if OCTAGON + +#import "keychain/ckks/CKKSNearFutureScheduler.h" +#import "keychain/ckks/CloudKitDependencies.h" +#import "keychain/ckks/CKKSLockStateTracker.h" +#import "keychain/ckks/CKKSCKAccountStateTracker.h" +#import "keychain/ckks/CKKSReachabilityTracker.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTRamp : NSObject + +@property (nonatomic, readonly) NSString* featureName; +@property (nonatomic, readonly) CKKSCKAccountStateTracker *accountTracker; +@property (nonatomic, readonly) CKKSLockStateTracker *lockStateTracker; +@property (nonatomic, readonly) CKKSReachabilityTracker *reachabilityTracker; + +-(instancetype) initWithRecordName:(NSString *) recordName + featureName:(NSString*) featureName + container:(CKContainer*) container + database:(CKDatabase*) database + zoneID:(CKRecordZoneID*) zoneID + accountTracker:(CKKSCKAccountStateTracker*) accountTracker + lockStateTracker:(CKKSLockStateTracker*) lockStateTracker + reachabilityTracker:(CKKSReachabilityTracker*) reachabilityTracker + fetchRecordRecordsOperationClass:(Class) fetchRecordRecordsOperationClass; + +-(void) fetchRampRecord:(NSQualityOfService)qos + reply:(void (^)(BOOL featureAllowed, BOOL featurePromoted, BOOL featureVisible, NSInteger retryAfter, NSError *rampStateFetchError))recordRampStateFetchCompletionBlock; +-(BOOL) checkRampState:(NSInteger*)retryAfter qos:(NSQualityOfService)qos error:(NSError**)error; +@end +NS_ASSUME_NONNULL_END +#endif /* OCTAGON */ +#endif /* OTRamping_h */ diff --git a/keychain/ot/OTRamping.m b/keychain/ot/OTRamping.m new file mode 100644 index 00000000..73991155 --- /dev/null +++ b/keychain/ot/OTRamping.m @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2018 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import +#import +#import +#import +#import +#import "OTRamping.h" +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSNearFutureScheduler.h" +#import "keychain/ckks/CKKSAnalytics.h" +#import "keychain/ot/OTDefines.h" + +static NSString* kFeatureAllowedKey = @"FeatureAllowed"; +static NSString* kFeaturePromotedKey = @"FeaturePromoted"; +static NSString* kFeatureVisibleKey = @"FeatureVisible"; +static NSString* kRetryAfterKey = @"RetryAfter"; +static NSString* kRampPriorityKey = @"RampPriority"; + +#define kCKRampManagerDefaultRetryTimeInSeconds 86400 + +#if OCTAGON +@interface OTRamp (lockstateTracker) +@end +#endif + +@interface OTRamp () +@property (nonatomic, strong) CKContainer *container; +@property (nonatomic, strong) CKDatabase *database; + +@property (nonatomic, strong) CKRecordZone *zone; +@property (nonatomic, strong) CKRecordZoneID *zoneID; + +@property (nonatomic, strong) NSString *recordName; +@property (nonatomic, strong) NSString *featureName; +@property (nonatomic, strong) CKRecordID *recordID; + +@property (nonatomic, strong) CKKSCKAccountStateTracker *accountTracker; +@property (nonatomic, strong) CKKSLockStateTracker *lockStateTracker; +@property (nonatomic, strong) CKKSReachabilityTracker *reachabilityTracker; + +@property CKKSAccountStatus accountStatus; + +@property (readonly) Class fetchRecordRecordsOperationClass; + +@end + +@implementation OTRamp + +-(instancetype) initWithRecordName:(NSString *) recordName + featureName:(NSString*) featureName + container:(CKContainer*) container + database:(CKDatabase*) database + zoneID:(CKRecordZoneID*) zoneID + accountTracker:(CKKSCKAccountStateTracker*) accountTracker + lockStateTracker:(CKKSLockStateTracker*) lockStateTracker + reachabilityTracker:(CKKSReachabilityTracker*) reachabilityTracker +fetchRecordRecordsOperationClass:(Class) fetchRecordRecordsOperationClass + +{ + self = [super init]; + if(self){ + _container = container; + _recordName = [recordName copy]; + _featureName = [featureName copy]; + _database = database; + _zoneID = zoneID; + _accountTracker = accountTracker; + _lockStateTracker = lockStateTracker; + _reachabilityTracker = reachabilityTracker; + _fetchRecordRecordsOperationClass = fetchRecordRecordsOperationClass; + } + return self; +} + +-(void) fetchRampRecord:(NSQualityOfService)qos reply:(void (^)(BOOL featureAllowed, BOOL featurePromoted, BOOL featureVisible, NSInteger retryAfter, NSError *rampStateFetchError))recordRampStateFetchCompletionBlock +{ + __weak __typeof(self) weakSelf = self; + + CKOperationConfiguration *opConfig = [[CKOperationConfiguration alloc] init]; + opConfig.allowsCellularAccess = YES; + opConfig.qualityOfService = qos; + + _recordID = [[CKRecordID alloc] initWithRecordName:_recordName zoneID:_zoneID]; + CKFetchRecordsOperation *operation = [[[self.fetchRecordRecordsOperationClass class] alloc] initWithRecordIDs:@[ _recordID]]; + + operation.desiredKeys = @[kFeatureAllowedKey, kFeaturePromotedKey, kFeatureVisibleKey, kRetryAfterKey]; + + operation.configuration = opConfig; + operation.fetchRecordsCompletionBlock = ^(NSDictionary * _Nullable recordsByRecordID, NSError * _Nullable operationError) { + __strong __typeof(weakSelf) strongSelf = weakSelf; + if(!strongSelf) { + secnotice("octagon", "received callback for released object"); + operationError = [NSError errorWithDomain:octagonErrorDomain code:OTErrorCKCallback userInfo:@{NSLocalizedDescriptionKey: @"Received callback for released object"}]; + recordRampStateFetchCompletionBlock(NO, NO, NO, kCKRampManagerDefaultRetryTimeInSeconds , operationError); + return; + } + + BOOL featureAllowed = NO; + BOOL featurePromoted = NO; + BOOL featureVisible = NO; + NSInteger retryAfter = kCKRampManagerDefaultRetryTimeInSeconds; + + secnotice("octagon", "Fetch operation records %@ fetchError %@", recordsByRecordID, operationError); + // There should only be only one record. + CKRecord *rampRecord = recordsByRecordID[strongSelf.recordID]; + + if (rampRecord) { + featureAllowed = [rampRecord[kFeatureAllowedKey] boolValue]; + featurePromoted = [rampRecord[kFeaturePromotedKey] boolValue]; + featureVisible = [rampRecord[kFeatureVisibleKey] boolValue]; + retryAfter = [rampRecord[kRetryAfterKey] integerValue]; + + secnotice("octagon", "Fetch ramp state - featureAllowed %@, featurePromoted: %@, featureVisible: %@, retryAfter: %ld", (featureAllowed ? @YES : @NO), (featurePromoted ? @YES : @NO), (featureVisible ? @YES : @NO), (long)retryAfter); + } else { + secerror("octagon: Couldn't find CKRecord for ramp. Defaulting to not ramped in"); + operationError = [NSError errorWithDomain:octagonErrorDomain code:OTErrorRecordNotFound userInfo:@{NSLocalizedDescriptionKey: @" Couldn't find CKRecord for ramp. Defaulting to not ramped in"}]; + } + recordRampStateFetchCompletionBlock(featureAllowed, featurePromoted, featureVisible, retryAfter, operationError); + }; + + [self.database addOperation: operation]; + secnotice("octagon", "Attempting to fetch ramp state from CloudKit"); +} + +-(BOOL) checkRampState:(NSInteger*)retryAfter qos:(NSQualityOfService)qos error:(NSError**)error +{ + __block BOOL isFeatureEnabled = NO; + __block NSError* localError = nil; + __block NSInteger localRetryAfter = 0; + + if(self.lockStateTracker.isLocked){ + secnotice("octagon","device is locked! can't check ramp state"); + localError = [NSError errorWithDomain:(__bridge NSString*)kSecErrorDomain + code:errSecInteractionNotAllowed + userInfo:@{NSLocalizedDescriptionKey: @"device is locked"}]; + if(error){ + *error = localError; + } + return NO; + } + if(self.accountTracker.currentCKAccountInfo.accountStatus != CKAccountStatusAvailable){ + secnotice("octagon","not signed in! can't check ramp state"); + localError = [NSError errorWithDomain:octagonErrorDomain + code:OTErrorNotSignedIn + userInfo:@{NSLocalizedDescriptionKey: @"not signed in"}]; + if(error){ + *error = localError; + } + return NO; + } + if(!self.reachabilityTracker.currentReachability){ + secnotice("octagon","no network! can't check ramp state"); + localError = [NSError errorWithDomain:octagonErrorDomain + code:OTErrorNoNetwork + userInfo:@{NSLocalizedDescriptionKey: @"no network"}]; + if(error){ + *error = localError; + } + return NO; + } + + //defaults write to for whether or not a ramp record returns "enabled or disabled" + CFBooleanRef enabled = (CFBooleanRef)CFPreferencesCopyValue((__bridge CFStringRef)self.recordName, + CFSTR("com.apple.security"), + kCFPreferencesAnyUser, kCFPreferencesAnyHost); + if(enabled && CFGetTypeID(enabled) == CFBooleanGetTypeID()){ + BOOL localConfigEnable = (enabled == kCFBooleanTrue); + secnotice("octagon", "feature is %@: %@ (local config)", localConfigEnable ? @"enabled" : @"disabled", self.recordName); + CFReleaseNull(enabled); + return localConfigEnable; + } + CFReleaseNull(enabled); + + CKKSAnalytics* logger = [CKKSAnalytics logger]; + SFAnalyticsActivityTracker *tracker = [logger logSystemMetricsForActivityNamed:CKKSActivityOTFetchRampState withAction:nil]; + + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [tracker start]; + + [self fetchRampRecord:qos reply:^(BOOL featureAllowed, BOOL featurePromoted, BOOL featureVisible, NSInteger retryAfter, NSError *rampStateFetchError) { + secnotice("octagon", "fetch ramp records returned with featureAllowed: %d,\n featurePromoted: %d,\n featureVisible: %d,\n", featureAllowed, featurePromoted, featureVisible); + + isFeatureEnabled = featureAllowed; + localRetryAfter = retryAfter; + if(rampStateFetchError){ + localError = rampStateFetchError; + } + dispatch_semaphore_signal(sema); + }]; + + long timeout = (SecCKKSTestsEnabled() ? 2*NSEC_PER_SEC : NSEC_PER_SEC * 65); + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, timeout)) != 0) { + secnotice("octagon", "timed out waiting for response from CloudKit\n"); + localError = [NSError errorWithDomain:octagonErrorDomain code:OTErrorCKTimeOut userInfo:@{NSLocalizedDescriptionKey: @"Failed to deserialize bottle peer"}]; + + [logger logUnrecoverableError:localError forEvent:OctagonEventRamp withAttributes:@{ + OctagonEventAttributeFailureReason : @"cloud kit timed out"} + ]; + } + + [tracker stop]; + + if(localRetryAfter > 0){ + secnotice("octagon", "cloud kit asked security to retry: %ld", localRetryAfter); + *retryAfter = localRetryAfter; + } + + if(localError){ + secerror("octagon: had an error fetching ramp state: %@", localError); + [logger logUnrecoverableError:localError forEvent:OctagonEventRamp withAttributes:@{ + OctagonEventAttributeFailureReason : @"fetching ramp state"} + ]; + if(error){ + *error = localError; + } + } + if(isFeatureEnabled){ + [logger logSuccessForEventNamed:OctagonEventRamp]; + } + + return isFeatureEnabled; + +} + +- (void)ckAccountStatusChange:(CKKSAccountStatus)oldStatus to:(CKKSAccountStatus)currentStatus { + secnotice("octagon", "%@ Received notification of CloudKit account status change, moving from %@ to %@", + self.zoneID.zoneName, + [CKKSCKAccountStateTracker stringFromAccountStatus: oldStatus], + [CKKSCKAccountStateTracker stringFromAccountStatus: currentStatus]); + + switch(currentStatus) { + case CKKSAccountStatusAvailable: { + secnotice("octagon", "Logged into iCloud."); + self.accountStatus = CKKSAccountStatusAvailable; + } + break; + + case CKKSAccountStatusNoAccount: { + secnotice("octagon", "Logging out of iCloud. Shutting down."); + self.accountStatus = CKKSAccountStatusNoAccount; + } + break; + + case CKKSAccountStatusUnknown: { + // We really don't expect to receive this as a notification, but, okay! + secnotice("octagon", "Account status has become undetermined. Pausing for %@", self.zoneID.zoneName); + self.accountStatus = CKKSAccountStatusNoAccount; + + } + break; + } +} + +@end +#endif + + diff --git a/keychain/ot/OctagonControlServer.h b/keychain/ot/OctagonControlServer.h new file mode 100644 index 00000000..35658dba --- /dev/null +++ b/keychain/ot/OctagonControlServer.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#define kSecuritydOctagonServiceName "com.apple.security.octagon" + +__BEGIN_DECLS + +void OctagonControlServerInitialize(void); + +__END_DECLS diff --git a/keychain/ot/OctagonControlServer.m b/keychain/ot/OctagonControlServer.m new file mode 100644 index 00000000..a1fdf15a --- /dev/null +++ b/keychain/ot/OctagonControlServer.m @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import +#import + +#import +#import "SecEntitlements.h" +#import "keychain/ot/OctagonControlServer.h" +#import "keychain/ot/OTManager.h" +#import "keychain/ot/OT.h" + +@interface OctagonControlServer : NSObject +@end + +@implementation OctagonControlServer + +- (BOOL)listener:(__unused NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection +{ +#if OCTAGON + NSNumber *num = [newConnection valueForEntitlement:kSecEntitlementPrivateOctagon]; + if (![num isKindOfClass:[NSNumber class]] || ![num boolValue]) { + secerror("octagon: Client pid: %d doesn't have entitlement: %@", + [newConnection processIdentifier], kSecEntitlementPrivateOctagon); + return NO; + } + // In the future, we should consider vending a proxy object that can return a nicer error. + if (!SecOTIsEnabled()) { + secerror("Octagon: Client pid: %d attempted to use Octagon, but Octagon is not enabled.", + newConnection.processIdentifier); + return NO; + } + + secnotice("octagon", "received connection from client pid %d", [newConnection processIdentifier]); + newConnection.exportedInterface = OTSetupControlProtocol([NSXPCInterface interfaceWithProtocol:@protocol(OTControlProtocol)]); + newConnection.exportedObject = [OTManager manager]; + + [newConnection resume]; + + return YES; +#else // OCTAGON + secerror("octagon does not exist on this platform"); + return NO; +#endif // OCTAGON +} +@end + +void +OctagonControlServerInitialize(void) +{ + static dispatch_once_t once; + static OctagonControlServer *server; + static NSXPCListener *listener; + + dispatch_once(&once, ^{ + @autoreleasepool { + server = [OctagonControlServer new]; + + listener = [[NSXPCListener alloc] initWithMachServiceName:@(kSecuritydOctagonServiceName)]; + listener.delegate = server; + [listener resume]; + } + }); +} diff --git a/keychain/ot/SFECPublicKey+SPKI.m b/keychain/ot/SFECPublicKey+SPKI.m new file mode 100644 index 00000000..91531dc3 --- /dev/null +++ b/keychain/ot/SFECPublicKey+SPKI.m @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import "SFPublicKey+SPKI.h" + +#import +#import + +@implementation SFECPublicKey (OTSubjectPublicKeyInfo) + +- (NSData *)asSPKI +{ + NSDictionary *keyAttributes = @{ + (__bridge id)kSecAttrKeyClass : (__bridge id)kSecAttrKeyClassPublic, + (__bridge id)kSecAttrKeyType : (__bridge id)kSecAttrKeyTypeEC, + }; + SecKeyRef seckey = SecKeyCreateWithData((__bridge CFDataRef)self.keyData, (__bridge CFDictionaryRef)keyAttributes, NULL); + NSData *spki = CFBridgingRelease(SecKeyCopySubjectPublicKeyInfo(seckey)); + CFRelease(seckey); + return spki; +} + ++ (instancetype)fromSPKI:(NSData *)spki +{ + SecKeyRef seckey = SecKeyCreateFromSubjectPublicKeyInfoData(NULL, (__bridge CFDataRef)spki); + return [[SFECPublicKey alloc] initWithSecKey:seckey]; +} + +@end + +#endif diff --git a/keychain/ot/SFPublicKey+SPKI.h b/keychain/ot/SFPublicKey+SPKI.h new file mode 100644 index 00000000..4d8218f3 --- /dev/null +++ b/keychain/ot/SFPublicKey+SPKI.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SFPublicKey (OTSubjectPublicKeyInfo) + +- (NSData *)asSPKI; ++ (instancetype)fromSPKI:(NSData *)spki; + +@end + +NS_ASSUME_NONNULL_END +#endif diff --git a/keychain/ot/proto/OTAuthenticatedCiphertext.proto b/keychain/ot/proto/OTAuthenticatedCiphertext.proto new file mode 100644 index 00000000..fdd0aabf --- /dev/null +++ b/keychain/ot/proto/OTAuthenticatedCiphertext.proto @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2017 Apple Inc. All Rights Reserved. +* +* @APPLE_LICENSE_HEADER_START@ +* +* This file contains Original Code and/or Modifications of Original Code +* as defined in and that are subject to the Apple Public Source License +* Version 2.0 (the 'License'). You may not use this file except in +* compliance with the License. Please obtain a copy of the License at +* http://www.opensource.apple.com/apsl/ and read it before using this +* file. +* +* The Original Code and all software distributed under the License are +* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, +* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. +* Please see the License for the specific language governing rights and +* limitations under the License. +* +* @APPLE_LICENSE_HEADER_END@ +*/ + +syntax = "proto2"; + +option objc_class_naming = "extended"; +option objc_class_visibility = "hidden"; + +package OT; + +message AuthenticatedCiphertext { + required bytes ciphertext = 1; + required bytes authenticationCode = 2; + required bytes initializationVector = 3; +} diff --git a/keychain/ot/proto/OTBottle.proto b/keychain/ot/proto/OTBottle.proto new file mode 100644 index 00000000..bbcc0e97 --- /dev/null +++ b/keychain/ot/proto/OTBottle.proto @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +syntax = "proto2"; + +option objc_class_naming = "extended"; +option objc_class_visibility = "hidden"; + +package OT; + +import "OTAuthenticatedCiphertext.proto"; + +message Bottle { + optional string peerID = 1; + optional string spID = 2; + + // Tags 3, 4, 5 and 6 were briefly used during development for the raw public key data, with nothing to specify the key type. + // They are replaced with the following, encoded as SubjectPublicKeyInfo: + optional bytes reserved3 = 3; + optional bytes reserved4 = 4; + optional bytes reserved5 = 5; + optional bytes reserved6 = 6; + + // as SubjectPublicKeyInfo (SPKI): + optional bytes escrowedSigningSPKI = 8; + optional bytes escrowedEncryptionSPKI = 9; + optional bytes peerSigningSPKI = 10; + optional bytes peerEncryptionSPKI = 11; + + // Tag 7 was briefly used during development for contents encoded with NSKeyedArchiver. + optional bytes reserved7 = 7; + + optional AuthenticatedCiphertext contents = 12; +} + diff --git a/keychain/ot/proto/OTBottleContents.proto b/keychain/ot/proto/OTBottleContents.proto new file mode 100644 index 00000000..541e8ddf --- /dev/null +++ b/keychain/ot/proto/OTBottleContents.proto @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +syntax = "proto2"; + +option objc_class_naming = "extended"; +option objc_class_visibility = "hidden"; + +package OT; + +import "OTPrivateKey.proto"; + +message BottleContents { + // tags 1 and 2 were briefly used during development for the raw private key data, with nothing to specify the key type. + optional bytes reserved1 = 1; + optional bytes reserved2 = 2; + + optional PrivateKey peerSigningPrivKey = 3; + optional PrivateKey peerEncryptionPrivKey = 4; +} diff --git a/keychain/ot/proto/OTPrivateKey.proto b/keychain/ot/proto/OTPrivateKey.proto new file mode 100644 index 00000000..bcb80a6c --- /dev/null +++ b/keychain/ot/proto/OTPrivateKey.proto @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2017 Apple Inc. All Rights Reserved. +* +* @APPLE_LICENSE_HEADER_START@ +* +* This file contains Original Code and/or Modifications of Original Code +* as defined in and that are subject to the Apple Public Source License +* Version 2.0 (the 'License'). You may not use this file except in +* compliance with the License. Please obtain a copy of the License at +* http://www.opensource.apple.com/apsl/ and read it before using this +* file. +* +* The Original Code and all software distributed under the License are +* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, +* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. +* Please see the License for the specific language governing rights and +* limitations under the License. +* +* @APPLE_LICENSE_HEADER_END@ +*/ + +syntax = "proto2"; + +option objc_class_naming = "extended"; +option objc_class_visibility = "hidden"; + +package OT; + +message PrivateKey { + enum KeyType { + EC_NIST_CURVES = 1; // kSecAttrKeyTypeEC + } + + required KeyType keyType = 1; + required bytes keyData = 2; +} diff --git a/keychain/ot/proto/source/OTAuthenticatedCiphertext.h b/keychain/ot/proto/source/OTAuthenticatedCiphertext.h new file mode 100644 index 00000000..bd0b0acd --- /dev/null +++ b/keychain/ot/proto/source/OTAuthenticatedCiphertext.h @@ -0,0 +1,41 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTAuthenticatedCiphertext.proto + +#import +#import + +#ifdef __cplusplus +#define OTAUTHENTICATEDCIPHERTEXT_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define OTAUTHENTICATEDCIPHERTEXT_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface OTAuthenticatedCiphertext : PBCodable +{ + NSData *_authenticationCode; + NSData *_ciphertext; + NSData *_initializationVector; +} + + +@property (nonatomic, retain) NSData *ciphertext; + +@property (nonatomic, retain) NSData *authenticationCode; + +@property (nonatomic, retain) NSData *initializationVector; + +// Performs a shallow copy into other +- (void)copyTo:(OTAuthenticatedCiphertext *)other; + +// Performs a deep merge from other into self +// If set in other, singular values in self are replaced in self +// Singular composite values are recursively merged +// Repeated values from other are appended to repeated values in self +- (void)mergeFrom:(OTAuthenticatedCiphertext *)other; + +OTAUTHENTICATEDCIPHERTEXT_FUNCTION BOOL OTAuthenticatedCiphertextReadFrom(__unsafe_unretained OTAuthenticatedCiphertext *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/ot/proto/source/OTAuthenticatedCiphertext.m b/keychain/ot/proto/source/OTAuthenticatedCiphertext.m new file mode 100644 index 00000000..050bcc18 --- /dev/null +++ b/keychain/ot/proto/source/OTAuthenticatedCiphertext.m @@ -0,0 +1,167 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTAuthenticatedCiphertext.proto + +#import "OTAuthenticatedCiphertext.h" +#import +#import +#import + +#if !__has_feature(objc_arc) +# error This generated file depends on ARC but it is not enabled; turn on ARC, or use 'objc_use_arc' option to generate non-ARC code. +#endif + +@implementation OTAuthenticatedCiphertext + +@synthesize ciphertext = _ciphertext; +@synthesize authenticationCode = _authenticationCode; +@synthesize initializationVector = _initializationVector; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_ciphertext) + { + [dict setObject:self->_ciphertext forKey:@"ciphertext"]; + } + if (self->_authenticationCode) + { + [dict setObject:self->_authenticationCode forKey:@"authenticationCode"]; + } + if (self->_initializationVector) + { + [dict setObject:self->_initializationVector forKey:@"initializationVector"]; + } + return dict; +} + +BOOL OTAuthenticatedCiphertextReadFrom(__unsafe_unretained OTAuthenticatedCiphertext *self, __unsafe_unretained PBDataReader *reader) { + while (PBReaderHasMoreData(reader)) { + uint32_t tag = 0; + uint8_t aType = 0; + + PBReaderReadTag32AndType(reader, &tag, &aType); + + if (PBReaderHasError(reader)) + break; + + if (aType == TYPE_END_GROUP) { + break; + } + + switch (tag) { + + case 1 /* ciphertext */: + { + NSData *new_ciphertext = PBReaderReadData(reader); + self->_ciphertext = new_ciphertext; + } + break; + case 2 /* authenticationCode */: + { + NSData *new_authenticationCode = PBReaderReadData(reader); + self->_authenticationCode = new_authenticationCode; + } + break; + case 3 /* initializationVector */: + { + NSData *new_initializationVector = PBReaderReadData(reader); + self->_initializationVector = new_initializationVector; + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return OTAuthenticatedCiphertextReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* ciphertext */ + { + assert(nil != self->_ciphertext); + PBDataWriterWriteDataField(writer, self->_ciphertext, 1); + } + /* authenticationCode */ + { + assert(nil != self->_authenticationCode); + PBDataWriterWriteDataField(writer, self->_authenticationCode, 2); + } + /* initializationVector */ + { + assert(nil != self->_initializationVector); + PBDataWriterWriteDataField(writer, self->_initializationVector, 3); + } +} + +- (void)copyTo:(OTAuthenticatedCiphertext *)other +{ + other.ciphertext = _ciphertext; + other.authenticationCode = _authenticationCode; + other.initializationVector = _initializationVector; +} + +- (id)copyWithZone:(NSZone *)zone +{ + OTAuthenticatedCiphertext *copy = [[[self class] allocWithZone:zone] init]; + copy->_ciphertext = [_ciphertext copyWithZone:zone]; + copy->_authenticationCode = [_authenticationCode copyWithZone:zone]; + copy->_initializationVector = [_initializationVector copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + OTAuthenticatedCiphertext *other = (OTAuthenticatedCiphertext *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_ciphertext && !other->_ciphertext) || [self->_ciphertext isEqual:other->_ciphertext]) + && + ((!self->_authenticationCode && !other->_authenticationCode) || [self->_authenticationCode isEqual:other->_authenticationCode]) + && + ((!self->_initializationVector && !other->_initializationVector) || [self->_initializationVector isEqual:other->_initializationVector]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_ciphertext hash] + ^ + [self->_authenticationCode hash] + ^ + [self->_initializationVector hash] + ; +} + +- (void)mergeFrom:(OTAuthenticatedCiphertext *)other +{ + if (other->_ciphertext) + { + [self setCiphertext:other->_ciphertext]; + } + if (other->_authenticationCode) + { + [self setAuthenticationCode:other->_authenticationCode]; + } + if (other->_initializationVector) + { + [self setInitializationVector:other->_initializationVector]; + } +} + +@end + diff --git a/keychain/ot/proto/source/OTBottle.h b/keychain/ot/proto/source/OTBottle.h new file mode 100644 index 00000000..e4eda9bd --- /dev/null +++ b/keychain/ot/proto/source/OTBottle.h @@ -0,0 +1,88 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTBottle.proto + +#import +#import + +@class OTAuthenticatedCiphertext; + +#ifdef __cplusplus +#define OTBOTTLE_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define OTBOTTLE_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface OTBottle : PBCodable +{ + OTAuthenticatedCiphertext *_contents; + NSData *_escrowedEncryptionSPKI; + NSData *_escrowedSigningSPKI; + NSData *_peerEncryptionSPKI; + NSString *_peerID; + NSData *_peerSigningSPKI; + NSData *_reserved3; + NSData *_reserved4; + NSData *_reserved5; + NSData *_reserved6; + NSData *_reserved7; + NSString *_spID; +} + + +@property (nonatomic, readonly) BOOL hasPeerID; +@property (nonatomic, retain) NSString *peerID; + +@property (nonatomic, readonly) BOOL hasSpID; +@property (nonatomic, retain) NSString *spID; + +@property (nonatomic, readonly) BOOL hasReserved3; +/** + * Tags 3, 4, 5 and 6 were briefly used during development for the raw public key data, with nothing to specify the key type. + * They are replaced with the following, encoded as SubjectPublicKeyInfo: + */ +@property (nonatomic, retain) NSData *reserved3; + +@property (nonatomic, readonly) BOOL hasReserved4; +@property (nonatomic, retain) NSData *reserved4; + +@property (nonatomic, readonly) BOOL hasReserved5; +@property (nonatomic, retain) NSData *reserved5; + +@property (nonatomic, readonly) BOOL hasReserved6; +@property (nonatomic, retain) NSData *reserved6; + +@property (nonatomic, readonly) BOOL hasEscrowedSigningSPKI; +/** as SubjectPublicKeyInfo (SPKI): */ +@property (nonatomic, retain) NSData *escrowedSigningSPKI; + +@property (nonatomic, readonly) BOOL hasEscrowedEncryptionSPKI; +@property (nonatomic, retain) NSData *escrowedEncryptionSPKI; + +@property (nonatomic, readonly) BOOL hasPeerSigningSPKI; +@property (nonatomic, retain) NSData *peerSigningSPKI; + +@property (nonatomic, readonly) BOOL hasPeerEncryptionSPKI; +@property (nonatomic, retain) NSData *peerEncryptionSPKI; + +@property (nonatomic, readonly) BOOL hasReserved7; +/** Tag 7 was briefly used during development for contents encoded with NSKeyedArchiver. */ +@property (nonatomic, retain) NSData *reserved7; + +@property (nonatomic, readonly) BOOL hasContents; +@property (nonatomic, retain) OTAuthenticatedCiphertext *contents; + +// Performs a shallow copy into other +- (void)copyTo:(OTBottle *)other; + +// Performs a deep merge from other into self +// If set in other, singular values in self are replaced in self +// Singular composite values are recursively merged +// Repeated values from other are appended to repeated values in self +- (void)mergeFrom:(OTBottle *)other; + +OTBOTTLE_FUNCTION BOOL OTBottleReadFrom(__unsafe_unretained OTBottle *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/ot/proto/source/OTBottle.m b/keychain/ot/proto/source/OTBottle.m new file mode 100644 index 00000000..0799e2ed --- /dev/null +++ b/keychain/ot/proto/source/OTBottle.m @@ -0,0 +1,527 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTBottle.proto + +#import "OTBottle.h" +#import +#import +#import + +#import "OTAuthenticatedCiphertext.h" + +#if !__has_feature(objc_arc) +# error This generated file depends on ARC but it is not enabled; turn on ARC, or use 'objc_use_arc' option to generate non-ARC code. +#endif + +@implementation OTBottle + +- (BOOL)hasPeerID +{ + return _peerID != nil; +} +@synthesize peerID = _peerID; +- (BOOL)hasSpID +{ + return _spID != nil; +} +@synthesize spID = _spID; +- (BOOL)hasReserved3 +{ + return _reserved3 != nil; +} +@synthesize reserved3 = _reserved3; +- (BOOL)hasReserved4 +{ + return _reserved4 != nil; +} +@synthesize reserved4 = _reserved4; +- (BOOL)hasReserved5 +{ + return _reserved5 != nil; +} +@synthesize reserved5 = _reserved5; +- (BOOL)hasReserved6 +{ + return _reserved6 != nil; +} +@synthesize reserved6 = _reserved6; +- (BOOL)hasEscrowedSigningSPKI +{ + return _escrowedSigningSPKI != nil; +} +@synthesize escrowedSigningSPKI = _escrowedSigningSPKI; +- (BOOL)hasEscrowedEncryptionSPKI +{ + return _escrowedEncryptionSPKI != nil; +} +@synthesize escrowedEncryptionSPKI = _escrowedEncryptionSPKI; +- (BOOL)hasPeerSigningSPKI +{ + return _peerSigningSPKI != nil; +} +@synthesize peerSigningSPKI = _peerSigningSPKI; +- (BOOL)hasPeerEncryptionSPKI +{ + return _peerEncryptionSPKI != nil; +} +@synthesize peerEncryptionSPKI = _peerEncryptionSPKI; +- (BOOL)hasReserved7 +{ + return _reserved7 != nil; +} +@synthesize reserved7 = _reserved7; +- (BOOL)hasContents +{ + return _contents != nil; +} +@synthesize contents = _contents; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_peerID) + { + [dict setObject:self->_peerID forKey:@"peerID"]; + } + if (self->_spID) + { + [dict setObject:self->_spID forKey:@"spID"]; + } + if (self->_reserved3) + { + [dict setObject:self->_reserved3 forKey:@"reserved3"]; + } + if (self->_reserved4) + { + [dict setObject:self->_reserved4 forKey:@"reserved4"]; + } + if (self->_reserved5) + { + [dict setObject:self->_reserved5 forKey:@"reserved5"]; + } + if (self->_reserved6) + { + [dict setObject:self->_reserved6 forKey:@"reserved6"]; + } + if (self->_escrowedSigningSPKI) + { + [dict setObject:self->_escrowedSigningSPKI forKey:@"escrowedSigningSPKI"]; + } + if (self->_escrowedEncryptionSPKI) + { + [dict setObject:self->_escrowedEncryptionSPKI forKey:@"escrowedEncryptionSPKI"]; + } + if (self->_peerSigningSPKI) + { + [dict setObject:self->_peerSigningSPKI forKey:@"peerSigningSPKI"]; + } + if (self->_peerEncryptionSPKI) + { + [dict setObject:self->_peerEncryptionSPKI forKey:@"peerEncryptionSPKI"]; + } + if (self->_reserved7) + { + [dict setObject:self->_reserved7 forKey:@"reserved7"]; + } + if (self->_contents) + { + [dict setObject:[_contents dictionaryRepresentation] forKey:@"contents"]; + } + return dict; +} + +BOOL OTBottleReadFrom(__unsafe_unretained OTBottle *self, __unsafe_unretained PBDataReader *reader) { + while (PBReaderHasMoreData(reader)) { + uint32_t tag = 0; + uint8_t aType = 0; + + PBReaderReadTag32AndType(reader, &tag, &aType); + + if (PBReaderHasError(reader)) + break; + + if (aType == TYPE_END_GROUP) { + break; + } + + switch (tag) { + + case 1 /* peerID */: + { + NSString *new_peerID = PBReaderReadString(reader); + self->_peerID = new_peerID; + } + break; + case 2 /* spID */: + { + NSString *new_spID = PBReaderReadString(reader); + self->_spID = new_spID; + } + break; + case 3 /* reserved3 */: + { + NSData *new_reserved3 = PBReaderReadData(reader); + self->_reserved3 = new_reserved3; + } + break; + case 4 /* reserved4 */: + { + NSData *new_reserved4 = PBReaderReadData(reader); + self->_reserved4 = new_reserved4; + } + break; + case 5 /* reserved5 */: + { + NSData *new_reserved5 = PBReaderReadData(reader); + self->_reserved5 = new_reserved5; + } + break; + case 6 /* reserved6 */: + { + NSData *new_reserved6 = PBReaderReadData(reader); + self->_reserved6 = new_reserved6; + } + break; + case 7 /* reserved7 */: + { + NSData *new_reserved7 = PBReaderReadData(reader); + self->_reserved7 = new_reserved7; + } + break; + case 8 /* escrowedSigningSPKI */: + { + NSData *new_escrowedSigningSPKI = PBReaderReadData(reader); + self->_escrowedSigningSPKI = new_escrowedSigningSPKI; + } + break; + case 9 /* escrowedEncryptionSPKI */: + { + NSData *new_escrowedEncryptionSPKI = PBReaderReadData(reader); + self->_escrowedEncryptionSPKI = new_escrowedEncryptionSPKI; + } + break; + case 10 /* peerSigningSPKI */: + { + NSData *new_peerSigningSPKI = PBReaderReadData(reader); + self->_peerSigningSPKI = new_peerSigningSPKI; + } + break; + case 11 /* peerEncryptionSPKI */: + { + NSData *new_peerEncryptionSPKI = PBReaderReadData(reader); + self->_peerEncryptionSPKI = new_peerEncryptionSPKI; + } + break; + case 12 /* contents */: + { + OTAuthenticatedCiphertext *new_contents = [[OTAuthenticatedCiphertext alloc] init]; + self->_contents = new_contents; + PBDataReaderMark mark_contents; + BOOL markError = !PBReaderPlaceMark(reader, &mark_contents); + if (markError) + { + return NO; + } + BOOL inError = !OTAuthenticatedCiphertextReadFrom(new_contents, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_contents); + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return OTBottleReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* peerID */ + { + if (self->_peerID) + { + PBDataWriterWriteStringField(writer, self->_peerID, 1); + } + } + /* spID */ + { + if (self->_spID) + { + PBDataWriterWriteStringField(writer, self->_spID, 2); + } + } + /* reserved3 */ + { + if (self->_reserved3) + { + PBDataWriterWriteDataField(writer, self->_reserved3, 3); + } + } + /* reserved4 */ + { + if (self->_reserved4) + { + PBDataWriterWriteDataField(writer, self->_reserved4, 4); + } + } + /* reserved5 */ + { + if (self->_reserved5) + { + PBDataWriterWriteDataField(writer, self->_reserved5, 5); + } + } + /* reserved6 */ + { + if (self->_reserved6) + { + PBDataWriterWriteDataField(writer, self->_reserved6, 6); + } + } + /* reserved7 */ + { + if (self->_reserved7) + { + PBDataWriterWriteDataField(writer, self->_reserved7, 7); + } + } + /* escrowedSigningSPKI */ + { + if (self->_escrowedSigningSPKI) + { + PBDataWriterWriteDataField(writer, self->_escrowedSigningSPKI, 8); + } + } + /* escrowedEncryptionSPKI */ + { + if (self->_escrowedEncryptionSPKI) + { + PBDataWriterWriteDataField(writer, self->_escrowedEncryptionSPKI, 9); + } + } + /* peerSigningSPKI */ + { + if (self->_peerSigningSPKI) + { + PBDataWriterWriteDataField(writer, self->_peerSigningSPKI, 10); + } + } + /* peerEncryptionSPKI */ + { + if (self->_peerEncryptionSPKI) + { + PBDataWriterWriteDataField(writer, self->_peerEncryptionSPKI, 11); + } + } + /* contents */ + { + if (self->_contents != nil) + { + PBDataWriterWriteSubmessage(writer, self->_contents, 12); + } + } +} + +- (void)copyTo:(OTBottle *)other +{ + if (_peerID) + { + other.peerID = _peerID; + } + if (_spID) + { + other.spID = _spID; + } + if (_reserved3) + { + other.reserved3 = _reserved3; + } + if (_reserved4) + { + other.reserved4 = _reserved4; + } + if (_reserved5) + { + other.reserved5 = _reserved5; + } + if (_reserved6) + { + other.reserved6 = _reserved6; + } + if (_reserved7) + { + other.reserved7 = _reserved7; + } + if (_escrowedSigningSPKI) + { + other.escrowedSigningSPKI = _escrowedSigningSPKI; + } + if (_escrowedEncryptionSPKI) + { + other.escrowedEncryptionSPKI = _escrowedEncryptionSPKI; + } + if (_peerSigningSPKI) + { + other.peerSigningSPKI = _peerSigningSPKI; + } + if (_peerEncryptionSPKI) + { + other.peerEncryptionSPKI = _peerEncryptionSPKI; + } + if (_contents) + { + other.contents = _contents; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + OTBottle *copy = [[[self class] allocWithZone:zone] init]; + copy->_peerID = [_peerID copyWithZone:zone]; + copy->_spID = [_spID copyWithZone:zone]; + copy->_reserved3 = [_reserved3 copyWithZone:zone]; + copy->_reserved4 = [_reserved4 copyWithZone:zone]; + copy->_reserved5 = [_reserved5 copyWithZone:zone]; + copy->_reserved6 = [_reserved6 copyWithZone:zone]; + copy->_reserved7 = [_reserved7 copyWithZone:zone]; + copy->_escrowedSigningSPKI = [_escrowedSigningSPKI copyWithZone:zone]; + copy->_escrowedEncryptionSPKI = [_escrowedEncryptionSPKI copyWithZone:zone]; + copy->_peerSigningSPKI = [_peerSigningSPKI copyWithZone:zone]; + copy->_peerEncryptionSPKI = [_peerEncryptionSPKI copyWithZone:zone]; + copy->_contents = [_contents copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + OTBottle *other = (OTBottle *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_peerID && !other->_peerID) || [self->_peerID isEqual:other->_peerID]) + && + ((!self->_spID && !other->_spID) || [self->_spID isEqual:other->_spID]) + && + ((!self->_reserved3 && !other->_reserved3) || [self->_reserved3 isEqual:other->_reserved3]) + && + ((!self->_reserved4 && !other->_reserved4) || [self->_reserved4 isEqual:other->_reserved4]) + && + ((!self->_reserved5 && !other->_reserved5) || [self->_reserved5 isEqual:other->_reserved5]) + && + ((!self->_reserved6 && !other->_reserved6) || [self->_reserved6 isEqual:other->_reserved6]) + && + ((!self->_reserved7 && !other->_reserved7) || [self->_reserved7 isEqual:other->_reserved7]) + && + ((!self->_escrowedSigningSPKI && !other->_escrowedSigningSPKI) || [self->_escrowedSigningSPKI isEqual:other->_escrowedSigningSPKI]) + && + ((!self->_escrowedEncryptionSPKI && !other->_escrowedEncryptionSPKI) || [self->_escrowedEncryptionSPKI isEqual:other->_escrowedEncryptionSPKI]) + && + ((!self->_peerSigningSPKI && !other->_peerSigningSPKI) || [self->_peerSigningSPKI isEqual:other->_peerSigningSPKI]) + && + ((!self->_peerEncryptionSPKI && !other->_peerEncryptionSPKI) || [self->_peerEncryptionSPKI isEqual:other->_peerEncryptionSPKI]) + && + ((!self->_contents && !other->_contents) || [self->_contents isEqual:other->_contents]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_peerID hash] + ^ + [self->_spID hash] + ^ + [self->_reserved3 hash] + ^ + [self->_reserved4 hash] + ^ + [self->_reserved5 hash] + ^ + [self->_reserved6 hash] + ^ + [self->_reserved7 hash] + ^ + [self->_escrowedSigningSPKI hash] + ^ + [self->_escrowedEncryptionSPKI hash] + ^ + [self->_peerSigningSPKI hash] + ^ + [self->_peerEncryptionSPKI hash] + ^ + [self->_contents hash] + ; +} + +- (void)mergeFrom:(OTBottle *)other +{ + if (other->_peerID) + { + [self setPeerID:other->_peerID]; + } + if (other->_spID) + { + [self setSpID:other->_spID]; + } + if (other->_reserved3) + { + [self setReserved3:other->_reserved3]; + } + if (other->_reserved4) + { + [self setReserved4:other->_reserved4]; + } + if (other->_reserved5) + { + [self setReserved5:other->_reserved5]; + } + if (other->_reserved6) + { + [self setReserved6:other->_reserved6]; + } + if (other->_reserved7) + { + [self setReserved7:other->_reserved7]; + } + if (other->_escrowedSigningSPKI) + { + [self setEscrowedSigningSPKI:other->_escrowedSigningSPKI]; + } + if (other->_escrowedEncryptionSPKI) + { + [self setEscrowedEncryptionSPKI:other->_escrowedEncryptionSPKI]; + } + if (other->_peerSigningSPKI) + { + [self setPeerSigningSPKI:other->_peerSigningSPKI]; + } + if (other->_peerEncryptionSPKI) + { + [self setPeerEncryptionSPKI:other->_peerEncryptionSPKI]; + } + if (self->_contents && other->_contents) + { + [self->_contents mergeFrom:other->_contents]; + } + else if (!self->_contents && other->_contents) + { + [self setContents:other->_contents]; + } +} + +@end + diff --git a/keychain/ot/proto/source/OTBottleContents.h b/keychain/ot/proto/source/OTBottleContents.h new file mode 100644 index 00000000..926ae2d0 --- /dev/null +++ b/keychain/ot/proto/source/OTBottleContents.h @@ -0,0 +1,52 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTBottleContents.proto + +#import +#import + +@class OTPrivateKey; +@class OTPrivateKey; + +#ifdef __cplusplus +#define OTBOTTLECONTENTS_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define OTBOTTLECONTENTS_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface OTBottleContents : PBCodable +{ + OTPrivateKey *_peerEncryptionPrivKey; + OTPrivateKey *_peerSigningPrivKey; + NSData *_reserved1; + NSData *_reserved2; +} + + +@property (nonatomic, readonly) BOOL hasReserved1; +/** tags 1 and 2 were briefly used during development for the raw private key data, with nothing to specify the key type. */ +@property (nonatomic, retain) NSData *reserved1; + +@property (nonatomic, readonly) BOOL hasReserved2; +@property (nonatomic, retain) NSData *reserved2; + +@property (nonatomic, readonly) BOOL hasPeerSigningPrivKey; +@property (nonatomic, retain) OTPrivateKey *peerSigningPrivKey; + +@property (nonatomic, readonly) BOOL hasPeerEncryptionPrivKey; +@property (nonatomic, retain) OTPrivateKey *peerEncryptionPrivKey; + +// Performs a shallow copy into other +- (void)copyTo:(OTBottleContents *)other; + +// Performs a deep merge from other into self +// If set in other, singular values in self are replaced in self +// Singular composite values are recursively merged +// Repeated values from other are appended to repeated values in self +- (void)mergeFrom:(OTBottleContents *)other; + +OTBOTTLECONTENTS_FUNCTION BOOL OTBottleContentsReadFrom(__unsafe_unretained OTBottleContents *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/ot/proto/source/OTBottleContents.m b/keychain/ot/proto/source/OTBottleContents.m new file mode 100644 index 00000000..19d9d61b --- /dev/null +++ b/keychain/ot/proto/source/OTBottleContents.m @@ -0,0 +1,263 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTBottleContents.proto + +#import "OTBottleContents.h" +#import +#import +#import + +#import "OTPrivateKey.h" + +#if !__has_feature(objc_arc) +# error This generated file depends on ARC but it is not enabled; turn on ARC, or use 'objc_use_arc' option to generate non-ARC code. +#endif + +@implementation OTBottleContents + +- (BOOL)hasReserved1 +{ + return _reserved1 != nil; +} +@synthesize reserved1 = _reserved1; +- (BOOL)hasReserved2 +{ + return _reserved2 != nil; +} +@synthesize reserved2 = _reserved2; +- (BOOL)hasPeerSigningPrivKey +{ + return _peerSigningPrivKey != nil; +} +@synthesize peerSigningPrivKey = _peerSigningPrivKey; +- (BOOL)hasPeerEncryptionPrivKey +{ + return _peerEncryptionPrivKey != nil; +} +@synthesize peerEncryptionPrivKey = _peerEncryptionPrivKey; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_reserved1) + { + [dict setObject:self->_reserved1 forKey:@"reserved1"]; + } + if (self->_reserved2) + { + [dict setObject:self->_reserved2 forKey:@"reserved2"]; + } + if (self->_peerSigningPrivKey) + { + [dict setObject:[_peerSigningPrivKey dictionaryRepresentation] forKey:@"peerSigningPrivKey"]; + } + if (self->_peerEncryptionPrivKey) + { + [dict setObject:[_peerEncryptionPrivKey dictionaryRepresentation] forKey:@"peerEncryptionPrivKey"]; + } + return dict; +} + +BOOL OTBottleContentsReadFrom(__unsafe_unretained OTBottleContents *self, __unsafe_unretained PBDataReader *reader) { + while (PBReaderHasMoreData(reader)) { + uint32_t tag = 0; + uint8_t aType = 0; + + PBReaderReadTag32AndType(reader, &tag, &aType); + + if (PBReaderHasError(reader)) + break; + + if (aType == TYPE_END_GROUP) { + break; + } + + switch (tag) { + + case 1 /* reserved1 */: + { + NSData *new_reserved1 = PBReaderReadData(reader); + self->_reserved1 = new_reserved1; + } + break; + case 2 /* reserved2 */: + { + NSData *new_reserved2 = PBReaderReadData(reader); + self->_reserved2 = new_reserved2; + } + break; + case 3 /* peerSigningPrivKey */: + { + OTPrivateKey *new_peerSigningPrivKey = [[OTPrivateKey alloc] init]; + self->_peerSigningPrivKey = new_peerSigningPrivKey; + PBDataReaderMark mark_peerSigningPrivKey; + BOOL markError = !PBReaderPlaceMark(reader, &mark_peerSigningPrivKey); + if (markError) + { + return NO; + } + BOOL inError = !OTPrivateKeyReadFrom(new_peerSigningPrivKey, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_peerSigningPrivKey); + } + break; + case 4 /* peerEncryptionPrivKey */: + { + OTPrivateKey *new_peerEncryptionPrivKey = [[OTPrivateKey alloc] init]; + self->_peerEncryptionPrivKey = new_peerEncryptionPrivKey; + PBDataReaderMark mark_peerEncryptionPrivKey; + BOOL markError = !PBReaderPlaceMark(reader, &mark_peerEncryptionPrivKey); + if (markError) + { + return NO; + } + BOOL inError = !OTPrivateKeyReadFrom(new_peerEncryptionPrivKey, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_peerEncryptionPrivKey); + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return OTBottleContentsReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* reserved1 */ + { + if (self->_reserved1) + { + PBDataWriterWriteDataField(writer, self->_reserved1, 1); + } + } + /* reserved2 */ + { + if (self->_reserved2) + { + PBDataWriterWriteDataField(writer, self->_reserved2, 2); + } + } + /* peerSigningPrivKey */ + { + if (self->_peerSigningPrivKey != nil) + { + PBDataWriterWriteSubmessage(writer, self->_peerSigningPrivKey, 3); + } + } + /* peerEncryptionPrivKey */ + { + if (self->_peerEncryptionPrivKey != nil) + { + PBDataWriterWriteSubmessage(writer, self->_peerEncryptionPrivKey, 4); + } + } +} + +- (void)copyTo:(OTBottleContents *)other +{ + if (_reserved1) + { + other.reserved1 = _reserved1; + } + if (_reserved2) + { + other.reserved2 = _reserved2; + } + if (_peerSigningPrivKey) + { + other.peerSigningPrivKey = _peerSigningPrivKey; + } + if (_peerEncryptionPrivKey) + { + other.peerEncryptionPrivKey = _peerEncryptionPrivKey; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + OTBottleContents *copy = [[[self class] allocWithZone:zone] init]; + copy->_reserved1 = [_reserved1 copyWithZone:zone]; + copy->_reserved2 = [_reserved2 copyWithZone:zone]; + copy->_peerSigningPrivKey = [_peerSigningPrivKey copyWithZone:zone]; + copy->_peerEncryptionPrivKey = [_peerEncryptionPrivKey copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + OTBottleContents *other = (OTBottleContents *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_reserved1 && !other->_reserved1) || [self->_reserved1 isEqual:other->_reserved1]) + && + ((!self->_reserved2 && !other->_reserved2) || [self->_reserved2 isEqual:other->_reserved2]) + && + ((!self->_peerSigningPrivKey && !other->_peerSigningPrivKey) || [self->_peerSigningPrivKey isEqual:other->_peerSigningPrivKey]) + && + ((!self->_peerEncryptionPrivKey && !other->_peerEncryptionPrivKey) || [self->_peerEncryptionPrivKey isEqual:other->_peerEncryptionPrivKey]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_reserved1 hash] + ^ + [self->_reserved2 hash] + ^ + [self->_peerSigningPrivKey hash] + ^ + [self->_peerEncryptionPrivKey hash] + ; +} + +- (void)mergeFrom:(OTBottleContents *)other +{ + if (other->_reserved1) + { + [self setReserved1:other->_reserved1]; + } + if (other->_reserved2) + { + [self setReserved2:other->_reserved2]; + } + if (self->_peerSigningPrivKey && other->_peerSigningPrivKey) + { + [self->_peerSigningPrivKey mergeFrom:other->_peerSigningPrivKey]; + } + else if (!self->_peerSigningPrivKey && other->_peerSigningPrivKey) + { + [self setPeerSigningPrivKey:other->_peerSigningPrivKey]; + } + if (self->_peerEncryptionPrivKey && other->_peerEncryptionPrivKey) + { + [self->_peerEncryptionPrivKey mergeFrom:other->_peerEncryptionPrivKey]; + } + else if (!self->_peerEncryptionPrivKey && other->_peerEncryptionPrivKey) + { + [self setPeerEncryptionPrivKey:other->_peerEncryptionPrivKey]; + } +} + +@end + diff --git a/keychain/ot/proto/source/OTPrivateKey.h b/keychain/ot/proto/source/OTPrivateKey.h new file mode 100644 index 00000000..d5e281c8 --- /dev/null +++ b/keychain/ot/proto/source/OTPrivateKey.h @@ -0,0 +1,62 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTPrivateKey.proto + +#import +#import + +typedef NS_ENUM(int32_t, OTPrivateKey_KeyType) { + /** kSecAttrKeyTypeEC */ + OTPrivateKey_KeyType_EC_NIST_CURVES = 1, +}; +#ifdef __OBJC__ +NS_INLINE NSString *OTPrivateKey_KeyTypeAsString(OTPrivateKey_KeyType value) +{ + switch (value) + { + case OTPrivateKey_KeyType_EC_NIST_CURVES: return @"EC_NIST_CURVES"; + default: return [NSString stringWithFormat:@"(unknown: %i)", value]; + } +} +#endif /* __OBJC__ */ +#ifdef __OBJC__ +NS_INLINE OTPrivateKey_KeyType StringAsOTPrivateKey_KeyType(NSString *value) +{ + if ([value isEqualToString:@"EC_NIST_CURVES"]) return OTPrivateKey_KeyType_EC_NIST_CURVES; + return OTPrivateKey_KeyType_EC_NIST_CURVES; +} +#endif /* __OBJC__ */ + +#ifdef __cplusplus +#define OTPRIVATEKEY_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define OTPRIVATEKEY_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface OTPrivateKey : PBCodable +{ + NSData *_keyData; + OTPrivateKey_KeyType _keyType; +} + + +@property (nonatomic) OTPrivateKey_KeyType keyType; +- (NSString *)keyTypeAsString:(OTPrivateKey_KeyType)value; +- (OTPrivateKey_KeyType)StringAsKeyType:(NSString *)str; + +@property (nonatomic, retain) NSData *keyData; + +// Performs a shallow copy into other +- (void)copyTo:(OTPrivateKey *)other; + +// Performs a deep merge from other into self +// If set in other, singular values in self are replaced in self +// Singular composite values are recursively merged +// Repeated values from other are appended to repeated values in self +- (void)mergeFrom:(OTPrivateKey *)other; + +OTPRIVATEKEY_FUNCTION BOOL OTPrivateKeyReadFrom(__unsafe_unretained OTPrivateKey *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/ot/proto/source/OTPrivateKey.m b/keychain/ot/proto/source/OTPrivateKey.m new file mode 100644 index 00000000..442cd4c8 --- /dev/null +++ b/keychain/ot/proto/source/OTPrivateKey.m @@ -0,0 +1,141 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTPrivateKey.proto + +#import "OTPrivateKey.h" +#import +#import +#import + +#if !__has_feature(objc_arc) +# error This generated file depends on ARC but it is not enabled; turn on ARC, or use 'objc_use_arc' option to generate non-ARC code. +#endif + +@implementation OTPrivateKey + +@synthesize keyType = _keyType; +- (NSString *)keyTypeAsString:(OTPrivateKey_KeyType)value +{ + return OTPrivateKey_KeyTypeAsString(value); +} +- (OTPrivateKey_KeyType)StringAsKeyType:(NSString *)str +{ + return StringAsOTPrivateKey_KeyType(str); +} +@synthesize keyData = _keyData; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + [dict setObject:OTPrivateKey_KeyTypeAsString(self->_keyType) forKey:@"keyType"]; + if (self->_keyData) + { + [dict setObject:self->_keyData forKey:@"keyData"]; + } + return dict; +} + +BOOL OTPrivateKeyReadFrom(__unsafe_unretained OTPrivateKey *self, __unsafe_unretained PBDataReader *reader) { + while (PBReaderHasMoreData(reader)) { + uint32_t tag = 0; + uint8_t aType = 0; + + PBReaderReadTag32AndType(reader, &tag, &aType); + + if (PBReaderHasError(reader)) + break; + + if (aType == TYPE_END_GROUP) { + break; + } + + switch (tag) { + + case 1 /* keyType */: + { + self->_keyType = PBReaderReadInt32(reader); + } + break; + case 2 /* keyData */: + { + NSData *new_keyData = PBReaderReadData(reader); + self->_keyData = new_keyData; + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return OTPrivateKeyReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* keyType */ + { + PBDataWriterWriteInt32Field(writer, self->_keyType, 1); + } + /* keyData */ + { + assert(nil != self->_keyData); + PBDataWriterWriteDataField(writer, self->_keyData, 2); + } +} + +- (void)copyTo:(OTPrivateKey *)other +{ + other->_keyType = _keyType; + other.keyData = _keyData; +} + +- (id)copyWithZone:(NSZone *)zone +{ + OTPrivateKey *copy = [[[self class] allocWithZone:zone] init]; + copy->_keyType = _keyType; + copy->_keyData = [_keyData copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + OTPrivateKey *other = (OTPrivateKey *)object; + return [other isMemberOfClass:[self class]] + && + self->_keyType == other->_keyType + && + ((!self->_keyData && !other->_keyData) || [self->_keyData isEqual:other->_keyData]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + PBHashInt((NSUInteger)_keyType) + ^ + [self->_keyData hash] + ; +} + +- (void)mergeFrom:(OTPrivateKey *)other +{ + self->_keyType = other->_keyType; + if (other->_keyData) + { + [self setKeyData:other->_keyData]; + } +} + +@end + diff --git a/keychain/ot/tests/OTBottledPeerTLK.m b/keychain/ot/tests/OTBottledPeerTLK.m new file mode 100644 index 00000000..9a88281f --- /dev/null +++ b/keychain/ot/tests/OTBottledPeerTLK.m @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLEself.LICENSEself.HEADERself.START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLEself.LICENSEself.HEADERself.END@ + */ + +#if OCTAGON + +#import "OTTestsBase.h" + +@interface BottledPeerRestoreTLKTests : OTTestsBase +@property CKKSSOSSelfPeer* remotePeer1; +@property CKKSSOSPeer* remotePeer2; +@property CKKSSOSSelfPeer* untrustedPeer; + +@end + +@implementation BottledPeerRestoreTLKTests + +- (void)setUp +{ + [super setUp]; + + //set up a bottled peer and stick it in localStore + NSError* error = nil; + + self.remotePeer1 = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:self.sosPeerID + encryptionKey:self.peerEncryptionKey + signingKey:self.peerSigningKey]; + + [self.currentPeers addObject:self.remotePeer1]; + + OTBottledPeer *bp = [[OTBottledPeer alloc]initWithPeerID:self.egoPeerID spID:self.sosPeerID peerSigningKey:self.peerSigningKey peerEncryptionKey:self.peerEncryptionKey escrowKeys:self.escrowKeys error:&error]; + + XCTAssertNotNil(bp, @"plaintext should not be nil"); + XCTAssertNil(error, @"error should be nil"); + XCTAssertNotNil(self.escrowKeys.signingKey, @"signing public key should not be nil"); + XCTAssertNotNil(self.escrowKeys.encryptionKey, @"encryption public key should not be nil"); + + OTBottledPeerSigned *bpSigned = [[OTBottledPeerSigned alloc]initWithBottledPeer:bp escrowedSigningKey:self.escrowKeys.signingKey peerSigningKey:self.peerSigningKey error:&error]; + + OTBottledPeerRecord* record = [bpSigned asRecord:[self currentIdentity:&error].spID]; + self.recordName = record.recordName; + + OTIdentity* identity = [self currentIdentity:&error]; + [self.localStore insertBottledPeerRecord:record escrowRecordID:identity.spID error:&error]; + + self.remotePeer1 = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"remote-peer1" + encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; + + self.remotePeer2 = [[CKKSSOSPeer alloc] initWithSOSPeerID:@"remote-peer2" + encryptionPublicKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]].publicKey + signingPublicKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]].publicKey]; + + // Local SOS trusts these peers + [self.currentPeers addObject:self.remotePeer1]; + [self.currentPeers addObject:self.remotePeer2]; + + self.untrustedPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"untrusted-peer" + encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; +} + +- (void)tearDown +{ + _remotePeer1 = nil; + _remotePeer2 = nil; + _untrustedPeer = nil; + [super tearDown]; +} + +-(void) testTLKSharingWithRestoredBottledPeer +{ + NSError* error = nil; + + OTBottledPeerRecord *rec = [self.localStore readLocalBottledPeerRecordWithRecordID:self.recordName error:&error]; + XCTAssertNotNil(rec, @"rec should not be nil: %@", error); + XCTAssertNil(error, @"error should be nil: %@", error); + + OTBottledPeerSigned *bps = [[OTBottledPeerSigned alloc] initWithBottledPeerRecord:rec + escrowKeys:self.escrowKeys + error:&error]; + XCTAssertNil(error, @"error should be nil: %@", error); + XCTAssertNotNil(bps, @"signed bottled peer should not be nil: %@", error); + XCTAssertTrue([bps.bp.peerEncryptionKey isEqual:self.peerEncryptionKey], @"enrolled and restored peer encryption keys should match"); + XCTAssertTrue([bps.bp.peerSigningKey isEqual:self.peerSigningKey], @"enrolled and restored peer signing keys should match"); + + + CKKSSelves* selves = [[CKKSViewManager manager] fetchSelfPeers:&error]; + XCTAssertNotNil(selves, @"selves should not be nil: %@", error); + + XCTAssertTrue([selves.allSelves count] == 2, @"should have 2 selves"); + NSArray *arrayOfSelves = [selves.allSelves allObjects]; + XCTAssertNotNil(arrayOfSelves, @"arrayOfSelves should not be nil: %@", error); + + CKKSSOSSelfPeer *ourRestoredPeer = [arrayOfSelves objectAtIndex:0]; + if([ourRestoredPeer.peerID isEqualToString:@"spid-local-peer"]){ + ourRestoredPeer = [arrayOfSelves objectAtIndex:1]; + } + + XCTAssertTrue([ourRestoredPeer.peerID containsString:self.sosPeerID], @"peer ids should match!"); + XCTAssertTrue([ourRestoredPeer.signingKey isEqual:self.peerSigningKey], @"signing keys should match"); + XCTAssertTrue([ourRestoredPeer.encryptionKey isEqual:self.peerEncryptionKey], @"encryption keys should match"); + + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; + [self startCKKSSubsystem]; + + // The CKKS subsystem should not try to write anything to the CloudKit database, but it should enter waitfortlk + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "Key state should become waitfortlk"); + + // peer1 arrives to save the day + // The CKKS subsystem should accept the keys, and share the TLK back to itself + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; + + [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:ourRestoredPeer zoneID:self.keychainZoneID]; + [self.keychainView notifyZoneChange:nil]; + [self.keychainView waitForFetchAndIncomingQueueProcessing]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); + + // We expect a single record to be uploaded for each key class + [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID + checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; + [self addGenericPassword: @"data" account: @"account-delete-me"]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + + [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID + checkItem: [self checkClassABlock:self.keychainZoneID message:@"Object was encrypted under class A key in hierarchy"]]; + [self addGenericPassword:@"asdf" + account:@"account-class-A" + viewHint:nil + access:(id)kSecAttrAccessibleWhenUnlocked + expecting:errSecSuccess + message:@"Adding class A item"]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + +- (nullable OTIdentity *)currentIdentity:(NSError * _Nullable __autoreleasing * _Nullable)error { + return [[OTIdentity alloc]initWithPeerID:@"ego peer id" spID:self.sosPeerID peerSigningKey:self.peerSigningKey peerEncryptionkey:self.peerEncryptionKey error:error]; +} + +@end +#endif diff --git a/keychain/ot/tests/OTBottledPeerTests.m b/keychain/ot/tests/OTBottledPeerTests.m new file mode 100644 index 00000000..20cdbe42 --- /dev/null +++ b/keychain/ot/tests/OTBottledPeerTests.m @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import +#import +#import +#import "OTTestsBase.h" +#import +#import +#import +#import +#import + +#import "keychain/ot/OTBottledPeer.h" +#import "keychain/ot/OTBottledPeerSigned.h" + +#import "keychain/ckks/CKKS.h" + +static NSString* const testDSID = @"123456789"; + +@interface UnitTestOTBottledPeer : OTTestsBase + +@end + +@implementation UnitTestOTBottledPeer + +- (void)setUp +{ + [super setUp]; + self.continueAfterFailure = NO; + NSError* error = nil; + + self.sosPeerID = @"spID"; + self.egoPeerID = @"egoPeerID"; + self.peerSigningKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + self.peerEncryptionKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + self.escrowKeys = [[OTEscrowKeys alloc]initWithSecret:self.secret dsid:testDSID error:&error]; +} + +- (void)tearDown +{ + [super tearDown]; +} + +-(void)testBottledPeerCreation +{ + NSError* error = nil; + + OTBottledPeer *bp = [[OTBottledPeer alloc]initWithPeerID:self.egoPeerID spID:self.sosPeerID peerSigningKey:self.peerSigningKey peerEncryptionKey:self.peerEncryptionKey escrowKeys:self.escrowKeys error:&error]; + + XCTAssertNotNil(bp, @"bottled peer should not be nil"); + XCTAssertNil(error, @"error should be nil"); + XCTAssertNotNil(self.escrowKeys.signingKey, @"signing public key should not be nil"); + XCTAssertNotNil(self.escrowKeys.encryptionKey, @"encryption public key should not be nil"); + +} + +-(void)testSignedBottledPeerCreation +{ + NSError* error = nil; + + OTBottledPeer *bp = [[OTBottledPeer alloc]initWithPeerID:self.egoPeerID spID:self.sosPeerID peerSigningKey:self.peerSigningKey peerEncryptionKey:self.peerEncryptionKey escrowKeys:self.escrowKeys error:&error]; + + XCTAssertNotNil(bp, @"plaintext should not be nil"); + XCTAssertNil(error, @"error should be nil"); + XCTAssertNotNil(self.escrowKeys.signingKey, @"signing public key should not be nil"); + XCTAssertNotNil(self.escrowKeys.encryptionKey, @"encryption public key should not be nil"); + + OTBottledPeerSigned *bpSigned = [[OTBottledPeerSigned alloc]initWithBottledPeer:bp escrowedSigningKey:self.escrowKeys.signingKey peerSigningKey:self.peerSigningKey error:&error]; + XCTAssertNil(error, @"error should be nil"); + XCTAssertNotNil(bpSigned, @"bottled peer signed should not be nil"); + +} + +-(void)testCreatingBottledPeerFromRecord +{ + NSError* error = nil; + OTBottledPeer *bp = [[OTBottledPeer alloc]initWithPeerID:self.egoPeerID spID:self.sosPeerID peerSigningKey:self.peerSigningKey peerEncryptionKey:self.peerEncryptionKey escrowKeys:self.escrowKeys error:&error]; + + XCTAssertNotNil(bp, @"plaintext should not be nil"); + XCTAssertNil(error, @"error should be nil"); + XCTAssertNotNil(self.escrowKeys.signingKey, @"signing public key should not be nil"); + XCTAssertNotNil(self.escrowKeys.encryptionKey, @"encryption public key should not be nil"); + + OTBottledPeerSigned *bpSigned = [[OTBottledPeerSigned alloc]initWithBottledPeer:bp escrowedSigningKey:self.escrowKeys.signingKey peerSigningKey:self.peerSigningKey error:&error]; + + OTBottledPeerRecord* record = [bpSigned asRecord:@"escrowRecordID"]; + OTBottledPeerSigned *bpRestored = [[OTBottledPeerSigned alloc] initWithBottledPeerRecord:record escrowKeys:self.escrowKeys error:&error]; + XCTAssertNotNil(bpRestored, @"bottled peer signed should not be nil"); +} + +-(void)testRestoringBottledPeerSigned +{ + NSError* error = nil; + OTBottledPeer *bp = [[OTBottledPeer alloc]initWithPeerID:self.egoPeerID spID:self.sosPeerID peerSigningKey:self.peerSigningKey peerEncryptionKey:self.peerEncryptionKey escrowKeys:self.escrowKeys error:&error]; + + XCTAssertNotNil(bp, @"plaintext should not be nil"); + XCTAssertNil(error, @"error should be nil"); + + SFECKeySpecifier *keySpecifier = [[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]; + id digestOperation = [[SFSHA384DigestOperation alloc] init]; + SFEC_X962SigningOperation* xso = [[SFEC_X962SigningOperation alloc] initWithKeySpecifier:keySpecifier digestOperation:digestOperation]; + + NSData* signatureUsingEscrow = [xso sign:bp.data withKey:self.escrowKeys.signingKey error:&error].signature; + XCTAssertNil(error, @"error should not be nil"); + + NSData* signatureUsingPeerKey = [xso sign:bp.data withKey:self.peerSigningKey error:&error].signature; + XCTAssertNil(error, @"error should not be nil"); + + XCTAssertNotNil(signatureUsingEscrow, @"signature using escrow signing key should not be nil"); + XCTAssertNotNil(signatureUsingPeerKey, @"signature using peer signing key should not be nil"); + + + OTBottledPeerSigned *bpSigned = [[OTBottledPeerSigned alloc]initWithBottledPeer:bp signatureUsingEscrow:signatureUsingEscrow signatureUsingPeerKey:signatureUsingPeerKey escrowedSigningPubKey:[self.escrowKeys.signingKey publicKey] error:&error]; + + XCTAssertNotNil(bpSigned, @"bottled peer signed should not be nil"); + + bpSigned = [[OTBottledPeerSigned alloc]initWithBottledPeer:bp signatureUsingEscrow:[NSData data] signatureUsingPeerKey:[NSData data] escrowedSigningPubKey:[self.escrowKeys.signingKey publicKey] error:&error]; + + XCTAssertNil(bpSigned, @"bottled peer signed should be nil"); + XCTAssertNotNil(error, @"error should not be nil"); + +} + +@end + +#endif /* OCTAGON */ diff --git a/keychain/ot/tests/OTCloudStoreTests.m b/keychain/ot/tests/OTCloudStoreTests.m new file mode 100644 index 00000000..3fc7b178 --- /dev/null +++ b/keychain/ot/tests/OTCloudStoreTests.m @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import + +#import +#import + +#import "OTTestsBase.h" + +static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; +static NSString* OTCKRecordEscrowRecordID = @"escrowRecordID"; + +@interface OTCloudStoreUnitTests : OTTestsBase +@property (nonatomic, strong) OTBottledPeerRecord* fakeBottledPeerRecord; +@end + +@implementation OTCloudStoreUnitTests + + +- (void)setUp { + [super setUp]; + self.continueAfterFailure = NO; + self.fakeBottledPeerRecord = [[OTBottledPeerRecord alloc] init]; + self.fakeBottledPeerRecord.bottle = [@"bottled peer data" dataUsingEncoding:NSUTF8StringEncoding]; + self.fakeBottledPeerRecord.signatureUsingEscrowKey = [@"bottled peer escrow sig" dataUsingEncoding:NSUTF8StringEncoding]; + self.fakeBottledPeerRecord.signatureUsingPeerKey = [@"bottled peer peer sig" dataUsingEncoding:NSUTF8StringEncoding]; + self.fakeBottledPeerRecord.peerID = @"peer id"; + self.fakeBottledPeerRecord.spID = @"sos peer id"; + self.fakeBottledPeerRecord.escrowRecordID = @"escrowRecordID"; + self.fakeBottledPeerRecord.escrowedSigningSPKI = [@"escrowedSigningSPKI" dataUsingEncoding:kCFStringEncodingUTF8]; + self.fakeBottledPeerRecord.peerSigningSPKI = [@"peerSigningSPKI" dataUsingEncoding:kCFStringEncodingUTF8]; +} + +- (void)tearDown { + self.zones = nil; + self.operationQueue = nil; + + [super tearDown]; +} + +- (void)testWriteSameBottledPeerTwiceToFakeRecord { + NSError* error = nil; + + NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil]; + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:YES]; + [self startCKKSSubsystem]; + XCTAssertTrue([self.cloudStore uploadBottledPeerRecord:self.fakeBottledPeerRecord escrowRecordID:self.fakeBottledPeerRecord.escrowRecordID error:&error], @"should create bottled peer record"); + XCTAssertNil(error, "error should be nil"); + + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self releaseCloudKitFetchHold]; + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:YES]; + + XCTAssertTrue([self.cloudStore uploadBottledPeerRecord:self.fakeBottledPeerRecord escrowRecordID:self.fakeBottledPeerRecord.escrowRecordID error:&error], @"should create bottled peer record"); + XCTAssertNil(error, "error should be nil"); + + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self releaseCloudKitFetchHold]; +} + +- (void)testWriteBottledPeerToFakeRecord { + NSError* error = nil; + + NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionary]; + recordDictionary[OTCKRecordBottledPeerType] = [[NSNumber alloc] initWithInt:1]; + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:YES]; + [self startCKKSSubsystem]; + + XCTAssertTrue([self.cloudStore uploadBottledPeerRecord:self.fakeBottledPeerRecord escrowRecordID:self.fakeBottledPeerRecord.escrowRecordID error:&error], @"should create bottled peer record"); + XCTAssertNil(error, "error should be nil"); + + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self releaseCloudKitFetchHold]; +} + +- (void)testWriteMultipleBottledPeersToSAMEFakeRecord { + NSError* error = nil; + + NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionary]; + + recordDictionary[OTCKRecordBottledPeerType] = [[NSNumber alloc] initWithInt:1]; + + [self startCKKSSubsystem]; + + for(int i = 0; i < 10; i++){ + [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; + + XCTAssertTrue([self.cloudStore uploadBottledPeerRecord:self.fakeBottledPeerRecord escrowRecordID:self.fakeBottledPeerRecord.escrowRecordID error:&error], @"should create bottled peer record"); + + [self waitForCKModifications]; + + XCTAssertNil(error, "error should be nil"); + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self releaseCloudKitFetchHold]; + } +} + +- (void)testWriteBottledPeersToDifferentFakeRecord { + NSError* error = nil; + + NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionary]; + + recordDictionary[OTCKRecordBottledPeerType] = [[NSNumber alloc] initWithInt:1]; + + [self startCKKSSubsystem]; + + for(int i = 0; i < 10; i++){ + [self expectAddedCKModifyRecords:recordDictionary holdFetch:YES]; + NSString *escrowID = [NSString stringWithFormat:@"bp-sospeer%d-hash", i]; + self.fakeBottledPeerRecord.escrowRecordID = escrowID; + XCTAssertTrue([self.cloudStore uploadBottledPeerRecord:self.fakeBottledPeerRecord escrowRecordID:escrowID error:&error], @"should create bottled peer record"); + [self waitForCKModifications]; + + XCTAssertNil(error, "error should be nil"); + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self releaseCloudKitFetchHold]; + } + XCTAssertTrue( [[self.cloudStore retrieveListOfEligibleEscrowRecordIDs:&error] count] == 10, @"should have 1 record"); +} + + +- (void)testReadBottledPeerRecordFromCloudKit { + NSError *error = nil; + [self startCKKSSubsystem]; + + CKRecord* newRecord = [[CKRecord alloc]initWithRecordType:OTCKRecordBottledPeerType]; + newRecord[OTCKRecordEscrowRecordID] = @"escrowRecordID"; + [self.otFakeZone addToZone:newRecord]; + + [self.cloudStore notifyZoneChange:nil]; + + [self waitForCKModifications]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + XCTAssertTrue( [[self.cloudStore retrieveListOfEligibleEscrowRecordIDs:&error] count] > 0, @"should have 1 record"); +} + +-(void) testOTCloudStoreDownloadBP{ + NSError* error = nil; + [self startCKKSSubsystem]; + + CKRecord* newRecord = [[CKRecord alloc]initWithRecordType:OTCKRecordBottledPeerType]; + newRecord[OTCKRecordEscrowRecordID] = @"escrowRecordID"; + [self.otFakeZone addToZone:newRecord]; + + XCTAssertTrue([self.cloudStore downloadBottledPeerRecord:&error] == YES, @"downloading records should succeed:%@", error); + XCTAssertNil(error, @"error should be nil"); + + [self waitForCKModifications]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + + XCTAssertNil(error, "error should be nil"); + XCTAssertEqual([[self.cloudStore retrieveListOfEligibleEscrowRecordIDs:&error] count], (unsigned long)1, @"should have 1 record"); + XCTAssertNil(error, "error should be nil"); +} + +-(void) testOTCloudStoreDownloadMultipleBP{ + NSError* error = nil; + [self startCKKSSubsystem]; + + for(int i = 0; i < 10; i++){ + CKRecord* newRecord = [[CKRecord alloc]initWithRecordType:OTCKRecordBottledPeerType zoneID:self.otZoneID]; + newRecord[OTCKRecordEscrowRecordID] = [NSString stringWithFormat:@"escrowRecordID%d", i]; + [self.otFakeZone addToZone:newRecord]; + } + [self waitForCKModifications]; + + XCTAssertTrue([self.cloudStore downloadBottledPeerRecord:&error] == YES, @"downloading records should succeed:%@", error); + XCTAssertNil(error, @"error should be nil"); + [self waitForCKModifications]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + + XCTAssertNil(error, "error should be nil"); + XCTAssertEqual( [[self.cloudStore retrieveListOfEligibleEscrowRecordIDs:&error] count], (unsigned long)10, @"should have 1 record"); +} + +-(void) testOTCloudStoreUploadMultipleToSameRecord{ + NSError* error = nil; + [self startCKKSSubsystem]; + CKRecord* newRecord = [[CKRecord alloc]initWithRecordType:OTCKRecordBottledPeerType zoneID:self.otZoneID]; + newRecord[OTCKRecordEscrowRecordID] = @"escrowRecordID"; + for(int i = 0; i < 10; i++){ + [self.otFakeZone addToZone:newRecord]; + } + [self waitForCKModifications]; + + XCTAssertTrue([self.cloudStore downloadBottledPeerRecord:&error] == YES, @"downloading records should succeed:%@", error); + XCTAssertNil(error, @"error should be nil"); + [self waitForCKModifications]; + + OCMVerifyAllWithDelay(self.mockDatabase, 8); + + XCTAssertNil(error, "error should be nil"); + XCTAssertEqual([[self.cloudStore retrieveListOfEligibleEscrowRecordIDs:&error] count], (unsigned long)1, @"should have 1 record"); +} + +-(void) testRemoveRecordIDs{ + + [self startCKKSSubsystem]; + NSError *error = nil; + CKRecord* newRecord = [[CKRecord alloc]initWithRecordType:OTCKRecordBottledPeerType zoneID:self.otZoneID]; + newRecord[OTCKRecordEscrowRecordID] = @"escrowRecordID"; + [self expectCKFetch]; + + [self.otFakeZone addToZone:newRecord]; + [self waitForCKModifications]; + + [self.cloudStore notifyZoneChange:nil]; + [self waitForCKModifications]; + + XCTAssertTrue( [[self.cloudStore retrieveListOfEligibleEscrowRecordIDs:&error] count] == 1, @"should have 1 record"); + + [self expectCKFetch]; + XCTAssertTrue([self.cloudStore downloadBottledPeerRecord:&error] == YES, @"downloading records should succeed:%@", error); + XCTAssertNil(error, @"error should be nil"); + [self waitForCKModifications]; +} + +-(void) testFetchTimeout +{ + [self startCKKSSubsystem]; + + NSError* error = nil; + CKRecord* newRecord = [[CKRecord alloc]initWithRecordType:OTCKRecordBottledPeerType zoneID:self.otZoneID]; + newRecord[OTCKRecordEscrowRecordID] = @"escrowRecordID"; + + [self holdCloudKitFetches]; + + [self.cloudStore downloadBottledPeerRecord:&error]; + + XCTAssertNotNil(error, "error should not be nil"); + XCTAssertTrue([(NSString*)error.userInfo[@"NSLocalizedDescription"] isEqualToString:@"Operation(CKKSResultOperation(cloudkit-fetch-and-process-changes)) timed out waiting to start for []"], "expecting timed out error"); +} + +-(void) testModifyRecordsTimeout +{ + NSError* error = nil; + + NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil]; + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; + + [self startCKKSSubsystem]; + + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:4*NSEC_PER_SEC], @"Key state should have arrived at ready"); + + [self holdCloudKitModifications]; + + [self.cloudStore uploadBottledPeerRecord:self.fakeBottledPeerRecord + escrowRecordID:self.fakeBottledPeerRecord.escrowRecordID error:&error]; + + XCTAssertNotNil(error, "error should not be nil"); + XCTAssertTrue([(NSString*)error.userInfo[@"NSLocalizedDescription"] isEqualToString:@"Operation(CKKSResultOperation(cloudkit-modify-changes)) timed out waiting to start for []"], "expecting timed out error"); + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; + + [self releaseCloudKitModificationHold]; + [self waitForCKModifications]; +} + +@end + +#endif /* OCTAGON */ + diff --git a/keychain/ot/tests/OTContextTests.m b/keychain/ot/tests/OTContextTests.m new file mode 100644 index 00000000..261eb069 --- /dev/null +++ b/keychain/ot/tests/OTContextTests.m @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +#if OCTAGON + +#import +#import +#import + +#import "OTTestsBase.h" + +static NSString* const testContextID = @"Foo"; +static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; + +@interface UnitTestOTContext : OTTestsBase +@property (nonatomic, strong) OTBottledPeerRecord* fakeBottledPeerRecord; +@end + +@implementation UnitTestOTContext + +- (void)setUp +{ + [super setUp]; + self.continueAfterFailure = NO; +} + +- (void)tearDown +{ + self.zones = nil; + self.operationQueue = nil; + [super tearDown]; +} + +-(void) testEnroll +{ + NSError* error = nil; + + NSString* escrowRecordID = [self currentIdentity:&error].spID; + XCTAssertNil(error, @"error should be nil: %@", error); + XCTAssertNotNil(escrowRecordID, @"escrowRecordID should not be nil: %@", error); + + NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil]; + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:YES]; + [self startCKKSSubsystem]; + + OTPreflightInfo* info = nil; + XCTAssertNotNil(info = [self.context preflightBottledPeer:testContextID entropy:self.secret error:&error], @"preflight sould return info:%@", error); + XCTAssertNil(error, @"error should be nil: %@", error); + XCTAssertNotNil(info, @"preflight info should not be nil: %@", error); + XCTAssertNotNil(info.bottleID, @"escrowRecordID should not be nil: %@", error); + XCTAssertNotNil(info.escrowedSigningSPKI, @"signingPubKey should be nil: %@", error); + + OTBottledPeerRecord* bprecord = [self.localStore readLocalBottledPeerRecordWithRecordID:info.bottleID error:&error]; + XCTAssertNotNil(bprecord, @"bprecord should not be nil: %@", error); + + XCTAssertTrue([self.context.cloudStore uploadBottledPeerRecord:bprecord escrowRecordID:escrowRecordID error:&error], @"launch should succeed"); + XCTAssertNil(error, @"error should be nil: %@", error); + [self releaseCloudKitFetchHold]; + + [self expectCKFetch]; + XCTAssertEqual( [[self.cloudStore retrieveListOfEligibleEscrowRecordIDs:&error] count], (unsigned long)1, @"should have 1 record"); +} + +-(void) testEnrollAndRestore +{ + NSError* error = nil; + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + + NSString* escrowRecordID = [self currentIdentity:&error].spID; + XCTAssertNil(error, @"error should be nil: %@", error); + XCTAssertNotNil(escrowRecordID, @"escrowRecordID should not be nil: %@", error); + + NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil]; + + [self startCKKSSubsystem]; + + OTPreflightInfo* info = nil; + XCTAssertNotNil(info = [self.context preflightBottledPeer:testContextID entropy:self.secret error:&error], @"preflight sould return info"); + XCTAssertNil(error, @"error should be nil: %@", error); + XCTAssertNotNil(info, @"preflight info should not be nil: %@", error); + XCTAssertNotNil(info.bottleID, @"escrowRecordID should not be nil: %@", error); + XCTAssertNotNil(info.escrowedSigningSPKI, @"signingPubKey should be nil: %@", error); + + OTBottledPeerRecord* bprecord = [self.localStore readLocalBottledPeerRecordWithRecordID:info.bottleID error:&error]; + XCTAssertNotNil(bprecord, @"bprecord should not be nil: %@", error); + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; + XCTAssertTrue([self.cloudStore uploadBottledPeerRecord:bprecord escrowRecordID:bprecord.escrowRecordID error:&error], @"should create bottled peer record"); + XCTAssertNil(error, "error should be nil"); + [self waitForCKModifications]; + + [self releaseCloudKitFetchHold]; + + OTBottledPeerSigned* bp = [self.context restoreFromEscrowRecordID:escrowRecordID secret:self.secret error:&error]; + [self waitForCKModifications]; + + XCTAssertTrue( [[self.cloudStore retrieveListOfEligibleEscrowRecordIDs:&error] count] == 1, @"should have 1 record"); + [self waitForCKModifications]; + + XCTAssertNil(error, @"error should be nil: %@", error); + XCTAssertNotNil(bp, @"signed bottled peer should not be nil: %@", error); + XCTAssertTrue([bp.bp.peerEncryptionKey isEqual:self.peerEncryptionKey], @"enrolled and restored peer encryption keys should match"); + XCTAssertTrue([bp.bp.peerSigningKey isEqual:self.peerSigningKey], @"enrolled and restored peer signing keys should match"); +} + +-(void)testEnrollAndRestoreFromCloudKit +{ + NSError* error = nil; + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + + NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil]; + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:YES]; + [self startCKKSSubsystem]; + + OTPreflightInfo* info = nil; + XCTAssertNotNil(info = [self.context preflightBottledPeer:testContextID entropy:self.secret error:&error], @"preflight sould return info"); + XCTAssertNil(error, @"error should be nil: %@", error); + XCTAssertNotNil(info, @"preflight info should not be nil: %@", error); + XCTAssertNotNil(info.bottleID, @"bottleID should not be nil: %@", error); + XCTAssertNotNil(info.escrowedSigningSPKI, @"signingPubKey should be nil: %@", error); + + OTBottledPeerRecord* bprecord = [self.localStore readLocalBottledPeerRecordWithRecordID:info.bottleID error:&error]; + XCTAssertNotNil(bprecord, @"bprecord should not be nil: %@", error); + + XCTAssertTrue([self.context.cloudStore uploadBottledPeerRecord:bprecord escrowRecordID:info.bottleID error:&error], @"launch should succeed"); + XCTAssertNil(error, @"error should be nil: %@", error); + + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self releaseCloudKitFetchHold]; + + XCTAssertTrue([[self.cloudStore retrieveListOfEligibleEscrowRecordIDs:&error] count] > 0, @"should have multiple records"); + OTIdentity *identity = [self currentIdentity:&error]; + + XCTAssertNil(error, @"error should be nil: %@", error); + XCTAssertNotNil(self.escrowKeys, @"escrow keys should not be nil: %@", error); + + NSString* recordName = [OTBottledPeerRecord constructRecordID:identity.spID escrowSigningSPKI:[self.escrowKeys.signingKey.publicKey asSPKI]]; + + OTBottledPeerRecord *rec = [self.localStore readLocalBottledPeerRecordWithRecordID:recordName error:&error]; + + XCTAssertNotNil(rec.signatureUsingEscrowKey, @"signatureUsingEscrow should not be nil: %@", error); + + XCTAssertNotNil(rec.signatureUsingPeerKey, @"signatureUsingPeerKey should not be nil: %@", error); + + XCTAssertNotNil(rec.bottle, @"bottle should not be nil: %@", error); + + + OTBottledPeerSigned *bps = [[OTBottledPeerSigned alloc] initWithBottledPeerRecord:rec + escrowKeys:self.escrowKeys + error:&error]; + XCTAssertNil(error, @"error should be nil: %@", error); + XCTAssertNotNil(bps, @"signed bottled peer should not be nil: %@", error); + XCTAssertTrue([bps.bp.peerEncryptionKey isEqual:self.peerEncryptionKey], @"enrolled and restored peer encryption keys should match"); + XCTAssertTrue([bps.bp.peerSigningKey isEqual:self.peerSigningKey], @"enrolled and restored peer signing keys should match"); +} + +-(void) testScrubbing +{ + NSError* error = nil; + + NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil]; + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:YES]; + [self startCKKSSubsystem]; + + OTPreflightInfo* info = nil; + XCTAssertNotNil(info = [self.context preflightBottledPeer:testContextID entropy:self.secret error:&error], @"preflight sould return info"); + XCTAssertNil(error, @"error should be nil: %@", error); + XCTAssertNotNil(info, @"preflight info should not be nil: %@", error); + XCTAssertNotNil(info.bottleID, @"escrowRecordID should not be nil: %@", error); + XCTAssertNotNil(info.escrowedSigningSPKI, @"signingPubKey should be nil: %@", error); + + XCTAssertTrue([self.context scrubBottledPeer:testContextID bottleID:info.bottleID error:&error], @"scrubbing bottled peer should succeed"); + XCTAssertNil(error, @"error should be nil: %@", error); + NSArray* list = [self.context.cloudStore retrieveListOfEligibleEscrowRecordIDs:&error]; + XCTAssertTrue([list count] == 0, @"there should be 0 records in localstore"); +} + +-(void) testGettingListOfRecordIDS +{ + NSError* error = nil; + + NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil]; + [self expectAddedCKModifyRecords:recordDictionary holdFetch:YES]; + [self startCKKSSubsystem]; + + OTPreflightInfo* info = nil; + XCTAssertNotNil(info = [self.context preflightBottledPeer:testContextID entropy:self.secret error:&error], @"preflight sould return info"); + XCTAssertNil(error, @"error should be nil: %@", error); + XCTAssertNotNil(info, @"preflight info should not be nil: %@", error); + XCTAssertNotNil(info.bottleID, @"bottleID should not be nil: %@", error); + XCTAssertNotNil(info.escrowedSigningSPKI, @"signingPubKey should be nil: %@", error); + + OTBottledPeerRecord* bprecord = [self.localStore readLocalBottledPeerRecordWithRecordID:info.bottleID error:&error]; + XCTAssertNotNil(bprecord, @"bprecord should not be nil: %@", error); + + XCTAssertTrue([self.context.cloudStore uploadBottledPeerRecord:bprecord escrowRecordID:info.bottleID error:&error], @"launch should succeed"); + XCTAssertNil(error, @"error should be nil: %@", error); + + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self releaseCloudKitFetchHold]; + + NSArray* list = [self.context.cloudStore retrieveListOfEligibleEscrowRecordIDs:&error]; + XCTAssertNotNil(list, @"list should not be nil"); + XCTAssertTrue([list count] > 0, @"list of escrow record ids should not be empty"); +} + +- (nullable OTIdentity *)currentIdentity:(NSError**)error { + + return [[OTIdentity alloc]initWithPeerID:@"ego peer id" spID:@"sos peer id" peerSigningKey:self.peerSigningKey peerEncryptionkey:self.peerEncryptionKey error:error]; +} + +@end +#endif + diff --git a/keychain/ot/tests/OTEscrowKeyTests.m b/keychain/ot/tests/OTEscrowKeyTests.m new file mode 100644 index 00000000..cd1954e7 --- /dev/null +++ b/keychain/ot/tests/OTEscrowKeyTests.m @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import +#import +#import +#import "keychain/ot/OTEscrowKeys.h" +#import "keychain/ckks/CKKS.h" +#import "OTTestsBase.h" + +static NSString* const testDSID = @"123456789"; + +static const uint8_t signingKey_384[] = { + 0x04, 0xe4, 0x1b, 0x3e, 0x88, 0x81, 0x9f, 0x3b, 0x80, 0xd0, 0x28, 0x1c, + 0xd9, 0x07, 0xa0, 0x8c, 0xa1, 0x89, 0xa8, 0x3b, 0x69, 0x91, 0x17, 0xa7, + 0x1f, 0x00, 0x31, 0x91, 0x82, 0x89, 0x1f, 0x5c, 0x44, 0x2d, 0xd6, 0xa8, + 0x22, 0x1f, 0x22, 0x7d, 0x27, 0x21, 0xf2, 0xc9, 0x75, 0xf2, 0xda, 0x41, + 0x61, 0x55, 0x29, 0x11, 0xf7, 0x71, 0xcf, 0x66, 0x52, 0x2a, 0x27, 0xfe, + 0x77, 0x1e, 0xd4, 0x3d, 0xfb, 0xbc, 0x59, 0xe4, 0xed, 0xa4, 0x79, 0x2a, + 0x9b, 0x73, 0x3e, 0xf4, 0xf4, 0xe3, 0xaf, 0xf2, 0x8d, 0x34, 0x90, 0x92, + 0x47, 0x53, 0xd0, 0x34, 0x1e, 0x49, 0x87, 0xeb, 0x11, 0x89, 0x0f, 0x9c, + 0xa4, 0x99, 0xe8, 0x4f, 0x39, 0xbe, 0x21, 0x94, 0x88, 0xba, 0x4c, 0xa5, + 0x6a, 0x60, 0x1c, 0x2f, 0x77, 0x80, 0xd2, 0x73, 0x14, 0x33, 0x46, 0x5c, + 0xda, 0xee, 0x13, 0x8a, 0x3a, 0xdb, 0x4e, 0x05, 0x4d, 0x0f, 0x6d, 0x96, + 0xcd, 0x28, 0xab, 0x52, 0x4c, 0x12, 0x2b, 0x79, 0x80, 0xfe, 0x9a, 0xe4, + 0xf4 +}; + +static const uint8_t encryptionKey_384[] = { + 0x04, 0x99, 0xf9, 0x9a, 0x9b, 0x48, 0xe2, 0xf8, 0x69, 0xd3, 0xf9, 0x60, + 0xa0, 0xf4, 0x86, 0xda, 0xb3, 0x35, 0x3d, 0x97, 0x7d, 0xc3, 0xf4, 0x13, + 0x24, 0x78, 0x06, 0x10, 0xd5, 0x46, 0x55, 0x7a, 0x8a, 0x4d, 0x80, 0x0d, + 0x71, 0x19, 0x46, 0x4b, 0x15, 0x93, 0x36, 0xb0, 0xf4, 0x6e, 0x41, 0x30, + 0x09, 0x55, 0x25, 0x3b, 0x06, 0xdd, 0xf8, 0x85, 0xdc, 0xf2, 0x0b, 0xc7, + 0x33, 0x21, 0x99, 0x3c, 0x79, 0xa6, 0xb1, 0x0f, 0xf0, 0x55, 0xfa, 0xe8, + 0x6d, 0x3f, 0x0d, 0x57, 0x21, 0x08, 0xd2, 0x7e, 0x73, 0x4a, 0xe7, 0x4a, + 0xb3, 0xdf, 0xed, 0x86, 0x06, 0xa6, 0xf2, 0x03, 0xe6, 0x20, 0xd4, 0x82, + 0x39, 0x29, 0xcf, 0x6d, 0x76, 0x3e, 0x9a, 0xaa, 0x29, 0x4f, 0x33, 0x84, + 0x5a, 0x38, 0x50, 0x35, 0xca, 0x3f, 0x69, 0x92, 0xb1, 0xb3, 0x8b, 0x26, + 0x2b, 0xb5, 0xd6, 0x25, 0xcf, 0x2d, 0x18, 0xc4, 0x5e, 0x24, 0x34, 0xc5, + 0xcc, 0x83, 0x2f, 0xff, 0x08, 0x85, 0x0f, 0x89, 0xb5, 0xb1, 0xc1, 0x17, + 0x2a +}; + +static const uint8_t symmetricKey_384[] = { + 0x31, 0xf1, 0xe3, 0x7b, 0x76, 0x3f, 0x99, 0x65, 0x74, 0xab, 0xe8, 0x2b, + 0x8f, 0x06, 0x78, 0x57, 0x1b, 0xaa, 0x07, 0xb3, 0xab, 0x79, 0x81, 0xcb, + 0xc5, 0x89, 0x1e, 0x78, 0x28, 0x8d, 0x8e, 0x36 +}; + +@interface UnitTestEscrowKeys : OTTestsBase + +@end + +@implementation UnitTestEscrowKeys + +- (void)setUp +{ + [super setUp]; + NSError *error = nil; + + self.continueAfterFailure = NO; + NSString* secretString = @"I'm a secretI'm a secretI'm a secretI'm a secretI'm a secretI'm a secret"; + + self.secret = [[NSData alloc]initWithBytes:[secretString UTF8String] length:[secretString length]]; + self.escrowKeys = [[OTEscrowKeys alloc]initWithSecret:self.secret dsid:testDSID error:&error]; + + XCTAssertNil(error, @"error should be initialized"); + XCTAssertNotNil(self.escrowKeys, @"escrow keys should be initialized"); +} + +- (void)tearDown +{ + [super tearDown]; +} + +-(void) testEscrowKeyAllocations +{ + XCTAssertNotNil(self.escrowKeys.symmetricKey, @"escrowed symmetric key pair should not be nil"); + XCTAssertNotNil(self.escrowKeys.secret, @"escrowed secret should not be nil"); + XCTAssertNotNil(self.escrowKeys.dsid, @"account dsid should not be nil"); + XCTAssertNotNil(self.escrowKeys.signingKey, @"escrowed signing key should not be nil"); + XCTAssertNotNil(self.escrowKeys.encryptionKey, @"escrowed encryption key should not be nil"); +} +-(void) testEscrowKeyTestVectors +{ + NSError* error = nil; + + //test vectors + NSData* testv1 = [OTEscrowKeys generateEscrowKey:kOTEscrowKeySigning masterSecret:self.secret dsid:testDSID error:&error]; + NSData* signingFromBytes = [[NSData alloc] initWithBytes:signingKey_384 length:sizeof(signingKey_384)]; + XCTAssertTrue([testv1 isEqualToData:signingFromBytes], @"signing keys should match"); + + NSData* testv2 = [OTEscrowKeys generateEscrowKey:kOTEscrowKeyEncryption masterSecret:self.secret dsid:testDSID error:&error]; + NSData* encryptionFromBytes = [[NSData alloc] initWithBytes:encryptionKey_384 length:sizeof(encryptionKey_384)]; + XCTAssertTrue([testv2 isEqualToData:encryptionFromBytes], @"encryption keys should match"); + + NSData* testv3 = [OTEscrowKeys generateEscrowKey:kOTEscrowKeySymmetric masterSecret:self.secret dsid:testDSID error:&error]; + NSData* symmetricKeyFromBytes = [[NSData alloc]initWithBytes:symmetricKey_384 length:sizeof(symmetricKey_384)]; + XCTAssertTrue([testv3 isEqualToData:symmetricKeyFromBytes], @"symmetric keys should match"); + + NSString* newSecretString = @"I'm f secretI'm a secretI'm a secretI'm a secretI'm a secretI'm a secret"; + NSData* newSecret = [[NSData alloc]initWithBytes:[newSecretString UTF8String] length:[newSecretString length]]; + + NSData* testv4 = [OTEscrowKeys generateEscrowKey:kOTEscrowKeySigning masterSecret:newSecret dsid:testDSID error:&error]; + XCTAssertFalse([testv4 isEqualToData:signingFromBytes], @"signing keys should not match"); + + NSData* testv5 = [OTEscrowKeys generateEscrowKey:kOTEscrowKeyEncryption masterSecret:newSecret dsid:testDSID error:&error]; + XCTAssertFalse([testv5 isEqualToData:encryptionFromBytes], @"encryption keys should not match"); + + NSData* testv6 = [OTEscrowKeys generateEscrowKey:kOTEscrowKeySymmetric masterSecret:newSecret dsid:testDSID error:&error]; + XCTAssertFalse([testv6 isEqualToData:symmetricKeyFromBytes], @"symmetric keys should not match"); +} + +-(void) testEmptyArguments +{ + NSError* error = nil; + OTEscrowKeys* newSet = [[OTEscrowKeys alloc] initWithSecret:[NSData data] dsid:testDSID error:&error]; + XCTAssertNotNil(error, @"error should be initialized"); + XCTAssertNil(newSet, @"escrow keys should not be initialized"); + + newSet = [[OTEscrowKeys alloc] initWithSecret:self.secret dsid:[NSString string] error:&error]; + XCTAssertNotNil(error, @"error should be initialized"); + XCTAssertNil(newSet, @"escrow keys should not be initialized"); +} + + +@end + +#endif /* OCTAGON */ + diff --git a/keychain/ot/tests/OTLocalStoreTests.m b/keychain/ot/tests/OTLocalStoreTests.m new file mode 100644 index 00000000..1fe81114 --- /dev/null +++ b/keychain/ot/tests/OTLocalStoreTests.m @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import "OTTestsBase.h" + +/* Octagon Trust Local Context Record Constants */ +static NSString* OTCKRecordContextID = @"contextID"; +static NSString* OTCKRecordDSID = @"accountDSID"; +static NSString* OTCKRecordContextName = @"contextName"; +static NSString* OTCKRecordZoneCreated = @"zoneCreated"; +static NSString* OTCKRecordSubscribedToChanges = @"subscribedToChanges"; +static NSString* OTCKRecordChangeToken = @"changeToken"; +static NSString* OTCKRecordEgoPeerID = @"egoPeerID"; +static NSString* OTCKRecordEgoPeerCreationDate = @"egoPeerCreationDate"; +static NSString* OTCKRecordRecoverySigningSPKI = @"recoverySigningSPKI"; +static NSString* OTCKRecordRecoveryEncryptionSPKI = @"recoveryEncryptionSPKI"; +static NSString* OTCKRecordBottledPeerTableEntry = @"bottledPeer"; + +/* Octagon Trust Local Peer Record */ +static NSString* OTCKRecordPeerID = @"peerID"; +static NSString* OTCKRecordPermanentInfo = @"permanentInfo"; +static NSString* OTCKRecordStableInfo = @"stableInfo"; +static NSString* OTCKRecordDynamicInfo = @"dynamicInfo"; +static NSString* OTCKRecordRecoveryVoucher = @"recoveryVoucher"; +static NSString* OTCKRecordIsEgoPeer = @"isEgoPeer"; + +/* Octagon Trust BottledPeerSchema */ +static NSString* OTCKRecordEscrowRecordID = @"escrowRecordID"; +static NSString* OTCKRecordRecordID = @"bottledPeerRecordID"; +static NSString* OTCKRecordSPID = @"spID"; +static NSString* OTCKRecordEscrowSigningSPKI = @"escrowSigningSPKI"; +static NSString* OTCKRecordPeerSigningSPKI = @"peerSigningSPKI"; +static NSString* OTCKRecordEscrowSigningPubKey = @"escrowSigningPubKey"; +static NSString* OTCKRecordPeerSigningPubKey = @"peerSigningPubKey"; +static NSString* OTCKRecordSignatureFromEscrow = @"signatureUsingEscrow"; +static NSString* OTCKRecordSignatureFromPeerKey = @"signatureUsingPeerKey"; +static NSString* OTCKRecordBottle = @"bottle"; + +static NSString* const testDSID = @"123456789"; + +@interface UnitTestOTLocalStore : OTTestsBase +@end + +@implementation UnitTestOTLocalStore + +- (void)setUp +{ + [super setUp]; + + self.continueAfterFailure = NO; +} + +- (void)tearDown +{ + [super tearDown]; +} + +-(void)testDBConnection +{ + NSError* error = nil; + + XCTAssertTrue([self.localStore closeDBWithError:&error], @"failed attempt at closing the db"); + XCTAssertNil(error, @"error should be nil:%@", error); + + XCTAssertTrue([self.localStore openDBWithError:&error], @"could not open db"); + XCTAssertNil(error, @"error should be nil:%@", error); + + XCTAssertTrue([self.localStore closeDBWithError:&error], @"failed attempt at closing the db"); + XCTAssertNil(error, @"error should be nil:%@", error); + + XCTAssertTrue([self.localStore openDBWithError:&error], @"could not open db"); + XCTAssertNil(error, @"error should be nil:%@", error); +} + +-(void) testDBLocalContextRetrieval +{ + NSString* contextAndDSID = [NSString stringWithFormat:@"testContextRetreival-%@", testDSID]; + _SFECKeyPair *recoverySigningPublicKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + _SFECKeyPair *recoveryEncryptionPublicKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + NSError* error = nil; + NSDictionary *attributes = @{ + OTCKRecordContextID : @"testContextRetreival", + OTCKRecordDSID : testDSID, + OTCKRecordContextName : @"newFoo", + OTCKRecordZoneCreated : @(NO), + OTCKRecordSubscribedToChanges : @(NO), + OTCKRecordChangeToken : [NSData data], + OTCKRecordEgoPeerID : @"OctagonPeerID", + OTCKRecordEgoPeerCreationDate : [NSDate date], + OTCKRecordRecoverySigningSPKI : [[recoverySigningPublicKey publicKey] keyData], + OTCKRecordRecoveryEncryptionSPKI :[[recoveryEncryptionPublicKey publicKey] keyData]}; + + XCTAssertTrue([self.localStore insertLocalContextRecord:attributes error:&error], @"inserting new context failed"); + XCTAssertNil(error, @"error should be nil:%@", error); + + OTContextRecord* record = [self.localStore readLocalContextRecordForContextIDAndDSID:contextAndDSID error:&error]; + XCTAssertNotNil(record, @"fetching attributes returned nil"); + XCTAssertNotNil(record.contextID, @"fetching attributes returned nil"); + XCTAssertNotNil(record.contextName, @"fetching attributes returned nil"); + XCTAssertNotNil(record.dsid, @"fetching attributes returned nil"); + XCTAssertNotNil(record.egoPeerCreationDate, @"fetching attributes returned nil"); + XCTAssertNotNil(record.egoPeerID, @"fetching attributes returned nil"); + XCTAssertNotNil(record.recoveryEncryptionSPKI, @"fetching attributes returned nil"); + XCTAssertNotNil(record.recoverySigningSPKI, @"fetching attributes returned nil"); + + XCTAssertNil(error, @"failed to read local context for test local store"); + + OTContextRecord* recordToTestEquality = [[OTContextRecord alloc]init]; + recordToTestEquality.contextName = @"newFoo"; + recordToTestEquality.contextID = @"testContextRetreival"; + recordToTestEquality.dsid = testDSID; + recordToTestEquality.contextName = @"newFoo"; + recordToTestEquality.egoPeerID = @"OctagonPeerID"; + recordToTestEquality.recoveryEncryptionSPKI = [[recoveryEncryptionPublicKey publicKey] keyData]; + recordToTestEquality.recoverySigningSPKI = [[recoverySigningPublicKey publicKey] keyData]; + + OTContextRecord* recordFromDB = [self.localStore readLocalContextRecordForContextIDAndDSID:contextAndDSID error:&error]; + XCTAssertTrue([recordFromDB isEqual:recordToTestEquality], @"OTContext should be equal"); +} + +-(void) testDBMultipleContexts +{ + NSError* error = nil; + NSString* newFooContextAndDSID = [NSString stringWithFormat:@"newFoo-%@", testDSID]; + + _SFECKeyPair *recoverySigningPublicKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + _SFECKeyPair *recoveryEncryptionPublicKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + NSDictionary *attributes = @{ + OTCKRecordContextID : @"newFoo", + OTCKRecordContextName : @"newFoo", + OTCKRecordDSID : testDSID, + OTCKRecordZoneCreated : @(NO), + OTCKRecordSubscribedToChanges : @(NO), + OTCKRecordChangeToken : [NSData data], + OTCKRecordEgoPeerID : @"OctagonPeerID", + OTCKRecordEgoPeerCreationDate : [NSDate date], + OTCKRecordRecoverySigningSPKI : [[recoverySigningPublicKey publicKey] keyData], // FIXME not SPKI + OTCKRecordRecoveryEncryptionSPKI : [[recoveryEncryptionPublicKey publicKey] keyData]}; + + + XCTAssertTrue([self.localStore insertLocalContextRecord:attributes error:&error], @"inserting new context failed"); + XCTAssertNil(error, @"error should be nil:%@", error); + + NSString* foo2ContextAndDSID = [NSString stringWithFormat:@"Foo2-%@", testDSID]; + attributes = @{ + OTCKRecordContextID : @"Foo2", + OTCKRecordContextName : @"Foo2", + OTCKRecordDSID : testDSID, + OTCKRecordZoneCreated : @(NO), + OTCKRecordSubscribedToChanges : @(NO), + OTCKRecordChangeToken : [NSData data], + OTCKRecordEgoPeerID : @"OctagonPeerID2", + OTCKRecordEgoPeerCreationDate : [NSDate date], + OTCKRecordRecoverySigningSPKI : [[recoverySigningPublicKey publicKey] keyData], // FIXME not SPKI + OTCKRecordRecoveryEncryptionSPKI :[[recoveryEncryptionPublicKey publicKey] keyData]}; + + XCTAssertTrue([self.localStore insertLocalContextRecord:attributes error:&error], @"inserting new context failed"); + XCTAssertNil(error, @"error should be nil:%@", error); + + OTContextRecord* recordNewFoo = [self.localStore readLocalContextRecordForContextIDAndDSID:newFooContextAndDSID error:&error]; + + XCTAssertNotNil(recordNewFoo, @"fetching attributes returned nil"); + XCTAssertNotNil(recordNewFoo.contextID, @"fetching attributes returned nil"); + XCTAssertNotNil(recordNewFoo.contextName, @"fetching attributes returned nil"); + XCTAssertNotNil(recordNewFoo.dsid, @"fetching attributes returned nil"); + XCTAssertNotNil(recordNewFoo.egoPeerCreationDate, @"fetching attributes returned nil"); + XCTAssertNotNil(recordNewFoo.egoPeerID, @"fetching attributes returned nil"); + XCTAssertNotNil(recordNewFoo.recoveryEncryptionSPKI, @"fetching attributes returned nil"); + XCTAssertNotNil(recordNewFoo.recoverySigningSPKI, @"fetching attributes returned nil"); + + XCTAssertNil(error, @"failed to read local context for test local store"); + + OTContextRecord* recordFoo2 = [self.localStore readLocalContextRecordForContextIDAndDSID:foo2ContextAndDSID error:&error]; + + XCTAssertNotNil(recordFoo2, @"fetching attributes returned nil"); + XCTAssertNotNil(recordFoo2.contextID, @"fetching attributes returned nil"); + XCTAssertNotNil(recordFoo2.contextName, @"fetching attributes returned nil"); + XCTAssertNotNil(recordFoo2.dsid, @"fetching attributes returned nil"); + XCTAssertNotNil(recordFoo2.egoPeerCreationDate, @"fetching attributes returned nil"); + XCTAssertNotNil(recordFoo2.egoPeerID, @"fetching attributes returned nil"); + XCTAssertNotNil(recordFoo2.recoveryEncryptionSPKI, @"fetching attributes returned nil"); + XCTAssertNotNil(recordFoo2.recoverySigningSPKI, @"fetching attributes returned nil"); + XCTAssertNil(error, @"failed to read local context for test local store"); + +} + +-(void) testRowUpdates +{ + NSError* error = nil; + NSString* escrowRecordID = @"escrow record 1"; + NSString* escrowRecordID2 = @"escrow record 2"; + NSString* escrowRecordID3 = @"escrow record 3"; + + OTBottledPeerRecord* record = [[OTBottledPeerRecord alloc]init]; + OTBottledPeerRecord* record2 = [[OTBottledPeerRecord alloc]init]; + OTBottledPeerRecord* record3 = [[OTBottledPeerRecord alloc]init]; + + record.escrowRecordID = escrowRecordID; + record2.escrowRecordID = escrowRecordID2; + record3.escrowRecordID = escrowRecordID3; + + record.escrowedSigningSPKI = [@"escrowedSigingSPKI" dataUsingEncoding:kCFStringEncodingUTF8]; + record2.escrowedSigningSPKI = [@"escrowedSigingSPI" dataUsingEncoding:kCFStringEncodingUTF8]; + record3.escrowedSigningSPKI = [@"escrowedSigingSPKI" dataUsingEncoding:kCFStringEncodingUTF8]; + + XCTAssertTrue([self.localStore insertBottledPeerRecord:record escrowRecordID:escrowRecordID error:&error]); + XCTAssertNil(error, @"error should be nil:%@", error); + + XCTAssertTrue([self.localStore insertBottledPeerRecord:record2 escrowRecordID:escrowRecordID2 error:&error]); + XCTAssertNil(error, @"error should be nil:%@", error); + + XCTAssertTrue([self.localStore insertBottledPeerRecord:record3 escrowRecordID:escrowRecordID3 error:&error]); + XCTAssertNil(error, @"error should be nil:%@", error); + + + OTBottledPeerRecord *bp = [self.localStore readLocalBottledPeerRecordWithRecordID:record.recordName error:&error]; + XCTAssertNotNil(bp); + XCTAssertNil(error, @"error should be nil:%@", error); + + OTBottledPeerRecord *bp2 = [self.localStore readLocalBottledPeerRecordWithRecordID:record2.recordName error:&error]; + XCTAssertNotNil(bp2); + XCTAssertNil(error, @"error should be nil:%@", error); + + OTBottledPeerRecord *bp3 = [self.localStore readLocalBottledPeerRecordWithRecordID:record3.recordName error:&error]; + XCTAssertNotNil(bp3); + XCTAssertNil(error, @"error should be nil:%@", error); + + XCTAssertTrue([self.localStore updateLocalContextRecordRowWithContextID:self.localStore.contextID columnName:OTCKRecordContextName newValue:(void*)@"SuperSuperFoo" error:&error], @"could not update column:%@ with value:%@", OTCKRecordContextName, @"SuperSuperFoo"); + XCTAssertNil(error, @"error should be nil:%@", error); + + XCTAssertTrue([self.localStore updateLocalContextRecordRowWithContextID:self.localStore.contextID columnName:OTCKRecordEgoPeerID newValue:(void*)@"NewPeerID" error:&error], @"could not update column:%@ with value:%@", OTCKRecordEgoPeerID, @"NewPeerID"); + XCTAssertNil(error, @"error should be nil:%@", error); + + XCTAssertTrue([self.localStore updateLocalContextRecordRowWithContextID:self.localStore.contextID columnName:OTCKRecordRecoverySigningSPKI newValue:(void*)[[NSData alloc]initWithBase64EncodedString:@"I'm a string" options:NSDataBase64DecodingIgnoreUnknownCharacters] error:&error], @"could not update column:%@ with value:%@", OTCKRecordContextName, @"NewPeerID"); + XCTAssertNil(error, @"error should be nil:%@", error); + + XCTAssertFalse([self.localStore updateLocalContextRecordRowWithContextID:self.localStore.contextID columnName:@"ColumnName" newValue:(void*)@"value" error:&error], @"could not update column:%@ with value:%@", @"ColumnName", @"value"); + XCTAssertNotNil(error, @"error should not be nil: %@", error); +} + +@end + +#endif /* OCTAGON */ diff --git a/keychain/ot/tests/OTLockStateNetworkingTests.m b/keychain/ot/tests/OTLockStateNetworkingTests.m new file mode 100644 index 00000000..b1fd55f1 --- /dev/null +++ b/keychain/ot/tests/OTLockStateNetworkingTests.m @@ -0,0 +1,654 @@ +/* +* Copyright (c) 2017 Apple Inc. All Rights Reserved. +* +* @APPLE_LICENSE_HEADER_START@ +* +* This file contains Original Code and/or Modifications of Original Code +* as defined in and that are subject to the Apple Public Source License +* Version 2.0 (the 'License'). You may not use this file except in +* compliance with the License. Please obtain a copy of the License at +* http://www.opensource.apple.com/apsl/ and read it before using this +* file. +* +* The Original Code and all software distributed under the License are +* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, +* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. +* Please see the License for the specific language governing rights and +* limitations under the License. +* +* @APPLE_LICENSE_HEADER_END@ +*/ + +#if OCTAGON + +#import + +#import +#import + +#import "OTTestsBase.h" + +static NSString* const testContextID = @"Foo"; +static NSString* const testDSID = @"123456789"; + +static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; +/* Octagon Trust BottledPeerSchema */ +static NSString* OTCKRecordEscrowRecordID = @"escrowRecordID"; +static NSString* OTCKRecordRecordID = @"bottledPeerRecordID"; +static NSString* OTCKRecordSPID = @"spID"; +static NSString* OTCKRecordEscrowSigningSPKI = @"escrowSigningSPKI"; +static NSString* OTCKRecordPeerSigningSPKI = @"peerSigningSPKI"; +static NSString* OTCKRecordEscrowSigningPubKey = @"escrowSigningPubKey"; +static NSString* OTCKRecordPeerSigningPubKey = @"peerSigningPubKey"; +static NSString* OTCKRecordSignatureFromEscrow = @"signatureUsingEscrow"; +static NSString* OTCKRecordSignatureFromPeerKey = @"signatureUsingPeerKey"; +static NSString* OTCKRecordBottle = @"bottle"; + +static NSString* OTCKRecordPeerID = @"peerID"; + +@interface OTLockStateNetworkingTests : OTTestsBase +@property (nonatomic, strong) OTBottledPeerRecord* fakeBottledPeerRecord; +@end + +@implementation OTLockStateNetworkingTests + +- (void)setUp { + [super setUp]; + + self.continueAfterFailure = NO; + NSError* error = nil; + + OTBottledPeer *bp = [[OTBottledPeer alloc]initWithPeerID:self.egoPeerID spID:self.sosPeerID peerSigningKey:self.peerSigningKey peerEncryptionKey:self.peerEncryptionKey escrowKeys:self.escrowKeys error:&error]; + + XCTAssertNotNil(bp, @"plaintext should not be nil"); + XCTAssertNil(error, @"error should be nil"); + XCTAssertNotNil(self.escrowKeys.signingKey, @"signing public key should not be nil"); + XCTAssertNotNil(self.escrowKeys.encryptionKey, @"encryption public key should not be nil"); + + OTBottledPeerSigned *bpSigned = [[OTBottledPeerSigned alloc]initWithBottledPeer:bp escrowedSigningKey:self.escrowKeys.signingKey peerSigningKey:self.peerSigningKey error:&error]; + + self.fakeBottledPeerRecord = [bpSigned asRecord:self.sosPeerID]; + + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + +} + +- (void)tearDown { + + [super tearDown]; +} + +//Bottle Check tests + +-(void) testGrabbingBottleLocallyCheckPerfectConditions +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + [self startCKKSSubsystem]; + + __block NSData* localEntropy = nil; + __block NSString* localBottleID = nil; + + self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer fired"]; + + [self.otControl preflightBottledPeer:testContextID + dsid:testDSID + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + localEntropy = entropy; + localBottleID = bottleID; + XCTAssertNotNil(entropy, "entropy should not be nil"); + XCTAssertNotNil(bottleID, "bottle id should not be nil"); + XCTAssertNotNil(signingPublicKey, "signing pub key should not be nil"); + XCTAssertNil(error, "error should be nil"); + }]; + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + self.spiBlockExpectation = [self expectationWithDescription:@"launch bottled peer fired"]; + + NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil]; + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; + + [self.otControl launchBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(error, "error should be nil"); + }]; + + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + NSError* localError = nil; + XCTAssertTrue([self.context doesThisDeviceHaveABottle:&localError] == BOTTLE, @"should have a bottle"); + XCTAssertNil(localError, "error should be nil"); +} + +-(void) testGrabbingBottleFromCloudKitCheckPerfectConditions +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + CKRecord* newRecord = [[CKRecord alloc]initWithRecordType:OTCKRecordBottledPeerType]; + newRecord[OTCKRecordPeerID] = self.fakeBottledPeerRecord.peerID; + newRecord[OTCKRecordSPID] = @"spID"; + newRecord[OTCKRecordEscrowSigningSPKI] = self.fakeBottledPeerRecord.escrowedSigningSPKI; + newRecord[OTCKRecordPeerSigningSPKI] = self.fakeBottledPeerRecord.peerSigningSPKI; + newRecord[OTCKRecordEscrowRecordID] = self.fakeBottledPeerRecord.escrowRecordID; + newRecord[OTCKRecordBottle] = self.fakeBottledPeerRecord.bottle; + newRecord[OTCKRecordSignatureFromEscrow] = self.fakeBottledPeerRecord.signatureUsingEscrowKey; + newRecord[OTCKRecordSignatureFromPeerKey] = self.fakeBottledPeerRecord.signatureUsingPeerKey; + + [self.otFakeZone addToZone:newRecord]; + + [self startCKKSSubsystem]; + + NSError* localError = nil; + XCTAssertTrue([self.context doesThisDeviceHaveABottle:&localError] == BOTTLE, @"should have a bottle"); + XCTAssertNil(localError, "error should be nil"); +} + +-(void) testBottleCheckWhenLocked +{ + NSError* error = nil; + self.aksLockState = true; + [self.lockStateTracker recheck]; + [self setUpRampRecordsInCloudKitWithFeatureOff]; + + XCTAssertTrue([self.context doesThisDeviceHaveABottle:&error] == UNCLEAR, @"bottle check should return unclear"); + + XCTAssertNotNil(error, "error should not be nil"); + XCTAssertTrue(error.code == -25308, @"error should be interaction not allowed"); +} + +-(void) testBottleCheckWithNoNetwork +{ + NSError* error = nil; + self.accountStatus = CKAccountStatusAvailable; + [self startCKKSSubsystem]; + + [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + + self.reachabilityFlags = 0; + [self.reachabilityTracker recheck]; + XCTAssertTrue([self.context doesThisDeviceHaveABottle:&error] == UNCLEAR, @"bottle check should return unclear"); + XCTAssertTrue(error.code == OTErrorNoNetwork, @"should have returned no network error"); +} + +-(void) testBottleCheckWhenNotSignedIn +{ + NSError* error = nil; + + self.accountStatus = CKAccountStatusNoAccount; + [self startCKKSSubsystem]; + + [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + + XCTAssertTrue([self.context doesThisDeviceHaveABottle:&error] == UNCLEAR, @"bottle check should return unclear"); + XCTAssertTrue(error.code == OTErrorNotSignedIn, @"should have returned not signed in error"); +} + + +//Preflight tests +-(void)testPreflightNotSignedIn +{ + self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer fired"]; + + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + self.accountStatus = CKAccountStatusNoAccount; + + [self startCKKSSubsystem]; + + [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + + [self.otControl preflightBottledPeer:testContextID + dsid:testDSID + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(entropy, "entropy should not be nil"); + XCTAssertNil(bottleID, "bottle id should not be nil"); + XCTAssertNil(signingPublicKey, "signing pub key should not be nil"); + XCTAssertTrue(error.code == OTErrorNotSignedIn, @"should have returned not signed in error"); + }]; + + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + +} + +-(void) testPreflightWithNoNetwork +{ + self.accountStatus = CKAccountStatusAvailable; + [self startCKKSSubsystem]; + + [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + + self.reachabilityFlags = 0; + [self.reachabilityTracker recheck]; + + [self.otControl preflightBottledPeer:testContextID + dsid:testDSID + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(entropy, "entropy should not be nil"); + XCTAssertNil(bottleID, "bottle id should not be nil"); + XCTAssertNil(signingPublicKey, "signing pub key should not be nil"); + XCTAssertTrue(error.code == OTErrorNoNetwork, @"should have returned OTErrorNoNetwork in error"); + }]; + +} + +-(void) testPreflightWhenLocked +{ + self.aksLockState = true; + [self.lockStateTracker recheck]; + + [self.otControl preflightBottledPeer:testContextID + dsid:testDSID + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(entropy, "entropy should not be nil"); + XCTAssertNil(bottleID, "bottle id should not be nil"); + XCTAssertNil(signingPublicKey, "signing pub key should not be nil"); + XCTAssertTrue(error.code == errSecInteractionNotAllowed, @"should have returned errSecInteractionNotAllowed in error"); + }]; +} + +//Launch Bottle tests +-(void)testLaunchNotSignedIn +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + self.accountStatus = CKAccountStatusNoAccount; + + [self startCKKSSubsystem]; + + [self.enroll.accountTracker notifyCKAccountStatusChangeAndWaitForSignal]; + [self.context.accountTracker notifyCKAccountStatusChangeAndWaitForSignal]; + + self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer fired"]; + + [self.otControl preflightBottledPeer:OTDefaultContext + dsid:@"dsid" + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(entropy, "shouldn't return any entropy"); + XCTAssertNil(bottleID, "shouldn't return a bottle ID"); + XCTAssertNil(signingPublicKey, "shouldn't return a signingPublicKey"); + XCTAssertTrue(error.code == OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); + }]; + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + self.spiBlockExpectation = [self expectationWithDescription:@"launch SPI fired"]; + self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; + + NSString* localBottleID = @"random bottle id"; + [self.otControl launchBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertTrue(error.code == OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); + }]; + + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; +} + +-(void) testLaunchWithNoNetwork +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + self.accountStatus = CKAccountStatusAvailable; + [self startCKKSSubsystem]; + + [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + + self.reachabilityFlags = 0; + [self.reachabilityTracker recheck]; + + [self startCKKSSubsystem]; + + self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer fired"]; + + [self.otControl preflightBottledPeer:OTDefaultContext + dsid:@"dsid" + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(entropy, "shouldn't return any entropy"); + XCTAssertNil(bottleID, "shouldn't return a bottle ID"); + XCTAssertNil(signingPublicKey, "shouldn't return a signingPublicKey"); + XCTAssertTrue(error.code == OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); + }]; + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + + self.spiBlockExpectation = [self expectationWithDescription:@"launch SPI fired"]; + self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; + + NSString* localBottleID = @"random bottle id"; + [self.otControl launchBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertTrue(error.code == OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); + }]; + + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; +} + +-(void) testLaunchWhenLocked +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + self.aksLockState = true; + [self.lockStateTracker recheck]; + + [self startCKKSSubsystem]; + + self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer fired"]; + + [self.otControl preflightBottledPeer:OTDefaultContext + dsid:@"dsid" + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(entropy, "shouldn't return any entropy"); + XCTAssertNil(bottleID, "shouldn't return a bottle ID"); + XCTAssertNil(signingPublicKey, "shouldn't return a signingPublicKey"); + XCTAssertTrue(error.code == errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); + }]; + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + + self.spiBlockExpectation = [self expectationWithDescription:@"launch SPI fired"]; + self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; + + NSString* localBottleID = @"random bottle id"; + [self.otControl launchBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertTrue(error.code == errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); + }]; + + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; +} + +//Scrub tests +-(void)testScrubNotSignedIn +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + self.accountStatus = CKAccountStatusNoAccount; + [self startCKKSSubsystem]; + + [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + + self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer SPI fired"]; + self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; + + [self.otControl preflightBottledPeer:testContextID + dsid:testDSID + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(entropy, "entropy should be nil"); + XCTAssertNil(bottleID, "bottle id should be nil"); + XCTAssertNil(signingPublicKey, "signing pub key should be nil"); + XCTAssertTrue(error.code == OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); + }]; + + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + __block NSString* localBottleID = @"random bottle id"; + self.spiBlockExpectation = [self expectationWithDescription:@"scrub bottled peer SPI fired"]; + self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; + + [self.otControl scrubBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertTrue(error.code == OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); + }]; + + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + +} + +-(void) testScrubWithNoNetwork +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + self.accountStatus = CKAccountStatusAvailable; + [self startCKKSSubsystem]; + + [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + + self.reachabilityFlags = 0; + [self.reachabilityTracker recheck]; + + self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer SPI fired"]; + self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; + + [self.otControl preflightBottledPeer:testContextID + dsid:testDSID + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(entropy, "entropy should be nil"); + XCTAssertNil(bottleID, "bottle id should be nil"); + XCTAssertNil(signingPublicKey, "signing pub key should be nil"); + XCTAssertTrue(error.code == OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); + }]; + + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + __block NSString* localBottleID = @"random bottle id"; + self.spiBlockExpectation = [self expectationWithDescription:@"scrub bottled peer SPI fired"]; + self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; + + [self.otControl scrubBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertTrue(error.code == OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); + }]; + + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; +} + +-(void) testScrubWhenLocked +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + self.aksLockState = true; + [self.lockStateTracker recheck]; + + self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer SPI fired"]; + self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; + + [self.otControl preflightBottledPeer:testContextID + dsid:testDSID + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(entropy, "entropy should be nil"); + XCTAssertNil(bottleID, "bottle id should be nil"); + XCTAssertNil(signingPublicKey, "signing pub key should be nil"); + XCTAssertTrue(error.code == errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); + }]; + + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + __block NSString* localBottleID = @"random bottle id"; + self.spiBlockExpectation = [self expectationWithDescription:@"scrub bottled peer SPI fired"]; + self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; + + [self.otControl scrubBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertTrue(error.code == errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); + }]; + + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; +} + +//Restore tests +-(void)testRestoreNotSignedIn +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + self.accountStatus = CKAccountStatusNoAccount; + [self startCKKSSubsystem]; + + [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + + self.spiBlockExpectation = [self expectationWithDescription:@"restore SPI fired"]; + self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; + + [self.otControl restore:testContextID + dsid:testDSID + secret:self.secret + escrowRecordID:self.sosPeerID + reply:^(NSData* signingKeyData, NSData* encryptionKeyData, NSError* _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(signingKeyData, "Signing key data should be nil"); + XCTAssertNil(encryptionKeyData, "encryption key data should be nil"); + XCTAssertTrue(error.code == OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); + }]; + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + +} + +-(void) testRestoreWithNoNetwork +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + self.accountStatus = CKAccountStatusAvailable; + [self startCKKSSubsystem]; + + [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + + self.reachabilityFlags = 0; + [self.reachabilityTracker recheck]; + + self.spiBlockExpectation = [self expectationWithDescription:@"restore SPI fired"]; + self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; + + [self.otControl restore:testContextID + dsid:testDSID + secret:self.secret + escrowRecordID:self.sosPeerID + reply:^(NSData* signingKeyData, NSData* encryptionKeyData, NSError* _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(signingKeyData, "Signing key data should be nil"); + XCTAssertNil(encryptionKeyData, "encryption key data should be nil"); + XCTAssertTrue(error.code == OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); + }]; + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; +} + +-(void) testRestoreWhenLocked +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + self.aksLockState = true; + [self.lockStateTracker recheck]; + + self.spiBlockExpectation = [self expectationWithDescription:@"restore SPI fired"]; + self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; + + [self.otControl restore:testContextID + dsid:testDSID + secret:self.secret + escrowRecordID:self.sosPeerID + reply:^(NSData* signingKeyData, NSData* encryptionKeyData, NSError* _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(signingKeyData, "Signing key data should be nil"); + XCTAssertNil(encryptionKeyData, "encryption key data should be nil"); + XCTAssertTrue(error.code == errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); + }]; + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; +} + +//Generic Ramp tests +-(void)testEnrollRampNotSignedIn +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + NSError* error = nil; + NSInteger retryAfter = 0; + + self.accountStatus = CKAccountStatusNoAccount; + [self startCKKSSubsystem]; + + [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + + [self.enroll checkRampState:&retryAfter qos:NSQualityOfServiceUserInitiated error:&error]; + + XCTAssertTrue(error.code == OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); + +} + +-(void) testEnrollRampWithNoNetwork +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + NSError* error = nil; + NSInteger retryAfter = 0; + + self.accountStatus = CKAccountStatusAvailable; + [self startCKKSSubsystem]; + + [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + + self.reachabilityFlags = 0; + [self.reachabilityTracker recheck]; + + [self.enroll checkRampState:&retryAfter qos:NSQualityOfServiceUserInitiated error:&error]; + + XCTAssertTrue(error.code == OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); +} + +-(void) testEnrollRampWhenLocked +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + NSError* error = nil; + NSInteger retryAfter = 0; + + self.aksLockState = true; + [self.lockStateTracker recheck]; + + [self.enroll checkRampState:&retryAfter qos:NSQualityOfServiceUserInitiated error:&error]; + + XCTAssertTrue(error.code == errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); +} + +-(void) testTimeBetweenCFUAttempts +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + NSError* error = nil; + + [self.manager scheduledCloudKitRampCheck:&error]; + XCTAssertNotNil(self.manager.lastPostedCoreFollowUp, "core followup should have been posted"); + NSDate* firstTime = self.manager.lastPostedCoreFollowUp; + + sleep(2); + + [self.manager scheduledCloudKitRampCheck:&error]; + XCTAssertNotNil(self.manager.lastPostedCoreFollowUp, "core followup should have been posted"); + NSDate* secondTime = self.manager.lastPostedCoreFollowUp; + + XCTAssertTrue([secondTime timeIntervalSinceDate:firstTime] >= 2, "time difference should be slightly more than 2 seconds"); +} + +@end +#endif diff --git a/keychain/ot/tests/OTRampingTests.m b/keychain/ot/tests/OTRampingTests.m new file mode 100644 index 00000000..1bbb1dcd --- /dev/null +++ b/keychain/ot/tests/OTRampingTests.m @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import + +#import +#import + +#import "OTTestsBase.h" +#import "keychain/ot/OTConstants.h" + +static NSString* const testContextID = @"Foo"; +static NSString* const testDSID = @"123456789"; + +static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; + +@interface OTRampingUnitTests : OTTestsBase + +@end + +@implementation OTRampingUnitTests + +- (void)setUp { + [super setUp]; + self.continueAfterFailure = NO; +} + +- (void)tearDown { + [super tearDown]; +} + +-(void) testPreflightWithFeatureOnOn +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + [self startCKKSSubsystem]; + + [self.otControl preflightBottledPeer:testContextID + dsid:testDSID + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + XCTAssertNotNil(entropy, "entropy should not be nil"); + XCTAssertNotNil(bottleID, "bottle id should not be nil"); + XCTAssertNotNil(signingPublicKey, "signing pub key should not be nil"); + XCTAssertNil(error, "error should be nil"); + }]; + +} + +-(void) testLaunchWithRampOn +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + [self startCKKSSubsystem]; + + __block NSData* localEntropy = nil; + __block NSString* localBottleID = nil; + + self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer fired"]; + + [self.otControl preflightBottledPeer:testContextID + dsid:testDSID + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + localEntropy = entropy; + localBottleID = bottleID; + XCTAssertNotNil(entropy, "entropy should not be nil"); + XCTAssertNotNil(bottleID, "bottle id should not be nil"); + XCTAssertNotNil(signingPublicKey, "signing pub key should not be nil"); + XCTAssertNil(error, "error should be nil"); + }]; + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + self.spiBlockExpectation = [self expectationWithDescription:@"launch bottled peer fired"]; + + NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil]; + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; + + [self.otControl launchBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(error, "error should be nil"); + }]; + + [self waitForExpectationsWithTimeout:1.0 handler:nil]; +} + +-(void) testRestoreWithRampOn +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + [self startCKKSSubsystem]; + + __block NSData* localEntropy = nil; + __block NSString* localBottleID = nil; + + self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer fired"]; + + [self.otControl preflightBottledPeer:OTDefaultContext + dsid:@"dsid" + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + localEntropy = entropy; + localBottleID = bottleID; + XCTAssertNotNil(entropy, "entropy should not be nil"); + XCTAssertNotNil(bottleID, "bottle id should not be nil"); + XCTAssertNotNil(signingPublicKey, "signing pub key should not be nil"); + XCTAssertNil(error, "error should be nil"); + }]; + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + __block NSData* localSigningKeyData = nil; + __block NSData* localEncryptionKeyData = nil; + + self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer fired"]; + + [self.otControl restore:testContextID + dsid:testDSID + secret:localEntropy + escrowRecordID:self.sosPeerID + reply:^(NSData* signingKeyData, NSData* encryptionKeyData, NSError* _Nullable error) { + [self.spiBlockExpectation fulfill]; + localSigningKeyData = signingKeyData; + localEncryptionKeyData = encryptionKeyData; + XCTAssertNotNil(signingKeyData, "Signing key data should not be nil"); + XCTAssertNotNil(encryptionKeyData, "encryption key data should not be nil"); + XCTAssertNil(error, "error should not be nil"); + }]; + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + NSError* localError = nil; + + OTIdentity *ourSelf = [self currentIdentity:&localError]; + XCTAssertTrue([localSigningKeyData isEqualToData:[ourSelf.peerSigningKey.publicKey keyData]], @"signing keys should be equal!"); + XCTAssertTrue([localEncryptionKeyData isEqualToData:[ourSelf.peerEncryptionKey.publicKey keyData]], @"signing keys should be equal!"); +} + +-(void) testScrubWithRampOn +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + [self startCKKSSubsystem]; + + __block NSString* localBottleID = nil; + + self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer fired"]; + + [self.otControl preflightBottledPeer:testContextID + dsid:testDSID + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + localBottleID = bottleID; + XCTAssertNotNil(entropy, "entropy should not be nil"); + XCTAssertNotNil(bottleID, "bottle id should not be nil"); + XCTAssertNotNil(signingPublicKey, "signing pub key should not be nil"); + XCTAssertNil(error, "error should be nil"); + }]; + + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + self.spiBlockExpectation = [self expectationWithDescription:@"scrub scheduler fired"]; + + [self.otControl scrubBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(error, "error should be nil"); + }]; + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + NSError* localError = nil; + NSArray* bottles = [self.localStore readAllLocalBottledPeerRecords:&localError]; + XCTAssertNotNil(localError, "error should not be nil"); + XCTAssertTrue([bottles count] == 0, "should be 0 bottles"); +} + +-(void) testPreflightWithRampOff +{ + [self setUpRampRecordsInCloudKitWithFeatureOff]; + + [self startCKKSSubsystem]; + + self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer fired"]; + + [self.otControl preflightBottledPeer:OTDefaultContext + dsid:@"dsid" + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(entropy, "shouldn't return any entropy"); + XCTAssertNil(bottleID, "shouldn't return a bottle ID"); + XCTAssertNil(signingPublicKey, "shouldn't return a signingPublicKey"); + XCTAssertTrue(error.code == OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); + }]; + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; +} + +-(void) testPreflightWithRecordNotThere +{ + [self startCKKSSubsystem]; + + self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer fired"]; + + [self.otControl preflightBottledPeer:OTDefaultContext + dsid:@"dsid" + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(entropy, "shouldn't return any entropy"); + XCTAssertNil(bottleID, "shouldn't return a bottle ID"); + XCTAssertNil(signingPublicKey, "shouldn't return a signingPublicKey"); + XCTAssertNotNil(error, "should not be nil"); + }]; + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; +} + +-(void) testLaunchWithRampOff +{ + [self setUpRampRecordsInCloudKitWithFeatureOff]; + + [self startCKKSSubsystem]; + + self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer fired"]; + + [self.otControl preflightBottledPeer:OTDefaultContext + dsid:@"dsid" + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(entropy, "shouldn't return any entropy"); + XCTAssertNil(bottleID, "shouldn't return a bottle ID"); + XCTAssertNil(signingPublicKey, "shouldn't return a signingPublicKey"); + XCTAssertTrue(error.code == OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); + }]; + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + + self.spiBlockExpectation = [self expectationWithDescription:@"launch SPI fired"]; + + NSString* localBottleID = @"random bottle id"; + [self.otControl launchBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertTrue(error.code == OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); + }]; + + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; +} +-(void) testRestoreWithRampOff +{ + [self setUpRampRecordsInCloudKitWithFeatureOff]; + [self startCKKSSubsystem]; + + self.spiBlockExpectation = [self expectationWithDescription:@"restore SPI fired"]; + + [self.otControl restore:testContextID + dsid:testDSID + secret:self.secret + escrowRecordID:self.sosPeerID + reply:^(NSData* signingKeyData, NSData* encryptionKeyData, NSError* _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(signingKeyData, "Signing key data should be nil"); + XCTAssertNil(encryptionKeyData, "encryption key data should be nil"); + XCTAssertTrue(error.code == OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); + }]; + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; +} + +-(void) testScrubWithRampOff +{ + [self setUpRampRecordsInCloudKitWithFeatureOff]; + [self startCKKSSubsystem]; + + self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer SPI fired"]; + + [self.otControl preflightBottledPeer:testContextID + dsid:testDSID + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(entropy, "entropy should be nil"); + XCTAssertNil(bottleID, "bottle id should be nil"); + XCTAssertNil(signingPublicKey, "signing pub key should be nil"); + XCTAssertTrue(error.code == OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); + }]; + + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + __block NSString* localBottleID = @"random bottle id"; + self.spiBlockExpectation = [self expectationWithDescription:@"scrub bottled peer SPI fired"]; + + [self.otControl scrubBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertTrue(error.code == OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); + }]; + + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:4*NSEC_PER_SEC], @"Key state should have arrived at ready"); +} + +-(void) testRampFetchTimeout +{ + [self startCKKSSubsystem]; + + __block NSError* localError = nil; + + [self holdCloudKitFetches]; + + [self.otControl preflightBottledPeer:OTDefaultContext + dsid:@"dsid" + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + localError = error; + XCTAssertNil(entropy, "shouldn't return any entropy"); + XCTAssertNil(bottleID, "shouldn't return a bottle ID"); + XCTAssertNil(signingPublicKey, "shouldn't return a signingPublicKey"); + XCTAssertTrue(error.code == OTErrorCKTimeOut, "should return a OTErrorCKTimeout error"); + }]; +} + +-(void)testCFUWithRampOn +{ + NSError* localError = nil; + NSInteger retryAfterInSeconds = 0; + + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + XCTAssertTrue([self.cfu checkRampState:&retryAfterInSeconds qos:NSQualityOfServiceUserInitiated error:&localError], @"should be true"); +} + +-(void)testCFUWithRampOff +{ + NSError* localError = nil; + NSInteger retryAfterInSeconds = 0; + [self setUpRampRecordsInCloudKitWithFeatureOff]; + + XCTAssertTrue(![self.cfu checkRampState:&retryAfterInSeconds qos:NSQualityOfServiceUserInitiated error:&localError], @"should be false"); + + XCTAssertTrue(retryAfterInSeconds != 0, @"should be asked to retry later"); +} + +-(void)testCFUWithNonExistentRampRecord +{ + NSError* localError = nil; + NSInteger retryAfterInSeconds = 0; + XCTAssertTrue(![self.cfu checkRampState:&retryAfterInSeconds qos:NSQualityOfServiceUserInitiated error:&localError], @"should be false"); +} + +@end + +#endif /* OCTAGON */ + diff --git a/keychain/ot/tests/OTTests-Info.plist b/keychain/ot/tests/OTTests-Info.plist new file mode 100644 index 00000000..6c6c23c4 --- /dev/null +++ b/keychain/ot/tests/OTTests-Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/keychain/ot/tests/OTTestsBase.h b/keychain/ot/tests/OTTestsBase.h new file mode 100644 index 00000000..f50be97e --- /dev/null +++ b/keychain/ot/tests/OTTestsBase.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#ifndef OTTestsBase_h +#define OTTestsBase_h + +#import +#import +#import + +#import "keychain/ot/OTContext.h" +#import "keychain/ot/OTEscrowKeys.h" +#import "keychain/ot/OTDefines.h" +#import "keychain/ot/OTControl.h" +#import "keychain/ot/OTManager.h" +#import "SFPublicKey+SPKI.h" +#import + +#import +#import + +#import "keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.h" +#import "keychain/ckks/tests/CloudKitMockXCTest.h" +#import "keychain/ckks/tests/MockCloudKit.h" +#import "keychain/ckks/tests/CKKSTests.h" +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSViewManager.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTTestsBase : CloudKitKeychainSyncingTestsBase +@property id otControl; +@property OTManager* manager; +@property (nonatomic, strong) OTCloudStore* cloudStore; +@property (nonatomic, strong) OTLocalStore* localStore; +@property (nonatomic, strong) FakeCKZone* otFakeZone; +@property (nonatomic, strong) CKRecordZoneID* otZoneID; +@property (nonatomic, strong) OTContext* context; +@property (nonatomic, strong) _SFECKeyPair* peerSigningKey; +@property (nonatomic, strong) _SFECKeyPair* peerEncryptionKey; +@property (nonatomic, strong) NSData* secret; +@property (nonatomic, strong) NSString* recordName; +@property (nonatomic, strong) NSString* egoPeerID; +@property (nonatomic, strong) NSString* sosPeerID; +@property (nonatomic, strong) OTEscrowKeys* escrowKeys; + +@property (nonatomic, strong) FakeCKZone* rampZone; +@property (nonatomic, strong) CKRecord *enrollRampRecord; +@property (nonatomic, strong) CKRecord *restoreRampRecord; +@property (nonatomic, strong) CKRecord *cfuRampRecord; + +@property (nonatomic, strong) OTRamp *enroll; +@property (nonatomic, strong) OTRamp *restore; +@property (nonatomic, strong) OTRamp *cfu; +@property (nonatomic, strong) CKKSNearFutureScheduler* scheduler; +@property (nonatomic, strong) XCTestExpectation *expectation; +@property (nonatomic, strong) XCTestExpectation *spiBlockExpectation; + +@property (nonatomic, strong) CKRecordZoneID* rampZoneID; + +-(OTRamp*) fakeRamp:(NSString*)recordName featureName:(NSString*)featureName; + +-(void)expectAddedCKModifyRecords:(NSDictionary*)records holdFetch:(BOOL)shouldHoldTheFetch; +-(void)expectDeletedCKModifyRecords:(NSDictionary*)records holdFetch:(BOOL)shouldHoldTheFetch; +-(void) setUpRampRecordsInCloudKitWithFeatureOn; +-(void) setUpRampRecordsInCloudKitWithFeatureOff; + +@end +NS_ASSUME_NONNULL_END + +#endif /* OTTestsBase_h */ +#endif /* OCTAGON */ diff --git a/keychain/ot/tests/OTTestsBase.m b/keychain/ot/tests/OTTestsBase.m new file mode 100644 index 00000000..81738098 --- /dev/null +++ b/keychain/ot/tests/OTTestsBase.m @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if OCTAGON + +#import "OTTestsBase.h" + +static NSString* const testContextID = @"Foo"; +static NSString* const testDSID = @"123456789"; +static int _test_num = 0; +static NSString* _path; +static NSString* _dbPath; + +static NSString* OTCKZoneName = @"OctagonTrust"; + +static NSString* const kOTRampZoneName = @"metadata_zone"; +static NSString* const kOTRampForEnrollmentRecordName = @"metadata_rampstate_enroll"; +static NSString* const kOTRampForRestoreRecordName = @"metadata_rampstate_restore"; +static NSString* const kOTRampForCFURecordName = @"metadata_rampstate_cfu"; + +static NSString* kFeatureAllowedKey = @"FeatureAllowed"; +static NSString* kFeaturePromotedKey = @"FeaturePromoted"; +static NSString* kFeatureVisibleKey = @"FeatureVisible"; +static NSString* kRetryAfterKey = @"RetryAfter"; +static NSString* kRampPriorityKey = @"RampPriority"; + +static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; + +@implementation OTTestsBase + +// Override our base class +-(NSSet*)managedViewList { + return [NSSet setWithObject:@"keychain"]; +} + ++ (void)setUp { + SecCKKSEnable(); + SecCKKSResetSyncing(); + [super setUp]; +} + +- (void)setUp +{ + [super setUp]; + + self.continueAfterFailure = NO; + NSError* error = nil; + + _path = @"/tmp/ottrusttests"; + _dbPath = [_path stringByAppendingFormat:@"/ottest.db.%d",_test_num++]; + + XCTAssertTrue([[NSFileManager defaultManager] createDirectoryAtPath:_path withIntermediateDirectories:YES attributes:nil error:nil], @"directory created!"); + self.localStore = [[OTLocalStore alloc]initWithContextID:testContextID dsid:testDSID path:_dbPath error:&error]; + XCTAssertNil(error, "error should be nil"); + + self.cloudStore = [[OTCloudStore alloc] initWithContainer:self.mockContainer + zoneName:OTCKZoneName + accountTracker:self.mockAccountStateTracker + reachabilityTracker:self.mockReachabilityTracker + localStore:self.localStore + contextID:testContextID + dsid:testDSID + fetchRecordZoneChangesOperationClass:self.mockFakeCKFetchRecordZoneChangesOperation + fetchRecordsOperationClass:self.mockFakeCKFetchRecordZoneChangesOperation + queryOperationClass:self.mockFakeCKQueryOperation + modifySubscriptionsOperationClass:self.mockFakeCKModifySubscriptionsOperation + modifyRecordZonesOperationClass:self.mockFakeCKFetchRecordsOperation + apsConnectionClass:self.mockFakeCKModifySubscriptionsOperation + operationQueue:nil]; + + NSString* secretString = @"I'm a secretI'm a secretI'm a secretI'm a secretI'm a secretI'm a secret"; + self.secret = [[NSData alloc]initWithBytes:[secretString UTF8String] length:[secretString length]]; + + self.context = [[OTContext alloc]initWithContextID:testContextID dsid:testDSID localStore:self.localStore cloudStore:self.cloudStore identityProvider:self error:&error]; + XCTAssertNil(error, "error should be nil"); + + self.sosPeerID = @"spID"; + self.egoPeerID = @"egoPeerID"; + self.peerSigningKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + self.peerEncryptionKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + self.escrowKeys = [[OTEscrowKeys alloc]initWithSecret:self.secret dsid:testDSID error:&error]; + + XCTAssertNotNil(self.context, @"context not initialized"); + + self.otZoneID = [[CKRecordZoneID alloc] initWithZoneName:OTCKZoneName ownerName:CKCurrentUserDefaultName]; + + XCTAssertNotNil(self.otZoneID, @"cloudkit record zone id is not initialized"); + + self.otFakeZone = [[FakeCKZone alloc] initZone: self.otZoneID]; + XCTAssertNotNil(self.otFakeZone, @"fake ot zone is not initialized"); + + self.zones[self.otZoneID] = self.otFakeZone; + XCTAssertNotNil(self.zones, @"ot zones set is not initialized"); + + self.rampZoneID = [[CKRecordZoneID alloc] initWithZoneName:kOTRampZoneName ownerName:CKCurrentUserDefaultName]; + self.rampZone = [[FakeCKZone alloc]initZone:self.rampZoneID]; + self.zones[self.rampZoneID] = self.rampZone; + + self.cfu = [self fakeRamp:kOTRampForCFURecordName featureName:@"FAKE-cfu"]; + self.enroll = [self fakeRamp:kOTRampForEnrollmentRecordName featureName:@"FAKE-enroll"]; + self.restore = [self fakeRamp:kOTRampForRestoreRecordName featureName:@"FAKE-restore"]; + + self.scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay:50*NSEC_PER_MSEC keepProcessAlive:true + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{ + [self.expectation fulfill]; + }]; + self.manager = [[OTManager alloc] initWithContext:self.context + localStore:self.localStore + enroll:self.enroll + restore:self.restore + cfu:self.cfu + cfuScheduler:self.scheduler]; + + id mockConnection = OCMPartialMock([[NSXPCConnection alloc] init]); + OCMStub([mockConnection remoteObjectProxyWithErrorHandler:[OCMArg any]]).andCall(self, @selector(manager)); + self.otControl = [[OTControl alloc] initWithConnection:mockConnection]; + XCTAssertNotNil(self.otControl, "Should have received control object"); + + [self startCKKSSubsystem]; + + self.accountStatus = CKAccountStatusAvailable; + self.circleStatus = kSOSCCInCircle; + [self.cfu.accountTracker notifyCKAccountStatusChangeAndWaitForSignal]; + + [self.context.accountTracker notifyCKAccountStatusChangeAndWaitForSignal]; + [self.enroll.accountTracker notifyCKAccountStatusChangeAndWaitForSignal]; + [self.restore.accountTracker notifyCKAccountStatusChangeAndWaitForSignal]; + + [self.context.accountTracker notifyCircleStatusChangeAndWaitForSignal]; + [self.cfu.accountTracker notifyCircleStatusChangeAndWaitForSignal]; + [self.enroll.accountTracker notifyCircleStatusChangeAndWaitForSignal]; + [self.restore.accountTracker notifyCircleStatusChangeAndWaitForSignal]; + + self.reachabilityFlags = kSCNetworkReachabilityFlagsReachable; + [self.context.reachabilityTracker recheck]; + [self.cfu.reachabilityTracker recheck]; + [self.enroll.reachabilityTracker recheck]; + [self.restore.reachabilityTracker recheck]; + +} + + +- (void)tearDown +{ + NSError *error = nil; + + [_localStore removeAllBottledPeerRecords:&error]; + [_localStore deleteAllContexts:&error]; + + _context = nil; + _cloudStore = nil; + _localStore = nil; + _escrowKeys = nil; + _peerSigningKey = nil; + _peerEncryptionKey = nil; + _otFakeZone = nil; + _otZoneID = nil; + + _rampZone = nil; + _rampZoneID = nil; + _cfuRampRecord = nil; + _enrollRampRecord = nil; + _restoreRampRecord = nil; + _scheduler = nil; + + [super tearDown]; +} + +-(OTRamp*) fakeRamp:(NSString*)recordName featureName:(NSString*)featureName +{ + + OTRamp* ramp = [[OTRamp alloc]initWithRecordName:recordName + featureName:featureName + container:self.mockContainer + database:self.mockDatabase + zoneID:self.rampZoneID + accountTracker:[CKKSViewManager manager].accountTracker + lockStateTracker:[CKKSViewManager manager].lockStateTracker + reachabilityTracker:[CKKSViewManager manager].reachabilityTracker + fetchRecordRecordsOperationClass:self.mockFakeCKFetchRecordsOperation]; + + return ramp; +} + +-(void) setUpRampRecordsInCloudKitWithFeatureOff +{ + CKRecordID* enrollRecordID = [[CKRecordID alloc] initWithRecordName:kOTRampForEnrollmentRecordName zoneID:self.rampZoneID]; + self.enrollRampRecord = [[CKRecord alloc] initWithRecordType:kOTRampForEnrollmentRecordName recordID:enrollRecordID]; + self.enrollRampRecord[kFeatureAllowedKey] = @NO; + self.enrollRampRecord[kFeaturePromotedKey] = @NO; //always false right now + self.enrollRampRecord[kFeatureVisibleKey] = @NO; + self.enrollRampRecord[kRetryAfterKey] = [[NSNumber alloc]initWithInt:3600]; + + CKRecordID* restoreRecordID = [[CKRecordID alloc] initWithRecordName:kOTRampForRestoreRecordName zoneID:self.rampZoneID]; + self.restoreRampRecord = [[CKRecord alloc] initWithRecordType:kOTRampForEnrollmentRecordName recordID:restoreRecordID]; + self.restoreRampRecord[kFeatureAllowedKey] = @NO; + self.restoreRampRecord[kFeaturePromotedKey] = @NO; //always false right now + self.restoreRampRecord[kFeatureVisibleKey] = @NO; + self.restoreRampRecord[kRetryAfterKey] = [[NSNumber alloc]initWithInt:3600]; + + CKRecordID* cfuRecordID = [[CKRecordID alloc] initWithRecordName:kOTRampForCFURecordName zoneID:self.rampZoneID]; + self.cfuRampRecord = [[CKRecord alloc] initWithRecordType:kOTRampForCFURecordName recordID:cfuRecordID]; + self.cfuRampRecord[kFeatureAllowedKey] = @NO; + self.cfuRampRecord[kFeaturePromotedKey] = @NO; //always false right now + self.cfuRampRecord[kFeatureVisibleKey] = @NO; + self.cfuRampRecord[kRetryAfterKey] = [[NSNumber alloc]initWithInt:3600]; + + [self.rampZone addToZone:self.enrollRampRecord]; + [self.rampZone addToZone:self.restoreRampRecord]; + [self.rampZone addToZone:self.cfuRampRecord]; +} + +-(void) setUpRampRecordsInCloudKitWithFeatureOn +{ + CKRecordID* enrollRecordID = [[CKRecordID alloc] initWithRecordName:kOTRampForEnrollmentRecordName zoneID:self.rampZoneID]; + self.enrollRampRecord = [[CKRecord alloc] initWithRecordType:kOTRampForEnrollmentRecordName recordID:enrollRecordID]; + self.enrollRampRecord[kFeatureAllowedKey] = @YES; + self.enrollRampRecord[kFeaturePromotedKey] = @NO; //always false right now + self.enrollRampRecord[kFeatureVisibleKey] = @YES; + self.enrollRampRecord[kRetryAfterKey] = [[NSNumber alloc]initWithInt:3600]; + + CKRecordID* restoreRecordID = [[CKRecordID alloc] initWithRecordName:kOTRampForRestoreRecordName zoneID:self.rampZoneID]; + self.restoreRampRecord = [[CKRecord alloc] initWithRecordType:kOTRampForEnrollmentRecordName recordID:restoreRecordID]; + self.restoreRampRecord[kFeatureAllowedKey] = @YES; + self.restoreRampRecord[kFeaturePromotedKey] = @NO; //always false right now + self.restoreRampRecord[kFeatureVisibleKey] = @YES; + self.restoreRampRecord[kRetryAfterKey] = [[NSNumber alloc]initWithInt:3600]; + + CKRecordID* cfuRecordID = [[CKRecordID alloc] initWithRecordName:kOTRampForCFURecordName zoneID:self.rampZoneID]; + self.cfuRampRecord = [[CKRecord alloc] initWithRecordType:kOTRampForCFURecordName recordID:cfuRecordID]; + self.cfuRampRecord[kFeatureAllowedKey] = @YES; + self.cfuRampRecord[kFeaturePromotedKey] = @NO; //always false right now + self.cfuRampRecord[kFeatureVisibleKey] = @YES; + self.cfuRampRecord[kRetryAfterKey] = [[NSNumber alloc]initWithInt:3600]; + + [self.rampZone addToZone:self.enrollRampRecord]; + [self.rampZone addToZone:self.restoreRampRecord]; + [self.rampZone addToZone:self.cfuRampRecord]; +} + + +-(void)expectAddedCKModifyRecords:(NSDictionary*)records holdFetch:(BOOL)shouldHoldTheFetch +{ + __weak __typeof(self) weakSelf = self; + + [self expectCKModifyRecords:records + deletedRecordTypeCounts:nil + zoneID:self.otZoneID + checkModifiedRecord:^BOOL (CKRecord* record){ + if([record.recordType isEqualToString: OTCKRecordBottledPeerType]) { + return YES; + } else { //not a Bottled Peer Record Type + return NO; + } + } + runAfterModification:^{ + __strong __typeof(self) strongSelf = weakSelf; + [strongSelf holdCloudKitFetches]; + } + ]; +} + +-(void)expectDeletedCKModifyRecords:(NSDictionary*)records holdFetch:(BOOL)shouldHoldTheFetch +{ + __weak __typeof(self) weakSelf = self; + + [self expectCKModifyRecords:[NSMutableDictionary dictionary] + deletedRecordTypeCounts:records + zoneID:self.otZoneID + checkModifiedRecord:^BOOL (CKRecord* record){ + if([record.recordType isEqualToString: OTCKRecordBottledPeerType]) { + return YES; + } else { //not a Bottled Peer Record Type + return NO; + } + } + runAfterModification:^{ + __strong __typeof(self) strongSelf = weakSelf; + [strongSelf holdCloudKitFetches]; + } + ]; +} + +- (nullable OTIdentity *)currentIdentity:(NSError * _Nullable __autoreleasing * _Nullable)error { + return [[OTIdentity alloc]initWithPeerID:self.egoPeerID spID:self.sosPeerID peerSigningKey:self.peerSigningKey peerEncryptionkey:self.peerEncryptionKey error:error]; +} + + +@end +#endif diff --git a/keychain/otctl/otctl-Entitlements.plist b/keychain/otctl/otctl-Entitlements.plist new file mode 100644 index 00000000..cfc36cb7 --- /dev/null +++ b/keychain/otctl/otctl-Entitlements.plist @@ -0,0 +1,8 @@ + + + + + com.apple.private.octagon + + + diff --git a/keychain/otctl/otctl.m b/keychain/otctl/otctl.m new file mode 100644 index 00000000..416d4d56 --- /dev/null +++ b/keychain/otctl/otctl.m @@ -0,0 +1,529 @@ +// +// Security +// + +#import +#import +#import +#import +#import +#import +#import +#import "keychain/ot/OTControl.h" +#import "keychain/ot/OTConstants.h" +#include "lib/SecArgParse.h" +#include +#include + +@interface OTControlCLI : NSObject +@property OTControl* control; +@end + +@implementation OTControlCLI + + +- (instancetype) initWithOTControl:(OTControl*)control { + if ((self = [super init])) { + _control = control; + } + + return self; +} + +- (long)preflightBottledPeer:(NSString*)contextID dsid:(NSString*)dsid +{ + __block long ret = 0; + +#if OCTAGON + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [self.control preflightBottledPeer:contextID dsid:dsid reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + if(error){ + printf("Error pushing: %s\n", [[error description] UTF8String]); + ret = (error.code == 0 ? -1 : error.code); + }else if(entropy && bottleID && signingPublicKey){ + printf("\nSuccessfully preflighted bottle ID: %s\n", [bottleID UTF8String]); + printf("\nEntropy used: %s\n", [[entropy base64EncodedStringWithOptions:0] UTF8String]); + printf("\nSigning Public Key: %s\n", [[signingPublicKey base64EncodedStringWithOptions:0] UTF8String]); + ret = 0; + }else{ + printf("Failed to preflight bottle and no error was returned.."); + ret = -1; + } + + dispatch_semaphore_signal(sema); + }]; + + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { + printf("\n\nError: timed out waiting for response\n"); + return -1; + } + return ret; +#else + return -1; +#endif +} + +- (long)launchBottledPeer:(NSString*)contextID bottleID:(NSString*)bottleID +{ + __block long ret = 0; + +#if OCTAGON + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [self.control launchBottledPeer:contextID bottleID:bottleID reply:^(NSError * _Nullable error) { + if(error) + { + printf("Error pushing: %s\n", [[error description] UTF8String]); + ret = (error.code == 0 ? -1 : error.code); + } else { + printf("\nSuccessfully launched bottleID: %s\n", [bottleID UTF8String]); + ret = 0; + } + + dispatch_semaphore_signal(sema); + }]; + + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { + printf("\n\nError: timed out waiting for response\n"); + return -1; + } + return ret; +#else + return -1; +#endif +} + +- (long)scrubBottledPeer:(NSString*)contextID bottleID:(NSString*)bottleID +{ + __block long ret = 0; + +#if OCTAGON + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [self.control scrubBottledPeer:contextID bottleID:bottleID reply:^(NSError * _Nullable error) { + if(error) + { + printf("Error pushing: %s\n", [[error description] UTF8String]); + ret = (error.code == 0 ? -1 : error.code); + } else { + printf("\nSuccessfully scrubbed bottle ID: %s\n", [bottleID UTF8String]); + ret = 0; + } + + dispatch_semaphore_signal(sema); + }]; + + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { + printf("\n\nError: timed out waiting for response\n"); + return -1; + } + return ret; +#else + ret = -1; + return ret; +#endif +} + + +- (long)enroll:(NSString*)contextID dsid:(NSString*)dsid +{ + __block long ret = 0; + +#if OCTAGON + dispatch_semaphore_t semaForPreFlight = dispatch_semaphore_create(0); + dispatch_semaphore_t semaForLaunch = dispatch_semaphore_create(0); + __block NSString* bottleRecordID = nil; + __block NSError* localError = nil; + + [self.control preflightBottledPeer:contextID dsid:dsid reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + if(error) + { + localError = error; + printf("Error pushing: %s\n", [[error description] UTF8String]); + ret = (error.code == 0 ? -1 : error.code); + } else { + bottleRecordID = bottleID; + printf("\nSuccessfully preflighted bottle ID: %s\n", [bottleID UTF8String]); + printf("\nEntropy used: %s\n", [[entropy base64EncodedStringWithOptions:0] UTF8String]); + printf("\nSigning Public Key: %s\n", [[signingPublicKey base64EncodedStringWithOptions:0] UTF8String]); + ret = 0; + } + + dispatch_semaphore_signal(semaForPreFlight); + }]; + + if(dispatch_semaphore_wait(semaForPreFlight, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { + printf("\n\nError: timed out waiting for response\n"); + return -1; + } + + if(localError == nil){ + [self.control launchBottledPeer:contextID bottleID:bottleRecordID reply:^(NSError * _Nullable error) { + if(error) + { + printf("Error pushing: %s\n", [[error description] UTF8String]); + ret = (error.code == 0 ? -1 : error.code); + } else { + printf("\nSuccessfully launched bottleID: %s\n", [bottleRecordID UTF8String]); + ret = 0; + } + + dispatch_semaphore_signal(semaForLaunch); + }]; + + if(dispatch_semaphore_wait(semaForLaunch, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { + printf("\n\nError: timed out waiting for response\n"); + return -1; + } + } + printf("Complete.\n"); + return ret; +#else + return -1; +#endif +} + + +- (long)restore:(NSString*)contextID dsid:(NSString*)dsid secret:(NSData*)secret escrowRecordID:(NSString*)escrowRecordID +{ + __block long ret = 0; + +#if OCTAGON + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [self.control restore:contextID dsid:dsid secret:secret escrowRecordID:escrowRecordID reply:^(NSData* signingKeyData, NSData* encryptionKeyData, NSError *error) { + if(error) + { + printf("Error pushing: %s\n", [[error description] UTF8String]); + ret = (error.code == 0 ? -1 : error.code); + } else { + + printf("Complete.\n"); + ret = 0; + } + + NSString* signingKeyString = [signingKeyData base64EncodedStringWithOptions:0]; + NSString* encryptionKeyString = [encryptionKeyData base64EncodedStringWithOptions:0]; + + printf("Signing Key:\n %s\n", [signingKeyString UTF8String]); + printf("Encryption Key:\n %s\n", [encryptionKeyString UTF8String]); + dispatch_semaphore_signal(sema); + }]; + + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { + printf("\n\nError: timed out waiting for response\n"); + return -1; + } + return ret; +#else + ret = -1; + return ret; +#endif +} + +- (long) reset +{ + __block long ret = 0; + +#if OCTAGON + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + [self.control reset:^(BOOL reset, NSError* error){ + if(error) + { + printf("Error pushing: %s\n", [[error description] UTF8String]); + ret = (error.code == 0 ? -1 : error.code); + } else { + printf("success\n"); + } + + dispatch_semaphore_signal(sema); + }]; + + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { + printf("\n\nError: timed out waiting for response\n"); + return -1; + } + + printf("Complete.\n"); + return ret; +#else + ret = -1; + return ret; +#endif +} + +- (long) listOfRecords +{ + __block long ret = 0; + +#if OCTAGON + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + [self.control listOfRecords:^(NSArray* list, NSError* error){ + if(error) + { + printf("Error pushing: %s\n", [[error description] UTF8String]); + ret = (error.code == 0 ? -1 : error.code); + } else { + [list enumerateObjectsUsingBlock:^(NSString* _Nonnull escrowRecordID, NSUInteger idx, BOOL * _Nonnull stop) { + printf("escrowRecordID: %s\n", [escrowRecordID UTF8String]); + }]; + ret = 0; + } + + dispatch_semaphore_signal(sema); + }]; + + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { + printf("\n\nError: timed out waiting for response\n"); + return -1; + } + + printf("Complete.\n"); + return ret; +#else + ret = -1; + return ret; +#endif +} + +- (long)octagonKeys +{ + __block long ret = 0; + +#if OCTAGON + dispatch_semaphore_t semaForGettingEncryptionKey = dispatch_semaphore_create(0); + dispatch_semaphore_t semaForGettingSigningKey = dispatch_semaphore_create(0); + [self.control encryptionKey:^(NSData *encryptionKey, NSError * error) { + if(error) + { + printf("Error pushing: %s\n", [[error description] UTF8String]); + ret = (error.code == 0 ? -1 : error.code); + } else { + NSString* encryptionKeyString = [encryptionKey base64EncodedStringWithOptions:0]; + printf("Encryption Key:\n %s\n", [encryptionKeyString UTF8String]); + ret = 0; + } + + dispatch_semaphore_signal(semaForGettingEncryptionKey); + }]; + + [self.control signingKey:^(NSData *signingKey, NSError * error) { + if(error) + { + printf("Error pushing: %s\n", [[error description] UTF8String]); + ret = (error.code == 0 ? -1 : error.code); + } else { + NSString* signingKeyString = [signingKey base64EncodedStringWithOptions:0]; + printf("Signing Key:\n %s\n", [signingKeyString UTF8String]); + ret = 0; + } + + dispatch_semaphore_signal(semaForGettingSigningKey); + }]; + + + if(dispatch_semaphore_wait(semaForGettingEncryptionKey, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { + printf("\n\nError: timed out waiting for response\n"); + return -1; + } + if(dispatch_semaphore_wait(semaForGettingSigningKey, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { + printf("\n\nError: timed out waiting for response\n"); + return -1; + } + printf("Complete.\n"); + return ret; +#else + ret = -1; + return ret; +#endif +} + +@end + +static bool SecOTIsEnabled(void) { + + bool userDefaultsShouldBottledPeer = true; + CFBooleanRef enabled = (CFBooleanRef)CFPreferencesCopyValue(CFSTR("EnableOTRestore"), + CFSTR("com.apple.security"), + kCFPreferencesAnyUser, kCFPreferencesAnyHost); + if(enabled && CFGetTypeID(enabled) == CFBooleanGetTypeID()){ + if(enabled == kCFBooleanFalse){ + secnotice("octagon", "Octagon Restore Disabled"); + userDefaultsShouldBottledPeer = false; + } + if(enabled == kCFBooleanTrue){ + secnotice("octagon", "Octagon Restore Enabled"); + userDefaultsShouldBottledPeer = true; + } + } + + CFReleaseNull(enabled); + return userDefaultsShouldBottledPeer; +} + +static int enroll = false; +static int restore = false; +static int octagonkeys = false; +static int reset = false; + +static int prepbp = false; +static int launch = false; +static int scrub = false; + +static int listOfRecords = false; +static char* bottleIDArg = NULL; +static char* contextNameArg = NULL; +static char* secretArg = NULL; + +int main(int argc, char **argv) +{ + if(!SecIsInternalRelease()) + { + secnotice("octagon", "Tool not available on non internal builds"); + return -1; + } + + if(!SecOTIsEnabled()) + { + printf("To use this tool, enable defaults write for EnableOTRestore\n defaults write (~)/Library/Preferences/com.apple.security EnableOTRestore -bool YES\n"); + return -1; + } + static struct argument options[] = { + { .shortname='s', .longname="secret", .argument=&secretArg, .description="escrow secret"}, + { .shortname='e', .longname="bottleID", .argument=&bottleIDArg, .description="bottle record id"}, + { .shortname='c', .longname="context", .argument=&contextNameArg, .description="context name"}, + + { .command="restore", .flag=&restore, .flagval=true, .description="Restore fake bottled peer"}, + { .command="enroll", .flag=&enroll, .flagval=true, .description="Enroll fake bottled peer"}, + { .command="keys", .flag=&octagonkeys, .shortname='k', .flagval=true, .description="Octagon Signing + Encryption Keys"}, + { .command="reset", .flag=&reset, .flagval=true, .description="Reset Octagon Trust Zone"}, + { .command="list", .flag=&listOfRecords, .flagval=true, .description="List of current Bottled Peer Records IDs"}, + + { .command="prepbp", .flag=&prepbp, .shortname='p', .flagval=true, .description="Preflights a bottled peer"}, + { .command="launch", .flag=&launch, .flagval=true, .description="Launches a bottled peer"}, + { .command="scrub", .flag=&scrub, .flagval=true, .description="Scrub bottled peer"}, + + {} + }; + + static struct arguments args = { + .programname="otctl", + .description="Control and report on Octagon Trust", + .arguments = options, + }; + + if(!options_parse(argc, argv, &args)) { + printf("\n"); + print_usage(&args); + return -1; + } + + @autoreleasepool { + NSError* error = nil; + + OTControl* rpc = [OTControl controlObject:&error]; + if(error || !rpc) { + errx(1, "no OTControl failed: %s", [[error description] UTF8String]); + } + + OTControlCLI* ctl = [[OTControlCLI alloc] initWithOTControl:rpc]; + + if(enroll) { + long ret = 0; + NSString* context = contextNameArg ? [NSString stringWithCString: contextNameArg encoding: NSUTF8StringEncoding] : OTDefaultContext; + ret = [ctl enroll:context dsid:@"12345678"]; + return (int)ret; + } + if(prepbp){ + long ret = 0; + NSString* context = contextNameArg ? [NSString stringWithCString: contextNameArg encoding: NSUTF8StringEncoding] : OTDefaultContext; + + //requires secret, context is optional + ret = [ctl preflightBottledPeer:context dsid:@"12345678"]; + return (int)ret; + } + if(launch){ + long ret = 0; + + NSString* bottleID = bottleIDArg ? [NSString stringWithCString: bottleIDArg encoding: NSUTF8StringEncoding] : nil; + NSString* context = contextNameArg ? [NSString stringWithCString: contextNameArg encoding: NSUTF8StringEncoding] : OTDefaultContext; + //requires bottleID, context is optional + if(bottleID && [bottleID length] > 0 && ![bottleID isEqualToString:@"(null)"]){ + ret = [ctl launchBottledPeer:context bottleID:bottleID]; + } + else{ + print_usage(&args); + return -1; + } + + return (int)ret; + } + if(scrub){ + long ret = 0; + + NSString* bottleID = bottleIDArg ? [NSString stringWithCString: bottleIDArg encoding: NSUTF8StringEncoding] : nil; + NSString* context = contextNameArg ? [NSString stringWithCString: contextNameArg encoding: NSUTF8StringEncoding] : OTDefaultContext; + + //requires bottle ID, context is optional + if(bottleID && [bottleID length] > 0 && ![bottleID isEqualToString:@"(null)"]){ + ret = [ctl scrubBottledPeer:context bottleID:bottleID]; + } + else{ + print_usage(&args); + return -1; + } + return (int)ret; + } + + if(restore) { + long ret = 0; + NSData* secretData = nil; + NSString* secretString = secretArg ? [NSString stringWithCString: secretArg encoding: NSUTF8StringEncoding] : nil; + NSString* bottleID = bottleIDArg ? [NSString stringWithCString: bottleIDArg encoding: NSUTF8StringEncoding] : nil; + NSString* context = contextNameArg ? [NSString stringWithCString: contextNameArg encoding: NSUTF8StringEncoding] : OTDefaultContext; + + //requires secret and bottle ID, context is optional + if(secretString && [secretString length] > 0){ + secretData = [[NSData alloc] initWithBase64EncodedString:secretString options:0];; + } + else{ + print_usage(&args); + return -1; + } + + + if(bottleID && [bottleID length] > 0 && ![bottleID isEqualToString:@"(null)"]){ + ret = [ctl restore:context dsid:@"12345678" secret:secretData escrowRecordID:bottleID]; + } + else{ + print_usage(&args); + return -1; + } + return (int)ret; + } + if(octagonkeys){ + long ret = 0; + ret = [ctl octagonKeys]; + return (int)ret; + } + if(listOfRecords){ + long ret = 0; + ret = [ctl listOfRecords]; + return (int)ret; + } + if(reset){ + long ret = 0; + ret = [ctl reset]; + return (int)ret; + } + else { + print_usage(&args); + return -1; + } + + + } + return 0; +} + diff --git a/keychain/trust/.open_source_exclude b/keychain/trust/.open_source_exclude deleted file mode 100644 index e69de29b..00000000 diff --git a/keychain/trust/TrustedPeers/Info.plist b/keychain/trust/TrustedPeers/Info.plist deleted file mode 100644 index dcf21d96..00000000 --- a/keychain/trust/TrustedPeers/Info.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSHumanReadableCopyright - Copyright © 2017 Apple, Inc. All rights reserved. - NSPrincipalClass - - - diff --git a/keychain/trust/TrustedPeers/TPCategoryRule.h b/keychain/trust/TrustedPeers/TPCategoryRule.h deleted file mode 100644 index a06b61eb..00000000 --- a/keychain/trust/TrustedPeers/TPCategoryRule.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -NS_ASSUME_NONNULL_BEGIN - -/*! - This class represents a single rule that, if it matches a prefix - of a model ID, assigns a category to that model. - - This class is just a pair of strings, for the prefix: category - mappings contained in a policy's modelToCategory array. - - This class is a value type -- its members are immutable and - instances with identical contents are interchangeable. - */ -@interface TPCategoryRule : NSObject - -@property (nonatomic, readonly) NSString *prefix; -@property (nonatomic, readonly) NSString *category; - -+ (instancetype)ruleWithPrefix:(NSString *)prefix category:(NSString *)category; - -@end - -NS_ASSUME_NONNULL_END diff --git a/keychain/trust/TrustedPeers/TPCategoryRule.m b/keychain/trust/TrustedPeers/TPCategoryRule.m deleted file mode 100644 index 410f1eb9..00000000 --- a/keychain/trust/TrustedPeers/TPCategoryRule.m +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import "TPCategoryRule.h" - - -@interface TPCategoryRule () - -@property (nonatomic, copy) NSString *prefix; -@property (nonatomic, copy) NSString *category; - -@end - - -@implementation TPCategoryRule - -+ (instancetype)ruleWithPrefix:(NSString *)prefix category:(NSString *)category -{ - TPCategoryRule *rule = [[TPCategoryRule alloc] init]; - rule.prefix = prefix; - rule.category = category; - return rule; -} - -- (BOOL)isEqualToCategoryRule:(TPCategoryRule *)other -{ - if (other == self) { - return YES; - } - return [self.prefix isEqualToString:other.prefix] - && [self.category isEqualToString:other.category]; -} - -#pragma mark - NSObject - -- (BOOL)isEqual:(id)object -{ - if (self == object) { - return YES; - } - if (![object isKindOfClass:[TPCategoryRule class]]) { - return NO; - } - return [self isEqualToCategoryRule:object]; -} - -- (NSUInteger)hash -{ - return [self.prefix hash] ^ [self.category hash]; -} - -@end diff --git a/keychain/trust/TrustedPeers/TPCircle.h b/keychain/trust/TrustedPeers/TPCircle.h deleted file mode 100644 index fa2a660a..00000000 --- a/keychain/trust/TrustedPeers/TPCircle.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -NS_ASSUME_NONNULL_BEGIN - -/*! - A "circle" identifies a set of peers that should be included and - a set of peers that should be excluded from trust membership. - - This class is a value type -- its members are immutable and - instances with identical contents are interchangeable. - It overrides isEqual and hash, so that two instances with - identical contents will compare as equal. - */ -@interface TPCircle : NSObject - -@property (nonatomic, readonly) NSString *circleID; -@property (nonatomic, readonly) NSSet* includedPeerIDs; -@property (nonatomic, readonly) NSSet* excludedPeerIDs; - -/*! - A convenience for allocating and initializing an instance from array literals. - */ -+ (instancetype)circleWithIncludedPeerIDs:(nullable NSArray *)includedPeerIDs - excludedPeerIDs:(nullable NSArray *)excludedPeerIDs; - -/*! - A convenience for checking a provided circleID. Returns nil if it does not match. - */ -+ (nullable instancetype)circleWithID:(NSString *)circleID - includedPeerIDs:(nullable NSArray *)includedPeerIDs - excludedPeerIDs:(nullable NSArray *)excludedPeerIDs; - -/*! - Construct a circle that includes a set of peer IDs and excludes a set of peer IDs. - */ -- (instancetype)initWithIncludedPeerIDs:(NSSet *)includedPeerIDs - excludedPeerIDs:(NSSet *)excludedPeerIDs; - -- (BOOL)isEqualToCircle:(TPCircle *)other; - -@end - -NS_ASSUME_NONNULL_END diff --git a/keychain/trust/TrustedPeers/TPCircle.m b/keychain/trust/TrustedPeers/TPCircle.m deleted file mode 100644 index 6955a2f1..00000000 --- a/keychain/trust/TrustedPeers/TPCircle.m +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import "TPCircle.h" -#import "TPHash.h" - -@interface TPCircle () -@property (nonatomic, strong) NSString* circleID; -@property (nonatomic, strong) NSSet* includedPeerIDs; -@property (nonatomic, strong) NSSet* excludedPeerIDs; -@end - -@implementation TPCircle - -+ (instancetype)circleWithIncludedPeerIDs:(NSArray *)includedPeerIDs - excludedPeerIDs:(NSArray *)excludedPeerIDs -{ - return [[TPCircle alloc] initWithIncludedPeerIDs:[NSSet setWithArray:includedPeerIDs] - excludedPeerIDs:[NSSet setWithArray:excludedPeerIDs]]; -} - -+ (instancetype)circleWithID:(NSString *)circleID - includedPeerIDs:(NSArray *)includedPeerIDs - excludedPeerIDs:(NSArray *)excludedPeerIDs -{ - TPCircle *circle = [TPCircle circleWithIncludedPeerIDs:includedPeerIDs - excludedPeerIDs:excludedPeerIDs]; - if ([circleID isEqualToString:circle.circleID]) { - return circle; - } else { - return nil; - } -} - -- (instancetype)initWithIncludedPeerIDs:(NSSet *)includedPeerIDs - excludedPeerIDs:(NSSet *)excludedPeerIDs -{ - self = [super init]; - if (self) { - // Copy the sets passed in, so that nobody can mutate them later. - _includedPeerIDs = [includedPeerIDs copy]; - _excludedPeerIDs = [excludedPeerIDs copy]; - - NSArray* sortedInc = [[includedPeerIDs allObjects] sortedArrayUsingSelector:@selector(compare:)]; - NSArray* sortedExc = [[excludedPeerIDs allObjects] sortedArrayUsingSelector:@selector(compare:)]; - - TPHashBuilder* hasher = [[TPHashBuilder alloc] initWithAlgo:kTPHashAlgoSHA256]; - { - const char* inc = "include: "; - [hasher updateWithBytes:inc len:strlen(inc)]; - for (NSString* peerID in sortedInc) { - [hasher updateWithData:[peerID dataUsingEncoding:NSUTF8StringEncoding]]; - } - } - { - const char* exc = "exclude: "; - [hasher updateWithBytes:exc len:strlen(exc)]; - for (NSString* peerID in sortedExc) { - [hasher updateWithData:[peerID dataUsingEncoding:NSUTF8StringEncoding]]; - } - } - _circleID = [hasher finalHash]; - } - return self; -} - -- (BOOL)isEqualToCircle:(TPCircle *)other -{ - return [self.includedPeerIDs isEqualToSet:other.includedPeerIDs] - && [self.excludedPeerIDs isEqualToSet:other.excludedPeerIDs]; -} - -#pragma mark - NSObject - -- (BOOL)isEqual:(id)object -{ - if (self == object) { - return YES; - } - if (![object isKindOfClass:[TPCircle class]]) { - return NO; - } - return [self isEqualToCircle:object]; -} - -- (NSUInteger)hash -{ - return [self.includedPeerIDs hash] ^ ([self.excludedPeerIDs hash] << 1); -} - -static NSString *setDescription(NSSet *set) -{ - return [[[set allObjects] sortedArrayUsingSelector:@selector(compare:)] componentsJoinedByString:@" "]; -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"{ in: [%@] ex: [%@] }", - setDescription(self.includedPeerIDs), - setDescription(self.excludedPeerIDs)]; -} - -@end diff --git a/keychain/trust/TrustedPeers/TPDecrypter.h b/keychain/trust/TrustedPeers/TPDecrypter.h deleted file mode 100644 index cc523a78..00000000 --- a/keychain/trust/TrustedPeers/TPDecrypter.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -NS_ASSUME_NONNULL_BEGIN - -@protocol TPDecrypter - -- (nullable NSData *)decryptData:(NSData *)ciphertext - withKey:(NSData *)key - error:(NSError **)error; - -@end - -NS_ASSUME_NONNULL_END diff --git a/keychain/trust/TrustedPeers/TPEncrypter.h b/keychain/trust/TrustedPeers/TPEncrypter.h deleted file mode 100644 index 48f2bea1..00000000 --- a/keychain/trust/TrustedPeers/TPEncrypter.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -NS_ASSUME_NONNULL_BEGIN - -@protocol TPEncrypter - -@property (nonatomic, readonly) NSData *decryptionKey; - -- (nullable NSData *)encryptData:(NSData *)plaintext error:(NSError **)error; - -@end - -NS_ASSUME_NONNULL_END diff --git a/keychain/trust/TrustedPeers/TPHash.h b/keychain/trust/TrustedPeers/TPHash.h deleted file mode 100644 index af304c29..00000000 --- a/keychain/trust/TrustedPeers/TPHash.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -NS_ASSUME_NONNULL_BEGIN - -/*! - A hash digest algorithm - */ -typedef NS_ENUM(NSInteger, TPHashAlgo) { - kTPHashAlgoUnknown = -1, - kTPHashAlgoSHA224 = 0, - kTPHashAlgoSHA256, - kTPHashAlgoSHA384, - kTPHashAlgoSHA512, -}; - -/*! - A hash prefixed with the name of the digest algorithm, e.g. - "SHA256:xxxx" where the 'x' are 8-bit bytes. - */ - - -@interface TPHashBuilder : NSObject - -+ (TPHashAlgo)algoOfHash:(NSString *)hash; - -- (instancetype)initWithAlgo:(TPHashAlgo)algo; -- (void)resetWithAlgo:(TPHashAlgo)algo; -- (void)updateWithData:(NSData *)data; -- (void)updateWithBytes:(const void *)data len:(size_t)len; -- (NSString *)finalHash; - -+ (NSString *)hashWithAlgo:(TPHashAlgo)algo ofData:(NSData *)data; -+ (NSString *)hashWithAlgo:(TPHashAlgo)algo ofBytes:(const void *)data len:(size_t)len; - -@end - -NS_ASSUME_NONNULL_END diff --git a/keychain/trust/TrustedPeers/TPHash.m b/keychain/trust/TrustedPeers/TPHash.m deleted file mode 100644 index 703c034d..00000000 --- a/keychain/trust/TrustedPeers/TPHash.m +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import "TPHash.h" - -#import - -@interface TPHashBuilder () - -@property (nonatomic, assign) TPHashAlgo algo; -@property (nonatomic, assign) CC_SHA256_CTX ctxSHA256; // used by SHA224 and SHA256 -@property (nonatomic, assign) CC_SHA512_CTX ctxSHA512; // used by SHA384 and SHA512 - -@end - -@implementation TPHashBuilder - -+ (TPHashAlgo)algoOfHash:(NSString *)hash -{ - if ([hash hasPrefix:@"SHA224:"]) { - return kTPHashAlgoSHA224; - } - if ([hash hasPrefix:@"SHA256:"]) { - return kTPHashAlgoSHA256; - } - if ([hash hasPrefix:@"SHA384:"]) { - return kTPHashAlgoSHA384; - } - if ([hash hasPrefix:@"SHA512:"]) { - return kTPHashAlgoSHA512; - } - return kTPHashAlgoUnknown; -} - -- (instancetype)init -{ - self = [super init]; - if (self) { - _algo = kTPHashAlgoUnknown; - } - return self; -} - -- (instancetype)initWithAlgo:(TPHashAlgo)algo -{ - self = [self init]; - [self resetWithAlgo:algo]; - return self; -} - -- (void)resetWithAlgo:(TPHashAlgo)algo -{ - _algo = algo; - switch (algo) { - case kTPHashAlgoSHA224: - CC_SHA224_Init(&_ctxSHA256); - break; - case kTPHashAlgoSHA256: - CC_SHA256_Init(&_ctxSHA256); - break; - case kTPHashAlgoSHA384: - CC_SHA384_Init(&_ctxSHA512); - break; - case kTPHashAlgoSHA512: - CC_SHA512_Init(&_ctxSHA512); - break; - default: - [self throwInvalidAlgo]; - } -} - -- (void)updateWithData:(NSData *)data -{ - [self updateWithBytes:data.bytes len:data.length]; -} - -- (void)updateWithBytes:(const void *)data len:(size_t)len -{ - switch (self.algo) { - case kTPHashAlgoSHA224: - CC_SHA224_Update(&_ctxSHA256, data, (CC_LONG)len); - break; - case kTPHashAlgoSHA256: - CC_SHA256_Update(&_ctxSHA256, data, (CC_LONG)len); - break; - case kTPHashAlgoSHA384: - CC_SHA384_Update(&_ctxSHA512, data, (CC_LONG)len); - break; - case kTPHashAlgoSHA512: - CC_SHA512_Update(&_ctxSHA512, data, (CC_LONG)len); - break; - default: - [self throwInvalidAlgo]; - } -} - -- (NSString *)finalHash -{ - NSMutableData* data = [NSMutableData alloc]; - NSString* name = nil; - switch (self.algo) { - case kTPHashAlgoSHA224: - data = [data initWithLength:224/8]; - CC_SHA224_Final(data.mutableBytes, &_ctxSHA256); - name = @"SHA224"; - break; - case kTPHashAlgoSHA256: - data = [data initWithLength:256/8]; - CC_SHA256_Final(data.mutableBytes, &_ctxSHA256); - name = @"SHA256"; - break; - case kTPHashAlgoSHA384: - data = [data initWithLength:384/8]; - CC_SHA384_Final(data.mutableBytes, &_ctxSHA512); - name = @"SHA384"; - break; - case kTPHashAlgoSHA512: - data = [data initWithLength:512/8]; - CC_SHA512_Final(data.mutableBytes, &_ctxSHA512); - name = @"SHA512"; - break; - default: - [self throwInvalidAlgo]; - } - NSString* hash = [NSString stringWithFormat:@"%@:%@", - name, [data base64EncodedStringWithOptions:0]]; - - // _ctxSHA* was "emptied" by the call to CC_SHA*_Final, - // so require the client to call resetWithAlgo: before reuse. - self.algo = kTPHashAlgoUnknown; - - return hash; -} - -- (void)throwInvalidAlgo -{ - NSException* ex = [NSException exceptionWithName:@"InvalidTPHashAlgo" - reason:@"Invalid TPHash algorithm" - userInfo:nil]; - @throw ex; -} - -+ (NSString *)hashWithAlgo:(TPHashAlgo)algo ofData:(NSData *)data -{ - return [TPHashBuilder hashWithAlgo:algo ofBytes:data.bytes len:data.length]; -} - -+ (NSString *)hashWithAlgo:(TPHashAlgo)algo ofBytes:(const void *)data len:(size_t)len -{ - TPHashBuilder *builder = [[TPHashBuilder alloc] initWithAlgo:algo]; - [builder updateWithBytes:data len:len]; - return [builder finalHash]; -} - -@end diff --git a/keychain/trust/TrustedPeers/TPModel.h b/keychain/trust/TrustedPeers/TPModel.h deleted file mode 100644 index e750acf9..00000000 --- a/keychain/trust/TrustedPeers/TPModel.h +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -#import "TPHash.h" -#import "TPSigningKey.h" -#import "TPDecrypter.h" -#import "TPTypes.h" - -@class TPCircle; -@class TPPeerPermanentInfo; -@class TPPeerStableInfo; -@class TPPeerDynamicInfo; -@class TPVoucher; -@class TPPolicyDocument; - - -typedef NS_OPTIONS(NSUInteger, TPPeerStatus) { - // Set if at least one of the peers I trust trusts me. - TPPeerStatusPartiallyReciprocated = 1 << 0, - - // Set if all of the peers I trust trust me. - TPPeerStatusFullyReciprocated = 1 << 1, - - // Set if I have been kicked out of trust. - TPPeerStatusExcluded = 1 << 2, - - // Set if my epoch is behind the latest epoch. - TPPeerStatusOutdatedEpoch = 1 << 3, - - // Set if my epoch is two or more epochs behind the latest. - TPPeerStatusAncientEpoch = 1 << 4, -}; - - -NS_ASSUME_NONNULL_BEGIN - -/*! - TPModel implements the Octagon Trust model, as per - https://confluence.sd.apple.com/display/KEY/Octagon+Trust - - It maintains a collection of peers and a collection of circles, - to track the peers and circles in CloudKit. - (This class does not communicate with CloudKit. The client of this class does that.) - - Normally there would be just one instance of TPModel, associated with a particular Apple ID. - (This class doesn't need to know what the Apple ID is.) - - This interface does not expose TPPeer* because the caller might mutate the peer object. - All the objects exposed by this interface are immutable. -*/ -@interface TPModel : NSObject - -- (instancetype)initWithDecrypter:(id)decrypter; - -- (TPCounter)latestEpochAmongPeerIDs:(NSSet *)peerIDs; - -- (void)registerPolicyDocument:(TPPolicyDocument *)policyDoc; - -/*! - Register a peer with the given permanentInfo. - - To access this peer invoke other TPModel methods and - pass permanentInfo.peerID as the peerID argument. - - (If a peer with this permanentInfo is already registered then registering it again - does nothing, and the existing TPPeer object internal to TPModel retains its state.) - */ -- (void)registerPeerWithPermanentInfo:(TPPeerPermanentInfo *)permanentInfo; - -- (void)deletePeerWithID:(NSString *)peerID; - -- (BOOL)hasPeerWithID:(NSString *)peerID; - -/*! - Asserts that peerID is registered. - */ -- (TPPeerStatus)statusOfPeerWithID:(NSString *)peerID; - -/*! - Asserts that peerID is registered. - */ -- (TPPeerPermanentInfo *)getPermanentInfoForPeerWithID:(NSString *)peerID; - -/*! - Asserts that peerID is registered. - */ -- (nullable TPPeerStableInfo *)getStableInfoForPeerWithID:(NSString *)peerID; - -/*! - Asserts that peerID is registered. - */ -- (nullable NSData *)getWrappedPrivateKeysForPeerWithID:(NSString *)peerID; - -/*! - Asserts that peerID is registered. - */ -- (void)setWrappedPrivateKeys:(nullable NSData *)wrappedPrivateKeys - forPeerWithID:(NSString *)peerID; - -/*! - Asserts that peerID is registered. - */ -- (nullable TPPeerDynamicInfo *)getDynamicInfoForPeerWithID:(NSString *)peerID; - -/*! - Asserts that peerID is registered. - */ -- (nullable TPCircle *)getCircleForPeerWithID:(NSString *)peerID; - - -- (void)registerCircle:(TPCircle *)circle; - -- (void)deleteCircleWithID:(NSString *)circleID; - -/*! - Returns nil if no circle matching circleID is registered. - */ -- (nullable TPCircle *)circleWithID:(NSString *)circleID; - - -/*! - An "update" with unchanged data is considered success. - Asserts that peerID is registered. - */ -- (TPResult)updateStableInfo:(TPPeerStableInfo *)stableInfo - forPeerWithID:(NSString *)peerID; - -/*! - Returns nil with error if the peer's trustSigningKey is unable to create - a signature because the private key is unavailable, e.g. because the device is locked. - - Asserts peerID is registered. - */ -- (TPPeerStableInfo *)createStableInfoWithDictionary:(NSDictionary *)dict - policyVersion:(TPCounter)policyVersion - policyHash:(NSString *)policyHash - policySecrets:(nullable NSDictionary *)policySecrets - forPeerWithID:(NSString *)peerID - error:(NSError **)error; - - -/*! - An "update" with unchanged data is considered success. - Asserts peerID is registered. - */ -- (TPResult)updateDynamicInfo:(TPPeerDynamicInfo *)dynamicInfo - forPeerWithID:(NSString *)peerID; - - -/*! - The returned voucher is not registered. - Asserts sponsorID is registered. - - Returns nil with nil error if policy determines that the sponsor - is not permitted to introduce this candidate. - - Returns nil with error if the sponsor's trustSigningKey is unable to create - a signature because the private key is unavailable, e.g. because the device is locked. - - The candidate need not be registered before making this call. - */ -- (nullable TPVoucher *)createVoucherForCandidate:(TPPeerPermanentInfo *)candidate - withSponsorID:(NSString *)sponsorID - error:(NSError **)error; - -/*! - Asserts that the sponsor is registered, so that the signature check can be performed. - The beneficiary need not be registered. - */ -- (TPResult)registerVoucher:(TPVoucher *)voucher; - - -- (NSSet *)calculateUnusedCircleIDs; - -/*! - Calculates updated dynamic info for a given peer, - according to the membership convergence algorithm. - - This method does not update the model. The calculated circle is not registered - and the peer is not updated with the calculated dynamicInfo. It is the caller's - responsibility to register/update them once they have been persisted to CloudKit. - - Peers listed in addingPeerIDs are taken to have been explicitly trusted by the user. - When the user adds a member of addingPeerIDs into trust, the peers already trusted - by that new peer are also taken to be trusted, even if the new peer is not qualified by - policy to *introduce* them into trust. This is neccessary in a scenario where a mid-level - device approves a lowly device, and the new lowly device should trust the high-level devices - already in the circle. The mid-level device is not *introducing* the high-level devices. - - Peers listed in removingPeerIDs are excluded from trust. - - Returns nil with error if the peer's trustSigningKey is unable to create - a signature because the private key is unavailable, e.g. because the device is locked. - - Asserts peerID is registered. - */ -- (nullable TPPeerDynamicInfo *)calculateDynamicInfoForPeerWithID:(NSString *)peerID - addingPeerIDs:(nullable NSArray *)addingPeerIDs - removingPeerIDs:(nullable NSArray *)removingPeerIDs - createClique:(nullable NSString* (^)())createClique - updatedCircle:(TPCircle * _Nullable * _Nullable)updatedCircle - error:(NSError **)error; - -/*! - A convenience method for tests, this calls calculateDynamicInfoForPeerWithID, - registers the results and returns the new circle. - */ -- (TPCircle *)advancePeerWithID:(NSString *)peerID - addingPeerIDs:(nullable NSArray *)addingPeerIDs - removingPeerIDs:(nullable NSArray *)removingPeerIDs - createClique:(nullable NSString* (^)())createClique; - -/*! - From our trusted peers, return the subset that is allowed - to access the given view, according to the current policy. - - Asserts peerID is registered. - */ -- (nullable NSSet *)getPeerIDsTrustedByPeerWithID:(NSString *)peerID - toAccessView:(NSString *)view - error:(NSError **)error; - -/*! - Returns a dictionary mapping from each peer ID - to the most recent clock seen from that peer. - */ -- (NSDictionary *)vectorClock; - -@end - -NS_ASSUME_NONNULL_END diff --git a/keychain/trust/TrustedPeers/TPModel.m b/keychain/trust/TrustedPeers/TPModel.m deleted file mode 100644 index 7ec2166a..00000000 --- a/keychain/trust/TrustedPeers/TPModel.m +++ /dev/null @@ -1,730 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import "TPModel.h" -#import "TPPeer.h" -#import "TPHash.h" -#import "TPCircle.h" -#import "TPVoucher.h" -#import "TPPeerPermanentInfo.h" -#import "TPPeerStableInfo.h" -#import "TPPeerDynamicInfo.h" -#import "TPPolicy.h" -#import "TPPolicyDocument.h" - - -@interface TPModel () -@property (nonatomic, strong) NSMutableDictionary* peersByID; -@property (nonatomic, strong) NSMutableDictionary* circlesByID; -@property (nonatomic, strong) NSMutableDictionary* policiesByVersion; -@property (nonatomic, strong) NSMutableSet* vouchers; -@property (nonatomic, strong) id decrypter; -@end - -@implementation TPModel - -- (instancetype)initWithDecrypter:(id)decrypter -{ - self = [super init]; - if (self) { - _peersByID = [[NSMutableDictionary alloc] init]; - _circlesByID = [[NSMutableDictionary alloc] init]; - _policiesByVersion = [[NSMutableDictionary alloc] init]; - _vouchers = [[NSMutableSet alloc] init]; - _decrypter = decrypter; - } - return self; -} - -- (TPCounter)latestEpochAmongPeerIDs:(NSSet *)peerIDs -{ - TPCounter latestEpoch = 0; - for (NSString *peerID in peerIDs) { - TPPeer *peer = self.peersByID[peerID]; - if (nil == peer) { - continue; - } - latestEpoch = MAX(latestEpoch, peer.permanentInfo.epoch); - } - return latestEpoch; -} - -- (void)registerPolicyDocument:(TPPolicyDocument *)policyDoc -{ - NSAssert(policyDoc, @"policyDoc must not be nil"); - self.policiesByVersion[@(policyDoc.policyVersion)] = policyDoc; -} - -- (void)registerPeerWithPermanentInfo:(TPPeerPermanentInfo *)permanentInfo -{ - NSAssert(permanentInfo, @"permanentInfo must not be nil"); - if (nil == [self.peersByID objectForKey:permanentInfo.peerID]) { - TPPeer *peer = [[TPPeer alloc] initWithPermanentInfo:permanentInfo]; - [self.peersByID setObject:peer forKey:peer.peerID]; - } else { - // Do nothing, to avoid overwriting the existing peer object which might have accumulated state. - } -} - -- (void)deletePeerWithID:(NSString *)peerID -{ - [self.peersByID removeObjectForKey:peerID]; -} - -- (BOOL)hasPeerWithID:(NSString *)peerID -{ - return nil != self.peersByID[peerID]; -} - -- (nonnull TPPeer *)peerWithID:(NSString *)peerID -{ - TPPeer *peer = [self.peersByID objectForKey:peerID]; - NSAssert(nil != peer, @"peerID is not registered: %@", peerID); - return peer; -} - -- (TPPeerStatus)statusOfPeerWithID:(NSString *)peerID -{ - TPPeer *peer = [self peerWithID:peerID]; - TPPeerStatus status = 0; - if (0 < [peer.circle.includedPeerIDs count]) { - status |= TPPeerStatusFullyReciprocated; - // This flag might get cleared again, below. - } - for (NSString *otherID in peer.circle.includedPeerIDs) { - if ([peerID isEqualToString:otherID]) { - continue; - } - TPPeer *otherPeer = self.peersByID[otherID]; - if (nil == otherPeer) { - continue; - } - if ([otherPeer.circle.includedPeerIDs containsObject:peerID]) { - status |= TPPeerStatusPartiallyReciprocated; - } else { - status &= ~TPPeerStatusFullyReciprocated; - } - if ([otherPeer.circle.excludedPeerIDs containsObject:peerID]) { - status |= TPPeerStatusExcluded; - } - if (otherPeer.permanentInfo.epoch > peer.permanentInfo.epoch) { - status |= TPPeerStatusOutdatedEpoch; - } - if (otherPeer.permanentInfo.epoch > peer.permanentInfo.epoch + 1) { - status |= TPPeerStatusAncientEpoch; - } - } - if ([peer.circle.excludedPeerIDs containsObject:peerID]) { - status |= TPPeerStatusExcluded; - } - return status; -} - - -- (TPPeerPermanentInfo *)getPermanentInfoForPeerWithID:(NSString *)peerID -{ - return [self peerWithID:peerID].permanentInfo; -} - -- (TPPeerStableInfo *)getStableInfoForPeerWithID:(NSString *)peerID -{ - return [self peerWithID:peerID].stableInfo; -} - -- (NSData *)getWrappedPrivateKeysForPeerWithID:(NSString *)peerID -{ - return [self peerWithID:peerID].wrappedPrivateKeys; -} - -- (void)setWrappedPrivateKeys:(nullable NSData *)wrappedPrivateKeys - forPeerWithID:(NSString *)peerID -{ - [self peerWithID:peerID].wrappedPrivateKeys = wrappedPrivateKeys; -} - -- (TPPeerDynamicInfo *)getDynamicInfoForPeerWithID:(NSString *)peerID -{ - return [self peerWithID:peerID].dynamicInfo; -} - -- (TPCircle *)getCircleForPeerWithID:(NSString *)peerID -{ - return [self peerWithID:peerID].circle; -} - -- (void)registerCircle:(TPCircle *)circle -{ - NSAssert(circle, @"circle must not be nil"); - [self.circlesByID setObject:circle forKey:circle.circleID]; - - // A dynamicInfo might have been set on a peer before we had the circle identified by dynamicInfo.circleID. - // Check if this circle is referenced by any dynamicInfo.circleID. - [self.peersByID enumerateKeysAndObjectsUsingBlock:^(NSString *peerID, TPPeer *peer, BOOL *stop) { - if (nil == peer.circle && [peer.dynamicInfo.circleID isEqualToString:circle.circleID]) { - peer.circle = circle; - } - }]; -} - -- (void)deleteCircleWithID:(NSString *)circleID -{ - [self.peersByID enumerateKeysAndObjectsUsingBlock:^(NSString *peerID, TPPeer *peer, BOOL *stop) { - NSAssert(![circleID isEqualToString:peer.dynamicInfo.circleID], - @"circle being deleted is in use by peer %@, circle %@", peerID, circleID); - }]; - [self.circlesByID removeObjectForKey:circleID]; -} - -- (TPCircle *)circleWithID:(NSString *)circleID -{ - return [self.circlesByID objectForKey:circleID]; -} - -- (TPResult)updateStableInfo:(TPPeerStableInfo *)stableInfo - forPeerWithID:(NSString *)peerID -{ - TPPeer *peer = [self peerWithID:peerID]; - return [peer updateStableInfo:stableInfo]; -} - -- (TPPeerStableInfo *)createStableInfoWithDictionary:(NSDictionary *)dict - policyVersion:(TPCounter)policyVersion - policyHash:(NSString *)policyHash - policySecrets:(nullable NSDictionary *)policySecrets - forPeerWithID:(NSString *)peerID - error:(NSError **)error -{ - TPPeer *peer = [self peerWithID:peerID]; - TPCounter clock = [self maxClock] + 1; - return [TPPeerStableInfo stableInfoWithDict:dict - clock:clock - policyVersion:policyVersion - policyHash:policyHash - policySecrets:policySecrets - trustSigningKey:peer.permanentInfo.trustSigningKey - error:error]; -} - -- (TPResult)updateDynamicInfo:(TPPeerDynamicInfo *)dynamicInfo - forPeerWithID:(NSString *)peerID -{ - TPPeer *peer = [self peerWithID:peerID]; - TPResult result = [peer updateDynamicInfo:dynamicInfo]; - if (result != TPResultOk) { - return result; - } - TPCircle *circle = [self.circlesByID objectForKey:dynamicInfo.circleID]; - if (nil != circle) { - peer.circle = circle; - } else { - // When the corresponding circleID is eventually registered, - // a call to registerCircle: will set peer.circle. - } - return result; -} - -- (TPCounter)maxClock -{ - __block TPCounter maxClock = 0; - [self.peersByID enumerateKeysAndObjectsUsingBlock:^(NSString *peerID, TPPeer *peer, BOOL *stop) { - if (nil != peer.stableInfo) { - maxClock = MAX(maxClock, peer.stableInfo.clock); - } - if (nil != peer.dynamicInfo) { - maxClock = MAX(maxClock, peer.dynamicInfo.clock); - } - }]; - return maxClock; -} - -- (TPCounter)maxRemovals -{ - __block TPCounter maxRemovals = 0; - [self.peersByID enumerateKeysAndObjectsUsingBlock:^(NSString *peerID, TPPeer *peer, BOOL *stop) { - if (nil != peer.dynamicInfo) { - maxRemovals = MAX(maxRemovals, peer.dynamicInfo.removals); - } - }]; - return maxRemovals; -} - -- (TPPeerDynamicInfo *)createDynamicInfoForPeerWithID:(NSString *)peerID - circle:(TPCircle *)circle - clique:(NSString *)clique - newRemovals:(TPCounter)newRemovals - error:(NSError **)error -{ - TPPeer *peer = self.peersByID[peerID]; - - TPCounter clock = [self maxClock] + 1; - TPCounter removals = [self maxRemovals] + newRemovals; - - return [TPPeerDynamicInfo dynamicInfoWithCircleID:circle.circleID - clique:clique - removals:removals - clock:clock - trustSigningKey:peer.permanentInfo.trustSigningKey - error:error]; -} - -- (BOOL)canTrustCandidate:(TPPeerPermanentInfo *)candidate inEpoch:(TPCounter)epoch -{ - return candidate.epoch + 1 >= epoch; -} - -- (BOOL)canIntroduceCandidate:(TPPeerPermanentInfo *)candidate - withSponsor:(TPPeerPermanentInfo *)sponsor - toEpoch:(TPCounter)epoch - underPolicy:(id)policy -{ - if (![self canTrustCandidate:candidate inEpoch:sponsor.epoch]) { - return NO; - } - if (![self canTrustCandidate:candidate inEpoch:epoch]) { - return NO; - } - - NSString *sponsorCategory = [policy categoryForModel:sponsor.modelID]; - NSString *candidateCategory = [policy categoryForModel:candidate.modelID]; - - return [policy trustedPeerInCategory:sponsorCategory canIntroduceCategory:candidateCategory]; -} - -- (nullable TPVoucher *)createVoucherForCandidate:(TPPeerPermanentInfo *)candidate - withSponsorID:(NSString *)sponsorID - error:(NSError **)error -{ - TPPeer *sponsor = [self peerWithID:sponsorID]; - - NSSet *peerIDs = [sponsor.trustedPeerIDs setByAddingObject:candidate.peerID]; - id policy = [self policyForPeerIDs:peerIDs error:error]; - if (nil == policy) { - return nil; - } - - if (![self canIntroduceCandidate:candidate - withSponsor:sponsor.permanentInfo - toEpoch:sponsor.permanentInfo.epoch - underPolicy:policy]) - { - if (error) { - *error = nil; - } - return nil; - } - - // clock is correctly zero if sponsor does not yet have dynamicInfo - TPCounter clock = sponsor.dynamicInfo.clock; - return [TPVoucher voucherWithBeneficiaryID:candidate.peerID - sponsorID:sponsorID - clock:clock - trustSigningKey:sponsor.permanentInfo.trustSigningKey - error:error]; -} - -- (TPResult)registerVoucher:(TPVoucher *)voucher -{ - NSAssert(voucher, @"voucher must not be nil"); - TPPeer *sponsor = [self peerWithID:voucher.sponsorID]; - if (![sponsor.permanentInfo.trustSigningKey checkSignature:voucher.voucherInfoSig matchesData:voucher.voucherInfoPList]) { - return TPResultSignatureMismatch; - } - [self.vouchers addObject:voucher]; - return TPResultOk; -} - -- (NSSet *)calculateUnusedCircleIDs -{ - NSMutableSet* circleIDs = [NSMutableSet setWithArray:[self.circlesByID allKeys]]; - - [self.peersByID enumerateKeysAndObjectsUsingBlock:^(NSString *peerID, TPPeer *peer, BOOL *stop) { - if (nil != peer.dynamicInfo) { - [circleIDs removeObject:peer.dynamicInfo.circleID]; - } - }]; - return circleIDs; -} - -- (nullable NSError *)considerCandidateID:(NSString *)candidateID - withSponsor:(TPPeer *)sponsor - toExpandIncludedPeerIDs:(NSMutableSet*)includedPeerIDs - andExcludedPeerIDs:(NSMutableSet*)excludedPeerIDs - forEpoch:(TPCounter)epoch -{ - if ([includedPeerIDs containsObject:candidateID]) { - // Already included, nothing to do. - return nil; - } - if ([excludedPeerIDs containsObject:candidateID]) { - // Denied. - return nil; - } - - TPPeer *candidate = self.peersByID[candidateID]; - if (nil == candidate) { - return nil; - } - NSMutableSet *peerIDs = [NSMutableSet setWithSet:includedPeerIDs]; - [peerIDs minusSet:excludedPeerIDs]; - [peerIDs addObject:candidateID]; - NSError *error = nil; - id policy = [self policyForPeerIDs:peerIDs error:&error]; - if (nil == policy) { - return error; - } - - if ([self canIntroduceCandidate:candidate.permanentInfo - withSponsor:sponsor.permanentInfo - toEpoch:epoch - underPolicy:policy]) - { - [includedPeerIDs addObject:candidateID]; - [excludedPeerIDs unionSet:candidate.circle.excludedPeerIDs]; - - // The accepted candidate can now be a sponsor. - error = [self recursivelyExpandIncludedPeerIDs:includedPeerIDs - andExcludedPeerIDs:excludedPeerIDs - withPeersTrustedBySponsorID:candidateID - forEpoch:epoch]; - if (nil != error) { - return error; - } - } - return nil; -} - -- (nullable NSError *)considerVouchersSponsoredByPeer:(TPPeer *)sponsor - toReecursivelyExpandIncludedPeerIDs:(NSMutableSet*)includedPeerIDs - andExcludedPeerIDs:(NSMutableSet*)excludedPeerIDs - forEpoch:(TPCounter)epoch -{ - for (TPVoucher *voucher in self.vouchers) { - if ([voucher.sponsorID isEqualToString:sponsor.peerID] - && voucher.clock == sponsor.dynamicInfo.clock) - { - NSError *error = [self considerCandidateID:voucher.beneficiaryID - withSponsor:sponsor - toExpandIncludedPeerIDs:includedPeerIDs - andExcludedPeerIDs:excludedPeerIDs - forEpoch:epoch]; - if (nil != error) { - return error; - } - } - } - return nil; -} - -- (nullable NSError *)recursivelyExpandIncludedPeerIDs:(NSMutableSet*)includedPeerIDs - andExcludedPeerIDs:(NSMutableSet*)excludedPeerIDs - withPeersTrustedBySponsorID:(NSString *)sponsorID - forEpoch:(TPCounter)epoch -{ - TPPeer *sponsor = self.peersByID[sponsorID]; - if (nil == sponsor) { - // It is possible that we might receive a voucher sponsored - // by a peer that has not yet been registered or has been deleted, - // or that a peer will have a circle that includes a peer that - // has not yet been registered or has been deleted. - return nil; - } - [excludedPeerIDs unionSet:sponsor.circle.excludedPeerIDs]; - for (NSString *candidateID in sponsor.circle.includedPeerIDs) { - NSError *error = [self considerCandidateID:candidateID - withSponsor:sponsor - toExpandIncludedPeerIDs:includedPeerIDs - andExcludedPeerIDs:excludedPeerIDs - forEpoch:epoch]; - if (nil != error) { - return error; - } - } - return [self considerVouchersSponsoredByPeer:sponsor - toReecursivelyExpandIncludedPeerIDs:includedPeerIDs - andExcludedPeerIDs:excludedPeerIDs - forEpoch:epoch]; -} - -- (TPPeerDynamicInfo *)calculateDynamicInfoForPeerWithID:(NSString *)peerID - addingPeerIDs:(NSArray *)addingPeerIDs - removingPeerIDs:(NSArray *)removingPeerIDs - createClique:(NSString* (^)())createClique - updatedCircle:(TPCircle **)updatedCircle - error:(NSError **)error -{ - TPPeer *peer = [self peerWithID:peerID]; - TPCounter epoch = peer.permanentInfo.epoch; - - // If we have dynamicInfo then we must know the corresponding circle. - NSAssert(nil != peer.circle || nil == peer.dynamicInfo, @"dynamicInfo without corresponding circle"); - - // If I am excluded by myself then make no changes. I am no longer playing the game. - // This is useful in the case where I have replaced myself with a new peer. - if ([peer.circle.excludedPeerIDs containsObject:peerID]) { - if (updatedCircle) { - *updatedCircle = peer.circle; - } - return peer.dynamicInfo; - } - - NSMutableSet *includedPeerIDs = [NSMutableSet setWithSet:peer.circle.includedPeerIDs]; - NSMutableSet *excludedPeerIDs = [NSMutableSet setWithSet:peer.circle.excludedPeerIDs]; - - // I trust myself by default, though this might be overridden by excludedPeerIDs - [includedPeerIDs addObject:peerID]; - - // The user has explictly told us to trust addingPeerIDs. - // This implies that the peers included in the circles of addingPeerIDs should also be trusted, - // as long epoch tests pass. This is regardless of whether trust policy says a member of addingPeerIDs - // can *introduce* a peer in its circle, because it isn't introducing it, the user already trusts it. - [includedPeerIDs addObjectsFromArray:addingPeerIDs]; - for (NSString *addingPeerID in addingPeerIDs) { - TPPeer *addingPeer = self.peersByID[addingPeerID]; - for (NSString *candidateID in addingPeer.circle.includedPeerIDs) { - TPPeer *candidate = self.peersByID[candidateID]; - if (candidate && [self canTrustCandidate:candidate.permanentInfo inEpoch:epoch]) { - [includedPeerIDs addObject:candidateID]; - } - } - } - - [excludedPeerIDs addObjectsFromArray:removingPeerIDs]; - [includedPeerIDs minusSet:excludedPeerIDs]; - - // We iterate over a copy because the loop will mutate includedPeerIDs - NSSet* sponsorIDs = [includedPeerIDs copy]; - - for (NSString *sponsorID in sponsorIDs) { - NSError *err = [self recursivelyExpandIncludedPeerIDs:includedPeerIDs - andExcludedPeerIDs:excludedPeerIDs - withPeersTrustedBySponsorID:sponsorID - forEpoch:epoch]; - if (nil != err) { - if (error) { - *error = err; - } - return nil; - } - } - NSError *err = [self considerVouchersSponsoredByPeer:peer - toReecursivelyExpandIncludedPeerIDs:includedPeerIDs - andExcludedPeerIDs:excludedPeerIDs - forEpoch:epoch]; - if (nil != err) { - if (error) { - *error = err; - } - return nil; - } - - [includedPeerIDs minusSet:excludedPeerIDs]; - - NSString *clique = [self bestCliqueAmongPeerIDs:includedPeerIDs]; - if (nil == clique) { - clique = peer.dynamicInfo.clique; - } - if (nil == clique && nil != createClique) { - clique = createClique(); - } - if (nil == clique) { - // Either nil == createClique or createClique returned nil. - // We would create a clique but caller has said not to. - // Not an error, it's just what they asked for. - if (error) { - *error = nil; - } - return nil; - } - - TPCircle *newCircle; - if ([excludedPeerIDs containsObject:peerID]) { - // I have been kicked out, and anybody who trusts me should now exclude me. - newCircle = [TPCircle circleWithIncludedPeerIDs:addingPeerIDs excludedPeerIDs:@[peerID]]; - } else { - // Drop items from excludedPeerIDs that predate epoch - 1 - NSSet *filteredExcluded = [excludedPeerIDs objectsPassingTest:^BOOL(NSString *exPeerID, BOOL *stop) { - TPPeer *exPeer = self.peersByID[exPeerID]; - if (nil == exPeer) { - return YES; - } - // If we could trust it then we have to keep it in the exclude list. - return [self canTrustCandidate:exPeer.permanentInfo inEpoch:epoch]; - }]; - newCircle = [TPCircle circleWithIncludedPeerIDs:[includedPeerIDs allObjects] - excludedPeerIDs:[filteredExcluded allObjects]]; - } - if (updatedCircle) { - *updatedCircle = newCircle; - } - return [self createDynamicInfoForPeerWithID:peerID - circle:newCircle - clique:clique - newRemovals:[removingPeerIDs count] - error:error]; -} - -- (NSString *)bestCliqueAmongPeerIDs:(NSSet*)peerIDs -{ - // The "best" clique is considered the one that is last in lexical ordering. - NSString *bestClique = nil; - for (NSString *peerID in peerIDs) { - NSString *clique = self.peersByID[peerID].dynamicInfo.clique; - if (clique) { - if (bestClique && NSOrderedAscending != [bestClique compare:clique]) { - continue; - } - bestClique = clique; - } - } - return bestClique; -} - -- (TPCircle *)advancePeerWithID:(NSString *)peerID - addingPeerIDs:(NSArray *)addingPeerIDs - removingPeerIDs:(NSArray *)removingPeerIDs - createClique:(NSString* (^)())createClique -{ - TPCircle *circle = nil; - TPPeerDynamicInfo *dyn; - dyn = [self calculateDynamicInfoForPeerWithID:peerID - addingPeerIDs:addingPeerIDs - removingPeerIDs:removingPeerIDs - createClique:createClique - updatedCircle:&circle - error:NULL]; - if (dyn) { - [self registerCircle:circle]; - [self updateDynamicInfo:dyn forPeerWithID:peerID]; - return circle; - } else { - return nil; - } -} - -NSString *TPErrorDomain = @"com.apple.security.trustedpeers"; - -enum { - TPErrorUnknownPolicyVersion = 1, - TPErrorPolicyHashMismatch = 2, - TPErrorMissingStableInfo = 3, -}; - - -- (nullable id)policyForPeerIDs:(NSSet *)peerIDs - error:(NSError **)error -{ - NSAssert(peerIDs.count > 0, @"policyForPeerIDs does not accept empty set"); - - TPPolicyDocument *newestPolicyDoc = nil; - - // This will become the union of policySecrets across the members of peerIDs - NSMutableDictionary *secrets = [NSMutableDictionary dictionary]; - - for (NSString *peerID in peerIDs) { - TPPeerStableInfo *stableInfo = [self peerWithID:peerID].stableInfo; - if (nil == stableInfo) { - // Allowing missing stableInfo here might be useful if we are writing a voucher - // for a peer for which we got permanentInfo over some channel that does not - // also convey stableInfo. - continue; - } - for (NSString *name in stableInfo.policySecrets) { - secrets[name] = stableInfo.policySecrets[name]; - } - if (newestPolicyDoc && newestPolicyDoc.policyVersion > stableInfo.policyVersion) { - continue; - } - TPPolicyDocument *policyDoc = self.policiesByVersion[@(stableInfo.policyVersion)]; - if (nil == policyDoc) { - if (error) { - *error = [NSError errorWithDomain:TPErrorDomain - code:TPErrorUnknownPolicyVersion - userInfo:@{ - @"peerID": peerID, - @"policyVersion": @(stableInfo.policyVersion) - }]; - } - return nil; - } - if (![policyDoc.policyHash isEqualToString:stableInfo.policyHash]) { - if (error) { - *error = [NSError errorWithDomain:TPErrorDomain - code:TPErrorPolicyHashMismatch - userInfo:@{ - @"peerID": peerID, - @"policyVersion": @(stableInfo.policyVersion), - @"policyDocHash": policyDoc.policyHash, - @"peerExpectsHash": stableInfo.policyHash - }]; - } - return nil; - } - newestPolicyDoc = policyDoc; - } - if (nil == newestPolicyDoc) { - // Can happen if no members of peerIDs have stableInfo - if (error) { - *error = [NSError errorWithDomain:TPErrorDomain - code:TPErrorMissingStableInfo - userInfo:nil]; - } - return nil; - } - return [newestPolicyDoc policyWithSecrets:secrets decrypter:self.decrypter error:error]; -} - -- (NSSet *)getPeerIDsTrustedByPeerWithID:(NSString *)peerID - toAccessView:(NSString *)view - error:(NSError **)error -{ - TPCircle *circle = [self peerWithID:peerID].circle; - NSMutableSet *peerIDs = [NSMutableSet set]; - - id policy = [self policyForPeerIDs:circle.includedPeerIDs error:error]; - - for (NSString *candidateID in circle.includedPeerIDs) { - TPPeer *candidate = self.peersByID[candidateID]; - if (candidate != nil) { - NSString *category = [policy categoryForModel:candidate.permanentInfo.modelID]; - if ([policy peerInCategory:category canAccessView:view]) { - [peerIDs addObject:candidateID]; - } - } - } - return peerIDs; -} - -- (NSDictionary *)vectorClock -{ - NSMutableDictionary *dict = [NSMutableDictionary dictionary]; - - [self.peersByID enumerateKeysAndObjectsUsingBlock:^(NSString *peerID, TPPeer *peer, BOOL *stop) { - if (peer.stableInfo || peer.dynamicInfo) { - TPCounter clock = MAX(peer.stableInfo.clock, peer.dynamicInfo.clock); - dict[peerID] = @(clock); - } - }]; - return dict; -} - -@end diff --git a/keychain/trust/TrustedPeers/TPPeer.h b/keychain/trust/TrustedPeers/TPPeer.h deleted file mode 100644 index ae39c988..00000000 --- a/keychain/trust/TrustedPeers/TPPeer.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -#import "TPHash.h" -#import "TPSigningKey.h" -#import "TPTypes.h" - -@class TPCircle; -@class TPVoucher; -@class TPPeerPermanentInfo; -@class TPPeerStableInfo; -@class TPPeerDynamicInfo; - -NS_ASSUME_NONNULL_BEGIN - -@interface TPPeer : NSObject - -@property (nonatomic, readonly) NSString* peerID; - -@property (nonatomic, readonly) TPPeerPermanentInfo* permanentInfo; -@property (nonatomic, readonly, nullable) TPPeerStableInfo* stableInfo; -@property (nonatomic, readonly, nullable) TPPeerDynamicInfo* dynamicInfo; -@property (nonatomic, strong) NSData* wrappedPrivateKeys; - -// setCircle asserts that circle.circleID == dynamicInfo.circleID -@property (nonatomic, strong, nullable) TPCircle* circle; - -@property (nonatomic, readonly) NSSet* trustedPeerIDs; - -- (instancetype)initWithPermanentInfo:(TPPeerPermanentInfo *)permanentInfo; - -- (TPResult)updateStableInfo:(TPPeerStableInfo *)stableInfo; - -// Returns YES on success, or NO if: -// - the data or signature is invalid -// - this update makes a change without advancing dynamicInfo.clock -// -// An "update" with unchanged data is considered success. -// -// This call also sets self.circle to nil. -// The caller should subsequently call updateCircle to update it. -- (TPResult)updateDynamicInfo:(TPPeerDynamicInfo *)dynamicInfo; - -@end - -NS_ASSUME_NONNULL_END diff --git a/keychain/trust/TrustedPeers/TPPeer.m b/keychain/trust/TrustedPeers/TPPeer.m deleted file mode 100644 index c2e67065..00000000 --- a/keychain/trust/TrustedPeers/TPPeer.m +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import "TPPeer.h" -#import "TPPeerPermanentInfo.h" -#import "TPPeerStableInfo.h" -#import "TPPeerDynamicInfo.h" -#import "TPCircle.h" -#import "TPVoucher.h" - -@interface TPPeer () - -@property (nonatomic, strong) TPPeerPermanentInfo* permanentInfo; -@property (nonatomic, strong) TPPeerStableInfo* stableInfo; -@property (nonatomic, strong) TPPeerDynamicInfo* dynamicInfo; - -@end - - -@implementation TPPeer - -- (NSString *)peerID -{ - return self.permanentInfo.peerID; -} - -- (instancetype)initWithPermanentInfo:(TPPeerPermanentInfo *)permanentInfo -{ - self = [super init]; - if (self) { - _permanentInfo = permanentInfo; - } - return self; -} - -- (TPResult)updateStableInfo:(TPPeerStableInfo *)stableInfo -{ - if (![self.permanentInfo.trustSigningKey checkSignature:stableInfo.stableInfoSig - matchesData:stableInfo.stableInfoPList]) { - return TPResultSignatureMismatch; - } - if ([self.stableInfo isEqualToPeerStableInfo:stableInfo]) { - return TPResultOk; - } - if (self.stableInfo != nil && stableInfo.clock <= self.stableInfo.clock) { - return TPResultClockViolation; - } - self.stableInfo = stableInfo; - return TPResultOk; -} - -- (TPResult)updateDynamicInfo:(TPPeerDynamicInfo *)dynamicInfo -{ - if (![self.permanentInfo.trustSigningKey checkSignature:dynamicInfo.dynamicInfoSig - matchesData:dynamicInfo.dynamicInfoPList]) { - return TPResultSignatureMismatch; - } - if ([self.dynamicInfo isEqualToPeerDynamicInfo:dynamicInfo]) { - return TPResultOk; - } - if (self.dynamicInfo != nil && dynamicInfo.clock <= self.dynamicInfo.clock) { - return TPResultClockViolation; - } - self.dynamicInfo = dynamicInfo; - self.circle = nil; - return TPResultOk; -} - -- (void)setCircle:(TPCircle *)circle -{ - if (nil != circle) { - NSAssert([circle.circleID isEqualToString:self.dynamicInfo.circleID], - @"circle property must match dynamicInfo.circleID"); - } - _circle = circle; -} - -- (NSSet *)trustedPeerIDs -{ - if (self.dynamicInfo) { - NSAssert(self.circle, @"dynamicInfo needs corresponding circle"); - return self.circle.includedPeerIDs; - } else { - return [NSSet setWithObject:self.peerID]; - } -} - -@end diff --git a/keychain/trust/TrustedPeers/TPPeerDynamicInfo.h b/keychain/trust/TrustedPeers/TPPeerDynamicInfo.h deleted file mode 100644 index 85b52d72..00000000 --- a/keychain/trust/TrustedPeers/TPPeerDynamicInfo.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -#import "TPTypes.h" -#import "TPSigningKey.h" - -NS_ASSUME_NONNULL_BEGIN - -/*! - Having an instance of this class does *not* mean that - its signature has been checked. Checking the signature - is up to whoever consumes it. - - This class is a value type -- its members are immutable and - instances with identical contents are interchangeable. - */ -@interface TPPeerDynamicInfo : NSObject - -/*! - Can return nil with error if [trustSigningKey signatureForData:error:] errors. - */ -+ (nullable instancetype)dynamicInfoWithCircleID:(NSString *)circleID - clique:(NSString *)clique - removals:(TPCounter)removals - clock:(TPCounter)clock - trustSigningKey:(id)trustSigningKey - error:(NSError **)error; - -// Returns nil if data cannot be deserialized to a dictionary -// or that dictionary does not contain the expected keys and value types. -+ (nullable instancetype)dynamicInfoWithPListData:(NSData *)dynamicInfoPList - dynamicInfoSig:(NSData *)dynamicInfoSig; - -- (BOOL)isEqualToPeerDynamicInfo:(TPPeerDynamicInfo *)other; - -@property (nonatomic, readonly) NSString *circleID; -@property (nonatomic, readonly) NSString *clique; -@property (nonatomic, readonly) TPCounter removals; -@property (nonatomic, readonly) TPCounter clock; -@property (nonatomic, readonly) NSData *dynamicInfoPList; -@property (nonatomic, readonly) NSData *dynamicInfoSig; - -@end - -NS_ASSUME_NONNULL_END diff --git a/keychain/trust/TrustedPeers/TPPeerDynamicInfo.m b/keychain/trust/TrustedPeers/TPPeerDynamicInfo.m deleted file mode 100644 index 68399f35..00000000 --- a/keychain/trust/TrustedPeers/TPPeerDynamicInfo.m +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import "TPPeerDynamicInfo.h" -#import "TPUtils.h" - -static const NSString *kCircleID = @"circleID"; -static const NSString *kClique = @"clique"; -static const NSString *kRemovals = @"removals"; -static const NSString *kClock = @"clock"; - - -@interface TPPeerDynamicInfo () - -@property (nonatomic, strong) NSString *circleID; -@property (nonatomic, strong) NSString *clique; -@property (nonatomic, assign) TPCounter removals; -@property (nonatomic, assign) TPCounter clock; -@property (nonatomic, strong) NSData *dynamicInfoPList; -@property (nonatomic, strong) NSData *dynamicInfoSig; - -@end - - -@implementation TPPeerDynamicInfo - -+ (instancetype)dynamicInfoWithCircleID:(NSString *)circleID - clique:(NSString *)clique - removals:(TPCounter)removals - clock:(TPCounter)clock - trustSigningKey:(id)trustSigningKey - error:(NSError **)error -{ - NSDictionary *dict = @{ - kCircleID: circleID, - kClique: clique, - kRemovals: @(removals), - kClock: @(clock) - }; - NSData *data = [TPUtils serializedPListWithDictionary:dict]; - NSData *sig = [trustSigningKey signatureForData:data withError:error]; - if (nil == sig) { - return nil; - } - TPPeerDynamicInfo* info = [self dynamicInfoWithPListData:data dynamicInfoSig:sig]; - assert(info); - return info; -} - -+ (instancetype)dynamicInfoWithPListData:(NSData *)dynamicInfoPList - dynamicInfoSig:(NSData *)dynamicInfoSig -{ - id dict = [NSPropertyListSerialization propertyListWithData:dynamicInfoPList - options:NSPropertyListImmutable - format:nil - error:NULL]; - if (![dict isKindOfClass:[NSDictionary class]]) { - return nil; - } - - TPPeerDynamicInfo* info = [[TPPeerDynamicInfo alloc] init]; - - if (![dict[kCircleID] isKindOfClass:[NSString class]]) { - return nil; - } - info.circleID = dict[kCircleID]; - - if (![dict[kClique] isKindOfClass:[NSString class]]) { - return nil; - } - info.clique = dict[kClique]; - - if (![dict[kRemovals] isKindOfClass:[NSNumber class]]) { - return nil; - } - info.removals = [dict[kRemovals] unsignedLongLongValue]; - - if (![dict[kClock] isKindOfClass:[NSNumber class]]) { - return nil; - } - info.clock = [dict[kClock] unsignedLongLongValue]; - - info.dynamicInfoPList = [dynamicInfoPList copy]; - info.dynamicInfoSig = [dynamicInfoSig copy]; - - return info; -} - -- (BOOL)isEqualToPeerDynamicInfo:(TPPeerDynamicInfo *)other -{ - if (other == self) { - return YES; - } - return [self.dynamicInfoPList isEqualToData:other.dynamicInfoPList] - && [self.dynamicInfoSig isEqualToData:other.dynamicInfoSig]; -} - -#pragma mark - NSObject - -- (BOOL)isEqual:(id)object -{ - if (self == object) { - return YES; - } - if (![object isKindOfClass:[TPPeerDynamicInfo class]]) { - return NO; - } - return [self isEqualToPeerDynamicInfo:object]; -} - -@end diff --git a/keychain/trust/TrustedPeers/TPPeerPermanentInfo.h b/keychain/trust/TrustedPeers/TPPeerPermanentInfo.h deleted file mode 100644 index 3af2cc2c..00000000 --- a/keychain/trust/TrustedPeers/TPPeerPermanentInfo.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -#import "TPTypes.h" -#import "TPSigningKey.h" -#import "TPHash.h" - -NS_ASSUME_NONNULL_BEGIN - -/*! - This class is a value type -- its members are immutable and - instances with identical contents are interchangeable. - */ -@interface TPPeerPermanentInfo : NSObject - -/*! - Can return nil with error if [trustSigningKey signatureForData:error:] errors. - */ -+ (nullable instancetype)permanentInfoWithMachineID:(NSString *)machineID - modelID:(NSString *)modelID - epoch:(TPCounter)epoch - trustSigningKey:(id)trustSigningKey - peerIDHashAlgo:(TPHashAlgo)peerIDHashAlgo - error:(NSError **)error; - -// Returns nil if: -// - permanentInfoPList cannot be deserialized to a dictionary -// - that dictionary does not contain the expected keys and value types -// - permanentInfoSig does not match permanentInfoPList signed with the trustSigningKey from the dictionary -// - peerID does not match the hash of (permanentInfoPList + permanentInfoSig) -+ (nullable instancetype)permanentInfoWithPeerID:(NSString *)peerID - permanentInfoPList:(NSData *)permanentInfoPList - permanentInfoSig:(NSData *)permanentInfoSig - keyFactory:(id)keyFactory; - -@property (nonatomic, readonly) NSString* machineID; -@property (nonatomic, readonly) NSString* modelID; -@property (nonatomic, readonly) TPCounter epoch; -@property (nonatomic, readonly) id trustSigningKey; -@property (nonatomic, readonly) NSData *permanentInfoPList; -@property (nonatomic, readonly) NSData *permanentInfoSig; -@property (nonatomic, readonly) NSString *peerID; - -@end - -NS_ASSUME_NONNULL_END diff --git a/keychain/trust/TrustedPeers/TPPeerPermanentInfo.m b/keychain/trust/TrustedPeers/TPPeerPermanentInfo.m deleted file mode 100644 index 70672e28..00000000 --- a/keychain/trust/TrustedPeers/TPPeerPermanentInfo.m +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import "TPPeerPermanentInfo.h" -#import "TPUtils.h" - -static const NSString *kMachineID = @"machineID"; -static const NSString *kModelID = @"modelID"; -static const NSString *kEpoch = @"epoch"; -static const NSString *kTrustSigningKey = @"trustSigningKey"; - - -@interface TPPeerPermanentInfo () - -@property (nonatomic, strong) NSString* machineID; -@property (nonatomic, strong) NSString* modelID; -@property (nonatomic, assign) TPCounter epoch; -@property (nonatomic, strong) id trustSigningKey; -@property (nonatomic, strong) NSData *permanentInfoPList; -@property (nonatomic, strong) NSData *permanentInfoSig; -@property (nonatomic, strong) NSString *peerID; - -@end - - -@implementation TPPeerPermanentInfo - -+ (instancetype)permanentInfoWithMachineID:(NSString *)machineID - modelID:(NSString *)modelID - epoch:(TPCounter)epoch - trustSigningKey:(id)trustSigningKey - peerIDHashAlgo:(TPHashAlgo)peerIDHashAlgo - error:(NSError **)error -{ - TPPeerPermanentInfo* info = [[TPPeerPermanentInfo alloc] init]; - info.machineID = [machineID copy]; - info.modelID = [modelID copy]; - info.epoch = epoch; - info.trustSigningKey = trustSigningKey; - - NSDictionary *dict = @{ - kMachineID: machineID, - kModelID: modelID, - kEpoch: @(epoch), - kTrustSigningKey: [trustSigningKey publicKey] - }; - NSData *data = [TPUtils serializedPListWithDictionary:dict]; - NSData *sig = [trustSigningKey signatureForData:data withError:error]; - if (nil == sig) { - return nil; - } - info.permanentInfoPList = data; - info.permanentInfoSig = sig; - info.peerID = [TPPeerPermanentInfo peerIDForPermanentInfoPList:data - permanentInfoSig:sig - peerIDHashAlgo:peerIDHashAlgo]; - return info; -} - -+ (NSString *)peerIDForPermanentInfoPList:(NSData *)permanentInfoPList - permanentInfoSig:(NSData *)permanentInfoSig - peerIDHashAlgo:(TPHashAlgo)peerIDHashAlgo - -{ - TPHashBuilder *hasher = [[TPHashBuilder alloc] initWithAlgo:peerIDHashAlgo]; - [hasher updateWithData:permanentInfoPList]; - [hasher updateWithData:permanentInfoSig]; - return [hasher finalHash]; -} - -+ (instancetype)permanentInfoWithPeerID:(NSString *)peerID - permanentInfoPList:(NSData *)permanentInfoPList - permanentInfoSig:(NSData *)permanentInfoSig - keyFactory:(id)keyFactory -{ - id obj = [NSPropertyListSerialization propertyListWithData:permanentInfoPList - options:NSPropertyListImmutable - format:nil - error:NULL]; - if (![obj isKindOfClass:[NSDictionary class]]) { - return nil; - } - NSDictionary *dict = obj; - - TPPeerPermanentInfo *info = [[TPPeerPermanentInfo alloc] init]; - info.peerID = peerID; - info.permanentInfoPList = permanentInfoPList; - info.permanentInfoSig = permanentInfoSig; - - if (![dict[kMachineID] isKindOfClass:[NSString class]]) { - return nil; - } - info.machineID = dict[kMachineID]; - - if (![dict[kModelID] isKindOfClass:[NSString class]]) { - return nil; - } - info.modelID = dict[kModelID]; - - if (![dict[kEpoch] isKindOfClass:[NSNumber class]]) { - return nil; - } - info.epoch = [dict[kEpoch] unsignedLongLongValue]; - - if (![dict[kTrustSigningKey] isKindOfClass:[NSData class]]) { - return nil; - } - info.trustSigningKey = [keyFactory keyWithPublicKeyData:dict[kTrustSigningKey]]; - if (nil == info.trustSigningKey) { - return nil; - } - if (![info.trustSigningKey checkSignature:permanentInfoSig matchesData:permanentInfoPList]) { - return nil; - } - - // check peerID is hash of (permanentInfoPList + permanentInfoSig) - TPHashAlgo algo = [TPHashBuilder algoOfHash:peerID]; - if (algo == kTPHashAlgoUnknown) { - return nil; - } - NSString* checkHash = [TPPeerPermanentInfo peerIDForPermanentInfoPList:info.permanentInfoPList - permanentInfoSig:info.permanentInfoSig - peerIDHashAlgo:algo]; - if (![checkHash isEqualToString:peerID]) { - return nil; - } - - return info; -} - -@end diff --git a/keychain/trust/TrustedPeers/TPPeerStableInfo.h b/keychain/trust/TrustedPeers/TPPeerStableInfo.h deleted file mode 100644 index 4c15b304..00000000 --- a/keychain/trust/TrustedPeers/TPPeerStableInfo.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -#import "TPTypes.h" -#import "TPSigningKey.h" - -NS_ASSUME_NONNULL_BEGIN - -/*! - Having an instance of this class does *not* mean that - its signature has been checked. Checking the signature - is up to whoever consumes it. - - This class is a value type -- its members are immutable and - instances with identical contents are interchangeable. - */ -@interface TPPeerStableInfo : NSObject - -/*! - Can return nil with error if [trustSigningKey signatureForData:error:] errors. - */ -+ (nullable instancetype)stableInfoWithDict:(NSDictionary *)dict - clock:(TPCounter)clock - policyVersion:(TPCounter)policyVersion - policyHash:(NSString *)policyHash - policySecrets:(nullable NSDictionary *)policySecrets - trustSigningKey:(id)trustSigningKey - error:(NSError **)error; - -// Returns nil if data cannot be deserialized to a dictionary -+ (nullable instancetype)stableInfoWithPListData:(NSData *)stableInfoPList - stableInfoSig:(NSData *)stableInfoSig; - -- (BOOL)isEqualToPeerStableInfo:(TPPeerStableInfo *)other; - -@property (nonatomic, readonly) NSDictionary *dict; -@property (nonatomic, readonly) TPCounter clock; -@property (nonatomic, readonly) TPCounter policyVersion; -@property (nonatomic, readonly) NSString *policyHash; -@property (nonatomic, readonly) NSDictionary *policySecrets; -@property (nonatomic, readonly) NSData *stableInfoPList; -@property (nonatomic, readonly) NSData *stableInfoSig; - -@end - -NS_ASSUME_NONNULL_END diff --git a/keychain/trust/TrustedPeers/TPPeerStableInfo.m b/keychain/trust/TrustedPeers/TPPeerStableInfo.m deleted file mode 100644 index 9895f146..00000000 --- a/keychain/trust/TrustedPeers/TPPeerStableInfo.m +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import "TPPeerStableInfo.h" -#import "TPUtils.h" - -static const NSString *kClock = @"clock"; -static const NSString *kPolicyVersion = @"policyVersion"; -static const NSString *kPolicyHash = @"policyHash"; -static const NSString *kPolicySecrets = @"policySecrets"; - - -@interface TPPeerStableInfo () - -@property (nonatomic, strong) NSDictionary *dict; -@property (nonatomic, assign) TPCounter clock; -@property (nonatomic, assign) TPCounter policyVersion; -@property (nonatomic, strong) NSString *policyHash; -@property (nonatomic, strong) NSDictionary *policySecrets; -@property (nonatomic, strong) NSData *stableInfoPList; -@property (nonatomic, strong) NSData *stableInfoSig; - -@end - - -@implementation TPPeerStableInfo - -+ (instancetype)stableInfoWithDict:(NSDictionary *)dict - clock:(TPCounter)clock - policyVersion:(TPCounter)policyVersion - policyHash:(NSString *)policyHash - policySecrets:(NSDictionary *)policySecrets - trustSigningKey:(id)trustSigningKey - error:(NSError **)error -{ - NSMutableDictionary *mutDict = [NSMutableDictionary dictionaryWithDictionary:dict]; - mutDict[kClock] = @(clock); - mutDict[kPolicyVersion] = @(policyVersion); - mutDict[kPolicyHash] = policyHash; - mutDict[kPolicySecrets] = policySecrets; - - NSData *data = [TPUtils serializedPListWithDictionary:mutDict]; - NSData *sig = [trustSigningKey signatureForData:data withError:error]; - if (nil == sig) { - return nil; - } - TPPeerStableInfo *info = [self stableInfoWithPListData:data stableInfoSig:sig];; - assert(info); - return info; -} - -+ (instancetype)stableInfoWithPListData:(NSData *)stableInfoPList - stableInfoSig:(NSData *)stableInfoSig -{ - id dict = [NSPropertyListSerialization propertyListWithData:stableInfoPList - options:NSPropertyListImmutable - format:nil - error:NULL]; - if (![dict isKindOfClass:[NSDictionary class]]) { - return nil; - } - - TPPeerStableInfo* info = [[TPPeerStableInfo alloc] init]; - - if (![dict[kClock] isKindOfClass:[NSNumber class]]) { - return nil; - } - info.clock = [dict[kClock] unsignedLongLongValue]; - - if (![dict[kPolicyVersion] isKindOfClass:[NSNumber class]]) { - return nil; - } - info.policyVersion = [dict[kPolicyVersion] unsignedLongLongValue]; - - if (![dict[kPolicyHash] isKindOfClass:[NSString class]]) { - return nil; - } - info.policyHash = dict[kPolicyHash]; - - if ([dict[kPolicySecrets] isKindOfClass:[NSDictionary class]]) { - NSDictionary *secrets = dict[kPolicySecrets]; - for (id name in secrets) { - NSAssert([name isKindOfClass:[NSString class]], @"plist keys must be strings"); - if (![secrets[name] isKindOfClass:[NSData class]]) { - return nil; - } - } - info.policySecrets = secrets; - } else if (nil == dict[kPolicySecrets]) { - info.policySecrets = @{}; - } else { - return nil; - } - - info.dict = dict; - info.stableInfoPList = [stableInfoPList copy]; - info.stableInfoSig = [stableInfoSig copy]; - - return info; -} - -- (BOOL)isEqualToPeerStableInfo:(TPPeerStableInfo *)other -{ - if (other == self) { - return YES; - } - return [self.stableInfoPList isEqualToData:other.stableInfoPList] - && [self.stableInfoSig isEqualToData:other.stableInfoSig]; -} - -#pragma mark - NSObject - -- (BOOL)isEqual:(id)object -{ - if (self == object) { - return YES; - } - if (![object isKindOfClass:[TPPeerStableInfo class]]) { - return NO; - } - return [self isEqualToPeerStableInfo:object]; -} - -@end diff --git a/keychain/trust/TrustedPeers/TPPolicy.h b/keychain/trust/TrustedPeers/TPPolicy.h deleted file mode 100644 index 673cf478..00000000 --- a/keychain/trust/TrustedPeers/TPPolicy.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -NS_ASSUME_NONNULL_BEGIN - -@class TPCategoryRule; - -/*! - TPPolicy represents the ability to calculate Octagon Policy, as per - https://confluence.sd.apple.com/display/KEY/Octagon+Policy - - Instances of this class are typically obtained from TPPolicyDocument, - by passing a (possibly empty) dictionary of secrets to - policyWithSecrets:decrypter:error:. -*/ -@protocol TPPolicy - -- (nullable NSString *)categoryForModel:(NSString *)model; -- (BOOL)trustedPeerInCategory:(NSString *)trustedCategory canIntroduceCategory:(NSString *)candidateCategory; -- (BOOL)peerInCategory:(NSString *)category canAccessView:(NSString *)view; - -@end - - -@interface TPPolicy : NSObject - -+ (instancetype)policyWithModelToCategory:(NSArray *)modelToCategory - categoriesByView:(NSDictionary*> *)categoriesByView - introducersByCategory:(NSDictionary*> *)introducersByCategory; - -@end - -NS_ASSUME_NONNULL_END diff --git a/keychain/trust/TrustedPeers/TPPolicy.m b/keychain/trust/TrustedPeers/TPPolicy.m deleted file mode 100644 index 72b67648..00000000 --- a/keychain/trust/TrustedPeers/TPPolicy.m +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import "TPPolicy.h" -#import "TPCategoryRule.h" - - -@interface TPPolicy () - -@property (nonatomic, strong) NSArray *modelToCategory; -@property (nonatomic, strong) NSDictionary*> *categoriesByView; -@property (nonatomic, strong) NSDictionary*> *introducersByCategory; - -@end - - -@implementation TPPolicy - -+ (instancetype)policyWithModelToCategory:(NSArray *)modelToCategory - categoriesByView:(NSDictionary*> *)categoriesByView - introducersByCategory:(NSDictionary*> *)introducersByCategory -{ - TPPolicy *policy = [[TPPolicy alloc] init]; - policy.modelToCategory = [modelToCategory copy]; - policy.categoriesByView = [categoriesByView copy]; - policy.introducersByCategory = [introducersByCategory copy]; - return policy; -} - -- (nullable NSString *)categoryForModel:(NSString *)model -{ - for (TPCategoryRule *rule in self.modelToCategory) { - if ([model hasPrefix:rule.prefix]) { - return rule.category; - } - } - return nil; -} - -- (BOOL)trustedPeerInCategory:(NSString *)trustedCategory canIntroduceCategory:(NSString *)candidateCategory -{ - return [self.introducersByCategory[candidateCategory] containsObject:trustedCategory]; -} - -- (BOOL)peerInCategory:(NSString *)category canAccessView:(NSString *)view -{ - return [self.categoriesByView[view] containsObject:category]; -} - -@end diff --git a/keychain/trust/TrustedPeers/TPPolicyDocument.h b/keychain/trust/TrustedPeers/TPPolicyDocument.h deleted file mode 100644 index aa9359ba..00000000 --- a/keychain/trust/TrustedPeers/TPPolicyDocument.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -#import "TPPolicy.h" -#import "TPEncrypter.h" -#import "TPDecrypter.h" -#import "TPHash.h" -#import "TPTypes.h" - -NS_ASSUME_NONNULL_BEGIN - -/*! - This class is a value type -- its members are immutable and - instances with identical contents are interchangeable. - */ -@interface TPPolicyDocument : NSObject - -@property (nonatomic, readonly) TPCounter policyVersion; -@property (nonatomic, readonly) NSString *policyHash; -@property (nonatomic, readonly) NSData *pList; - -+ (nullable instancetype)policyDocWithHash:(NSString *)policyHash - pList:(NSData *)pList; - -+ (instancetype)policyDocWithVersion:(TPCounter)policyVersion - modelToCategory:(NSArray *)modelToCategory - categoriesByView:(NSDictionary*> *)categoriesByView - introducersByCategory:(NSDictionary*> *)introducersByCategory - redactions:(NSDictionary *)redactions - hashAlgo:(TPHashAlgo)hashAlgo; - -+ (nullable NSData *)redactionWithEncrypter:(id)encrypter - modelToCategory:(nullable NSArray *)modelToCategory - categoriesByView:(nullable NSDictionary*> *)categoriesByView - introducersByCategory:(nullable NSDictionary*> *)introducersByCategory - error:(NSError **)error; - -- (nullable id)policyWithSecrets:(NSDictionary *)secrets - decrypter:(id)decrypter - error:(NSError **)error; - -- (BOOL)isEqualToPolicyDocument:(TPPolicyDocument *)other; - -@end - -NS_ASSUME_NONNULL_END diff --git a/keychain/trust/TrustedPeers/TPPolicyDocument.m b/keychain/trust/TrustedPeers/TPPolicyDocument.m deleted file mode 100644 index a1c72c8e..00000000 --- a/keychain/trust/TrustedPeers/TPPolicyDocument.m +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import "TPPolicyDocument.h" -#import "TPPolicy.h" -#import "TPUtils.h" -#import "TPCategoryRule.h" - -static const NSString *kPolicyVersion = @"policyVersion"; -static const NSString *kModelToCategory = @"modelToCategory"; -static const NSString *kCategoriesByView = @"categoriesByView"; -static const NSString *kIntroducersByCategory = @"introducersByCategory"; -static const NSString *kRedactions = @"redactions"; -static const NSString *kPrefix = @"prefix"; -static const NSString *kCategory = @"category"; - -@interface TPPolicyDocument () - -@property (nonatomic, assign) TPCounter policyVersion; -@property (nonatomic, strong) NSString *policyHash; -@property (nonatomic, strong) NSData *pList; - -@property (nonatomic, strong) NSArray *modelToCategory; -@property (nonatomic, strong) NSDictionary*> *categoriesByView; -@property (nonatomic, strong) NSDictionary*> *introducersByCategory; -@property (nonatomic, strong) NSDictionary *redactions; - -@end - - -@implementation TPPolicyDocument - -+ (nullable NSArray *)modelToCategoryFromObj:(id)obj -{ - if (![obj isKindOfClass:[NSArray class]]) { - return nil; - } - NSArray *arr = obj; - NSMutableArray *rules = [[NSMutableArray alloc] initWithCapacity:arr.count]; - for (id item in arr) { - TPCategoryRule *rule = [self categoryRuleFromObj:item]; - if (nil == rule) { - return nil; - } - [rules addObject:rule]; - } - return rules; -} - -+ (nullable TPCategoryRule *)categoryRuleFromObj:(id)obj -{ - if (![obj isKindOfClass:[NSDictionary class]]) { - return nil; - } - NSDictionary *dict = obj; - if (![dict[kPrefix] isKindOfClass:[NSString class]]) { - return nil; - } - if (![dict[kCategory] isKindOfClass:[NSString class]]) { - return nil; - } - return [TPCategoryRule ruleWithPrefix:dict[kPrefix] category:dict[kCategory]]; -} - -// Used for parsing categoriesByView and introducersByCategory -// which both have the same structure. -+ (nullable NSDictionary*> *)dictionaryOfSetsFromObj:(id)obj -{ - if (![obj isKindOfClass:[NSDictionary class]]) { - return nil; - } - NSDictionary *dict = obj; - NSMutableDictionary*> *result = [NSMutableDictionary dictionary]; - for (id key in dict) { - if (![key isKindOfClass:[NSString class]]) { - return nil; - } - id value = dict[key]; - if (![value isKindOfClass:[NSArray class]]) { - return nil; - } - NSArray *arr = value; - for (id item in arr) { - if (![item isKindOfClass:[NSString class]]) { - return nil; - } - } - result[key] = [NSSet setWithArray:arr]; - } - return result; -} - -+ (nullable NSDictionary *)redactionsFromObj:(id)obj -{ - if (![obj isKindOfClass:[NSDictionary class]]) { - return nil; - } - NSDictionary *dict = obj; - for (id key in dict) { - if (![key isKindOfClass:[NSString class]]) { - return nil; - } - id value = dict[key]; - if (![value isKindOfClass:[NSData class]]) { - return nil; - } - } - return dict; -} - -+ (nullable instancetype)policyDocWithHash:(NSString *)policyHash - pList:(NSData *)pList -{ - TPHashAlgo algo = [TPHashBuilder algoOfHash:policyHash]; - NSString *hash = [TPHashBuilder hashWithAlgo:algo ofData:pList]; - if (![policyHash isEqualToString:hash]) { - return nil; - } - TPPolicyDocument *doc = [[TPPolicyDocument alloc] init]; - doc.policyHash = hash; - doc.pList = pList; - - id obj = [NSPropertyListSerialization propertyListWithData:pList - options:NSPropertyListImmutable - format:nil - error:NULL]; - if (![obj isKindOfClass:[NSDictionary class]]) { - return nil; - } - NSDictionary *dict = obj; - - if (![dict[kPolicyVersion] isKindOfClass:[NSNumber class]]) { - return nil; - } - doc.policyVersion = [dict[kPolicyVersion] unsignedLongLongValue]; - - doc.modelToCategory = [self modelToCategoryFromObj:dict[kModelToCategory]]; - if (nil == doc.modelToCategory) { - return nil; - } - doc.categoriesByView = [self dictionaryOfSetsFromObj:dict[kCategoriesByView]]; - if (nil == doc.categoriesByView) { - return nil; - } - doc.introducersByCategory = [self dictionaryOfSetsFromObj:dict[kIntroducersByCategory]]; - if (nil == doc.introducersByCategory) { - return nil; - } - doc.redactions = [self redactionsFromObj:dict[kRedactions]]; - if (nil == doc.redactions) { - return nil; - } - return doc; -} - -+ (instancetype)policyDocWithVersion:(TPCounter)policyVersion - modelToCategory:(NSArray *)modelToCategory - categoriesByView:(NSDictionary*> *)categoriesByView - introducersByCategory:(NSDictionary*> *)introducersByCategory - redactions:(NSDictionary *)redactions - hashAlgo:(TPHashAlgo)hashAlgo -{ - TPPolicyDocument *doc = [[TPPolicyDocument alloc] init]; - - doc.policyVersion = policyVersion; - - doc.modelToCategory = [TPPolicyDocument modelToCategoryFromObj:modelToCategory]; - NSAssert(doc.modelToCategory, @"malformed modelToCategory"); - - doc.categoriesByView = [TPPolicyDocument dictionaryOfSetsFromObj:categoriesByView]; - NSAssert(doc.categoriesByView, @"malformed categoriesByView"); - - doc.introducersByCategory = [TPPolicyDocument dictionaryOfSetsFromObj:introducersByCategory]; - NSAssert(doc.introducersByCategory, @"malformed introducersByCategory"); - - doc.redactions = [redactions copy]; - - NSDictionary *dict = @{ - kPolicyVersion: @(policyVersion), - kModelToCategory: modelToCategory, - kCategoriesByView: categoriesByView, - kIntroducersByCategory: introducersByCategory, - kRedactions: redactions - }; - doc.pList = [TPUtils serializedPListWithDictionary:dict]; - doc.policyHash = [TPHashBuilder hashWithAlgo:hashAlgo ofData:doc.pList]; - - return doc; -} - -+ (nullable NSData *)redactionWithEncrypter:(id)encrypter - modelToCategory:(nullable NSArray *)modelToCategory - categoriesByView:(nullable NSDictionary*> *)categoriesByView - introducersByCategory:(nullable NSDictionary*> *)introducersByCategory - error:(NSError **)error -{ - NSMutableDictionary *dict = [NSMutableDictionary dictionary]; - if (nil != modelToCategory) { - dict[kModelToCategory] = modelToCategory; - } - if (nil != categoriesByView) { - dict[kCategoriesByView] = categoriesByView; - } - if (nil != introducersByCategory) { - dict[kIntroducersByCategory] = introducersByCategory; - } - NSData *plist = [TPUtils serializedPListWithDictionary:dict]; - return [encrypter encryptData:plist error:error]; -} - -- (id)policyWithSecrets:(NSDictionary *)secrets - decrypter:(id)decrypter - error:(NSError **)error -{ - NSArray *modelToCategory = self.modelToCategory; - NSMutableDictionary*> *categoriesByView - = [NSMutableDictionary dictionaryWithDictionary:self.categoriesByView]; - NSMutableDictionary*> *introducersByCategory - = [NSMutableDictionary dictionaryWithDictionary:self.introducersByCategory]; - - // We are going to prepend extra items to modelToCategory. - // To make the resulting array order deterministic we sort secrets by name first. - NSArray *names = [secrets.allKeys sortedArrayUsingSelector:@selector(compare:)]; - for (NSString *name in names) { - NSData *key = secrets[name]; - NSData *ciphertext = self.redactions[name]; - if (nil == ciphertext) { - // This is normal. A new version might have no need to redact - // info that was revealed by keys for a previous version. - continue; - } - NSData *plist = [decrypter decryptData:ciphertext withKey:key error:error]; - if (nil == plist) { - return nil; - } - id obj = [NSPropertyListSerialization propertyListWithData:plist - options:NSPropertyListImmutable - format:nil - error:NULL]; - if (![obj isKindOfClass:[NSDictionary class]]) { - return nil; - } - NSDictionary *dict = obj; - - NSArray *extraModelToCategory; - extraModelToCategory = [TPPolicyDocument modelToCategoryFromObj:dict[kModelToCategory]]; - if (nil != extraModelToCategory) { - // Extra rules are prepended to the list so that they are considered first. - modelToCategory = [extraModelToCategory arrayByAddingObjectsFromArray:modelToCategory]; - } - - NSDictionary*> *extraCategoriesByView; - extraCategoriesByView = [TPPolicyDocument dictionaryOfSetsFromObj:dict[kCategoriesByView]]; - if (nil != extraCategoriesByView) { - [self mergeExtras:extraCategoriesByView intoDictionary:categoriesByView]; - } - - NSDictionary*> *extraIntroducersByCategory; - extraIntroducersByCategory = [TPPolicyDocument dictionaryOfSetsFromObj:dict[kIntroducersByCategory]]; - if (nil != extraIntroducersByCategory) { - [self mergeExtras:extraIntroducersByCategory intoDictionary:introducersByCategory]; - } - } - - return [TPPolicy policyWithModelToCategory:modelToCategory - categoriesByView:categoriesByView - introducersByCategory:introducersByCategory]; -} - -- (void)mergeExtras:(NSDictionary*> *)extras - intoDictionary:(NSMutableDictionary*> *)target -{ - for (NSString *name in extras) { - NSSet* extraSet = extras[name]; - if (target[name] == nil) { - target[name] = extraSet; - } else { - target[name] = [target[name] setByAddingObjectsFromSet:extraSet]; - } - } -} - -- (BOOL)isEqualToPolicyDocument:(TPPolicyDocument *)other -{ - if (other == self) { - return YES; - } - return self.policyVersion == other.policyVersion - && [self.policyHash isEqualToString:other.policyHash] - && [self.pList isEqualToData:other.pList] - && [self.modelToCategory isEqualToArray:other.modelToCategory] - && [self.categoriesByView isEqualToDictionary:other.categoriesByView] - && [self.introducersByCategory isEqualToDictionary:other.introducersByCategory] - && [self.redactions isEqualToDictionary:other.redactions]; -} - -#pragma mark - NSObject - -- (BOOL)isEqual:(id)object -{ - if (self == object) { - return YES; - } - if (![object isKindOfClass:[TPPolicyDocument class]]) { - return NO; - } - return [self isEqualToPolicyDocument:object]; -} - -- (NSUInteger)hash -{ - return [self.policyHash hash]; -} - -@end diff --git a/keychain/trust/TrustedPeers/TPSigningKey.h b/keychain/trust/TrustedPeers/TPSigningKey.h deleted file mode 100644 index a45159e8..00000000 --- a/keychain/trust/TrustedPeers/TPSigningKey.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -NS_ASSUME_NONNULL_BEGIN - -/*! - A protocol for signing blobs and checking signatures. - */ -@protocol TPSigningKey -- (NSData *)publicKey; -- (BOOL)checkSignature:(NSData *)sig matchesData:(NSData *)data; - -/*! - This method uses the private key to create a signature. - It will return nil with an error if the private key is not available, - e.g. due to the device being locked. - */ -- (nullable NSData *)signatureForData:(NSData *)data withError:(NSError **)error; -@end - - -/*! - A protocol for factories that construct TPSigningKey objects. - */ -@protocol TPSigningKeyFactory -// Return nil if data is malformed -- (nullable id )keyWithPublicKeyData:(NSData *)publicKey; -@end - -NS_ASSUME_NONNULL_END diff --git a/keychain/trust/TrustedPeers/TPTypes.h b/keychain/trust/TrustedPeers/TPTypes.h deleted file mode 100644 index 14893c59..00000000 --- a/keychain/trust/TrustedPeers/TPTypes.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -typedef unsigned long long TPCounter; - -typedef NS_ENUM(NSInteger, TPResult) { - TPResultOk, - TPResultSignatureMismatch, - TPResultClockViolation, -}; diff --git a/keychain/trust/TrustedPeers/TPUtils.h b/keychain/trust/TrustedPeers/TPUtils.h deleted file mode 100644 index b33ae4c1..00000000 --- a/keychain/trust/TrustedPeers/TPUtils.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface TPUtils : NSObject - -+ (NSData *)serializedPListWithDictionary:(NSDictionary *)dict; - -@end - -NS_ASSUME_NONNULL_END diff --git a/keychain/trust/TrustedPeers/TPUtils.m b/keychain/trust/TrustedPeers/TPUtils.m deleted file mode 100644 index 063a88bb..00000000 --- a/keychain/trust/TrustedPeers/TPUtils.m +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import "TPUtils.h" - -@implementation TPUtils - -+ (NSData *)serializedPListWithDictionary:(NSDictionary *)dict -{ - NSError *error = nil; - NSData *data = [NSPropertyListSerialization dataWithPropertyList:dict - format:NSPropertyListXMLFormat_v1_0 - options:0 - error:&error]; - if (nil == data) { - @throw [NSException exceptionWithName:@"Failed to serialize" - reason:[error description] - userInfo:nil]; - } - return data; -} - -@end diff --git a/keychain/trust/TrustedPeers/TPVoucher.h b/keychain/trust/TrustedPeers/TPVoucher.h deleted file mode 100644 index 05acb427..00000000 --- a/keychain/trust/TrustedPeers/TPVoucher.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -#import "TPSigningKey.h" -#import "TPTypes.h" - -NS_ASSUME_NONNULL_BEGIN - -/*! - A voucher is a record signed by a "sponsor" peer to say that - a "beneficiary" peer is trusted. - - The signature is not checked when an TPVoucher instance is - constructed, because the sponsor's signing key might not be - available at that time. - - This class is a value type -- its members are immutable and - instances with identical contents are interchangeable. - It overrides isEqual and hash, so that two instances with - identical contents will compare as equal. - */ -@interface TPVoucher : NSObject - -/*! - Can return nil with error if [trustSigningKey signatureForData:error:] errors. - */ -+ (nullable instancetype)voucherWithBeneficiaryID:(NSString *)beneficiaryID - sponsorID:(NSString *)sponsorID - clock:(TPCounter)clock - trustSigningKey:(id)trustSigningKey - error:(NSError **)error; - -// Returns nil if data cannot be deserialized to a dictionary -// or that dictionary does not contain the expected keys and value types. -// This method performs no signature checking; that should be done later, -// when the sponsor's trustSigningKey is available. -+ (nullable instancetype)voucherWithPList:(NSData *)voucherInfoPList - sig:(NSData *)voucherInfoSig; - -- (BOOL)isEqualToVoucher:(TPVoucher *)other; - -@property (nonatomic, readonly) NSString *beneficiaryID; -@property (nonatomic, readonly) NSString *sponsorID; -@property (nonatomic, readonly) TPCounter clock; -@property (nonatomic, readonly) NSData *voucherInfoPList; -@property (nonatomic, readonly) NSData *voucherInfoSig; - -@end - -NS_ASSUME_NONNULL_END diff --git a/keychain/trust/TrustedPeers/TPVoucher.m b/keychain/trust/TrustedPeers/TPVoucher.m deleted file mode 100644 index fe45a7d6..00000000 --- a/keychain/trust/TrustedPeers/TPVoucher.m +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import "TPVoucher.h" -#import "TPUtils.h" - -static const NSString *kBeneficiaryID = @"beneficiaryID"; -static const NSString *kSponsorID = @"sponsorID"; -static const NSString *kClock = @"clock"; - - -@interface TPVoucher () -@property (nonatomic, strong) NSString *beneficiaryID; -@property (nonatomic, strong) NSString *sponsorID; -@property (nonatomic, assign) TPCounter clock; -@property (nonatomic, strong) NSData *voucherInfoPList; -@property (nonatomic, strong) NSData *voucherInfoSig; -@end - - -@implementation TPVoucher - -+ (instancetype)voucherWithBeneficiaryID:(NSString *)beneficiaryID - sponsorID:(NSString *)sponsorID - clock:(TPCounter)clock - trustSigningKey:(id)trustSigningKey - error:(NSError **)error -{ - NSDictionary *dict = @{ - kBeneficiaryID: beneficiaryID, - kSponsorID: sponsorID, - kClock: @(clock) - }; - NSData *data = [TPUtils serializedPListWithDictionary:dict]; - NSData *sig = [trustSigningKey signatureForData:data withError:error]; - if (nil == sig) { - return nil; - } - - TPVoucher *voucher = [[TPVoucher alloc] init]; - voucher.beneficiaryID = [beneficiaryID copy]; - voucher.sponsorID = [sponsorID copy]; - voucher.clock = clock; - voucher.voucherInfoPList = data; - voucher.voucherInfoSig = sig; - return voucher; -} - -+ (instancetype)voucherWithPList:(NSData *)voucherInfoPList - sig:(NSData *)voucherInfoSig -{ - TPVoucher *voucher = [[TPVoucher alloc] init]; - voucher.voucherInfoPList = [voucherInfoPList copy]; - voucher.voucherInfoSig = [voucherInfoSig copy]; - - id dict = [NSPropertyListSerialization propertyListWithData:voucherInfoPList - options:NSPropertyListImmutable - format:nil - error:NULL]; - if (![dict isKindOfClass:[NSDictionary class]]) { - return nil; - } - - if (![dict[kBeneficiaryID] isKindOfClass:[NSString class]]) { - return nil; - } - voucher.beneficiaryID = dict[kBeneficiaryID]; - - if (![dict[kSponsorID] isKindOfClass:[NSString class]]) { - return nil; - } - voucher.sponsorID = dict[kSponsorID]; - - if (![dict[kClock] isKindOfClass:[NSNumber class]]) { - return nil; - } - voucher.clock = [dict[kClock] unsignedLongLongValue]; - - return voucher; -} - -- (BOOL)isEqualToVoucher:(TPVoucher *)other -{ - if (other == self) { - return YES; - } - return [self.voucherInfoPList isEqualToData:other.voucherInfoPList] - && [self.voucherInfoSig isEqualToData:other.voucherInfoSig]; -} - -#pragma mark - NSObject - -- (BOOL)isEqual:(id)object -{ - if (self == object) { - return YES; - } - if (![object isKindOfClass:[TPVoucher class]]) { - return NO; - } - return [self isEqualToVoucher:object]; -} - -- (NSUInteger)hash -{ - return [self.voucherInfoPList hash]; -} - -@end diff --git a/keychain/trust/TrustedPeers/TrustedPeers.h b/keychain/trust/TrustedPeers/TrustedPeers.h deleted file mode 100644 index 0d85290f..00000000 --- a/keychain/trust/TrustedPeers/TrustedPeers.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -//! Project version number for TrustedPeers. -FOUNDATION_EXPORT double TrustedPeersVersionNumber; - -//! Project version string for TrustedPeers. -FOUNDATION_EXPORT const unsigned char TrustedPeersVersionString[]; - -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import diff --git a/keychain/trust/TrustedPeersTests/Info.plist b/keychain/trust/TrustedPeersTests/Info.plist deleted file mode 100644 index 6c6c23c4..00000000 --- a/keychain/trust/TrustedPeersTests/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/keychain/trust/TrustedPeersTests/TPCircleTests.m b/keychain/trust/TrustedPeersTests/TPCircleTests.m deleted file mode 100644 index 4af9e0fd..00000000 --- a/keychain/trust/TrustedPeersTests/TPCircleTests.m +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import -#import - -@interface TPCircleTests : XCTestCase - -@end - -@implementation TPCircleTests - -- (void)testCircleIDChecks { - NSArray *included = @[@"A", @"B"]; - NSArray *excluded = @[@"C", @"D"]; - TPCircle *circle1 = [TPCircle circleWithIncludedPeerIDs:included excludedPeerIDs:excluded]; - TPCircle *circle2 = [TPCircle circleWithID:circle1.circleID includedPeerIDs:included excludedPeerIDs:excluded]; - XCTAssertEqual([circle1 hash], [circle2 hash]); - XCTAssertEqualObjects(circle1, circle2); - XCTAssert([circle1 isEqual:circle1]); - XCTAssertEqualObjects(circle1, circle2); - XCTAssertNotEqualObjects(circle1, @"foo"); - - // (Feel free to change the format of the description output, this is just for test coverage.) - XCTAssertEqualObjects([circle1 description], @"{ in: [A B] ex: [C D] }"); - - // Misuse circle1.circleID here, trying to construct a different circle with nil excludedPeerIDs: - TPCircle *circle3 = [TPCircle circleWithID:circle1.circleID includedPeerIDs:included excludedPeerIDs:nil]; - XCTAssertNil(circle3); -} - -@end diff --git a/keychain/trust/TrustedPeersTests/TPDummyDecrypter.h b/keychain/trust/TrustedPeersTests/TPDummyDecrypter.h deleted file mode 100644 index 790568ba..00000000 --- a/keychain/trust/TrustedPeersTests/TPDummyDecrypter.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface TPDummyDecrypter : NSObject - -+ (instancetype)dummyDecrypter; - -@end - -NS_ASSUME_NONNULL_END diff --git a/keychain/trust/TrustedPeersTests/TPDummyDecrypter.m b/keychain/trust/TrustedPeersTests/TPDummyDecrypter.m deleted file mode 100644 index f7df1949..00000000 --- a/keychain/trust/TrustedPeersTests/TPDummyDecrypter.m +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import "TPDummyDecrypter.h" - -@implementation TPDummyDecrypter - -+ (instancetype)dummyDecrypter -{ - return [[TPDummyDecrypter alloc] init]; -} - -- (nullable NSData *)decryptData:(NSData *)ciphertext - withKey:(NSData *)key - error:(NSError **)error -{ - // Repeating-key XOR - NSMutableData *plaintext = [NSMutableData dataWithLength:ciphertext.length]; - uint8_t *plainbytes = plaintext.mutableBytes; - const uint8_t *cipherbytes = ciphertext.bytes; - const uint8_t *keybytes = key.bytes; - NSUInteger keylen = key.length; - for (NSUInteger i = 0; i < ciphertext.length; i++) { - plainbytes[i] = cipherbytes[i] ^ keybytes[i % keylen]; - } - return plaintext; -} - -@end diff --git a/keychain/trust/TrustedPeersTests/TPDummyEncrypter.h b/keychain/trust/TrustedPeersTests/TPDummyEncrypter.h deleted file mode 100644 index a7d415cc..00000000 --- a/keychain/trust/TrustedPeersTests/TPDummyEncrypter.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -#import - -NS_ASSUME_NONNULL_BEGIN - -/*! - Weakly "encrypts" data to be decrypted with TPDummyDecrypter. - */ -@interface TPDummyEncrypter : NSObject - -+ (instancetype)dummyEncrypterWithKey:(NSData *)key; - -@end - -NS_ASSUME_NONNULL_END diff --git a/keychain/trust/TrustedPeersTests/TPDummyEncrypter.m b/keychain/trust/TrustedPeersTests/TPDummyEncrypter.m deleted file mode 100644 index 4a8fbb35..00000000 --- a/keychain/trust/TrustedPeersTests/TPDummyEncrypter.m +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import "TPDummyEncrypter.h" -#import "TPDummyDecrypter.h" - -@interface TPDummyEncrypter () -@property (nonatomic, strong) NSData *decryptionKey; -@end - -@implementation TPDummyEncrypter - -+ (instancetype)dummyEncrypterWithKey:(NSData *)key -{ - TPDummyEncrypter *enc = [[TPDummyEncrypter alloc] init]; - enc.decryptionKey = key; - return enc; -} - -- (nullable NSData *)encryptData:(NSData *)plaintext error:(NSError **)error -{ - // It's just XOR with rotating key, so "encryption" == "decryption" - return [[TPDummyDecrypter dummyDecrypter] decryptData:plaintext - withKey:self.decryptionKey - error:error]; -} - -@end diff --git a/keychain/trust/TrustedPeersTests/TPDummySigningKey.h b/keychain/trust/TrustedPeersTests/TPDummySigningKey.h deleted file mode 100644 index f6b4211f..00000000 --- a/keychain/trust/TrustedPeersTests/TPDummySigningKey.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -#import - -NS_ASSUME_NONNULL_BEGIN - -/*! - A dummy implementation of TPSigning for testing. - - It uses a very weak hash algorithm and no crypto, just enough for unit tests. - */ -@interface TPDummySigningKey : NSObject - -/*! - Setting this to NO causes signatureForData to return nil with an error. - */ -@property (nonatomic, assign) BOOL privateKeyIsAvailable; - -- (instancetype)initWithPublicKeyData:(NSData *)publicKey; - -@end - - -/*! - A factory that constructs TPDummySigningKey objects. - */ -@interface TPDummySigningKeyFactory : NSObject -+ (instancetype) dummySigningKeyFactory; -@end - -NS_ASSUME_NONNULL_END diff --git a/keychain/trust/TrustedPeersTests/TPDummySigningKey.m b/keychain/trust/TrustedPeersTests/TPDummySigningKey.m deleted file mode 100644 index 9c613ad9..00000000 --- a/keychain/trust/TrustedPeersTests/TPDummySigningKey.m +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import "TPDummySigningKey.h" - -@interface TPDummySigningKey () -@property (nonatomic, strong) NSData *publicKey; -@end - - -@implementation TPDummySigningKey - -- (instancetype)initWithPublicKeyData:(NSData *)publicKey -{ - self = [super init]; - if (self) { - _publicKey = publicKey; - _privateKeyIsAvailable = YES; - } - return self; -} - -- (NSData *)signatureForData:(NSData *)data withError:(NSError **)error -{ - if (self.privateKeyIsAvailable) { - return [self signatureForData:data]; - } else { - if (error) { - *error = [NSError errorWithDomain:@"TPDummySigningKey" code:1 userInfo:nil]; - } - return nil; - } -} - -- (NSData *)signatureForData:(NSData *)data -{ - // A really dumb hash that is just good enough for unit tests. - NSUInteger hash = [self.publicKey hash] ^ [data hash]; - return [NSData dataWithBytes:&hash length:sizeof(hash)]; -} - -- (BOOL)checkSignature:(NSData *)sig matchesData:(NSData *)data -{ - return [sig isEqualToData:[self signatureForData:data]]; -} - -@end - - -@implementation TPDummySigningKeyFactory - -- (id )keyWithPublicKeyData:(NSData *)publicKey -{ - if (0 == publicKey.length) { - return nil; - } - return [[TPDummySigningKey alloc] initWithPublicKeyData:publicKey]; -} - -+ (instancetype) dummySigningKeyFactory -{ - return [[TPDummySigningKeyFactory alloc] init]; -} - -@end diff --git a/keychain/trust/TrustedPeersTests/TPDummySigningKeyTests.m b/keychain/trust/TrustedPeersTests/TPDummySigningKeyTests.m deleted file mode 100644 index c67057ba..00000000 --- a/keychain/trust/TrustedPeersTests/TPDummySigningKeyTests.m +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import - -#import "TPDummySigningKey.h" - -@interface TPDummySigningKeyTests : XCTestCase - -@end - -@implementation TPDummySigningKeyTests - -- (void)testRoundTrip { - NSData *keyData = [@"The Key" dataUsingEncoding:NSUTF8StringEncoding]; - id key = [[TPDummySigningKey alloc] initWithPublicKeyData:keyData]; - NSData *data = [@"The Text" dataUsingEncoding:NSUTF8StringEncoding]; - NSData *sig = [key signatureForData:data withError:NULL]; - BOOL ok = [key checkSignature:sig matchesData:data]; - XCTAssert(ok); -} - -@end diff --git a/keychain/trust/TrustedPeersTests/TPHashTests.m b/keychain/trust/TrustedPeersTests/TPHashTests.m deleted file mode 100644 index 6599ca52..00000000 --- a/keychain/trust/TrustedPeersTests/TPHashTests.m +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import -#import - -@interface TPHashTests : XCTestCase - -@property (nonatomic, strong) NSData *hello; - -@end - -@implementation TPHashTests - -- (void)setUp -{ - self.hello = [@"hello" dataUsingEncoding:NSUTF8StringEncoding]; -} - -- (void)testSHA224 -{ - NSString *hash = [TPHashBuilder hashWithAlgo:kTPHashAlgoSHA224 ofData:self.hello]; - XCTAssertEqualObjects(hash, @"SHA224:6gmunMZ2jFD87pA+0FRVblv8g0eQfxJZiqJBkw=="); - TPHashAlgo algo = [TPHashBuilder algoOfHash:hash]; - XCTAssertEqual(kTPHashAlgoSHA224, algo); -} - -- (void)testSHA256 -{ - NSString *hash = [TPHashBuilder hashWithAlgo:kTPHashAlgoSHA256 ofData:self.hello]; - XCTAssertEqualObjects(hash, @"SHA256:LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ="); - TPHashAlgo algo = [TPHashBuilder algoOfHash:hash]; - XCTAssertEqual(kTPHashAlgoSHA256, algo); -} - -- (void)testSHA384 -{ - NSString *hash = [TPHashBuilder hashWithAlgo:kTPHashAlgoSHA384 ofData:self.hello]; - XCTAssertEqualObjects(hash, @"SHA384:WeF0h3dEjGnea4ANejO7+5/xtGPkQ1TDVTvNucZm+pASWjx5+QOXvfX2oT3oKGhP"); - TPHashAlgo algo = [TPHashBuilder algoOfHash:hash]; - XCTAssertEqual(kTPHashAlgoSHA384, algo); -} - -- (void)testSHA512 -{ - NSString *hash = [TPHashBuilder hashWithAlgo:kTPHashAlgoSHA512 ofData:self.hello]; - XCTAssertEqualObjects(hash, @"SHA512:m3HSJL1i83hdltRq0+o9czGb+8KJDKra4t/3JRlnPKcjI8PZm6XBHXx6zG4UuMXaDEZjR1wuXDre9G9zvN7AQw=="); - TPHashAlgo algo = [TPHashBuilder algoOfHash:hash]; - XCTAssertEqual(kTPHashAlgoSHA512, algo); -} - -- (void)testBadAlgo -{ - XCTAssertEqual(kTPHashAlgoUnknown, [TPHashBuilder algoOfHash:@""]); - XCTAssertEqual(kTPHashAlgoUnknown, [TPHashBuilder algoOfHash:@"foo"]); - XCTAssertEqual(kTPHashAlgoUnknown, [TPHashBuilder algoOfHash:@"foo:"]); - XCTAssertEqual(kTPHashAlgoUnknown, [TPHashBuilder algoOfHash:@":"]); - XCTAssertEqual(kTPHashAlgoUnknown, [TPHashBuilder algoOfHash:@"foo:bar"]); - XCTAssertEqual(kTPHashAlgoUnknown, [TPHashBuilder algoOfHash:@"SHA256"]); - - XCTAssertThrows([TPHashBuilder hashWithAlgo:kTPHashAlgoUnknown ofData:self.hello]); -} - -- (void)testBadReuse -{ - TPHashBuilder *builder = [[TPHashBuilder alloc] initWithAlgo:kTPHashAlgoSHA256]; - [builder finalHash]; - XCTAssertThrows([builder updateWithData:self.hello]); - XCTAssertThrows([builder finalHash]); -} - -@end diff --git a/keychain/trust/TrustedPeersTests/TPModelTests.m b/keychain/trust/TrustedPeersTests/TPModelTests.m deleted file mode 100644 index 655c45a4..00000000 --- a/keychain/trust/TrustedPeersTests/TPModelTests.m +++ /dev/null @@ -1,831 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import -#import -#import "TPDummySigningKey.h" -#import "TPDummyDecrypter.h" -#import "TPDummyEncrypter.h" - -@interface TPModelTests : XCTestCase - -@property (nonatomic, strong) TPModel *model; -@property (nonatomic, strong) TPPolicyDocument *policyDocV1; -@property (nonatomic, strong) TPPolicyDocument *policyDocV2; -@property (nonatomic, strong) NSString *secretName; -@property (nonatomic, strong) NSData *secretKey; - -@end - -@implementation TPModelTests - -- (TPModel *)makeModel -{ - id decrypter = [TPDummyDecrypter dummyDecrypter]; - TPModel *model = [[TPModel alloc] initWithDecrypter:decrypter]; - [model registerPolicyDocument:self.policyDocV1]; - [model registerPolicyDocument:self.policyDocV2]; - return model; -} - -- (void)setUp -{ - self.secretName = @"foo"; - TPDummyEncrypter *encrypter = [TPDummyEncrypter dummyEncrypterWithKey:[@"sekritkey" dataUsingEncoding:NSUTF8StringEncoding]]; - self.secretKey = encrypter.decryptionKey; - NSData *redaction = [TPPolicyDocument redactionWithEncrypter:encrypter - modelToCategory:@[ @{ @"prefix": @"iCycle", @"category": @"full" } ] - categoriesByView:nil - introducersByCategory:nil - error:NULL]; - - self.policyDocV1 - = [TPPolicyDocument policyDocWithVersion:1 - modelToCategory:@[ - @{ @"prefix": @"iPhone", @"category": @"full" }, - @{ @"prefix": @"iPad", @"category": @"full" }, - @{ @"prefix": @"Mac", @"category": @"full" }, - @{ @"prefix": @"iMac", @"category": @"full" }, - @{ @"prefix": @"AppleTV", @"category": @"tv" }, - @{ @"prefix": @"Watch", @"category": @"watch" }, - ] - categoriesByView:@{ - @"WiFi": @[ @"full", @"tv", @"watch" ], - @"SafariCreditCards": @[ @"full" ], - @"PCSEscrow": @[ @"full" ] - } - introducersByCategory:@{ - @"full": @[ @"full" ], - @"tv": @[ @"full", @"tv" ], - @"watch": @[ @"full", @"watch" ] - } - redactions:@{ - self.secretName: redaction - } - hashAlgo:kTPHashAlgoSHA256]; - - self.policyDocV2 - = [TPPolicyDocument policyDocWithVersion:2 - modelToCategory:@[ - @{ @"prefix": @"iCycle", @"category": @"full" }, // new - @{ @"prefix": @"iPhone", @"category": @"full" }, - @{ @"prefix": @"iPad", @"category": @"full" }, - @{ @"prefix": @"Mac", @"category": @"full" }, - @{ @"prefix": @"iMac", @"category": @"full" }, - @{ @"prefix": @"AppleTV", @"category": @"tv" }, - @{ @"prefix": @"Watch", @"category": @"watch" }, - ] - categoriesByView:@{ - @"WiFi": @[ @"full", @"tv", @"watch" ], - @"SafariCreditCards": @[ @"full" ], - @"PCSEscrow": @[ @"full" ] - } - introducersByCategory:@{ - @"full": @[ @"full" ], - @"tv": @[ @"full", @"tv" ], - @"watch": @[ @"full", @"watch" ] - } - redactions:@{} - hashAlgo:kTPHashAlgoSHA256]; - - self.model = [self makeModel]; -} - -- (TPPeerPermanentInfo *)makePeerWithMachineID:(NSString *)machineID -{ - return [self makePeerWithMachineID:machineID modelID:@"iPhone" epoch:1 key:machineID]; -} - -- (TPPeerPermanentInfo *)makePeerWithMachineID:(NSString *)machineID - modelID:(NSString *)modelID - epoch:(TPCounter)epoch - key:(NSString *)key -{ - NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding]; - id trustSigningKey = [[TPDummySigningKey alloc] initWithPublicKeyData:keyData]; - TPPeerPermanentInfo *permanentInfo - = [TPPeerPermanentInfo permanentInfoWithMachineID:machineID - modelID:modelID - epoch:epoch - trustSigningKey:trustSigningKey - peerIDHashAlgo:kTPHashAlgoSHA256 - error:NULL]; - [self.model registerPeerWithPermanentInfo:permanentInfo]; - - TPPeerStableInfo *stableInfo = [self.model createStableInfoWithDictionary:@{} - policyVersion:self.policyDocV1.policyVersion - policyHash:self.policyDocV1.policyHash - policySecrets:nil - forPeerWithID:permanentInfo.peerID - error:NULL]; - [self.model updateStableInfo:stableInfo forPeerWithID:permanentInfo.peerID]; - return permanentInfo; -} - -static BOOL circleEquals(TPCircle *circle, NSArray *includedPeerIDs, NSArray *excludedPeerIDs) -{ - return [circle isEqualToCircle:[TPCircle circleWithIncludedPeerIDs:includedPeerIDs excludedPeerIDs:excludedPeerIDs]]; -} - -- (void)testModelBasics -{ - NSString *A = [self makePeerWithMachineID:@"aaa"].peerID; - NSString *B = [self makePeerWithMachineID:@"bbb"].peerID; - NSString *C = [self makePeerWithMachineID:@"ccc"].peerID; - - TPCircle *circle; - - // A trusts B, establishes clique - circle = [self.model advancePeerWithID:A addingPeerIDs:@[B] removingPeerIDs:@[] createClique:^NSString *{ - return @"clique1"; - }]; - XCTAssert(circleEquals(circle, @[A, B], @[])); - - // B trusts A - circle = [self.model advancePeerWithID:B addingPeerIDs:@[A] removingPeerIDs:@[] createClique:nil]; - XCTAssert(circleEquals(circle, @[A, B], @[])); - - // A trusts C - circle = [self.model advancePeerWithID:A addingPeerIDs:@[C] removingPeerIDs:@[] createClique:nil]; - XCTAssert(circleEquals(circle, @[A, B, C], @[])); - - // C trusts A - circle = [self.model advancePeerWithID:C addingPeerIDs:@[A] removingPeerIDs:@[] createClique:nil]; - XCTAssert(circleEquals(circle, @[A, B, C], @[])); - - // Updating B (B should now trust C) - circle = [self.model advancePeerWithID:B addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[A, B, C], @[])); - - // Updating B again (should be no change) - circle = [self.model advancePeerWithID:B addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[A, B, C], @[])); - - // A decides to exclude B - circle = [self.model advancePeerWithID:A addingPeerIDs:nil removingPeerIDs:@[B] createClique:nil]; - XCTAssert(circleEquals(circle, @[A, C], @[B])); - - // Updating C (C should now exclude B) - circle = [self.model advancePeerWithID:C addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[A, C], @[B])); - - // Updating B (B should now exclude itself and include nobody) - circle = [self.model advancePeerWithID:B addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[], @[B])); - - // Updating B again (should be no change) - circle = [self.model advancePeerWithID:B addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[], @[B])); - - // C decides to exclude itself - circle = [self.model advancePeerWithID:C addingPeerIDs:nil removingPeerIDs:@[C] createClique:nil]; - XCTAssert(circleEquals(circle, @[], @[C])); - - // Updating C (should be no change) - circle = [self.model advancePeerWithID:C addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[], @[C])); - - // Updating A (A should now exclude C) - circle = [self.model advancePeerWithID:A addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[A], @[B, C])); -} - -- (void)testPeerReplacement -{ - NSString *A = [self makePeerWithMachineID:@"aaa"].peerID; - NSString *B = [self makePeerWithMachineID:@"bbb"].peerID; - NSString *C = [self makePeerWithMachineID:@"ccc"].peerID; - - TPCircle *circle; - - // A trusts B, establishes clique. A is in a drawer. - circle = [self.model advancePeerWithID:A addingPeerIDs:@[B] removingPeerIDs:@[] createClique:^NSString *{ - return @"clique1"; - }]; - XCTAssert(circleEquals(circle, @[A, B], @[])); - - // B trusts A - circle = [self.model advancePeerWithID:B addingPeerIDs:@[A] removingPeerIDs:@[] createClique:nil]; - XCTAssert(circleEquals(circle, @[A, B], @[])); - - // B decides to replace itself with C. - circle = [self.model advancePeerWithID:B addingPeerIDs:@[C] removingPeerIDs:@[B] createClique:nil]; - XCTAssert(circleEquals(circle, @[C], @[B])); - - // B should be able to update itself without forgetting it trusts C. - circle = [self.model advancePeerWithID:B addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[C], @[B])); - - // When A wakes up, it should trust C instead of B. - circle = [self.model advancePeerWithID:A addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[A, C], @[B])); -} - -- (void)testVoucher -{ - TPPeerPermanentInfo *aaa = [self makePeerWithMachineID:@"aaa"]; - TPPeerPermanentInfo *bbb = [self makePeerWithMachineID:@"bbb"]; - TPPeerPermanentInfo *ccc = [self makePeerWithMachineID:@"ccc"]; - - NSString *A = aaa.peerID; - NSString *B = bbb.peerID; - NSString *C = ccc.peerID; - - TPCircle *circle; - - // A establishes clique. - circle = [self.model advancePeerWithID:A addingPeerIDs:nil removingPeerIDs:nil createClique:^NSString *{ - return @"clique1"; - }]; - XCTAssert(circleEquals(circle, @[A], @[])); - - // B trusts A - circle = [self.model advancePeerWithID:B addingPeerIDs:@[A] removingPeerIDs:@[] createClique:nil]; - XCTAssert(circleEquals(circle, @[A, B], @[])); - - // C trusts A - circle = [self.model advancePeerWithID:C addingPeerIDs:@[A] removingPeerIDs:@[] createClique:nil]; - XCTAssert(circleEquals(circle, @[A, C], @[])); - - // B gets a voucher from A - TPVoucher *voucher = [self.model createVoucherForCandidate:bbb withSponsorID:A error:NULL]; - XCTAssertNotNil(voucher); - XCTAssertEqual(TPResultOk, [self.model registerVoucher:voucher]); - - // Updating C, it sees the voucher and now trusts B - circle = [self.model advancePeerWithID:C addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[A, B, C], @[])); - - // Updating A, it sees the voucher (sponsored by A itself) and now trusts B. - // (A updating its dynamicInfo also expires the voucher.) - circle = [self.model advancePeerWithID:A addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[A, B], @[])); -} - -- (void)testExpiredVoucher -{ - TPPeerPermanentInfo *aaa = [self makePeerWithMachineID:@"aaa"]; - TPPeerPermanentInfo *bbb = [self makePeerWithMachineID:@"bbb"]; - TPPeerPermanentInfo *ccc = [self makePeerWithMachineID:@"ccc"]; - TPPeerPermanentInfo *ddd = [self makePeerWithMachineID:@"ddd"]; - - NSString *A = aaa.peerID; - NSString *B = bbb.peerID; - NSString *C = ccc.peerID; - NSString *D = ddd.peerID; - - TPCircle *circle; - - // A establishes clique. - circle = [self.model advancePeerWithID:A addingPeerIDs:nil removingPeerIDs:nil createClique:^NSString *{ - return @"clique1"; - }]; - XCTAssert(circleEquals(circle, @[A], @[])); - - // B trusts A - circle = [self.model advancePeerWithID:B addingPeerIDs:@[A] removingPeerIDs:@[] createClique:nil]; - XCTAssert(circleEquals(circle, @[A, B], @[])); - - // C trusts A - circle = [self.model advancePeerWithID:C addingPeerIDs:@[A] removingPeerIDs:@[] createClique:nil]; - XCTAssert(circleEquals(circle, @[A, C], @[])); - - // B gets a voucher from A (but doesn't register the voucher yet because A would notice it) - TPVoucher *voucher = [self.model createVoucherForCandidate:bbb withSponsorID:A error:NULL]; - - // A advances its clock by deciding to trust D - circle = [self.model advancePeerWithID:A addingPeerIDs:@[D] removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[A, D], @[])); - - // Register the voucher, which is now expired because A has advanced its clock - [self.model registerVoucher:voucher]; - - // Updating C, it ignores the expired voucher for B - circle = [self.model advancePeerWithID:C addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[A, C, D], @[])); -} - -- (void)testVoucherWithBadSignature -{ - TPPeerPermanentInfo *aaa = [self makePeerWithMachineID:@"aaa"]; - TPPeerPermanentInfo *bbb = [self makePeerWithMachineID:@"bbb"]; - - NSString *A = aaa.peerID; - NSString *B = bbb.peerID; - - TPCircle *circle; - - // A establishes clique. - circle = [self.model advancePeerWithID:A addingPeerIDs:nil removingPeerIDs:nil createClique:^NSString *{ - return @"clique1"; - }]; - XCTAssert(circleEquals(circle, @[A], @[])); - - // B trusts A - circle = [self.model advancePeerWithID:B addingPeerIDs:@[A] removingPeerIDs:@[] createClique:nil]; - XCTAssert(circleEquals(circle, @[A, B], @[])); - - // B gets a voucher from A, but signed by B's key - TPVoucher *voucher = [TPVoucher voucherWithBeneficiaryID:B - sponsorID:A - clock:[self.model getDynamicInfoForPeerWithID:A].clock - trustSigningKey:bbb.trustSigningKey - error:NULL]; - XCTAssertNotNil(voucher); - XCTAssertEqual(TPResultSignatureMismatch, [self.model registerVoucher:voucher]); -} - -- (void)testVoucherPolicy -{ - TPPeerPermanentInfo *aaa = [self makePeerWithMachineID:@"aaa" modelID:@"watch" epoch:1 key:@"aaa"]; - TPPeerPermanentInfo *bbb = [self makePeerWithMachineID:@"bbb"]; - - NSString *A = aaa.peerID; - - // B is a phone trying to get a voucher from A which is a watch - TPVoucher *voucher = [self.model createVoucherForCandidate:bbb withSponsorID:A error:NULL]; - XCTAssertNil(voucher); -} - -- (void)testDynamicInfoReplay -{ - NSString *A = [self makePeerWithMachineID:@"aaa"].peerID; - NSString *B = [self makePeerWithMachineID:@"bbb"].peerID; - - TPCircle *circle; - - // A establishes clique, trusts B. - circle = [self.model advancePeerWithID:A addingPeerIDs:@[B] removingPeerIDs:nil createClique:^NSString *{ - return @"clique1"; - }]; - XCTAssert(circleEquals(circle, @[A, B], @[])); - - // Attacker snapshots A's dynamicInfo - TPPeerDynamicInfo *dyn = [self.model getDynamicInfoForPeerWithID:A]; - - // A excludes B - circle = [self.model advancePeerWithID:A addingPeerIDs:nil removingPeerIDs:@[B] createClique:nil]; - XCTAssert(circleEquals(circle, @[A], @[B])); - - // Attacker replays the old snapshot - XCTAssertEqual(TPResultClockViolation, [self.model updateDynamicInfo:dyn forPeerWithID:A]); - - circle = [self.model getCircleForPeerWithID:A]; - XCTAssert(circleEquals(circle, @[A], @[B])); -} - -- (void)testPhoneApprovingWatch -{ - NSString *phoneA = [self makePeerWithMachineID:@"phoneA" modelID:@"iPhone7,1" epoch:1 key:@"phoneA"].peerID; - NSString *watch = [self makePeerWithMachineID:@"watch" modelID:@"Watch1,1" epoch:1 key:@"watch"].peerID; - - TPCircle *circle; - - // phoneA establishes clique, trusts watch. - circle = [self.model advancePeerWithID:phoneA addingPeerIDs:@[watch] removingPeerIDs:nil createClique:^NSString *{ - return @"clique1"; - }]; - XCTAssert(circleEquals(circle, @[phoneA, watch], @[])); -} - -- (void)testWatchApprovingPhone -{ - NSString *phoneA = [self makePeerWithMachineID:@"phoneA" modelID:@"iPhone7,1" epoch:1 key:@"phoneA"].peerID; - NSString *phoneB = [self makePeerWithMachineID:@"phoneB" modelID:@"iPhone7,1" epoch:1 key:@"phoneB"].peerID; - NSString *watch = [self makePeerWithMachineID:@"watch" modelID:@"Watch1,1" epoch:1 key:@"watch"].peerID; - - TPCircle *circle; - - // phoneA establishes clique, trusts watch. - circle = [self.model advancePeerWithID:phoneA addingPeerIDs:@[watch] removingPeerIDs:nil createClique:^NSString *{ - return @"clique1"; - }]; - XCTAssert(circleEquals(circle, @[phoneA, watch], @[])); - - // watch trusts phoneA and phoneB - circle = [self.model advancePeerWithID:watch addingPeerIDs:@[phoneA, phoneB] removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[phoneA, phoneB, watch], @[])); - - // phoneA updates, and it should ignore phoneB, so no change. - circle = [self.model advancePeerWithID:phoneA addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[phoneA, watch], @[])); -} - -- (void)testNilCreateClique -{ - NSString *A = [self makePeerWithMachineID:@"aaa"].peerID; - - TPCircle *circle; - - // Try to establish dynamicInfo without providing createClique - circle = [self.model advancePeerWithID:A addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssertNil(circle); -} - -- (void)testCliqueConvergence -{ - NSString *A = [self makePeerWithMachineID:@"aaa"].peerID; - NSString *B = [self makePeerWithMachineID:@"bbb"].peerID; - - TPCircle *circle; - - // A establishes clique1 - circle = [self.model advancePeerWithID:A addingPeerIDs:@[] removingPeerIDs:@[] createClique:^NSString *{ - return @"clique1"; - }]; - XCTAssert(circleEquals(circle, @[A], @[])); - XCTAssert([[self.model getDynamicInfoForPeerWithID:A].clique isEqualToString:@"clique1"]); - - // B establishes clique2 - circle = [self.model advancePeerWithID:B addingPeerIDs:@[] removingPeerIDs:@[] createClique:^NSString *{ - return @"clique2"; - }]; - XCTAssert(circleEquals(circle, @[B], @[])); - XCTAssert([[self.model getDynamicInfoForPeerWithID:B].clique isEqualToString:@"clique2"]); - - // A trusts B. A should now switch to clique2, which is later than clique1 in lexical order. - circle = [self.model advancePeerWithID:A addingPeerIDs:@[B] removingPeerIDs:@[] createClique:nil]; - XCTAssert(circleEquals(circle, @[A, B], @[])); - XCTAssert([[self.model getDynamicInfoForPeerWithID:A].clique isEqualToString:@"clique2"]); -} - -- (void)testRemovalCounts -{ - NSString *A = [self makePeerWithMachineID:@"aaa"].peerID; - NSString *B = [self makePeerWithMachineID:@"bbb"].peerID; - NSString *C = [self makePeerWithMachineID:@"ccc"].peerID; - - // A establishes clique with B and C - [self.model advancePeerWithID:A addingPeerIDs:@[B, C] removingPeerIDs:@[] createClique:^NSString *{ - return @"clique1"; - }]; - XCTAssertEqual(0ULL, [self.model getDynamicInfoForPeerWithID:A].removals); - - // B trusts A - [self.model advancePeerWithID:B addingPeerIDs:@[A] removingPeerIDs:@[] createClique:nil]; - XCTAssertEqual(0ULL, [self.model getDynamicInfoForPeerWithID:B].removals); - - // A removes C - [self.model advancePeerWithID:A addingPeerIDs:nil removingPeerIDs:@[C] createClique:nil]; - XCTAssertEqual(1ULL, [self.model getDynamicInfoForPeerWithID:A].removals); - - // B updates, and now shows 1 removal - [self.model advancePeerWithID:B addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssertEqual(1ULL, [self.model getDynamicInfoForPeerWithID:B].removals); -} - -- (void)testCommunicatingModels -{ - TPPeerPermanentInfo *aaa = [self makePeerWithMachineID:@"aaa"]; - TPPeerPermanentInfo *bbb = [self makePeerWithMachineID:@"bbb"]; - TPPeerPermanentInfo *ccc = [self makePeerWithMachineID:@"ccc"]; - - NSString *A = aaa.peerID; - NSString *B = bbb.peerID; - NSString *C = ccc.peerID; - - // A lives on self.model, where it trusts B and C - [self.model advancePeerWithID:A addingPeerIDs:@[B, C] removingPeerIDs:nil createClique:^NSString *{ - return @"clique1"; - }]; - - // B lives on model2, where it trusts A - TPModel *model2 = [self makeModel]; - [model2 registerPeerWithPermanentInfo:aaa]; - [model2 registerPeerWithPermanentInfo:bbb]; - [model2 updateStableInfo:[self.model getStableInfoForPeerWithID:A] forPeerWithID:A]; - [model2 updateStableInfo:[self.model getStableInfoForPeerWithID:B] forPeerWithID:B]; - [model2 advancePeerWithID:B addingPeerIDs:@[A] removingPeerIDs:nil createClique:^NSString *{ - return @"clique1"; - }]; - - // A's circle and dynamicInfo are transmitted from model to model2 - TPCircle *circle = [self.model getCircleForPeerWithID:A]; - TPPeerDynamicInfo *dyn = [self.model getDynamicInfoForPeerWithID:A]; - [model2 updateDynamicInfo:dyn forPeerWithID:A]; - [model2 registerCircle:circle]; - - // B updates in model2, but C is not yet registered so is ignored. - circle = [model2 advancePeerWithID:B addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[A, B], @[])); - - // Now C registers in model2 - [model2 registerPeerWithPermanentInfo:ccc]; - - // B updates in model2, and now it trusts C. - circle = [model2 advancePeerWithID:B addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[A, B, C], @[])); -} - -- (void)testCommunicatingModelsWithVouchers -{ - TPPeerPermanentInfo *aaa = [self makePeerWithMachineID:@"aaa"]; - TPPeerPermanentInfo *bbb = [self makePeerWithMachineID:@"bbb"]; - TPPeerPermanentInfo *ccc = [self makePeerWithMachineID:@"ccc"]; - - NSString *A = aaa.peerID; - NSString *B = bbb.peerID; - NSString *C = ccc.peerID; - - // A lives on self.model, where it trusts B - [self.model advancePeerWithID:A addingPeerIDs:@[B] removingPeerIDs:nil createClique:^NSString *{ - return @"clique1"; - }]; - - // B lives on model2, where it trusts A - TPModel *model2 = [self makeModel]; - [model2 registerPeerWithPermanentInfo:aaa]; - [model2 registerPeerWithPermanentInfo:bbb]; - [model2 updateStableInfo:[self.model getStableInfoForPeerWithID:A] forPeerWithID:A]; - [model2 updateStableInfo:[self.model getStableInfoForPeerWithID:B] forPeerWithID:B]; - [model2 advancePeerWithID:B addingPeerIDs:@[A] removingPeerIDs:nil createClique:^NSString *{ - return @"clique1"; - }]; - - // A's circle and dynamicInfo are transmitted from model to model2 - TPCircle *circle = [self.model getCircleForPeerWithID:A]; - TPPeerDynamicInfo *dyn = [self.model getDynamicInfoForPeerWithID:A]; - [model2 updateDynamicInfo:dyn forPeerWithID:A]; - [model2 registerCircle:circle]; - - // A writes a voucher for C, and it is transmitted to model2 - TPVoucher *voucher = [self.model createVoucherForCandidate:ccc withSponsorID:A error:NULL]; - [model2 registerVoucher:voucher]; - - // B updates in model2, but C is not yet registered so is ignored. - circle = [model2 advancePeerWithID:B addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[A, B], @[])); - - // Now C registers in model2 - [model2 registerPeerWithPermanentInfo:ccc]; - [model2 updateStableInfo:[self.model getStableInfoForPeerWithID:C] forPeerWithID:C]; - - // B updates in model2, and now it trusts C. - circle = [model2 advancePeerWithID:B addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[A, B, C], @[])); -} - -- (void)testReregisterPeer -{ - TPPeerPermanentInfo *aaa = [self makePeerWithMachineID:@"aaa"]; - - NSString *A = aaa.peerID; - - [self.model advancePeerWithID:A addingPeerIDs:nil removingPeerIDs:nil createClique:^NSString *{ - return @"clique1"; - }]; - - // Registering the peer again should not overwrite its dynamicInfo or other state. - [self.model registerPeerWithPermanentInfo:aaa]; - XCTAssertNotNil([self.model getDynamicInfoForPeerWithID:A]); -} - -- (void)testPeerAccessors -{ - TPPeerPermanentInfo *aaa = [self makePeerWithMachineID:@"aaa"]; - - NSString *A = aaa.peerID; - - XCTAssert([self.model hasPeerWithID:A]); - - TPPeerPermanentInfo *aaa2 = [self.model getPermanentInfoForPeerWithID:A]; - XCTAssertEqualObjects(aaa, aaa2); - - TPPeerStableInfo *info = [self.model createStableInfoWithDictionary:@{ @"hello": @"world" } - policyVersion:1 - policyHash:@"" - policySecrets:nil - forPeerWithID:A - error:NULL]; - XCTAssertEqual(TPResultOk, [self.model updateStableInfo:info forPeerWithID:A]); - - XCTAssertEqualObjects([self.model getStableInfoForPeerWithID:A], info); - - [self.model deletePeerWithID:A]; - XCTAssertFalse([self.model hasPeerWithID:A]); -} - -- (void)testCircleAccessors -{ - TPCircle *circle = [TPCircle circleWithIncludedPeerIDs:@[@"A, B"] excludedPeerIDs:nil]; - XCTAssertNil([self.model circleWithID:circle.circleID]); - [self.model registerCircle:circle]; - XCTAssertNotNil([self.model circleWithID:circle.circleID]); - [self.model deleteCircleWithID:circle.circleID]; - XCTAssertNil([self.model circleWithID:circle.circleID]); -} - -- (void)testLatestEpoch -{ - NSString *A = [self makePeerWithMachineID:@"aaa" modelID:@"iPhone" epoch:0 key:@"aaa"].peerID; - NSString *B = [self makePeerWithMachineID:@"bbb" modelID:@"iPhone" epoch:1 key:@"aaa"].peerID; - NSString *C = [self makePeerWithMachineID:@"ccc" modelID:@"iPhone" epoch:2 key:@"aaa"].peerID; - - TPCounter epoch = [self.model latestEpochAmongPeerIDs:[NSSet setWithArray:@[A, B, C]]]; - XCTAssertEqual(epoch, 2ULL); -} - -- (void)testPeerStatus -{ - NSString *A = [self makePeerWithMachineID:@"aaa" modelID:@"iPhone" epoch:0 key:@"aaa"].peerID; - NSString *B = [self makePeerWithMachineID:@"bbb" modelID:@"iPhone" epoch:0 key:@"bbb"].peerID; - NSString *C = [self makePeerWithMachineID:@"ccc" modelID:@"iPhone" epoch:0 key:@"ccc"].peerID; - NSString *D = [self makePeerWithMachineID:@"ddd" modelID:@"iPhone" epoch:1 key:@"ddd"].peerID; - NSString *E = [self makePeerWithMachineID:@"eee" modelID:@"iPhone" epoch:2 key:@"eee"].peerID; - - XCTAssertEqual([self.model statusOfPeerWithID:A], 0); - - [self.model advancePeerWithID:A addingPeerIDs:@[B, C] removingPeerIDs:@[] createClique:^NSString *{ - return @"clique1"; - }]; - XCTAssertEqual([self.model statusOfPeerWithID:A], 0); - - [self.model advancePeerWithID:B addingPeerIDs:@[A, C] removingPeerIDs:@[] createClique:nil]; - XCTAssertEqual([self.model statusOfPeerWithID:A], TPPeerStatusPartiallyReciprocated); - - [self.model advancePeerWithID:C addingPeerIDs:@[A] removingPeerIDs:@[] createClique:nil]; - XCTAssertEqual([self.model statusOfPeerWithID:A], TPPeerStatusPartiallyReciprocated | TPPeerStatusFullyReciprocated); - - [self.model advancePeerWithID:C addingPeerIDs:@[] removingPeerIDs:@[A] createClique:nil]; - XCTAssertEqual([self.model statusOfPeerWithID:A], TPPeerStatusPartiallyReciprocated | TPPeerStatusExcluded); - - [self.model advancePeerWithID:A addingPeerIDs:@[] removingPeerIDs:@[] createClique:nil]; - XCTAssertEqual([self.model statusOfPeerWithID:A], TPPeerStatusExcluded); - - [self.model advancePeerWithID:B addingPeerIDs:@[D] removingPeerIDs:@[] createClique:nil]; - XCTAssertEqual([self.model statusOfPeerWithID:B], TPPeerStatusPartiallyReciprocated | TPPeerStatusOutdatedEpoch); - - [self.model advancePeerWithID:C addingPeerIDs:@[E] removingPeerIDs:@[] createClique:nil]; - [self.model advancePeerWithID:B addingPeerIDs:@[] removingPeerIDs:@[] createClique:nil]; - XCTAssertEqual([self.model statusOfPeerWithID:B], TPPeerStatusPartiallyReciprocated | TPPeerStatusOutdatedEpoch | TPPeerStatusAncientEpoch); -} - -- (void)testCalculateUnusedCircleIDs -{ - NSString *A = [self makePeerWithMachineID:@"aaa" modelID:@"iPhone" epoch:0 key:@"aaa"].peerID; - NSString *B = [self makePeerWithMachineID:@"bbb" modelID:@"iPhone" epoch:0 key:@"bbb"].peerID; - - [self.model advancePeerWithID:A addingPeerIDs:@[B] removingPeerIDs:@[] createClique:^NSString *{ - return @"clique1"; - }]; - [self.model advancePeerWithID:B addingPeerIDs:@[B] removingPeerIDs:@[] createClique:nil]; - - NSSet* unused; - unused = [self.model calculateUnusedCircleIDs]; - XCTAssertEqualObjects(unused, [NSSet set]); - - NSString *circleID = [self.model getCircleForPeerWithID:A].circleID; - - [self.model advancePeerWithID:A addingPeerIDs:@[] removingPeerIDs:@[B] createClique:nil]; - - unused = [self.model calculateUnusedCircleIDs]; - XCTAssertEqualObjects(unused, [NSSet setWithObject:circleID]); -} - -- (void)testGetPeerIDsTrustedByPeerWithID -{ - NSString *A = [self makePeerWithMachineID:@"aaa" modelID:@"iPhone7,1" epoch:0 key:@"aaa"].peerID; - NSString *B = [self makePeerWithMachineID:@"bbb" modelID:@"iPhone6,2" epoch:0 key:@"bbb"].peerID; - NSString *C = [self makePeerWithMachineID:@"ccc" modelID:@"Watch1,1" epoch:0 key:@"ccc"].peerID; - [self makePeerWithMachineID:@"ddd" modelID:@"iPhone7,1" epoch:0 key:@"ddd"]; - - [self.model advancePeerWithID:A addingPeerIDs:@[B, C] removingPeerIDs:@[] createClique:^NSString *{ - return @"clique1"; - }]; - - // Everyone can access WiFi. Only full peers can access SafariCreditCards - - NSSet* peerIDs; - NSSet* expected; - - peerIDs = [self.model getPeerIDsTrustedByPeerWithID:A toAccessView:@"WiFi" error:NULL]; - expected = [NSSet setWithArray:@[A, B, C]]; - XCTAssertEqualObjects(peerIDs, expected); - - peerIDs = [self.model getPeerIDsTrustedByPeerWithID:A toAccessView:@"SafariCreditCards" error:NULL]; - expected = [NSSet setWithArray:@[A, B]]; - XCTAssertEqualObjects(peerIDs, expected); -} - -- (void)testVectorClock -{ - NSString *A = [self makePeerWithMachineID:@"aaa"].peerID; - NSString *B = [self makePeerWithMachineID:@"bbb"].peerID; - NSString *C = [self makePeerWithMachineID:@"ccc"].peerID; - - [self.model advancePeerWithID:A addingPeerIDs:@[B] removingPeerIDs:@[] createClique:^NSString *{ - return @"clique1"; - }]; - [self.model advancePeerWithID:B addingPeerIDs:@[A] removingPeerIDs:@[] createClique:nil]; - - NSDictionary *dict; - NSDictionary *expected; - - dict = [self.model vectorClock]; - expected = @{ A: @4, B: @5, C: @3 }; - XCTAssertEqualObjects(dict, expected); - - [self.model advancePeerWithID:C addingPeerIDs:@[A] removingPeerIDs:@[B] createClique:nil]; - [self.model advancePeerWithID:A addingPeerIDs:@[] removingPeerIDs:@[] createClique:nil]; - [self.model advancePeerWithID:B addingPeerIDs:@[] removingPeerIDs:@[] createClique:nil]; - - dict = [self.model vectorClock]; - expected = @{ A: @7, B: @8, C: @6 }; - XCTAssertEqualObjects(dict, expected); -} - -- (void)testICycleApprovingPhoneWithNewPolicy -{ - NSString *phoneA = [self makePeerWithMachineID:@"phoneA" modelID:@"iPhone7,1" epoch:1 key:@"phoneA"].peerID; - NSString *phoneB = [self makePeerWithMachineID:@"phoneB" modelID:@"iPhone7,1" epoch:1 key:@"phoneB"].peerID; - NSString *icycle = [self makePeerWithMachineID:@"icycle" modelID:@"iCycle1,1" epoch:1 key:@"icycle"].peerID; - - TPCircle *circle; - - // phoneA establishes clique, trusts icycle - circle = [self.model advancePeerWithID:phoneA addingPeerIDs:@[icycle] removingPeerIDs:nil createClique:^NSString *{ - return @"clique1"; - }]; - XCTAssert(circleEquals(circle, @[phoneA, icycle], @[])); - - // icycle trusts phoneA and phoneB - circle = [self.model advancePeerWithID:icycle addingPeerIDs:@[phoneA, phoneB] removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[phoneA, phoneB, icycle], @[])); - - // phoneA updates, and it doesn't know iCycles can approve phones, so it should ignore phoneB, so no change. - circle = [self.model advancePeerWithID:phoneA addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[phoneA, icycle], @[])); - - // icycle presents a new policy that says iCycles can approve phones - TPPeerStableInfo *stableInfo = [self.model createStableInfoWithDictionary:@{} - policyVersion:self.policyDocV2.policyVersion - policyHash:self.policyDocV2.policyHash - policySecrets:nil - forPeerWithID:icycle - error:NULL]; - [self.model updateStableInfo:stableInfo forPeerWithID:icycle]; - - // phoneA updates again, sees the new policy that says iCycles can approve phones, and now trusts phoneB - circle = [self.model advancePeerWithID:phoneA addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[phoneA, phoneB, icycle], @[])); -} - -- (void)testICycleApprovingPhoneWithRedactedPolicy -{ - NSString *phoneA = [self makePeerWithMachineID:@"phoneA" modelID:@"iPhone7,1" epoch:1 key:@"phoneA"].peerID; - NSString *phoneB = [self makePeerWithMachineID:@"phoneB" modelID:@"iPhone7,1" epoch:1 key:@"phoneB"].peerID; - NSString *icycle = [self makePeerWithMachineID:@"icycle" modelID:@"iCycle1,1" epoch:1 key:@"icycle"].peerID; - - TPCircle *circle; - - // phoneA establishes clique, trusts icycle - circle = [self.model advancePeerWithID:phoneA addingPeerIDs:@[icycle] removingPeerIDs:nil createClique:^NSString *{ - return @"clique1"; - }]; - XCTAssert(circleEquals(circle, @[phoneA, icycle], @[])); - - // icycle trusts phoneA and phoneB - circle = [self.model advancePeerWithID:icycle addingPeerIDs:@[phoneA, phoneB] removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[phoneA, phoneB, icycle], @[])); - - // phoneA updates, and it doesn't know iCycles can approve phones, so it should ignore phoneB, so no change. - circle = [self.model advancePeerWithID:phoneA addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[phoneA, icycle], @[])); - - // icycle presents a new policy that says iCycles can approve phones - TPPeerStableInfo *stableInfo = [self.model createStableInfoWithDictionary:@{} - policyVersion:self.policyDocV1.policyVersion - policyHash:self.policyDocV1.policyHash - policySecrets:@{ - self.secretName: self.secretKey - } - forPeerWithID:icycle - error:NULL]; - [self.model updateStableInfo:stableInfo forPeerWithID:icycle]; - - // phoneA updates again, sees the new policy that says iCycles can approve phones, and now trusts phoneB - circle = [self.model advancePeerWithID:phoneA addingPeerIDs:nil removingPeerIDs:nil createClique:nil]; - XCTAssert(circleEquals(circle, @[phoneA, phoneB, icycle], @[])); -} - -@end diff --git a/keychain/trust/TrustedPeersTests/TPPeerPermanentInfoTests.m b/keychain/trust/TrustedPeersTests/TPPeerPermanentInfoTests.m deleted file mode 100644 index 58618257..00000000 --- a/keychain/trust/TrustedPeersTests/TPPeerPermanentInfoTests.m +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import -#import -#import "TPDummySigningKey.h" - -@interface TPPeerPermanentInfoTests : XCTestCase -@property (nonatomic, strong) TPPeerPermanentInfo* info; -@end - -@implementation TPPeerPermanentInfoTests - -- (void)setUp -{ - NSData *keyData = [@"key123" dataUsingEncoding:NSUTF8StringEncoding]; - TPDummySigningKey *key = [[TPDummySigningKey alloc] initWithPublicKeyData:keyData]; - - self.info - = [TPPeerPermanentInfo permanentInfoWithMachineID:@"machine123" - modelID:@"iPhone1,1" - epoch:7 - trustSigningKey:key - peerIDHashAlgo:kTPHashAlgoSHA256 - error:NULL]; - XCTAssertNotNil(self.info); -} - -- (void)testRoundTrip -{ - TPCounter epoch = 7; - NSString *machineID = @"machine123"; - NSString *modelID = @"iPhone1,1"; - - NSData *keyData = [@"key123" dataUsingEncoding:NSUTF8StringEncoding]; - - TPPeerPermanentInfo *info2 - = [TPPeerPermanentInfo permanentInfoWithPeerID:self.info.peerID - permanentInfoPList:self.info.permanentInfoPList - permanentInfoSig:self.info.permanentInfoSig - keyFactory:[TPDummySigningKeyFactory dummySigningKeyFactory]]; - - XCTAssertEqual(info2.epoch, epoch); - XCTAssert([info2.machineID isEqualToString:machineID]); - XCTAssert([info2.modelID isEqualToString:modelID]); - XCTAssert([info2.trustSigningKey.publicKey isEqualToData:keyData]); - - XCTAssert([info2.peerID isEqualToString:self.info.peerID]); - XCTAssert([info2.permanentInfoPList isEqualToData:self.info.permanentInfoPList]); - XCTAssert([info2.permanentInfoSig isEqualToData:self.info.permanentInfoSig]); -} - -- (void)testNonDictionary -{ - NSData *data = [NSPropertyListSerialization dataWithPropertyList:@[ @"foo", @"bar"] - format:NSPropertyListXMLFormat_v1_0 - options:0 - error:NULL]; - TPPeerPermanentInfo *info - = [TPPeerPermanentInfo permanentInfoWithPeerID:@"x" - permanentInfoPList:data - permanentInfoSig:data - keyFactory:[TPDummySigningKeyFactory dummySigningKeyFactory]]; - XCTAssertNil(info); -} - -- (void)testBadMachineID -{ - NSData *data = [TPUtils serializedPListWithDictionary:@{ - @"machineID": @5 - }]; - TPPeerPermanentInfo *info - = [TPPeerPermanentInfo permanentInfoWithPeerID:@"x" - permanentInfoPList:data - permanentInfoSig:data - keyFactory:[TPDummySigningKeyFactory dummySigningKeyFactory]]; - XCTAssertNil(info); -} - -- (void)testBadModelID -{ - NSData *data = [TPUtils serializedPListWithDictionary:@{ - @"machineID": @"aaa", - @"modelID": @5, - }]; - TPPeerPermanentInfo *info - = [TPPeerPermanentInfo permanentInfoWithPeerID:@"x" - permanentInfoPList:data - permanentInfoSig:data - keyFactory:[TPDummySigningKeyFactory dummySigningKeyFactory]]; - XCTAssertNil(info); -} - -- (void)testBadEpoch -{ - NSData *data = [TPUtils serializedPListWithDictionary:@{ - @"machineID": @"aaa", - @"modelID": @"iPhone7,1", - @"epoch": @"five", - }]; - TPPeerPermanentInfo *info - = [TPPeerPermanentInfo permanentInfoWithPeerID:@"x" - permanentInfoPList:data - permanentInfoSig:data - keyFactory:[TPDummySigningKeyFactory dummySigningKeyFactory]]; - XCTAssertNil(info); -} - -- (void)testBadTrustSigningKey -{ - NSData *data = [TPUtils serializedPListWithDictionary:@{ - @"machineID": @"aaa", - @"modelID": @"iPhone7,1", - @"epoch": @5, - @"trustSigningKey": @"foo", - }]; - TPPeerPermanentInfo *info - = [TPPeerPermanentInfo permanentInfoWithPeerID:@"x" - permanentInfoPList:data - permanentInfoSig:data - keyFactory:[TPDummySigningKeyFactory dummySigningKeyFactory]]; - XCTAssertNil(info); -} - -- (void)testBadTrustSigningKey2 -{ - NSData *data = [TPUtils serializedPListWithDictionary:@{ - @"machineID": @"aaa", - @"modelID": @"iPhone7,1", - @"epoch": @5, - @"trustSigningKey": [NSData data], - }]; - TPPeerPermanentInfo *info - = [TPPeerPermanentInfo permanentInfoWithPeerID:@"x" - permanentInfoPList:data - permanentInfoSig:data - keyFactory:[TPDummySigningKeyFactory dummySigningKeyFactory]]; - XCTAssertNil(info); -} - -- (void)testBadSignature -{ - TPPeerPermanentInfo *info2 - = [TPPeerPermanentInfo permanentInfoWithPeerID:self.info.peerID - permanentInfoPList:self.info.permanentInfoPList - permanentInfoSig:[NSData data] - keyFactory:[TPDummySigningKeyFactory dummySigningKeyFactory]]; - XCTAssertNil(info2); -} - -- (void)testBadHashAlgo -{ - TPPeerPermanentInfo *info2 - = [TPPeerPermanentInfo permanentInfoWithPeerID:@"foo" - permanentInfoPList:self.info.permanentInfoPList - permanentInfoSig:self.info.permanentInfoSig - keyFactory:[TPDummySigningKeyFactory dummySigningKeyFactory]]; - XCTAssertNil(info2); -} - -- (void)testBadPeerID -{ - TPPeerPermanentInfo *info2 - = [TPPeerPermanentInfo permanentInfoWithPeerID:@"SHA256:foo" - permanentInfoPList:self.info.permanentInfoPList - permanentInfoSig:self.info.permanentInfoSig - keyFactory:[TPDummySigningKeyFactory dummySigningKeyFactory]]; - XCTAssertNil(info2); -} - -- (void)testSigningKeyIsUnavailable -{ - NSData *keyData = [@"key123" dataUsingEncoding:NSUTF8StringEncoding]; - TPDummySigningKey *key = [[TPDummySigningKey alloc] initWithPublicKeyData:keyData]; - key.privateKeyIsAvailable = NO; - - NSError *error = nil; - TPPeerPermanentInfo *info - = [TPPeerPermanentInfo permanentInfoWithMachineID:@"machine123" - modelID:@"iPhone1,1" - epoch:7 - trustSigningKey:key - peerIDHashAlgo:kTPHashAlgoSHA256 - error:&error]; - XCTAssertNil(info); - XCTAssertNotNil(error); -} - -@end diff --git a/keychain/trust/TrustedPeersTests/TPPeerStableInfoTests.m b/keychain/trust/TrustedPeersTests/TPPeerStableInfoTests.m deleted file mode 100644 index 5c21166d..00000000 --- a/keychain/trust/TrustedPeersTests/TPPeerStableInfoTests.m +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import -#import -#import "TPDummySigningKey.h" - -@interface TPPeerStableInfoTests : XCTestCase - -@end - -@implementation TPPeerStableInfoTests - -- (void)testSigningKeyIsUnavailable -{ - NSData *keyData = [@"key123" dataUsingEncoding:NSUTF8StringEncoding]; - TPDummySigningKey *key = [[TPDummySigningKey alloc] initWithPublicKeyData:keyData]; - key.privateKeyIsAvailable = NO; - - NSError *error = nil; - TPPeerStableInfo *info - = [TPPeerStableInfo stableInfoWithDict:@{} - clock:1 - policyVersion:1 - policyHash:@"foo" - policySecrets:nil - trustSigningKey:key - error:&error]; - XCTAssertNil(info); - XCTAssertNotNil(error); -} - -- (void)testNonDictionary -{ - NSData *data = [NSPropertyListSerialization dataWithPropertyList:@[ @"foo", @"bar"] - format:NSPropertyListXMLFormat_v1_0 - options:0 - error:NULL]; - TPPeerStableInfo *info - = [TPPeerStableInfo stableInfoWithPListData:data - stableInfoSig:data]; - XCTAssertNil(info); -} - -- (void)testBadClock -{ - NSData *data = [TPUtils serializedPListWithDictionary:@{ - @"clock": @"five" - }]; - TPPeerStableInfo *info - = [TPPeerStableInfo stableInfoWithPListData:data - stableInfoSig:data]; - XCTAssertNil(info); -} - -- (void)testBadPolicyVersion -{ - NSData *data = [TPUtils serializedPListWithDictionary:@{ - @"clock": @5, - @"policyVersion": @"five", - }]; - TPPeerStableInfo *info - = [TPPeerStableInfo stableInfoWithPListData:data - stableInfoSig:data]; - XCTAssertNil(info); -} - -- (void)testBadPolicyHash -{ - NSData *data = [TPUtils serializedPListWithDictionary:@{ - @"clock": @5, - @"policyVersion": @5, - @"policyHash": @5 - }]; - TPPeerStableInfo *info - = [TPPeerStableInfo stableInfoWithPListData:data - stableInfoSig:data]; - XCTAssertNil(info); -} - -- (void)testBadSecrets -{ - NSData *data = [TPUtils serializedPListWithDictionary:@{ - @"clock": @5, - @"policyVersion": @5, - @"policyHash": @"foo", - @"policySecrets": @5 - }]; - TPPeerStableInfo *info - = [TPPeerStableInfo stableInfoWithPListData:data - stableInfoSig:data]; - XCTAssertNil(info); -} - -- (void)testBadSecretData -{ - NSData *data = [TPUtils serializedPListWithDictionary:@{ - @"clock": @5, - @"policyVersion": @5, - @"policyHash": @"foo", - @"policySecrets": @{ - @"foo": @5 - } - }]; - TPPeerStableInfo *info - = [TPPeerStableInfo stableInfoWithPListData:data - stableInfoSig:data]; - XCTAssertNil(info); -} - -@end diff --git a/keychain/trust/TrustedPeersTests/TPPeerTests.m b/keychain/trust/TrustedPeersTests/TPPeerTests.m deleted file mode 100644 index c882c766..00000000 --- a/keychain/trust/TrustedPeersTests/TPPeerTests.m +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import -#import -#import "TPDummySigningKey.h" - -@interface TPPeerTests : XCTestCase - -@property (nonatomic, strong) TPPeer *peer; -@property (nonatomic, strong) TPDummySigningKey *goodKey; -@property (nonatomic, strong) TPDummySigningKey *badKey; - -@end - -@implementation TPPeerTests - -- (void)setUp -{ - NSData *goodKeyData = [@"goodKey" dataUsingEncoding:NSUTF8StringEncoding]; - self.goodKey = [[TPDummySigningKey alloc] initWithPublicKeyData:goodKeyData]; - - NSData *badKeyData = [@"badKey" dataUsingEncoding:NSUTF8StringEncoding]; - self.badKey = [[TPDummySigningKey alloc] initWithPublicKeyData:badKeyData]; - - TPPeerPermanentInfo *permanentInfo; - permanentInfo = [TPPeerPermanentInfo permanentInfoWithMachineID:@"A" - modelID:@"iPhone8,1" - epoch:1 - trustSigningKey:self.goodKey - peerIDHashAlgo:kTPHashAlgoSHA256 - error:NULL]; - self.peer = [[TPPeer alloc] initWithPermanentInfo:permanentInfo]; -} - -- (void)testBadDynamicInfoKey -{ - // Create a dynamicInfo with the wrong key - TPPeerDynamicInfo *dynamicInfo = [TPPeerDynamicInfo dynamicInfoWithCircleID:@"123" - clique:@"clique" - removals:0 - clock:1 - trustSigningKey:self.badKey - error:NULL]; - XCTAssertEqual(TPResultSignatureMismatch, [self.peer updateDynamicInfo:dynamicInfo]); -} - -- (void)testStableInfo -{ - TPPeerStableInfo *info1 = [TPPeerStableInfo stableInfoWithDict:@{ @"hello": @"world1" } - clock:1 - policyVersion:1 - policyHash:@"" - policySecrets:nil - trustSigningKey:self.goodKey - error:NULL]; - XCTAssertEqual(TPResultOk, [self.peer updateStableInfo:info1]); - - // Attempt update without advancing clock - TPPeerStableInfo *info2 = [TPPeerStableInfo stableInfoWithDict:@{ @"hello": @"world2" } - clock:1 - policyVersion:1 - policyHash:@"" - policySecrets:nil - trustSigningKey:self.goodKey - error:NULL]; - XCTAssertEqual(TPResultClockViolation, [self.peer updateStableInfo:info2]); - XCTAssertEqualObjects(self.peer.stableInfo, info1); - - // Advance - TPPeerStableInfo *info3 = [TPPeerStableInfo stableInfoWithDict:@{ @"hello": @"world3" } - clock:3 - policyVersion:1 - policyHash:@"" - policySecrets:nil - trustSigningKey:self.goodKey - error:NULL]; - XCTAssertEqual(TPResultOk, [self.peer updateStableInfo:info3]); - - // No change, should return OK - XCTAssertEqual(TPResultOk, [self.peer updateStableInfo:info3]); - - // Attempt replay - XCTAssertEqual(TPResultClockViolation, [self.peer updateStableInfo:info1]); - XCTAssertEqualObjects(self.peer.stableInfo, info3); - - // Attempt update with wrong key - TPPeerStableInfo *info4 = [TPPeerStableInfo stableInfoWithDict:@{ @"hello": @"world4" } - clock:4 - policyVersion:1 - policyHash:@"" - policySecrets:nil - trustSigningKey:self.badKey - error:NULL]; - XCTAssertEqual(TPResultSignatureMismatch, [self.peer updateStableInfo:info4]); - XCTAssertEqualObjects(self.peer.stableInfo, info3); -} - -@end diff --git a/keychain/trust/TrustedPeersTests/TPPolicyDocumentTests.m b/keychain/trust/TrustedPeersTests/TPPolicyDocumentTests.m deleted file mode 100644 index 59ceb183..00000000 --- a/keychain/trust/TrustedPeersTests/TPPolicyDocumentTests.m +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import -#import - -@interface TPPolicyDocumentTests : XCTestCase - -@end - -@implementation TPPolicyDocumentTests - -- (void)testRoundTrip -{ - TPPolicyDocument *doc1 - = [TPPolicyDocument policyDocWithVersion:1 - modelToCategory:@[ - @{ @"prefix": @"iPhone", @"category": @"full" }, - @{ @"prefix": @"iPad", @"category": @"full" }, - @{ @"prefix": @"Mac", @"category": @"full" }, - @{ @"prefix": @"iMac", @"category": @"full" }, - @{ @"prefix": @"AppleTV", @"category": @"tv" }, - @{ @"prefix": @"Watch", @"category": @"watch" }, - ] - categoriesByView:@{ - @"WiFi": @[ @"full", @"tv", @"watch" ], - @"SafariCreditCards": @[ @"full" ], - @"PCSEscrow": @[ @"full" ] - } - introducersByCategory:@{ - @"full": @[ @"full" ], - @"tv": @[ @"full", @"tv" ], - @"watch": @[ @"full", @"watch" ] - } - redactions:@{ - @"foo": [@"bar" dataUsingEncoding:NSUTF8StringEncoding] - } - hashAlgo:kTPHashAlgoSHA256]; - - - TPPolicyDocument *doc2 = [TPPolicyDocument policyDocWithHash:doc1.policyHash pList:doc1.pList]; - XCTAssert([doc1 isEqualToPolicyDocument:doc2]); - - TPPolicyDocument *doc3 = [TPPolicyDocument policyDocWithHash:@"SHA256:foo" pList:doc1.pList]; - XCTAssertNil(doc3); -} - -@end diff --git a/keychain/trust/TrustedPeersTests/TPUtilsTests.m b/keychain/trust/TrustedPeersTests/TPUtilsTests.m deleted file mode 100644 index 0376bfbf..00000000 --- a/keychain/trust/TrustedPeersTests/TPUtilsTests.m +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import -#import - -@interface TPUtilsTests : XCTestCase - -@end - -@implementation TPUtilsTests - -- (void)testErrorHandling { - XCTAssertThrows([TPUtils serializedPListWithDictionary:@{ - @"foo": [NSSet setWithObject:@"bar"] - }]); -} - -@end diff --git a/keychain/trust/TrustedPeersTests/TPVoucherTests.m b/keychain/trust/TrustedPeersTests/TPVoucherTests.m deleted file mode 100644 index de49c6cd..00000000 --- a/keychain/trust/TrustedPeersTests/TPVoucherTests.m +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import -#import -#import "TPDummySigningKey.h" - -@interface TPVoucherTests : XCTestCase - -@end - -@implementation TPVoucherTests - -- (void)testRoundTrip -{ - NSData *keyData = [@"key" dataUsingEncoding:NSUTF8StringEncoding]; - id key = [[TPDummySigningKey alloc] initWithPublicKeyData:keyData]; - - TPVoucher *voucher1 = [TPVoucher voucherWithBeneficiaryID:@"B" - sponsorID:@"A" - clock:1 - trustSigningKey:key - error:NULL]; - TPVoucher *voucher1b = [TPVoucher voucherWithPList:voucher1.voucherInfoPList - sig:voucher1.voucherInfoSig]; - - XCTAssertEqualObjects(voucher1, voucher1b); - XCTAssertEqual([voucher1 hash], [voucher1b hash]); - XCTAssert([voucher1 isEqual:voucher1]); - XCTAssert([voucher1 isEqualToVoucher:voucher1]); - XCTAssert(![voucher1 isEqual:@"foo"]); - - TPVoucher *voucher2 = [TPVoucher voucherWithBeneficiaryID:@"C" - sponsorID:@"A" - clock:1 - trustSigningKey:key - error:NULL]; - XCTAssertNotEqualObjects(voucher1, voucher2); -} - -- (void)testMalformed -{ - NSData *data = [@"foo" dataUsingEncoding:NSUTF8StringEncoding]; - XCTAssertNil([TPVoucher voucherWithPList:data sig:data]); - - data = [TPUtils serializedPListWithDictionary:@{ - @"beneficiaryID": @[], - @"sponsorID": @"A", - @"clock": @1 - }]; - XCTAssertNil([TPVoucher voucherWithPList:data sig:data]); - - data = [TPUtils serializedPListWithDictionary:@{ - @"beneficiaryID": @"B", - @"sponsorID": @7, - @"clock": @1 - }]; - XCTAssertNil([TPVoucher voucherWithPList:data sig:data]); - - data = [TPUtils serializedPListWithDictionary:@{ - @"beneficiaryID": @"B", - @"sponsorID": @"A", - @"clock": @"foo" - }]; - XCTAssertNil([TPVoucher voucherWithPList:data sig:data]); -} - -- (void)testCannotSign -{ - NSData *keyData = [@"key" dataUsingEncoding:NSUTF8StringEncoding]; - TPDummySigningKey *key = [[TPDummySigningKey alloc] initWithPublicKeyData:keyData]; - key.privateKeyIsAvailable = NO; - - NSError *error = nil; - TPVoucher *voucher = [TPVoucher voucherWithBeneficiaryID:@"B" - sponsorID:@"A" - clock:1 - trustSigningKey:key - error:&error]; - XCTAssertNil(voucher); -} - -@end diff --git a/lib/SecArgParse.c b/lib/SecArgParse.c index 3a326ac6..c0b43cf0 100644 --- a/lib/SecArgParse.c +++ b/lib/SecArgParse.c @@ -145,7 +145,7 @@ bool options_parse(int argc, char * const *argv, struct arguments* args) { realargs.arguments[i+1] = args->arguments[i]; } - struct option* long_options = (struct option*) malloc((noptions+1) * sizeof(struct option)); + struct option* long_options = (struct option*) calloc((noptions+1), sizeof(struct option)); size_t short_options_length = 2* noptions * sizeof(char) + 2; // 2: one for -h, one for the null terminator char* short_options = (char*) malloc(short_options_length); @@ -165,7 +165,7 @@ bool options_parse(int argc, char * const *argv, struct arguments* args) { struct option* long_option = &long_options[option_index]; for(size_t i = 0; i < noptions; i++) { - if(realargs.arguments[i].longname && strncmp(long_option->name, realargs.arguments[i].longname, strlen(realargs.arguments[i].longname)) == 0) { + if(realargs.arguments[i].longname && long_option->name && strncmp(long_option->name, realargs.arguments[i].longname, strlen(realargs.arguments[i].longname)) == 0) { trigger(realargs.arguments[i], optarg); } } @@ -185,7 +185,8 @@ bool options_parse(int argc, char * const *argv, struct arguments* args) { } } if(i == noptions) { - return false; + success = false; + goto out; } } } diff --git a/libsecurity_smime/lib/CMSDecoder.c b/libsecurity_smime/lib/CMSDecoder.c index 73434598..48cb56e2 100644 --- a/libsecurity_smime/lib/CMSDecoder.c +++ b/libsecurity_smime/lib/CMSDecoder.c @@ -970,8 +970,8 @@ OSStatus CMSDecoderCopySignerAppleCodesigningHashAgility( int numContentInfos = 0; CFDataRef returnedValue = NULL; - require(cmsDecoder && hashAgilityAttrValue, xit); - require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), xit); + require(cmsDecoder && hashAgilityAttrValue, exit); + require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), exit); numContentInfos = SecCmsMessageContentLevelCount(cmsg); for (int dex = 0; !signedData && dex < numContentInfos; dex++) { @@ -987,7 +987,7 @@ OSStatus CMSDecoderCopySignerAppleCodesigningHashAgility( } } } -xit: +exit: if (status == errSecSuccess && returnedValue) { *hashAgilityAttrValue = (CFDataRef) CFRetain(returnedValue); } else { @@ -995,3 +995,49 @@ xit: } return status; } + +/* + * Obtain the Hash Agility V2 attribute value of signer 'signerIndex' + * of a CMS message, if present. + * + * Returns errSecParam if the CMS message was not signed or if signerIndex + * is greater than the number of signers of the message minus one. + * + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderCopySignerAppleCodesigningHashAgilityV2( + CMSDecoderRef cmsDecoder, + size_t signerIndex, /* usually 0 */ + CFDictionaryRef CF_RETURNS_RETAINED *hashAgilityV2AttrValues) /* RETURNED */ +{ + OSStatus status = errSecParam; + SecCmsMessageRef cmsg; + SecCmsSignedDataRef signedData = NULL; + int numContentInfos = 0; + CFDictionaryRef returnedValue = NULL; + + require(cmsDecoder && hashAgilityV2AttrValues, exit); + require_noerr(CMSDecoderGetCmsMessage(cmsDecoder, &cmsg), exit); + numContentInfos = SecCmsMessageContentLevelCount(cmsg); + for (int dex = 0; !signedData && dex < numContentInfos; dex++) + { + SecCmsContentInfoRef ci = SecCmsMessageContentLevel(cmsg, dex); + SECOidTag tag = SecCmsContentInfoGetContentTypeTag(ci); + if (tag == SEC_OID_PKCS7_SIGNED_DATA) + if ((signedData = (SecCmsSignedDataRef)SecCmsContentInfoGetContent(ci))) { + SecCmsSignerInfoRef signerInfo = SecCmsSignedDataGetSignerInfo(signedData, (int)signerIndex); + if (signerInfo) + { + status = SecCmsSignerInfoGetAppleCodesigningHashAgilityV2(signerInfo, &returnedValue); + break; + } + } + } +exit: + if (status == errSecSuccess && returnedValue) { + *hashAgilityV2AttrValues = (CFDictionaryRef) CFRetain(returnedValue); + } else { + *hashAgilityV2AttrValues = NULL; + } + return status; +} diff --git a/libsecurity_smime/lib/CMSDecoder.h b/libsecurity_smime/lib/CMSDecoder.h index 8355d3ce..7b754404 100644 --- a/libsecurity_smime/lib/CMSDecoder.h +++ b/libsecurity_smime/lib/CMSDecoder.h @@ -407,7 +407,22 @@ OSStatus CMSDecoderGetDecoder( OSStatus CMSDecoderCopySignerAppleCodesigningHashAgility( CMSDecoderRef cmsDecoder, size_t signerIndex, /* usually 0 */ - CFDataRef CF_RETURNS_RETAINED * _Nonnull hashAgilityAttrValue); /* RETURNED */ + CFDataRef _Nullable CF_RETURNS_RETAINED * _Nonnull hashAgilityAttrValue); /* RETURNED */ + + +/* + * Obtain the Hash Agility v2 attribute value of signer 'signerIndex' + * of a CMS message, if present. V2 encodes the hash agility values using DER. + * + * Returns errSecParam if the CMS message was not signed or if signerIndex + * is greater than the number of signers of the message minus one. + * + * This cannot be called until after CMSDecoderFinalizeMessage() is called. + */ +OSStatus CMSDecoderCopySignerAppleCodesigningHashAgilityV2( + CMSDecoderRef cmsDecoder, + size_t signerIndex, /* usually 0 */ + CFDictionaryRef _Nullable CF_RETURNS_RETAINED * _Nonnull hashAgilityAttrValues); /* RETURNED */ CF_ASSUME_NONNULL_END diff --git a/libsecurity_smime/lib/CMSEncoder.c b/libsecurity_smime/lib/CMSEncoder.c index c376a834..44d1dd0c 100644 --- a/libsecurity_smime/lib/CMSEncoder.c +++ b/libsecurity_smime/lib/CMSEncoder.c @@ -97,6 +97,7 @@ struct _CMSEncoder { CMSCertificateChainMode chainMode; CFDataRef hashAgilityAttrValue; + CFDictionaryRef hashAgilityV2AttrValues; }; static void cmsEncoderInit(CFTypeRef enc); @@ -526,6 +527,16 @@ static OSStatus cmsSetupForSignedData( break; } } + if(cmsEncoder->signedAttributes & kCMSAttrAppleCodesigningHashAgilityV2) { + ortn = SecCmsSignerInfoAddAppleCodesigningHashAgilityV2(signerInfo, cmsEncoder->hashAgilityV2AttrValues); + /* libsecurity_smime made a copy of the attribute value. We don't need it anymore. */ + CFReleaseNull(cmsEncoder->hashAgilityV2AttrValues); + if(ortn) { + ortn = cmsRtnToOSStatus(ortn); + CSSM_PERROR("SecCmsSignerInfoAddAppleCodesigningHashAgilityV2", ortn); + break; + } + } CFRELEASE(ourCert); ourCert = NULL; @@ -1008,6 +1019,22 @@ OSStatus CMSEncoderSetAppleCodesigningHashAgility( return errSecSuccess; } +/* + * Set the hash agility attribute for a CMSEncoder. + * This is only used if the kCMSAttrAppleCodesigningHashAgilityV2 attribute + * is included. + */ +OSStatus CMSEncoderSetAppleCodesigningHashAgilityV2( + CMSEncoderRef cmsEncoder, + CFDictionaryRef hashAgilityV2AttrValues) +{ + if (cmsEncoder == NULL || cmsEncoder->encState != ES_Init) { + return errSecParam; + } + cmsEncoder->hashAgilityV2AttrValues = CFRetainSafe(hashAgilityV2AttrValues); + return errSecSuccess; +} + OSStatus CMSEncoderSetCertificateChainMode( CMSEncoderRef cmsEncoder, CMSCertificateChainMode chainMode) diff --git a/libsecurity_smime/lib/CMSEncoder.h b/libsecurity_smime/lib/CMSEncoder.h index dda5f2f1..e548c56d 100644 --- a/libsecurity_smime/lib/CMSEncoder.h +++ b/libsecurity_smime/lib/CMSEncoder.h @@ -248,7 +248,8 @@ typedef CF_OPTIONS(uint32_t, CMSSignedAttributes) { /* * Include the Apple Codesigning Hash Agility. */ - kCMSAttrAppleCodesigningHashAgility = 0x0010 + kCMSAttrAppleCodesigningHashAgility = 0x0010, + kCMSAttrAppleCodesigningHashAgilityV2 = 0x0020, }; /* @@ -415,6 +416,18 @@ OSStatus CMSEncoderSetAppleCodesigningHashAgility( CMSEncoderRef cmsEncoder, CFDataRef hashAgilityAttrValue); +/* + * Set the hash agility attribute for a CMSEncoder. + * This is only used if the kCMSAttrAppleCodesigningHashAgilityV2 attribute + * is included. V2 encodes the hash agility values using DER. + * The dictionary should have CFNumberRef keys, corresponding to SECOidTags + * (from SecCmsBase.h) for digest algorithms, and CFDataRef values, + * corresponding to the digest value for that digest algorithm. + */ +OSStatus CMSEncoderSetAppleCodesigningHashAgilityV2( + CMSEncoderRef cmsEncoder, + CFDictionaryRef hashAgilityV2AttrValues); + CF_ASSUME_NONNULL_END diff --git a/libsecurity_smime/lib/CMSUtils.c b/libsecurity_smime/lib/CMSUtils.c index 80caf601..2caac62c 100644 --- a/libsecurity_smime/lib/CMSUtils.c +++ b/libsecurity_smime/lib/CMSUtils.c @@ -86,6 +86,7 @@ OSStatus cmsRtnToOSStatusDefault(OSStatus smimeRtn, // from libsecurity_smime if(smimeRtn == SECFailure) { /* This is a SECStatus. Try to get detailed error info. */ smimeRtn = PORT_GetError(); + PORT_SetError(0); // clean up the thread since we're handling this error if(smimeRtn == 0) { /* S/MIME just gave us generic error; no further info available; punt. */ dprintf("cmsRtnToOSStatus: SECFailure, no status avilable\n"); diff --git a/libsecurity_smime/lib/SecCmsBase.h b/libsecurity_smime/lib/SecCmsBase.h index 0111155b..c9e6e1ad 100644 --- a/libsecurity_smime/lib/SecCmsBase.h +++ b/libsecurity_smime/lib/SecCmsBase.h @@ -482,8 +482,9 @@ typedef enum { SEC_OID_ECDSA_WITH_SHA384 = 212, SEC_OID_ECDSA_WITH_SHA512 = 213, - /* Apple CMS Attribute */ + /* Apple CMS Attributes */ SEC_OID_APPLE_HASH_AGILITY = 214, + SEC_OID_APPLE_HASH_AGILITY_V2 = 215, SEC_OID_TOTAL } SECOidTag; diff --git a/libsecurity_smime/lib/SecCmsSignerInfo.h b/libsecurity_smime/lib/SecCmsSignerInfo.h index 257a1d26..ab132f23 100644 --- a/libsecurity_smime/lib/SecCmsSignerInfo.h +++ b/libsecurity_smime/lib/SecCmsSignerInfo.h @@ -100,6 +100,17 @@ SecCmsSignerInfoGetSigningTime(SecCmsSignerInfoRef sinfo, CFAbsoluteTime *stime) extern OSStatus SecCmsSignerInfoGetAppleCodesigningHashAgility(SecCmsSignerInfoRef sinfo, CFDataRef *sdata); +/*! + @function + @abstract Return the data in the signed Codesigning Hash Agility V2 attribute. + @param sinfo SignerInfo data for this signer, pointer to a CFDictionaryRef for attribute values + @discussion Returns a CFDictionaryRef containing the values of the attribute. V2 encodes the + hash agility values using DER. + @result A return value of SECFailure is an error. + */ +extern OSStatus +SecCmsSignerInfoGetAppleCodesigningHashAgilityV2(SecCmsSignerInfoRef sinfo, CFDictionaryRef *sdict); + /*! @function @abstract Return the signing cert of a CMS signerInfo. @@ -178,11 +189,21 @@ SecCmsSignerInfoAddCounterSignature(SecCmsSignerInfoRef signerinfo, /*! @function @abstract Add the Apple Codesigning Hash Agility attribute to the authenticated (i.e. signed) attributes of "signerinfo". - @discussion This is expected to be included in outgoing signed Apple code signatures. + @discussion This is expected to be included in outgoing Apple code signatures. */ OSStatus SecCmsSignerInfoAddAppleCodesigningHashAgility(SecCmsSignerInfoRef signerinfo, CFDataRef attrValue); +/*! + @function + @abstract Add the Apple Codesigning Hash Agility V2 attribute to the authenticated (i.e. signed) attributes of "signerinfo". + @discussion This is expected to be included in outgoing Apple code signatures. V2 encodes the hash agility values using DER. + The dictionary should have CFNumberRef keys, corresponding to SECOidTags for digest algorithms, and CFDataRef values, + corresponding to the digest value for that digest algorithm. + */ +OSStatus +SecCmsSignerInfoAddAppleCodesigningHashAgilityV2(SecCmsSignerInfoRef signerinfo, CFDictionaryRef attrValues); + /*! @function @abstract The following needs to be done in the S/MIME layer code after signature of a signerinfo has been verified. diff --git a/libsecurity_smime/lib/cmsattr.c b/libsecurity_smime/lib/cmsattr.c index 05d0033b..8bab00d0 100644 --- a/libsecurity_smime/lib/cmsattr.c +++ b/libsecurity_smime/lib/cmsattr.c @@ -114,19 +114,23 @@ loser: OSStatus SecCmsAttributeAddValue(PLArenaPool *poolp, SecCmsAttribute *attr, SecAsn1Item * value) { - SecAsn1Item copiedvalue; + SecAsn1Item *copiedvalue; void *mark; PORT_Assert (poolp != NULL); mark = PORT_ArenaMark(poolp); - /* XXX we need an object memory model #$%#$%! */ - if (SECITEM_CopyItem(poolp, &copiedvalue, value) != SECSuccess) - goto loser; + if (value != NULL) { + if ((copiedvalue = SECITEM_AllocItem(poolp, NULL, value->Length)) == NULL) + goto loser; - if (SecCmsArrayAdd(poolp, (void ***)&(attr->values), (void *)&copiedvalue) != SECSuccess) - goto loser; + if (SECITEM_CopyItem(poolp, copiedvalue, value) != SECSuccess) + goto loser; + + if (SecCmsArrayAdd(poolp, (void ***)&(attr->values), (void *)copiedvalue) != SECSuccess) + goto loser; + } PORT_ArenaUnmark(poolp, mark); return SECSuccess; @@ -237,6 +241,7 @@ cms_attr_choose_attr_value_template(void *src_or_dest, Boolean encoding, const c switch (oiddata->offset) { case SEC_OID_PKCS9_SMIME_CAPABILITIES: case SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE: + case SEC_OID_APPLE_HASH_AGILITY_V2: /* these guys need to stay DER-encoded */ default: /* same goes for OIDs that are not handled here */ diff --git a/libsecurity_smime/lib/cmscinfo.c b/libsecurity_smime/lib/cmscinfo.c index 24540480..00cb7ad2 100644 --- a/libsecurity_smime/lib/cmscinfo.c +++ b/libsecurity_smime/lib/cmscinfo.c @@ -192,8 +192,11 @@ SecCmsContentInfoSetContentData(SecCmsContentInfoRef cinfo, CFDataRef dataRef, B data->Data = NULL; } - if (SecCmsContentInfoSetContent(cinfo, SEC_OID_PKCS7_DATA, (void *)data) != SECSuccess) - return PORT_GetError(); + if (SecCmsContentInfoSetContent(cinfo, SEC_OID_PKCS7_DATA, (void *)data) != SECSuccess) { + OSStatus status = PORT_GetError(); + PORT_SetError(0); // clean the thread since we've returned this error + return status; + } cinfo->rawContent = (detached) ? NULL : (data) ? data : SECITEM_AllocItem(cinfo->cmsg->poolp, NULL, 1); diff --git a/libsecurity_smime/lib/cmsdecode.c b/libsecurity_smime/lib/cmsdecode.c index 2dd6f8ac..333cd1ee 100644 --- a/libsecurity_smime/lib/cmsdecode.c +++ b/libsecurity_smime/lib/cmsdecode.c @@ -182,12 +182,15 @@ nss_cms_decoder_notify(void *arg, Boolean before, void *dest, int depth) if (nss_cms_before_data(p7dcx) != SECSuccess) { SEC_ASN1DecoderClearFilterProc(p7dcx->dcx); /* stop all processing */ p7dcx->error = PORT_GetError(); + PORT_SetError(0); } } if (after && dest == &(cinfo->rawContent)) { /* we're right after of the data */ - if (nss_cms_after_data(p7dcx) != SECSuccess) + if (nss_cms_after_data(p7dcx) != SECSuccess) { p7dcx->error = PORT_GetError(); + PORT_SetError(0); + } /* we don't need to see the contents anymore */ SEC_ASN1DecoderClearFilterProc(p7dcx->dcx); @@ -595,6 +598,9 @@ SecCmsDecoderCreate(SecCmsContentCallback cb, void *cb_arg, SecCmsMessageRef cmsg; OSStatus result; + /* Clear the thread error to clean up dirty threads */ + PORT_SetError(0); + cmsg = SecCmsMessageCreate(); if (cmsg == NULL) goto loser; @@ -627,6 +633,7 @@ SecCmsDecoderCreate(SecCmsContentCallback cb, void *cb_arg, loser: result = PORT_GetError(); + PORT_SetError(0); // Clean the thread error since we've returned the error return result; } @@ -658,7 +665,8 @@ SecCmsDecoderUpdate(SecCmsDecoderRef p7dcx, const void *buf, CFIndex len) (void) SEC_ASN1DecoderFinish (p7dcx->dcx); p7dcx->dcx = NULL; } - PORT_SetError (p7dcx->error); + + PORT_SetError (0); // Clean the thread error since we've returned the error return p7dcx->error; } @@ -711,6 +719,7 @@ loser: p7dcx->dcx = NULL; p7dcx->childp7dcx = NULL; PORT_Free(p7dcx); + PORT_SetError(0); // Clean the thread error since we've returned the error return result; } diff --git a/libsecurity_smime/lib/cmsencode.c b/libsecurity_smime/lib/cmsencode.c index 9b89a58b..e9a97a57 100644 --- a/libsecurity_smime/lib/cmsencode.c +++ b/libsecurity_smime/lib/cmsencode.c @@ -176,8 +176,10 @@ nss_cms_encoder_notify(void *arg, Boolean before, void *dest, int depth) /* we're right before encoding the data (if we have some or not) */ /* (for encrypted data, we're right before the contentEncAlg which may change */ /* in nss_cms_before_data because of IV calculation when setting up encryption) */ - if (nss_cms_before_data(p7ecx) != SECSuccess) + if (nss_cms_before_data(p7ecx) != SECSuccess) { p7ecx->error = PORT_GetError(); + PORT_SetError(0); // Clean the thread error since we've returned the error + } } if (before && dest == &(cinfo->rawContent)) { if (childtype == SEC_OID_PKCS7_DATA && (item = cinfo->content.data) != NULL) @@ -188,8 +190,10 @@ nss_cms_encoder_notify(void *arg, Boolean before, void *dest, int depth) SEC_ASN1EncoderSetTakeFromBuf(p7ecx->ecx); } if (after && dest == &(cinfo->rawContent)) { - if (nss_cms_after_data(p7ecx) != SECSuccess) + if (nss_cms_after_data(p7ecx) != SECSuccess) { p7ecx->error = PORT_GetError(); + PORT_SetError(0); // Clean the thread error since we've returned the error + } SEC_ASN1EncoderClearNotifyProc(p7ecx->ecx); /* no need to get notified anymore */ } break; @@ -513,6 +517,9 @@ SecCmsEncoderCreate(SecCmsMessageRef cmsg, OSStatus result; SecCmsContentInfoRef cinfo; + /* Clear the thread error to clean up dirty threads */ + PORT_SetError(0); + SecCmsMessageSetEncodingParams(cmsg, pwfn, pwfn_arg, decrypt_key_cb, decrypt_key_cb_arg); p7ecx = (SecCmsEncoderRef)PORT_ZAlloc(sizeof(struct SecCmsEncoderStr)); @@ -561,6 +568,7 @@ SecCmsEncoderCreate(SecCmsMessageRef cmsg, if (p7ecx->ecx == NULL) { result = PORT_GetError(); PORT_Free(p7ecx); + PORT_SetError(0); // Clean the thread error since we've returned the error goto loser; } p7ecx->ecxupdated = PR_FALSE; @@ -582,6 +590,7 @@ SecCmsEncoderCreate(SecCmsMessageRef cmsg, if (SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0) != SECSuccess) { result = PORT_GetError(); PORT_Free(p7ecx); + PORT_SetError(0); // Clean the thread error since we've returned the error goto loser; } @@ -631,8 +640,10 @@ SecCmsEncoderUpdate(SecCmsEncoderRef p7ecx, const void *data, CFIndex len) /* hand it the data so it can encode it (let DER trickle up the chain) */ result = nss_cms_encoder_work_data(p7ecx, NULL, (const unsigned char *)data, len, PR_FALSE, PR_TRUE); - if (result) + if (result) { result = PORT_GetError(); + PORT_SetError(0); // Clean the thread error since we've returned the error + } } return result; } @@ -737,6 +748,7 @@ SecCmsEncoderFinish(SecCmsEncoderRef p7ecx) loser: SEC_ASN1EncoderFinish(p7ecx->ecx); PORT_Free (p7ecx); + PORT_SetError(0); // Clean the thread error since we've returned the error return result; } diff --git a/libsecurity_smime/lib/cmssiginfo.c b/libsecurity_smime/lib/cmssiginfo.c index 21d9fd9a..e2e06912 100644 --- a/libsecurity_smime/lib/cmssiginfo.c +++ b/libsecurity_smime/lib/cmssiginfo.c @@ -316,6 +316,10 @@ SecCmsSignerInfoDestroy(SecCmsSignerInfoRef si) CFRelease(si->hashAgilityAttrValue); } + if (si->hashAgilityV2AttrValues != NULL) { + CFRelease(si->hashAgilityV2AttrValues); + } + /* XXX storage ??? */ } @@ -899,6 +903,113 @@ SecCmsSignerInfoGetAppleCodesigningHashAgility(SecCmsSignerInfoRef sinfo, CFData return errSecAllocate; } +/* AgileHash ::= SEQUENCE { + hashType OBJECT IDENTIFIER, + hashValues OCTET STRING } +*/ +typedef struct { + SecAsn1Item digestOID; + SecAsn1Item digestValue; +} CMSAppleAgileHash; + +static const SecAsn1Template CMSAppleAgileHashTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(CMSAppleAgileHash) }, + { SEC_ASN1_OBJECT_ID, + offsetof(CMSAppleAgileHash, digestOID), }, + { SEC_ASN1_OCTET_STRING, + offsetof(CMSAppleAgileHash, digestValue), }, + { 0, } +}; + +static OSStatus CMSAddAgileHashToDictionary(CFMutableDictionaryRef dictionary, SecAsn1Item *DERAgileHash) { + PLArenaPool *tmppoolp = NULL; + OSStatus status = errSecSuccess; + CMSAppleAgileHash agileHash; + CFDataRef digestValue = NULL; + CFNumberRef digestTag = NULL; + + tmppoolp = PORT_NewArena(1024); + if (tmppoolp == NULL) { + return errSecAllocate; + } + + if ((status = SEC_ASN1DecodeItem(tmppoolp, &agileHash, CMSAppleAgileHashTemplate, DERAgileHash)) != errSecSuccess) { + goto loser; + } + + int64_t tag = SECOID_FindOIDTag(&agileHash.digestOID); + digestTag = CFNumberCreate(NULL, kCFNumberSInt64Type, &tag); + digestValue = CFDataCreate(NULL, agileHash.digestValue.Data, agileHash.digestValue.Length); + CFDictionaryAddValue(dictionary, digestTag, digestValue); + +loser: + CFReleaseNull(digestValue); + CFReleaseNull(digestTag); + if (tmppoolp) { + PORT_FreeArena(tmppoolp, PR_FALSE); + } + return status; +} + +/*! + @function + @abstract Return the data in the signed Codesigning Hash Agility V2 attribute. + @param sinfo SignerInfo data for this signer, pointer to a CFDictionaryRef for attribute values + @discussion Returns a CFDictionaryRef containing the values of the attribute + @result A return value of errSecInternal is an error trying to look up the oid. + A status value of success with null result data indicates the attribute was not present. + */ +OSStatus +SecCmsSignerInfoGetAppleCodesigningHashAgilityV2(SecCmsSignerInfoRef sinfo, CFDictionaryRef *sdict) +{ + SecCmsAttribute *attr; + + if (sinfo == NULL || sdict == NULL) { + return errSecParam; + } + + *sdict = NULL; + + if (sinfo->hashAgilityV2AttrValues != NULL) { + *sdict = sinfo->hashAgilityV2AttrValues; /* cached copy */ + return SECSuccess; + } + + attr = SecCmsAttributeArrayFindAttrByOidTag(sinfo->authAttr, SEC_OID_APPLE_HASH_AGILITY_V2, PR_TRUE); + + /* attribute not found */ + if (attr == NULL) { + return SECSuccess; + } + + /* attrValues SET OF AttributeValue + * AttributeValue ::= ANY + */ + SecAsn1Item **values = attr->values; + if (values == NULL) { /* There must be values */ + return errSecDecode; + } + + CFMutableDictionaryRef agileHashValues = CFDictionaryCreateMutable(NULL, SecCmsArrayCount((void **)values), + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + while (*values != NULL) { + (void)CMSAddAgileHashToDictionary(agileHashValues, *values++); + } + if (CFDictionaryGetCount(agileHashValues) != SecCmsArrayCount((void **)attr->values)) { + CFReleaseNull(agileHashValues); + return errSecDecode; + } + + sinfo->hashAgilityV2AttrValues = agileHashValues; /* make cached copy */ + if (sinfo->hashAgilityV2AttrValues) { + *sdict = sinfo->hashAgilityV2AttrValues; + return SECSuccess; + } + return errSecAllocate; +} + /* * Return the signing cert of a CMS signerInfo. * @@ -1215,7 +1326,7 @@ loser: /* * SecCmsSignerInfoAddMSSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the - * authenticated (i.e. signed) attributes of "signerinfo", using the OID prefered by Microsoft. + * authenticated (i.e. signed) attributes of "signerinfo", using the OID preferred by Microsoft. * * This is expected to be included in outgoing signed messages for email (S/MIME), * if compatibility with Microsoft mail clients is wanted. @@ -1289,7 +1400,7 @@ SecCmsSignerInfoAddCounterSignature(SecCmsSignerInfoRef signerinfo, /*! @function @abstract Add the Apple Codesigning Hash Agility attribute to the authenticated (i.e. signed) attributes of "signerinfo". - @discussion This is expected to be included in outgoing signed Apple code signatures. + @discussion This is expected to be included in outgoing Apple code signatures. */ OSStatus SecCmsSignerInfoAddAppleCodesigningHashAgility(SecCmsSignerInfoRef signerinfo, CFDataRef attrValue) @@ -1334,6 +1445,90 @@ loser: return status; } +static OSStatus CMSAddAgileHashToAttribute(PLArenaPool *poolp, SecCmsAttribute *attr, CFNumberRef cftag, CFDataRef value) { + PLArenaPool *tmppoolp = NULL; + int64_t tag; + SECOidData *digestOid = NULL; + CMSAppleAgileHash agileHash; + SecAsn1Item attrValue = { .Data = NULL, .Length = 0 }; + OSStatus status = errSecSuccess; + + memset(&agileHash, 0, sizeof(agileHash)); + + if(!CFNumberGetValue(cftag, kCFNumberSInt64Type, &tag)) { + return errSecParam; + } + digestOid = SECOID_FindOIDByTag((SECOidTag)tag); + + agileHash.digestValue.Data = (uint8_t *)CFDataGetBytePtr(value); + agileHash.digestValue.Length = CFDataGetLength(value); + agileHash.digestOID.Data = digestOid->oid.Data; + agileHash.digestOID.Length = digestOid->oid.Length; + + tmppoolp = PORT_NewArena(1024); + if (tmppoolp == NULL) { + return errSecAllocate; + } + + if (SEC_ASN1EncodeItem(tmppoolp, &attrValue, &agileHash, CMSAppleAgileHashTemplate) == NULL) { + status = errSecParam; + goto loser; + } + + status = SecCmsAttributeAddValue(poolp, attr, &attrValue); + +loser: + if (tmppoolp) { + PORT_FreeArena(tmppoolp, PR_FALSE); + } + return status; +} + +/*! + @function + @abstract Add the Apple Codesigning Hash Agility attribute to the authenticated (i.e. signed) attributes of "signerinfo". + @discussion This is expected to be included in outgoing Apple code signatures. + */ +OSStatus +SecCmsSignerInfoAddAppleCodesigningHashAgilityV2(SecCmsSignerInfoRef signerinfo, CFDictionaryRef attrValues) +{ + __block SecCmsAttribute *attr; + __block PLArenaPool *poolp = signerinfo->signedData->contentInfo.cmsg->poolp; + void *mark = PORT_ArenaMark(poolp); + OSStatus status = SECFailure; + + /* The value is required for this attribute. */ + if (!attrValues) { + status = errSecParam; + goto loser; + } + + if ((attr = SecCmsAttributeCreate(poolp, SEC_OID_APPLE_HASH_AGILITY_V2, + NULL, PR_TRUE)) == NULL) { + status = errSecAllocate; + goto loser; + } + + CFDictionaryForEach(attrValues, ^(const void *key, const void *value) { + if (!isNumber(key) || !isData(value)) { + return; + } + (void)CMSAddAgileHashToAttribute(poolp, attr, (CFNumberRef)key, (CFDataRef)value); + }); + + if (SecCmsSignerInfoAddAuthAttr(signerinfo, attr) != SECSuccess) { + status = errSecInternal; + goto loser; + } + + PORT_ArenaUnmark(poolp, mark); + return SECSuccess; + +loser: + PORT_ArenaRelease(poolp, mark); + return status; +} + SecCertificateRef SecCmsSignerInfoCopyCertFromEncryptionKeyPreference(SecCmsSignerInfoRef signerinfo) { SecCertificateRef cert = NULL; SecCmsAttribute *attr; @@ -1343,6 +1538,12 @@ SecCertificateRef SecCmsSignerInfoCopyCertFromEncryptionKeyPreference(SecCmsSign if (signerinfo->verificationStatus != SecCmsVSGoodSignature) return NULL; + /* Prep the rawCerts */ + SecAsn1Item **rawCerts = NULL; + if (signerinfo->signedData) { + rawCerts = signerinfo->signedData->rawCerts; + } + /* find preferred encryption cert */ if (!SecCmsArrayIsEmpty((void **)signerinfo->authAttr) && (attr = SecCmsAttributeArrayFindAttrByOidTag(signerinfo->authAttr, @@ -1351,11 +1552,17 @@ SecCertificateRef SecCmsSignerInfoCopyCertFromEncryptionKeyPreference(SecCmsSign ekp = SecCmsAttributeGetValue(attr); if (ekp == NULL) return NULL; + cert = SecSMIMEGetCertFromEncryptionKeyPreference(rawCerts, ekp); + } + if (cert) return cert; - SecAsn1Item **rawCerts = NULL; - if (signerinfo->signedData) { - rawCerts = signerinfo->signedData->rawCerts; - } + if (!SecCmsArrayIsEmpty((void **)signerinfo->authAttr) && + (attr = SecCmsAttributeArrayFindAttrByOidTag(signerinfo->authAttr, + SEC_OID_MS_SMIME_ENCRYPTION_KEY_PREFERENCE, PR_TRUE)) != NULL) + { /* we have a MS_SMIME_ENCRYPTION_KEY_PREFERENCE attribute! Find the cert. */ + ekp = SecCmsAttributeGetValue(attr); + if (ekp == NULL) + return NULL; cert = SecSMIMEGetCertFromEncryptionKeyPreference(rawCerts, ekp); } return cert; diff --git a/libsecurity_smime/lib/cmstpriv.h b/libsecurity_smime/lib/cmstpriv.h index 58f022a4..324e2ce1 100644 --- a/libsecurity_smime/lib/cmstpriv.h +++ b/libsecurity_smime/lib/cmstpriv.h @@ -207,6 +207,7 @@ struct SecCmsSignerInfoStr { SecPrivateKeyRef signingKey; /* Used if we're using subjKeyID*/ SecPublicKeyRef pubKey; CFDataRef hashAgilityAttrValue; + CFDictionaryRef hashAgilityV2AttrValues; }; #define SEC_CMS_SIGNER_INFO_VERSION_ISSUERSN 1 /* what we *create* */ #define SEC_CMS_SIGNER_INFO_VERSION_SUBJKEY 3 /* what we *create* */ diff --git a/libsecurity_smime/lib/secoid.c b/libsecurity_smime/lib/secoid.c index af40f9ca..491d64d4 100644 --- a/libsecurity_smime/lib/secoid.c +++ b/libsecurity_smime/lib/secoid.c @@ -481,6 +481,7 @@ __unused CONST_OID mqvSinglePassSha1kdf[] = {ANSI_X9_63_SCHEME, 4 }; /* Apple Hash Agility */ CONST_OID appleHashAgility[] = {APPLE_CMS_ATTRIBUTES, 1}; +CONST_OID appleHashAgilityV2[] = {APPLE_CMS_ATTRIBUTES, 2}; /* a special case: always associated with a caller-specified OID */ CONST_OID noOid[] = { 0 }; @@ -1161,6 +1162,9 @@ static const SECOidData oids[] = { OD( appleHashAgility, SEC_OID_APPLE_HASH_AGILITY, "appleCodesigningHashAgilityAttribute", CSSM_ALGID_NONE, INVALID_CERT_EXTENSION), + OD( appleHashAgilityV2, SEC_OID_APPLE_HASH_AGILITY_V2, + "appleCodesigningHashAgilityAttributeV2", CSSM_ALGID_NONE, + INVALID_CERT_EXTENSION), }; diff --git a/libsecurity_smime/lib/smimeutil.c b/libsecurity_smime/lib/smimeutil.c index 22694be9..3e7f1c04 100644 --- a/libsecurity_smime/lib/smimeutil.c +++ b/libsecurity_smime/lib/smimeutil.c @@ -758,8 +758,10 @@ static CFArrayRef CF_RETURNS_RETAINED copyCertsFromRawCerts(SecAsn1Item **rawCer for(dex=0; dexData, rawCerts[dex]->Length); - CFArrayAppendValue(certs, certificate); - CFRelease(certificate); + if (certificate) { + CFArrayAppendValue(certs, certificate); + CFRelease(certificate); + } certificate = NULL; } @@ -812,7 +814,7 @@ SecSMIMEGetCertFromEncryptionKeyPreference(SecAsn1Item **rawCerts, SecAsn1Item * } loser: if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE); - CFRelease(certs); + if (certs) CFRelease(certs); return cert; } diff --git a/libsecurity_smime/libCMS.xcodeproj/project.pbxproj b/libsecurity_smime/libCMS.xcodeproj/project.pbxproj index e87fd2ac..a11713cc 100644 --- a/libsecurity_smime/libCMS.xcodeproj/project.pbxproj +++ b/libsecurity_smime/libCMS.xcodeproj/project.pbxproj @@ -487,7 +487,7 @@ 4C2741E803E9FBAF00A80181 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0830; + LastUpgradeCheck = 0900; TargetAttributes = { D447C4DB1D31C9DD0082FC1D = { CreatedOnToolsVersion = 8.0; @@ -629,12 +629,18 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -741,7 +747,7 @@ "$(PROJECT_DIR)/..", "$(PROJECT_DIR)/../OSX/utilities", "$(PROJECT_DIR)/../OSX/sec", - "$(PROJECT_DIR)/../OSX/libsecurity_keychain/libDER", + "$(SDKROOT)/usr/local/include/security_libDER", "$(PROJECT_DIR)/../OSX/libsecurity_asn1", "$(PROJECT_DIR)/../header_symlinks/iOS/", "$(PROJECT_DIR)/../header_symlinks/", @@ -760,12 +766,18 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -867,7 +879,7 @@ "$(PROJECT_DIR)/..", "$(PROJECT_DIR)/../OSX/utilities", "$(PROJECT_DIR)/../OSX/sec", - "$(PROJECT_DIR)/../OSX/libsecurity_keychain/libDER", + "$(SDKROOT)/usr/local/include/security_libDER", "$(PROJECT_DIR)/../OSX/libsecurity_asn1", "$(PROJECT_DIR)/../header_symlinks/iOS/", "$(PROJECT_DIR)/../header_symlinks/", diff --git a/resources/English.lproj/Certificate.strings b/resources/English.lproj/Certificate.strings index 643fb21f..04daf46f 100644 Binary files a/resources/English.lproj/Certificate.strings and b/resources/English.lproj/Certificate.strings differ diff --git a/resources/English.lproj/CloudKeychain.strings b/resources/English.lproj/CloudKeychain.strings index e2c400c3..e1ba3019 100644 Binary files a/resources/English.lproj/CloudKeychain.strings and b/resources/English.lproj/CloudKeychain.strings differ diff --git a/resources/English.lproj/Trust.strings b/resources/English.lproj/Trust.strings new file mode 100644 index 00000000..7eac8dea Binary files /dev/null and b/resources/English.lproj/Trust.strings differ diff --git a/secdtests/secdtests-entitlements.plist b/secdtests/secdtests-entitlements.plist index f8a9fb8a..bf6ff173 100644 --- a/secdtests/secdtests-entitlements.plist +++ b/secdtests/secdtests-entitlements.plist @@ -36,6 +36,8 @@ com.apple.security.regressions com.apple.private.uninstall.deletion + com.apple.private.security.delete.all + keychain-access-groups com.apple.security.regressions @@ -46,17 +48,5 @@ com.apple.ProtectedCloudStorage com.apple.security.ckks - com.apple.private.ubiquity-kvstore-access - - com.apple.securityd - - com.apple.developer.ubiquity-kvstore-identifier - com.apple.security.cloudkeychainproxy - com.apple.developer.ubiquity-container-identifiers - - com.apple.security.cloudkeychainproxy - com.apple.security.cloudkeychain - CloudKeychainProxy.xpc - diff --git a/secdxctests/Info.plist b/secdxctests/Info.plist new file mode 100644 index 00000000..6c40a6cd --- /dev/null +++ b/secdxctests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/secdxctests/KeychainAPITests.m b/secdxctests/KeychainAPITests.m new file mode 100644 index 00000000..6252bc0c --- /dev/null +++ b/secdxctests/KeychainAPITests.m @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2018 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import "KeychainXCTest.h" +#import "SecDbKeychainItem.h" +#import "SecdTestKeychainUtilities.h" +#import "CKKS.h" +#import "SecDbKeychainItemV7.h" +#import "SecItemPriv.h" +#import "SecItemServer.h" +#import "spi.h" +#import "SecDbKeychainSerializedItemV7.h" +#import "SecDbKeychainSerializedMetadata.h" +#import "SecDbKeychainSerializedSecretData.h" +#import "SecDbKeychainSerializedAKSWrappedKey.h" +#import +#import +#import +#import + +void* testlist = NULL; + +#if USE_KEYSTORE + +@interface KeychainAPITests : KeychainXCTest +@end + +@implementation KeychainAPITests + ++ (void)setUp +{ + [super setUp]; + + SecCKKSDisable(); + securityd_init(NULL); +} + +- (void)setUp +{ + [super setUp]; + + NSArray* partsOfName = [self.name componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" ]"]]; + secd_test_setup_temp_keychain([partsOfName[1] UTF8String], NULL); +} + +- (void)testReturnValuesInSecItemUpdate +{ + NSDictionary* addQuery = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrService : @"TestService", + (id)kSecAttrNoLegacy : @(YES), + (id)kSecReturnAttributes : @(YES) + }; + + NSDictionary* updateQueryWithNoReturn = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrService : @"TestService", + (id)kSecAttrNoLegacy : @(YES) + }; + + CFTypeRef result = NULL; + + // Add the item + XCTAssertEqual(SecItemAdd((__bridge CFDictionaryRef)addQuery, &result), errSecSuccess, @"Should have succeeded in adding test item to keychain"); + XCTAssertNotNil((__bridge id)result, @"Should have received a dictionary back from SecItemAdd"); + CFReleaseNull(result); + + // And we can update the item + XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQueryWithNoReturn, (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"otherpassword" dataUsingEncoding:NSUTF8StringEncoding]}), errSecSuccess, "failed to update item with clean update query"); + + // great, a normal update works + // now let's do updates with various queries which include return parameters to ensure they succeed on macOS and throw errors on iOS. + // this is a status-quo compromise between changing iOS match macOS (which has lamé no-op characteristics) and changing macOS to match iOS, which risks breaking existing clients + +#if TARGET_OS_OSX + NSMutableDictionary* updateQueryWithReturnAttributes = updateQueryWithNoReturn.mutableCopy; + updateQueryWithReturnAttributes[(id)kSecReturnAttributes] = @(YES); + XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQueryWithReturnAttributes, (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"return-attributes" dataUsingEncoding:NSUTF8StringEncoding]}), errSecSuccess, "failed to update item with return attributes query"); + + NSMutableDictionary* updateQueryWithReturnData = updateQueryWithNoReturn.mutableCopy; + updateQueryWithReturnAttributes[(id)kSecReturnData] = @(YES); + XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQueryWithReturnData, (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"return-data" dataUsingEncoding:NSUTF8StringEncoding]}), errSecSuccess, "failed to update item with return data query"); + + NSMutableDictionary* updateQueryWithReturnRef = updateQueryWithNoReturn.mutableCopy; + updateQueryWithReturnAttributes[(id)kSecReturnRef] = @(YES); + XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQueryWithReturnRef, (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"return-ref" dataUsingEncoding:NSUTF8StringEncoding]}), errSecSuccess, "failed to update item with return ref query"); + + NSMutableDictionary* updateQueryWithReturnPersistentRef = updateQueryWithNoReturn.mutableCopy; + updateQueryWithReturnAttributes[(id)kSecReturnPersistentRef] = @(YES); + XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQueryWithReturnPersistentRef, (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"return-persistent-ref" dataUsingEncoding:NSUTF8StringEncoding]}), errSecSuccess, "failed to update item with return persistent ref query"); +#else + NSMutableDictionary* updateQueryWithReturnAttributes = updateQueryWithNoReturn.mutableCopy; + updateQueryWithReturnAttributes[(id)kSecReturnAttributes] = @(YES); + XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQueryWithReturnAttributes, (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"return-attributes" dataUsingEncoding:NSUTF8StringEncoding]}), errSecParam, "failed to generate error updating item with return attributes query"); + + NSMutableDictionary* updateQueryWithReturnData = updateQueryWithNoReturn.mutableCopy; + updateQueryWithReturnData[(id)kSecReturnData] = @(YES); + XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQueryWithReturnData, (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"return-data" dataUsingEncoding:NSUTF8StringEncoding]}), errSecParam, "failed to generate error updating item with return data query"); + + NSMutableDictionary* updateQueryWithReturnRef = updateQueryWithNoReturn.mutableCopy; + updateQueryWithReturnRef[(id)kSecReturnRef] = @(YES); + XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQueryWithReturnRef, (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"return-ref" dataUsingEncoding:NSUTF8StringEncoding]}), errSecParam, "failed to generate error updating item with return ref query"); + + NSMutableDictionary* updateQueryWithReturnPersistentRef = updateQueryWithNoReturn.mutableCopy; + updateQueryWithReturnPersistentRef[(id)kSecReturnPersistentRef] = @(YES); + XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQueryWithReturnPersistentRef, (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"return-persistent-ref" dataUsingEncoding:NSUTF8StringEncoding]}), errSecParam, "failed to generate error updating item with return persistent ref query"); +#endif +} + +@end + +#endif diff --git a/secdxctests/KeychainCryptoTests.m b/secdxctests/KeychainCryptoTests.m new file mode 100644 index 00000000..56625bed --- /dev/null +++ b/secdxctests/KeychainCryptoTests.m @@ -0,0 +1,769 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import "KeychainXCTest.h" +#import "SecDbKeychainItem.h" +#import "SecdTestKeychainUtilities.h" +#import "CKKS.h" +#import "SecDbKeychainItemV7.h" +#import "SecItemPriv.h" +#import "SecItemServer.h" +#import "spi.h" +#import "SecDbKeychainSerializedItemV7.h" +#import "SecDbKeychainSerializedMetadata.h" +#import "SecDbKeychainSerializedSecretData.h" +#import "SecDbKeychainSerializedAKSWrappedKey.h" +#import +#import +#import +#import +#import +#import + +@interface SecDbKeychainItemV7 () + ++ (SFAESKeySpecifier*)keySpecifier; + +@end + +#if USE_KEYSTORE +#include +#endif + +@interface KeychainCryptoTests : KeychainXCTest +@end + +@implementation KeychainCryptoTests + +#if USE_KEYSTORE +#include + +static keyclass_t parse_keyclass(CFTypeRef value) { + if (!value || CFGetTypeID(value) != CFStringGetTypeID()) { + return 0; + } + + if (CFEqual(value, kSecAttrAccessibleWhenUnlocked)) { + return key_class_ak; + } + else if (CFEqual(value, kSecAttrAccessibleAfterFirstUnlock)) { + return key_class_ck; + } + else if (CFEqual(value, kSecAttrAccessibleAlwaysPrivate)) { + return key_class_dk; + } + else if (CFEqual(value, kSecAttrAccessibleWhenUnlockedThisDeviceOnly)) { + return key_class_aku; + } + else if (CFEqual(value, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly)) { + return key_class_cku; + } + else if (CFEqual(value, kSecAttrAccessibleAlwaysThisDeviceOnlyPrivate)) { + return key_class_dku; + } + else if (CFEqual(value, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly)) { + return key_class_akpu; + } + else { + return 0; + } +} + +- (void)testBasicEncryptDecrypt +{ + CFDataRef enc = NULL; + CFErrorRef error = NULL; + SecAccessControlRef ac = NULL; + + NSDictionary* secretData = @{(id)kSecValueData : @"secret here"}; + + ac = SecAccessControlCreate(NULL, &error); + XCTAssertNotNil((__bridge id)ac, @"failed to create access control with error: %@", (__bridge id)error); + XCTAssertNil((__bridge id)error, @"encountered error attempting to create access control: %@", (__bridge id)error); + XCTAssertTrue(SecAccessControlSetProtection(ac, kSecAttrAccessibleWhenUnlocked, &error), @"failed to set access control protection with error: %@", error); + XCTAssertNil((__bridge id)error, @"encountered error attempting to set access control protection: %@", (__bridge id)error); + + XCTAssertTrue(ks_encrypt_data(KEYBAG_DEVICE, ac, NULL, (__bridge CFDictionaryRef)secretData, (__bridge CFDictionaryRef)@{}, NULL, &enc, true, &error), @"failed to encrypt data with error: %@", error); + XCTAssertTrue(enc != NULL, @"failed to get encrypted data from encryption function"); + XCTAssertNil((__bridge id)error, @"encountered error attempting to encrypt data: %@", (__bridge id)error); + CFReleaseNull(ac); + + CFMutableDictionaryRef attributes = NULL; + uint32_t version = 0; + + keyclass_t keyclass = 0; + XCTAssertTrue(ks_decrypt_data(KEYBAG_DEVICE, kAKSKeyOpDecrypt, &ac, NULL, enc, NULL, NULL, &attributes, &version, true, &keyclass, &error), @"failed to decrypt data with error: %@", error); + XCTAssertNil((__bridge id)error, @"encountered error attempting to decrypt data: %@", (__bridge id)error); + XCTAssertEqual(keyclass, key_class_ak, @"failed to get back the keyclass from decryption"); + + CFTypeRef aclProtection = ac ? SecAccessControlGetProtection(ac) : NULL; + XCTAssertNotNil((__bridge id)aclProtection, @"failed to get ACL from keychain item decryption"); + if (aclProtection) { + XCTAssertTrue(CFEqual(aclProtection, kSecAttrAccessibleWhenUnlocked), @"the acl we got back from decryption does not match what we put in"); + } + CFReleaseNull(ac); + + CFReleaseNull(error); + CFReleaseNull(enc); +} + +- (void)testGetMetadataThenData +{ + NSDictionary* item = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrService : @"TestService", + (id)kSecAttrNoLegacy : @(YES) }; + + OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to add test item to keychain"); + + NSMutableDictionary* metadataQuery = item.mutableCopy; + [metadataQuery removeObjectForKey:(id)kSecValueData]; + metadataQuery[(id)kSecReturnAttributes] = @(YES); + CFTypeRef foundItem = NULL; + result = SecItemCopyMatching((__bridge CFDictionaryRef)metadataQuery, &foundItem); + XCTAssertEqual(result, 0, @"failed to find the metadata for the item we just added in the keychain"); + + NSMutableDictionary* dataQuery = [(__bridge NSDictionary*)foundItem mutableCopy]; + dataQuery[(id)kSecReturnData] = @(YES); + dataQuery[(id)kSecClass] = (id)kSecClassGenericPassword; + dataQuery[(id)kSecAttrNoLegacy] = @(YES); + result = SecItemCopyMatching((__bridge CFDictionaryRef)dataQuery, &foundItem); + XCTAssertEqual(result, 0, @"failed to find the data for the item we just added to the keychain"); + + NSData* foundData = (__bridge NSData*)foundItem; + if ([foundData isKindOfClass:[NSData class]]) { + NSString* foundPassword = [[NSString alloc] initWithData:(__bridge NSData*)foundItem encoding:NSUTF8StringEncoding]; + XCTAssertEqualObjects(foundPassword, @"password", @"found password (%@) does not match the expected password", foundPassword); + } + else { + XCTAssertTrue(false, @"found data is not the expected class: %@", foundData); + } +} + +- (void)testGetReference +{ + NSDictionary* keyParams = @{ (id)kSecAttrKeyType : (id)kSecAttrKeyTypeRSA, (id)kSecAttrKeySizeInBits : @(1024) }; + SecKeyRef key = SecKeyCreateRandomKey((__bridge CFDictionaryRef)keyParams, NULL); + NSDictionary* item = @{ (id)kSecClass : (id)kSecClassKey, + (id)kSecValueRef : (__bridge id)key, + (id)kSecAttrLabel : @"TestLabel", + (id)kSecAttrNoLegacy : @(YES) }; + + OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to add test item to keychain"); + + NSMutableDictionary* refQuery = item.mutableCopy; + [refQuery removeObjectForKey:(id)kSecValueData]; + refQuery[(id)kSecReturnRef] = @(YES); + CFTypeRef foundItem = NULL; + result = SecItemCopyMatching((__bridge CFDictionaryRef)refQuery, &foundItem); + XCTAssertEqual(result, 0, @"failed to find the reference for the item we just added in the keychain"); + + NSData* originalKeyData = (__bridge_transfer NSData*)SecKeyCopyExternalRepresentation(key, NULL); + NSData* foundKeyData = (__bridge_transfer NSData*)SecKeyCopyExternalRepresentation((SecKeyRef)foundItem, NULL); + XCTAssertEqualObjects(originalKeyData, foundKeyData, @"found key does not match the key we put in the keychain"); +} + +- (void)testMetadataQueriesDoNotGetSecret +{ + NSDictionary* item = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrService : @"TestService", + (id)kSecAttrNoLegacy : @(YES) }; + + OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to add test item to keychain"); + + NSMutableDictionary* metadataQuery = item.mutableCopy; + [metadataQuery removeObjectForKey:(id)kSecValueData]; + metadataQuery[(id)kSecReturnAttributes] = @(YES); + CFTypeRef foundItem = NULL; + result = SecItemCopyMatching((__bridge CFDictionaryRef)metadataQuery, &foundItem); + XCTAssertEqual(result, 0, @"failed to find the metadata for the item we just added in the keychain"); + + NSData* data = [(__bridge NSDictionary*)foundItem valueForKey:(id)kSecValueData]; + XCTAssertNil(data, @"unexpectedly found data in a metadata query"); +} + +- (void)testDeleteItem +{ + NSDictionary* item = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrService : @"TestService", + (id)kSecAttrNoLegacy : @(YES) }; + + OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to add test item to keychain"); + + NSMutableDictionary* dataQuery = item.mutableCopy; + [dataQuery removeObjectForKey:(id)kSecValueData]; + dataQuery[(id)kSecReturnData] = @(YES); + CFTypeRef foundItem = NULL; + result = SecItemCopyMatching((__bridge CFDictionaryRef)dataQuery, &foundItem); + XCTAssertEqual(result, 0, @"failed to find the data for the item we just added in the keychain"); + + result = SecItemDelete((__bridge CFDictionaryRef)dataQuery); + XCTAssertEqual(result, 0, @"failed to delete item"); +} + +- (SecDbKeychainSerializedItemV7*)serializedItemWithPassword:(NSString*)password metadataAttributes:(NSDictionary*)metadata +{ + SecDbKeychainItemV7* item = [[SecDbKeychainItemV7 alloc] initWithSecretAttributes:@{(id)kSecValueData : password} metadataAttributes:metadata tamperCheck:[[NSUUID UUID] UUIDString] keyclass:9]; + [item encryptMetadataWithKeybag:0 error:nil]; + [item encryptSecretDataWithKeybag:0 accessControl:SecAccessControlCreate(NULL, NULL) acmContext:nil error:nil]; + SecDbKeychainSerializedItemV7* serializedItem = [[SecDbKeychainSerializedItemV7 alloc] init]; + serializedItem.encryptedMetadata = item.encryptedMetadataBlob; + serializedItem.encryptedSecretData = item.encryptedSecretDataBlob; + serializedItem.keyclass = 9; + return serializedItem; +} + +- (void)testTamperChecksThwartTampering +{ + SecDbKeychainSerializedItemV7* serializedItem1 = [self serializedItemWithPassword:@"first password" metadataAttributes:nil]; + SecDbKeychainSerializedItemV7* serializedItem2 = [self serializedItemWithPassword:@"second password" metadataAttributes:nil]; + + serializedItem1.encryptedSecretData = serializedItem2.encryptedSecretData; + NSData* tamperedSerializedItemBlob = serializedItem1.data; + + NSError* error = nil; + SecDbKeychainItemV7* item = [[SecDbKeychainItemV7 alloc] initWithData:tamperedSerializedItemBlob decryptionKeybag:0 error:&error]; + XCTAssertNil(item, @"unexpectedly deserialized an item blob which has been tampered"); + XCTAssertNotNil(error, @"failed to get an error when deserializing tampered item blob"); +} + +- (void)testCacheExpiration +{ + + NSDictionary* item = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrService : @"TestService", + (id)kSecAttrAccessible : (id)kSecAttrAccessibleWhenUnlocked, + (id)kSecAttrNoLegacy : @YES }; + + OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to add test item to keychain"); + + NSMutableDictionary* dataQuery = item.mutableCopy; + [dataQuery removeObjectForKey:(id)kSecValueData]; + dataQuery[(id)kSecReturnData] = @(YES); + + CFTypeRef foundItem = NULL; + + result = SecItemCopyMatching((__bridge CFDictionaryRef)dataQuery, &foundItem); + XCTAssertEqual(result, 0, @"failed to find the data for the item we just added in the keychain"); + CFReleaseNull(foundItem); + + self.lockState = LockStateLockedAndDisallowAKS; + + result = SecItemCopyMatching((__bridge CFDictionaryRef)dataQuery, &foundItem); + XCTAssertEqual(result, errSecInteractionNotAllowed, @"get the lock error"); + XCTAssertEqual(foundItem, NULL, @"got item anyway: %@", foundItem); + + self.lockState = LockStateUnlocked; + + result = SecItemCopyMatching((__bridge CFDictionaryRef)dataQuery, &foundItem); + XCTAssertEqual(result, 0, @"failed to find the data for the item we just added in the keychain"); + CFReleaseNull(foundItem); + + result = SecItemDelete((__bridge CFDictionaryRef)dataQuery); + XCTAssertEqual(result, 0, @"failed to delete item"); +} + +- (void)trashMetadataClassAKey +{ + CFErrorRef cferror = NULL; + + kc_with_dbt(true, &cferror, ^bool(SecDbConnectionRef dbt) { + CFErrorRef errref; + SecDbExec(dbt, CFSTR("DELETE FROM metadatakeys WHERE keyclass = '6'"), &errref); + CFReleaseNull(errref); + return true; + }); + CFReleaseNull(cferror); + + [[SecDbKeychainMetadataKeyStore sharedStore] dropClassAKeys]; +} + +- (void)testKeychainCorruptionCopyMatching +{ + NSDictionary* item = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrService : @"TestService", + (id)kSecAttrAccessible : (id)kSecAttrAccessibleWhenUnlocked, + (id)kSecAttrNoLegacy : @YES }; + + OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to add test item to keychain"); + + + NSMutableDictionary* dataQuery = item.mutableCopy; + [dataQuery removeObjectForKey:(id)kSecValueData]; + dataQuery[(id)kSecReturnData] = @(YES); + + CFTypeRef foundItem = NULL; + + result = SecItemCopyMatching((__bridge CFDictionaryRef)dataQuery, &foundItem); + XCTAssertEqual(result, 0, @"failed to find the data for the item we just added in the keychain"); + CFReleaseNull(foundItem); + + [self trashMetadataClassAKey]; + + /* when metadata corrupted, we should not find the item */ + result = SecItemCopyMatching((__bridge CFDictionaryRef)dataQuery, &foundItem); + XCTAssertEqual(result, errSecItemNotFound, @"failed to find the data for the item we just added in the keychain"); + CFReleaseNull(foundItem); + + /* semantics are odd, we should be able to delete it */ + result = SecItemDelete((__bridge CFDictionaryRef)dataQuery); + XCTAssertEqual(result, 0, @"failed to delete item"); +} + +- (void)testKeychainCorruptionAddOverCorruptedEntry +{ + CFTypeRef foundItem = NULL; + NSDictionary* item = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrService : @"TestService", + (id)kSecAttrAccessible : (id)kSecAttrAccessibleWhenUnlocked, + (id)kSecAttrNoLegacy : @YES }; + + OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to add test item to keychain"); + + NSMutableDictionary* dataQuery = item.mutableCopy; + [dataQuery removeObjectForKey:(id)kSecValueData]; + dataQuery[(id)kSecReturnData] = @(YES); + + result = SecItemCopyMatching((__bridge CFDictionaryRef)dataQuery, &foundItem); + XCTAssertEqual(result, 0, @"failed to find the data for the item we just added in the keychain"); + CFReleaseNull(foundItem); + + [self trashMetadataClassAKey]; + + result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to add test item to keychain"); + + result = SecItemDelete((__bridge CFDictionaryRef)dataQuery); + XCTAssertEqual(result, 0, @"failed to delete item"); +} + +- (void)testKeychainCorruptionUpdateCorruptedEntry +{ + CFTypeRef foundItem = NULL; + NSDictionary* item = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrService : @"TestService", + (id)kSecAttrAccessible : (id)kSecAttrAccessibleWhenUnlocked, + (id)kSecAttrNoLegacy : @YES }; + + OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to add test item to keychain"); + + NSMutableDictionary* dataQuery = item.mutableCopy; + [dataQuery removeObjectForKey:(id)kSecValueData]; + dataQuery[(id)kSecReturnData] = @(YES); + + result = SecItemCopyMatching((__bridge CFDictionaryRef)dataQuery, &foundItem); + XCTAssertEqual(result, 0, @"failed to find the data for the item we just added in the keychain"); + CFReleaseNull(foundItem); + + [self trashMetadataClassAKey]; + + NSMutableDictionary* updateQuery = item.mutableCopy; + updateQuery[(id)kSecValueData] = NULL; + NSDictionary *updateData = @{ + (id)kSecValueData : [@"foo" dataUsingEncoding:NSUTF8StringEncoding], + }; + + result = SecItemUpdate((__bridge CFDictionaryRef)updateQuery, + (__bridge CFDictionaryRef)updateData ); + XCTAssertEqual(result, errSecItemNotFound, @"failed to add test item to keychain"); + + result = SecItemDelete((__bridge CFDictionaryRef)dataQuery); + XCTAssertEqual(result, 0, @"failed to delete item"); +} + +- (id)encryptionOperation +{ + return nil; +} + +- (void)testNoCrashWhenMetadataDecryptionFails +{ + CFDataRef enc = NULL; + CFErrorRef error = NULL; + SecAccessControlRef ac = NULL; + + self.allowDecryption = NO; + + NSDictionary* secretData = @{(id)kSecValueData : @"secret here"}; + + ac = SecAccessControlCreate(NULL, &error); + XCTAssertNotNil((__bridge id)ac, @"failed to create access control with error: %@", (__bridge id)error); + XCTAssertNil((__bridge id)error, @"encountered error attempting to create access control: %@", (__bridge id)error); + XCTAssertTrue(SecAccessControlSetProtection(ac, kSecAttrAccessibleWhenUnlocked, &error), @"failed to set access control protection with error: %@", error); + XCTAssertNil((__bridge id)error, @"encountered error attempting to set access control protection: %@", (__bridge id)error); + + XCTAssertTrue(ks_encrypt_data(KEYBAG_DEVICE, ac, NULL, (__bridge CFDictionaryRef)secretData, (__bridge CFDictionaryRef)@{}, NULL, &enc, true, &error), @"failed to encrypt data with error: %@", error); + XCTAssertTrue(enc != NULL, @"failed to get encrypted data from encryption function"); + XCTAssertNil((__bridge id)error, @"encountered error attempting to encrypt data: %@", (__bridge id)error); + CFReleaseNull(ac); + + CFMutableDictionaryRef attributes = NULL; + uint32_t version = 0; + + keyclass_t keyclass = 0; + XCTAssertNoThrow(ks_decrypt_data(KEYBAG_DEVICE, kAKSKeyOpDecrypt, &ac, NULL, enc, NULL, NULL, &attributes, &version, true, &keyclass, &error), @"unexpected exception when decryption fails"); + XCTAssertEqual(keyclass, key_class_ak, @"failed to get back the keyclass when decryption failed"); + + self.allowDecryption = YES; +} + +#if 0 +// these tests fail until we address Fix keychain lock state check to be both secure and fast for EDU mode +- (void)testOperationsDontUseCachedKeysWhileLockedWithAKSAvailable // simulating the backup situation +{ + self.lockState = LockStateLockedAndAllowAKS; + + NSDictionary* item = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrService : @"TestService", + (id)kSecAttrNoLegacy : @(YES) }; + + OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to add test item to keychain"); + + NSMutableDictionary* metadataQuery = item.mutableCopy; + [metadataQuery removeObjectForKey:(id)kSecValueData]; + metadataQuery[(id)kSecReturnAttributes] = @(YES); + CFTypeRef foundItem = NULL; + result = SecItemCopyMatching((__bridge CFDictionaryRef)metadataQuery, &foundItem); + XCTAssertEqual(result, 0, @"failed to find the metadata for the item we just added in the keychain"); + + XCTAssertTrue(self.didAKSDecrypt, @"we did not go through AKS to decrypt the metadata key while locked - bad!"); + + NSMutableDictionary* dataQuery = item.mutableCopy; + dataQuery[(id)kSecReturnData] = @(YES); + result = SecItemCopyMatching((__bridge CFDictionaryRef)dataQuery, &foundItem); + XCTAssertEqual(result, 0, @"failed to find the data for the item we just added to the keychain"); + + NSData* foundData = (__bridge NSData*)foundItem; + if ([foundData isKindOfClass:[NSData class]]) { + NSString* foundPassword = [[NSString alloc] initWithData:(__bridge NSData*)foundItem encoding:NSUTF8StringEncoding]; + XCTAssertEqualObjects(foundPassword, @"password", @"found password (%@) does not match the expected password", foundPassword); + } + else { + XCTAssertTrue(false, @"found data is not the expected class: %@", foundData); + } +} + +- (void)testNoResultsWhenLocked +{ + NSDictionary* item = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrService : @"TestService", + (id)kSecAttrNoLegacy : @(YES) }; + + OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to add test item to keychain"); + + self.lockState = LockStateLockedAndDisallowAKS; + + NSMutableDictionary* metadataQuery = item.mutableCopy; + [metadataQuery removeObjectForKey:(id)kSecValueData]; + metadataQuery[(id)kSecReturnAttributes] = @(YES); + CFTypeRef foundItem = NULL; + result = SecItemCopyMatching((__bridge CFDictionaryRef)metadataQuery, &foundItem); + XCTAssertEqual(foundItem, NULL, @"somehow still got results when AKS was locked"); +} +#endif + +- (void)testRecoverFromBadMetadataKey +{ + // Disable caching, so we can change AKS encrypt/decrypt + id mockSecDbKeychainMetadataKeyStore = OCMClassMock([SecDbKeychainMetadataKeyStore class]); + OCMStub([mockSecDbKeychainMetadataKeyStore cachingEnabled]).andReturn(false); + + NSDictionary* addQuery = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrService : @"TestService", + (id)kSecAttrNoLegacy : @(YES), + (id)kSecReturnAttributes : @(YES), + }; + + NSDictionary* findQuery = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrService : @"TestService", + (id)kSecAttrNoLegacy : @(YES), + (id)kSecReturnAttributes : @(YES), + }; + +#if TARGET_OS_OSX + NSDictionary* updateQuery = findQuery; +#else + // iOS won't tolerate kSecReturnAttributes in SecItemUpdate + NSDictionary* updateQuery = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrService : @"TestService", + (id)kSecAttrNoLegacy : @(YES), + }; +#endif + + NSDictionary* addQuery2 = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : @"TestAccount-second", + (id)kSecAttrService : @"TestService-second", + (id)kSecAttrNoLegacy : @(YES), + (id)kSecReturnAttributes : @(YES), + }; + + NSDictionary* findQuery2 = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrAccount : @"TestAccount-second", + (id)kSecAttrService : @"TestService-second", + (id)kSecAttrNoLegacy : @(YES), + (id)kSecReturnAttributes : @(YES), + }; + + CFTypeRef result = NULL; + + // Add the item + XCTAssertEqual(SecItemAdd((__bridge CFDictionaryRef)addQuery, &result), errSecSuccess, @"Should have succeeded in adding test item to keychain"); + XCTAssertNotNil((__bridge id)result, @"Should have received a dictionary back from SecItemAdd"); + CFReleaseNull(result); + + // Add a second item, for fun and profit + XCTAssertEqual(SecItemAdd((__bridge CFDictionaryRef)addQuery2, &result), + errSecSuccess, + @"Should have succeeded in adding test2 item to keychain"); + + // And we can find te item + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)findQuery, &result), errSecSuccess, @"Should be able to find item"); + XCTAssertNotNil((__bridge id)result, @"Should have received a dictionary back from SecItemCopyMatching"); + CFReleaseNull(result); + + // And we can update the item + XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQuery, + (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"otherpassword" dataUsingEncoding:NSUTF8StringEncoding]}), + errSecSuccess, + "Should be able to update an item"); + + // And find it again + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)findQuery, &result), errSecSuccess, @"Should be able to find item"); + XCTAssertNotNil((__bridge id)result, @"Should have received a dictionary back from SecItemCopyMatching"); + CFReleaseNull(result); + + // And we can find the second item + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)findQuery2, &result), + errSecSuccess, @"Should be able to find second item"); + XCTAssertNotNil((__bridge id)result, @"Should have received a dictionary back from SecItemCopyMatching for item 2"); + CFReleaseNull(result); + + /////////////////////////////////////////////////////////////////////////////////// + // Now, the metadata keys go corrupt (fake that by changing the underlying AKS key) + [self setNewFakeAKSKey:[NSData dataWithBytes:"1234567890123456789000" length:32]]; + + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)findQuery, &result), errSecItemNotFound, + "should have received errSecItemNotFound when metadata keys are invalid"); + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)findQuery, &result), errSecItemNotFound, + "Multiple finds of the same item should receive errSecItemNotFound when metadata keys are invalid"); + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)findQuery, &result), errSecItemNotFound, + "Multiple finds of the same item should receive errSecItemNotFound when metadata keys are invalid"); + + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)findQuery2, &result), + errSecItemNotFound, @"Should not be able to find corrupt second item"); + XCTAssertNil((__bridge id)result, @"Should have received no data back from SICM for corrupt item"); + + // Updating the now-corrupt item should fail + XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQuery, + (__bridge CFDictionaryRef)@{ (id)kSecValueData: [@"otherpassword" dataUsingEncoding:NSUTF8StringEncoding] }), + errSecItemNotFound, + "Should not be able to update a corrupt item"); + + // Re-add the item (should succeed) + XCTAssertEqual(SecItemAdd((__bridge CFDictionaryRef)addQuery, &result), errSecSuccess, @"Should have succeeded in adding test item to keychain"); + XCTAssertNotNil((__bridge id)result, @"Should have received a dictionary back from SecItemAdd"); + CFReleaseNull(result); + + // And we can find it again + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)findQuery, &result), errSecSuccess, @"Should be able to find item"); + XCTAssertNotNil((__bridge id)result, @"Should have received a dictionary back from SecItemAdd"); + CFReleaseNull(result); + + // And update it + XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQuery, + (__bridge CFDictionaryRef)@{ (id)kSecValueData: [@"otherpassword" dataUsingEncoding:NSUTF8StringEncoding] }), + errSecSuccess, + "Should be able to update a fixed item"); + + ///////////// + // And our second item, which is wrapped under an old key, can't be found + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)findQuery2, &result), + errSecItemNotFound, @"Should not be able to find corrupt second item"); + XCTAssertNil((__bridge id)result, @"Should have received no data back from SICM for corrupt item"); + + // But can be re-added + XCTAssertEqual(SecItemAdd((__bridge CFDictionaryRef)addQuery2, &result), + errSecSuccess, + @"Should have succeeded in adding test2 item to keychain after corruption"); + XCTAssertNotNil((__bridge id)result, @"Should have received a dictionary back from SecItemAdd for item 2 (after corruption)"); + CFReleaseNull(result); + + // And we can find the second item again + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)findQuery2, &result), + errSecSuccess, @"Should be able to find second item after re-add"); + XCTAssertNotNil((__bridge id)result, @"Should have received a dictionary back from SecItemCopyMatching for item 2 (after re-add)"); + CFReleaseNull(result); + + [mockSecDbKeychainMetadataKeyStore stopMocking]; +} + +- (void)testRecoverDataFromBadKeyclassStorage +{ + NSDictionary* metadataAttributesInput = @{@"TestMetadata" : @"TestValue"}; + SecDbKeychainSerializedItemV7* serializedItem = [self serializedItemWithPassword:@"password" metadataAttributes:metadataAttributesInput]; + serializedItem.keyclass = (serializedItem.keyclass | key_class_last + 1); + + NSError* error = nil; + SecDbKeychainItemV7* item = [[SecDbKeychainItemV7 alloc] initWithData:serializedItem.data decryptionKeybag:0 error:&error]; + NSDictionary* metadataAttributesOut = [item metadataAttributesWithError:&error]; + XCTAssertEqualObjects(metadataAttributesOut, metadataAttributesInput, @"failed to retrieve metadata with error: %@", error); + XCTAssertNil(error, @"error encountered attempting to retrieve metadata: %@", error); +} + +- (NSData*)performItemEncryptionWithAccessibility:(CFStringRef)accessibility +{ + SecAccessControlRef ac = NULL; + CFDataRef enc = NULL; + CFErrorRef error = NULL; + + NSDictionary* secretData = @{(id)kSecValueData : @"secret here"}; + + ac = SecAccessControlCreate(NULL, &error); + XCTAssertNotNil((__bridge id)ac, @"failed to create access control with error: %@", (__bridge id)error); + XCTAssertNil((__bridge id)error, @"encountered error attempting to create access control: %@", (__bridge id)error); + XCTAssertTrue(SecAccessControlSetProtection(ac, accessibility, &error), @"failed to set access control protection with error: %@", error); + XCTAssertNil((__bridge id)error, @"encountered error attempting to set access control protection: %@", (__bridge id)error); + + XCTAssertTrue(ks_encrypt_data(KEYBAG_DEVICE, ac, NULL, (__bridge CFDictionaryRef)secretData, (__bridge CFDictionaryRef)@{}, NULL, &enc, true, &error), @"failed to encrypt data with error: %@", error); + XCTAssertTrue(enc != NULL, @"failed to get encrypted data from encryption function"); + XCTAssertNil((__bridge id)error, @"encountered error attempting to encrypt data: %@", (__bridge id)error); + CFReleaseNull(ac); + + return (__bridge_transfer NSData*)enc; +} + +- (void)performMetadataDecryptionOfData:(NSData*)encryptedData verifyingAccessibility:(CFStringRef)accessibility +{ + CFErrorRef error = NULL; + CFMutableDictionaryRef attributes = NULL; + uint32_t version = 0; + + SecAccessControlRef ac = SecAccessControlCreate(NULL, &error); + XCTAssertNotNil((__bridge id)ac, @"failed to create access control with error: %@", (__bridge id)error); + XCTAssertNil((__bridge id)error, @"encountered error attempting to create access control: %@", (__bridge id)error); + XCTAssertTrue(SecAccessControlSetProtection(ac, accessibility, &error), @"failed to set access control protection with error: %@", error); + XCTAssertNil((__bridge id)error, @"encountered error attempting to set access control protection: %@", (__bridge id)error); + + keyclass_t keyclass = 0; + XCTAssertTrue(ks_decrypt_data(KEYBAG_DEVICE, kAKSKeyOpDecrypt, &ac, NULL, (__bridge CFDataRef)encryptedData, NULL, NULL, &attributes, &version, false, &keyclass, &error), @"failed to decrypt data with error: %@", error); + XCTAssertNil((__bridge id)error, @"encountered error attempting to decrypt data: %@", (__bridge id)error); + XCTAssertEqual(keyclass & key_class_last, parse_keyclass(accessibility), @"failed to get back the keyclass from decryption"); + + CFReleaseNull(error); +} + +- (void)performMetadataEncryptDecryptWithAccessibility:(CFStringRef)accessibility +{ + NSData* encryptedData = [self performItemEncryptionWithAccessibility:accessibility]; + + [SecDbKeychainMetadataKeyStore resetSharedStore]; + + [self performMetadataDecryptionOfData:encryptedData verifyingAccessibility:accessibility]; +} + +- (void)testMetadataClassKeyDecryptionWithSimulatedAKSRolledKeys +{ + self.simulateRolledAKSKey = YES; + + [self performMetadataEncryptDecryptWithAccessibility:kSecAttrAccessibleWhenUnlocked]; + XCTAssertEqual(self.keyclassUsedForAKSDecryption, key_class_ak | key_class_last + 1); + + [self performMetadataEncryptDecryptWithAccessibility:kSecAttrAccessibleAfterFirstUnlock]; + XCTAssertEqual(self.keyclassUsedForAKSDecryption, key_class_ck | key_class_last + 1); + + [self performMetadataEncryptDecryptWithAccessibility:kSecAttrAccessibleAlways]; + XCTAssertEqual(self.keyclassUsedForAKSDecryption, key_class_dk | key_class_last + 1); + + [self performMetadataEncryptDecryptWithAccessibility:kSecAttrAccessibleWhenUnlockedThisDeviceOnly]; + XCTAssertEqual(self.keyclassUsedForAKSDecryption, key_class_aku | key_class_last + 1); + + [self performMetadataEncryptDecryptWithAccessibility:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly]; + XCTAssertEqual(self.keyclassUsedForAKSDecryption, key_class_cku | key_class_last + 1); + + [self performMetadataEncryptDecryptWithAccessibility:kSecAttrAccessibleAlwaysThisDeviceOnly]; + XCTAssertEqual(self.keyclassUsedForAKSDecryption, key_class_dku | key_class_last + 1); + + [self performMetadataEncryptDecryptWithAccessibility:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly]; + XCTAssertEqual(self.keyclassUsedForAKSDecryption, key_class_akpu | key_class_last + 1); +} + +- (void)testUpgradingMetadataKeyEntry +{ + // first, force the creation of a metadata key + NSData* encryptedData = [self performItemEncryptionWithAccessibility:kSecAttrAccessibleWhenUnlocked]; + + // now let's jury-rig this metadata key to look like an old one with no actualKeyclass information + __block CFErrorRef error = NULL; + __block bool ok = true; + ok &= kc_with_dbt(true, &error, ^bool(SecDbConnectionRef dbt) { + NSString* sql = [NSString stringWithFormat:@"UPDATE metadatakeys SET actualKeyclass = %d WHERE keyclass = %d", 0, key_class_ak]; + ok &= SecDbPrepare(dbt, (__bridge CFStringRef)sql, &error, ^(sqlite3_stmt* stmt) { + ok &= SecDbStep(dbt, stmt, &error, ^(bool* stop) { + // woohoo + }); + }); + + return ok; + }); + + // now, let's simulate AKS rejecting the decryption, and see if we recover and also update the database + self.simulateRolledAKSKey = YES; + [SecDbKeychainMetadataKeyStore resetSharedStore]; + [self performMetadataDecryptionOfData:encryptedData verifyingAccessibility:kSecAttrAccessibleWhenUnlocked]; +} + +#endif + +@end diff --git a/secdxctests/KeychainXCTest.h b/secdxctests/KeychainXCTest.h new file mode 100644 index 00000000..d8090993 --- /dev/null +++ b/secdxctests/KeychainXCTest.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import "KeychainXCTest.h" +#import "SecItemServer.h" +#import +#import +#import + +#if USE_KEYSTORE +#include + +typedef enum { + LockStateUnlocked, + LockStateLockedAndDisallowAKS, + LockStateLockedAndAllowAKS // this state matches how backup works while locked +} LockState; + +@interface KeychainXCTest : XCTestCase + +@property LockState lockState; +@property id mockSecDbKeychainItemV7; +@property bool allowDecryption; +@property BOOL didAKSDecrypt; +@property BOOL simulateRolledAKSKey; +@property keyclass_t keyclassUsedForAKSDecryption; + +@property SFAESKeySpecifier* keySpecifier; +@property SFAESKey* fakeAKSKey; + +- (bool)setNewFakeAKSKey:(NSData*)newKeyData; + +@end + +#endif diff --git a/secdxctests/KeychainXCTest.m b/secdxctests/KeychainXCTest.m new file mode 100644 index 00000000..77b1f8b3 --- /dev/null +++ b/secdxctests/KeychainXCTest.m @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2018 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import "KeychainXCTest.h" +#import "SecDbKeychainItem.h" +#import "SecdTestKeychainUtilities.h" +#import "CKKS.h" +#import "SecDbKeychainItemV7.h" +#import "SecItemPriv.h" +#import "SecItemServer.h" +#import "spi.h" +#import "SecDbKeychainSerializedItemV7.h" +#import "SecDbKeychainSerializedMetadata.h" +#import "SecDbKeychainSerializedSecretData.h" +#import "SecDbKeychainSerializedAKSWrappedKey.h" +#import +#import +#import +#import +#import + +#if USE_KEYSTORE + +@interface SecDbKeychainItemV7 () + ++ (SFAESKeySpecifier*)keySpecifier; + +@end + +@implementation KeychainXCTest + ++ (void)setUp +{ + [super setUp]; + + SecCKKSDisable(); + securityd_init(NULL); +} + +- (void)setUp +{ + [super setUp]; + + self.lockState = LockStateUnlocked; + self.allowDecryption = true; + self.didAKSDecrypt = NO; + self.simulateRolledAKSKey = NO; + + + self.keyclassUsedForAKSDecryption = 0; + + self.keySpecifier = [[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256]; + [self setNewFakeAKSKey:[NSData dataWithBytes:"1234567890123456789012" length:32]]; + + [SecDbKeychainMetadataKeyStore resetSharedStore]; + + self.mockSecDbKeychainItemV7 = OCMClassMock([SecDbKeychainItemV7 class]); + [[[[self.mockSecDbKeychainItemV7 stub] andCall:@selector(fakeAKSEncryptWithKeybag:keyclass:keyData:outKeyclass:wrappedKey:error:) onObject:self] ignoringNonObjectArgs] aksEncryptWithKeybag:0 keyclass:0 keyData:[OCMArg any] outKeyclass:NULL wrappedKey:[OCMArg any] error:NULL]; + [[[[self.mockSecDbKeychainItemV7 stub] andCall:@selector(fakeAKSDecryptWithKeybag:keyclass:wrappedKeyData:outKeyclass:unwrappedKey:error:) onObject:self] ignoringNonObjectArgs] aksDecryptWithKeybag:0 keyclass:0 wrappedKeyData:[OCMArg any] outKeyclass:NULL unwrappedKey:[OCMArg any] error:NULL]; + [[[self.mockSecDbKeychainItemV7 stub] andCall:@selector(decryptionOperation) onObject:self] decryptionOperation]; + [[[self.mockSecDbKeychainItemV7 stub] andCall:@selector(isKeychainUnlocked) onObject:self] isKeychainUnlocked]; + + NSArray* partsOfName = [self.name componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" ]"]]; + secd_test_setup_temp_keychain([partsOfName[1] UTF8String], NULL); +} + +- (void)tearDown +{ + [self.mockSecDbKeychainItemV7 stopMocking]; + [super tearDown]; +} + +- (bool)isKeychainUnlocked +{ + return self.lockState == LockStateUnlocked; +} + +- (id)decryptionOperation +{ + return self.allowDecryption ? [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:[SecDbKeychainItemV7 keySpecifier]] : nil; +} + +- (bool)setNewFakeAKSKey:(NSData*)newKeyData +{ + NSError* error = nil; + self.fakeAKSKey = [[SFAESKey alloc] initWithData:newKeyData specifier:self.keySpecifier error:&error]; + XCTAssertNil(error, "Should be no error making a fake AKS key"); + XCTAssertNotNil(self.fakeAKSKey, "Should have received a fake AKS key"); + return true; +} + +- (bool)fakeAKSEncryptWithKeybag:(keybag_handle_t)keybag + keyclass:(keyclass_t)keyclass + keyData:(NSData*)keyData + outKeyclass:(keyclass_t*)outKeyclass + wrappedKey:(NSMutableData*)wrappedKey + error:(NSError**)error +{ + if (self.lockState == LockStateLockedAndDisallowAKS) { + if (error) { + *error = [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecInteractionNotAllowed userInfo:NULL]; + } + return false; + } + + uint32_t keyLength = (uint32_t)keyData.length; + const uint8_t* keyBytes = keyData.bytes; + + NSData* dataToEncrypt = [NSData dataWithBytes:keyBytes length:keyLength]; + NSError* localError = nil; + + SFAuthenticatedEncryptionOperation* encryptionOperation = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:self.keySpecifier]; + encryptionOperation.authenticationCodeLength = 8; + SFAuthenticatedCiphertext* ciphertext = [encryptionOperation encrypt:dataToEncrypt withKey:self.fakeAKSKey error:&localError]; + + if (error) { + *error = localError; + } + + if (ciphertext) { + void* wrappedKeyMutableBytes = wrappedKey.mutableBytes; + memcpy(wrappedKeyMutableBytes, ciphertext.ciphertext.bytes, 32); + memcpy(wrappedKeyMutableBytes + 32, ciphertext.initializationVector.bytes, 32); + memcpy(wrappedKeyMutableBytes + 64, ciphertext.authenticationCode.bytes, 8); + + if (self.simulateRolledAKSKey && outKeyclass) { + *outKeyclass = keyclass | (key_class_last + 1); + } + + return true; + } + else { + return false; + } +} + +- (bool)fakeAKSDecryptWithKeybag:(keybag_handle_t)keybag + keyclass:(keyclass_t)keyclass + wrappedKeyData:(NSData*)wrappedKeyData + outKeyclass:(keyclass_t*)outKeyclass + unwrappedKey:(NSMutableData*)unwrappedKey + error:(NSError**)error +{ + if (self.lockState == LockStateLockedAndDisallowAKS) { + if (error) { + *error = [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecInteractionNotAllowed userInfo:NULL]; + } + return false; + } + + if (self.simulateRolledAKSKey && keyclass < key_class_last) { + // let's make decryption fail like it would if this were an old metadata key entry made with a generational AKS key, but we didn't store that info in the database + return false; + } + + const uint8_t* wrappedKeyBytes = wrappedKeyData.bytes; + + NSData* ciphertextData = [NSData dataWithBytes:wrappedKeyBytes length:32]; + NSData* ivData = [NSData dataWithBytes:wrappedKeyBytes + 32 length:32]; + NSData* authCodeData = [NSData dataWithBytes:wrappedKeyBytes + 64 length:8]; + SFAuthenticatedCiphertext* ciphertext = [[SFAuthenticatedCiphertext alloc] initWithCiphertext:ciphertextData authenticationCode:authCodeData initializationVector:ivData]; + + NSError* localError = nil; + + SFAuthenticatedEncryptionOperation* encryptionOperation = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:self.keySpecifier]; + encryptionOperation.authenticationCodeLength = 8; + NSData* decryptedData = [encryptionOperation decrypt:ciphertext withKey:self.fakeAKSKey error:&localError]; + + // in real securityd, we go through AKS rather than SFCryptoServices + // we need to translate the error for proper handling + if ([localError.domain isEqualToString:SFCryptoServicesErrorDomain] && localError.code == SFCryptoServicesErrorDecryptionFailed) { + if (!self.simulateRolledAKSKey && keyclass > key_class_last) { + // for this case we want to simulate what happens when we try decrypting with a rolled keyclass on a device which has never been rolled, which is it ends up with a NotPermitted error from AKS which the security layer translates as locked keybag + localError = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecInteractionNotAllowed userInfo:nil]; + } + else { + localError = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecDecode userInfo:nil]; + } + } + + if (error) { + *error = localError; + } + + self.keyclassUsedForAKSDecryption = keyclass; + if (decryptedData && decryptedData.length <= unwrappedKey.length) { + memcpy(unwrappedKey.mutableBytes, decryptedData.bytes, decryptedData.length); + unwrappedKey.length = decryptedData.length; + self.didAKSDecrypt = YES; + return true; + } + else { + return false; + } +} + +@end + +#endif diff --git a/sectask/SecEntitlements.h b/sectask/SecEntitlements.h index f366beb4..2784e788 100644 --- a/sectask/SecEntitlements.h +++ b/sectask/SecEntitlements.h @@ -123,6 +123,9 @@ __BEGIN_DECLS /* Entitlement to control usage of deletion of keychain items on app uninstallation */ #define kSecEntitlementPrivateUninstallDeletion CFSTR("com.apple.private.uninstall.deletion") +/* Entitlement to control usage of deletion of keychain items wholesale */ +#define kSecEntitlementPrivateDeleteAll CFSTR("com.apple.private.security.delete.all") + /* Entitlement to allow access to circle joining APIs in SOSCC */ #define kSecEntitlementCircleJoin CFSTR("com.apple.private.keychain.circle.join") @@ -152,6 +155,14 @@ __BEGIN_DECLS #define kSecEntitlementBackupTableOperationsDeleteAll CFSTR("com.apple.private.keychain.backuptableops.deleteall") +/* Entitlement to allow executing keychain control actions */ +#define kSecEntitlementKeychainControl CFSTR("com.apple.private.keychain.keychaincontrol") + +#if __OBJC__ +/* Entitlement to control use of OT */ +#define kSecEntitlementPrivateOctagon @"com.apple.private.octagon" +#endif + __END_DECLS #endif /* !_SECURITY_SECENTITLEMENTS_H_ */ diff --git a/security-sysdiagnose/security-sysdiagnose.entitlements.plist b/security-sysdiagnose/security-sysdiagnose.entitlements.plist index 2f7c59a9..481bf502 100644 --- a/security-sysdiagnose/security-sysdiagnose.entitlements.plist +++ b/security-sysdiagnose/security-sysdiagnose.entitlements.plist @@ -2,6 +2,8 @@ + com.apple.private.securityuploadd + keychain-access-groups com.apple.hap.pairing diff --git a/security-sysdiagnose/security-sysdiagnose.m b/security-sysdiagnose/security-sysdiagnose.m index eca91e9f..1456af69 100644 --- a/security-sysdiagnose/security-sysdiagnose.m +++ b/security-sysdiagnose/security-sysdiagnose.m @@ -40,6 +40,7 @@ #include "accountCirclesViewsPrint.h" #import "CKKSControlProtocol.h" #import "SecItemPriv.h" +#import "supdProtocol.h" #include @@ -99,16 +100,7 @@ circle_sysdiagnose(void) static void engine_sysdiagnose(void) { - [@"Engine state:\n" writeToStdOut]; - - CFErrorRef error = NULL; - - if (!SOSCCForEachEngineStateAsString(&error, ^(CFStringRef oneStateString) { - [(__bridge NSString*) oneStateString writeToStdOut]; - [@"\n" writeToStdOut]; - })) { - [[NSString stringWithFormat: @"No engine state, got error: %@", error] writeToStdOut]; - } + SOSCCDumpEngineInformation(); } /* @@ -247,54 +239,38 @@ idsproxy_sysdiagnose(void) } static void -kvs_sysdiagnose(void) { - SOSLogSetOutputTo(NULL,NULL); - SOSCCDumpCircleKVSInformation(NULL); -} - - -static void -ckks_analytics_sysdiagnose(void) +analytics_sysdiagnose(void) { - CFErrorRef error = NULL; - xpc_endpoint_t xpcEndpoint = _SecSecuritydCopyCKKSEndpoint(&error); - if (!xpcEndpoint) { - [[NSString stringWithFormat:@"failed to get CKKSControl endpoint with error: %@\n", error] writeToStdErr]; - return; - } - - NSXPCInterface* xpcInterface = [NSXPCInterface interfaceWithProtocol:@protocol(CKKSControlProtocol)]; - NSXPCListenerEndpoint* listenerEndpoint = [[NSXPCListenerEndpoint alloc] init]; - [listenerEndpoint _setEndpoint:xpcEndpoint]; - - NSXPCConnection* xpcConnection = [[NSXPCConnection alloc] initWithListenerEndpoint:listenerEndpoint]; + NSXPCConnection* xpcConnection = [[NSXPCConnection alloc] initWithMachServiceName:@"com.apple.securityuploadd" options:NSXPCConnectionPrivileged]; if (!xpcConnection) { - [@"failed to setup xpc connection for CKKSControl\n" writeToStdErr]; + [@"failed to setup xpc connection for securityuploadd\n" writeToStdErr]; + return; } - - xpcConnection.remoteObjectInterface = xpcInterface; + xpcConnection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(supdProtocol)]; [xpcConnection resume]; - + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [[xpcConnection remoteObjectProxyWithErrorHandler:^(NSError* rpcError) { [[NSString stringWithFormat:@"Error talking with daemon: %@\n", rpcError] writeToStdErr]; dispatch_semaphore_signal(semaphore); - }] rpcGetAnalyticsSysdiagnoseWithReply:^(NSString* sysdiagnose, NSError* rpcError) { - if (sysdiagnose && !error) { + }] getSysdiagnoseDumpWithReply:^(NSString* sysdiagnose) { + if (sysdiagnose) { [[NSString stringWithFormat:@"\nAnalytics sysdiagnose:\n\n%@\n", sysdiagnose] writeToStdOut]; } - else { - [[NSString stringWithFormat:@"error retrieving sysdiagnose: %@\n", rpcError] writeToStdErr]; - } - dispatch_semaphore_signal(semaphore); }]; - + if (dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60)) != 0) { [@"\n\nError: timed out waiting for response\n" writeToStdErr]; } } +static void +kvs_sysdiagnose(void) { + SOSLogSetOutputTo(NULL,NULL); + SOSCCDumpCircleKVSInformation(NULL); +} + int main(int argc, const char ** argv) { @@ -306,8 +282,8 @@ main(int argc, const char ** argv) homekit_sysdiagnose(); unlock_sysdiagnose(); idsproxy_sysdiagnose(); - ckks_analytics_sysdiagnose(); - + analytics_sysdiagnose(); + // Keep this one last kvs_sysdiagnose(); } diff --git a/securityd/etc/com.apple.securityd.plist b/securityd/etc/com.apple.securityd.plist index bc500da6..e1729686 100644 --- a/securityd/etc/com.apple.securityd.plist +++ b/securityd/etc/com.apple.securityd.plist @@ -33,8 +33,6 @@ LaunchOnlyOnce - BeginTransactionAtShutdown - EnableTransactions POSIXSpawnType diff --git a/securityd/securityd_service/securityd_service/main.c b/securityd/securityd_service/securityd_service/main.c index 57ccd3e0..28be2bed 100644 --- a/securityd/securityd_service/securityd_service/main.c +++ b/securityd/securityd_service/securityd_service/main.c @@ -296,6 +296,8 @@ _kb_save_bag_to_disk(service_user_record_t * ur, const char * bag_file, void * d if (renamex_np(tmp_bag, bag_file, RENAME_SWAP) != 0) { os_log(OS_LOG_DEFAULT, "Warning: atomic swap failed"); require_noerr_action(rename(tmp_bag, bag_file), done, os_log(OS_LOG_DEFAULT, "could not save keybag file")); + } else { + (void)unlink(tmp_bag); } result = true; @@ -474,7 +476,7 @@ out: } static int -_kb_set_user_uuid(service_context_t * context, const void * secret, int secret_len) +_kb_set_properties(service_context_t * context, const void * secret, int secret_len) { int result = KB_GeneralError; CFMutableDictionaryRef options = NULL; @@ -484,7 +486,17 @@ _kb_set_user_uuid(service_context_t * context, const void * secret, int secret_l /* set user uuid, if not already set */ passcode = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, secret, secret_len, kCFAllocatorNull); - MKBKeyBagSetUserUUID(options, passcode); + if (MKBKeyBagSetUserUUID(options, passcode)) { + os_log(OS_LOG_DEFAULT, "set user uuid failed"); + } + +#ifdef MKB_SUPPORTS_BIND_KEK + if (MKBKeyBagBindKEK(options, passcode)) { + os_log(OS_LOG_DEFAULT, "KEK bind failed"); + } +#else + os_log(OS_LOG_DEFAULT, "Not bindinig KEK, update SDK"); +#endif result = KB_Success; done: @@ -521,7 +533,7 @@ service_kb_create(service_context_t * context, const void * secret, int secret_l } if (rc == KB_Success) { - _kb_set_user_uuid(context, secret, secret_len); + _kb_set_properties(context, secret, secret_len); } done: @@ -572,8 +584,8 @@ _service_kb_load_uid(uid_t s_uid) os_log(OS_LOG_DEFAULT, "bag load failed 0x%x for uid (%i)", rc, s_uid); break; } - require_noerr(rc, done; _stage = 4); - require_noerr(rc = _service_kb_set_system(private_handle, s_uid), done; _stage = 5); + require_noerr_action(rc, done, _stage = 4); + require_noerr_action(rc = _service_kb_set_system(private_handle, s_uid), done, _stage = 5); } require(rc == KB_Success, done); @@ -759,7 +771,7 @@ service_kb_reset(service_context_t * context, const void * secret, int secret_le } if (rc == KB_Success) { - _kb_set_user_uuid(context, secret, secret_len); + _kb_set_properties(context, secret, secret_len); } done: diff --git a/securityd/securityd_service/securityd_service/service.entitlements b/securityd/securityd_service/securityd_service/service.entitlements index cd19a719..bbc96664 100644 --- a/securityd/securityd_service/securityd_service/service.entitlements +++ b/securityd/securityd_service/securityd_service/service.entitlements @@ -4,6 +4,8 @@ com.apple.keystore.access-keychain-keys + com.apple.keystore.config.bind_kek_to_kb + com.apple.keystore.config.set.user_uuid com.apple.keystore.device diff --git a/securityd/src/agentquery.cpp b/securityd/src/agentquery.cpp index afacd8b3..dbf52186 100644 --- a/securityd/src/agentquery.cpp +++ b/securityd/src/agentquery.cpp @@ -551,8 +551,14 @@ Reason QueryKeychainUse::queryUser (const char *database, const char *descriptio continue; passwordItem->getCssmData(data); + + { + // Must hold the 'common' lock to call decode; otherwise there's a data corruption issue + StLock _(const_cast(mPassphraseCheck)->common()); + reason = (const_cast(mPassphraseCheck)->decode(data) ? SecurityAgent::noReason : SecurityAgent::invalidPassphrase); + } } - while ((reason = (const_cast(mPassphraseCheck)->decode(data) ? SecurityAgent::noReason : SecurityAgent::invalidPassphrase))); + while (reason != SecurityAgent::noReason); readChoice(); } @@ -649,6 +655,9 @@ Reason QueryOld::operator () () // Reason QueryUnlock::accept(CssmManagedData &passphrase) { + // Must hold the 'common' lock to call decode; otherwise there's a data corruption issue + StLock _(safer_cast(database).common()); + if (safer_cast(database).decode(passphrase)) return SecurityAgent::noReason; else diff --git a/securityd/src/transition.cpp b/securityd/src/transition.cpp index 37852c0f..c3dffa69 100644 --- a/securityd/src/transition.cpp +++ b/securityd/src/transition.cpp @@ -772,6 +772,8 @@ kern_return_t ucsp_server_stashDbCheck(UCSP_ARGS, DbHandle db) kern_return_t ucsp_server_isLocked(UCSP_ARGS, DbHandle db, boolean_t *locked) { BEGIN_IPC(isLocked) + // Must hold the DB's common's lock to safely determine if it's locked. Locking is a mess in there. + StLock _(Server::database(db)->common()); *locked = Server::database(db)->isLocked(); END_IPC(DL) } diff --git a/supd/Info.plist b/supd/Info.plist new file mode 100644 index 00000000..e1e1219f --- /dev/null +++ b/supd/Info.plist @@ -0,0 +1,29 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + supd + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + XPC! + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + XPCService + + ServiceType + Application + + + diff --git a/supd/Tests/Info.plist b/supd/Tests/Info.plist new file mode 100644 index 00000000..6c40a6cd --- /dev/null +++ b/supd/Tests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/supd/Tests/SFAnalyticsTests.m b/supd/Tests/SFAnalyticsTests.m new file mode 100644 index 00000000..7ffa7b04 --- /dev/null +++ b/supd/Tests/SFAnalyticsTests.m @@ -0,0 +1,767 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import +#import "SFAnalytics.h" +#import "SFAnalyticsDefines.h" +#import +#import +#import + +@interface UnitTestAnalytics : SFAnalytics ++ (NSString*)databasePath; ++ (void)setDatabasePath:(NSString*)path; +@end + +// MARK: SFAnalytics subclass for custom DB + +@implementation UnitTestAnalytics +static NSString* _utapath; + ++ (NSString*)databasePath +{ + return _utapath; +} + ++ (void)setDatabasePath:(NSString*)path +{ + _utapath = path; +} + +@end + +@interface SFAnalyticsTests : XCTestCase +@end + +@implementation SFAnalyticsTests +{ + UnitTestAnalytics* _analytics; + NSString* _dbpath; + PQLConnection* _db; +} + +static NSString* _path; +static NSInteger _testnum; +static NSString* build = NULL; +static NSString* product = NULL; + +// MARK: Test helper methods + +- (void)assertNoSuccessEvents +{ + XCTAssertFalse([[_db fetch:@"select * from success_count"] next]); +} + +- (void)assertNoHardFailures +{ + XCTAssertFalse([[_db fetch:@"select * from hard_failures"] next]); +} + +- (void)assertNoSoftFailures +{ + XCTAssertFalse([[_db fetch:@"select * from soft_failures"] next]); +} + +- (void)assertNoAllEvents +{ + XCTAssertFalse([[_db fetch:@"select * from all_events"] next]); +} + +- (void)assertNoSamples +{ + XCTAssertFalse([[_db fetch:@"select * from samples"] next]); +} + +- (void)assertNoEventsAnywhere +{ + [self assertNoAllEvents]; + [self assertNoSuccessEvents]; + [self assertNoHardFailures]; + [self assertNoSoftFailures]; + [self assertNoSamples]; +} + +- (void)recentTimeStamp:(NSNumber*)timestamp +{ + XCTAssert([timestamp isKindOfClass:[NSNumber class]], @"Timestamp is an NSNumber"); + NSDate* eventTime = [NSDate dateWithTimeIntervalSince1970:[timestamp doubleValue]]; + XCTAssertLessThanOrEqual([[NSDate date] timeIntervalSinceDate:eventTime], 5, @"Timestamp (%@) is pretty recent", timestamp); +} + +- (void)properEventLogged:(PQLResultSet*)result eventType:(NSString*)eventType class:(SFAnalyticsEventClass)class attributes:(NSDictionary*)attrs +{ + [self _properEventLogged:result eventType:eventType class:class]; + + NSDictionary* rowdata = [NSPropertyListSerialization propertyListWithData:[result dataAtIndex:2] options:NSPropertyListImmutable format:nil error:nil]; + for (NSString* key in [attrs allKeys]) { + XCTAssert([attrs[key] isEqualToString:rowdata[key]], @"Attribute \"%@\" value \"%@\" matches expected \"%@\"", key, rowdata[key], attrs[key]); + } + XCTAssertFalse([result next], @"only one row returned"); +} + +- (void)properEventLogged:(PQLResultSet*)result eventType:(NSString*)eventType class:(SFAnalyticsEventClass)class +{ + [self _properEventLogged:result eventType:eventType class:class]; + XCTAssertFalse([result next], @"only one row returned"); +} + +- (void)_properEventLogged:(PQLResultSet*)result eventType:(NSString*)eventType class:(SFAnalyticsEventClass)class +{ + XCTAssert([result next], @"result found after adding an event"); + NSError* error = nil; + [result doubleAtIndex:1]; + NSDictionary* rowdata = [NSPropertyListSerialization propertyListWithData:[result dataAtIndex:2] options:NSPropertyListImmutable format:nil error:&error]; + XCTAssertNotNil(rowdata, @"able to deserialize db data, %@", error); + [self recentTimeStamp:rowdata[SFAnalyticsEventTime]]; + XCTAssertTrue([rowdata[SFAnalyticsEventType] isKindOfClass:[NSString class]] && [rowdata[SFAnalyticsEventType] isEqualToString:eventType], @"found eventType \"%@\" in db", eventType); + XCTAssertTrue([rowdata[SFAnalyticsEventClassKey] isKindOfClass:[NSNumber class]] && [rowdata[SFAnalyticsEventClassKey] intValue] == class, @"eventClass is %ld", class); + XCTAssertTrue([rowdata[@"build"] isEqualToString:build], @"event row includes build"); + XCTAssertTrue([rowdata[@"product"] isEqualToString:product], @"event row includes product"); +} + +- (void)checkSuccessCountsForEvent:(NSString*)eventType success:(int)success hard:(int)hard soft:(int)soft +{ + PQLResultSet* result = [_db fetch:@"select * from success_count where event_type = %@", eventType]; + XCTAssert([result next]); + XCTAssertTrue([[result stringAtIndex:0] isEqualToString:eventType], @"event name \"%@\", expected \"%@\"", [result stringAtIndex:0], eventType); + XCTAssertEqual([result intAtIndex:1], success, @"correct count of successes: %d / %d", [result intAtIndex:1], success); + XCTAssertEqual([result intAtIndex:2], hard, @"correct count of successes: %d / %d", [result intAtIndex:2], hard); + XCTAssertEqual([result intAtIndex:3], soft, @"correct count of successes: %d / %d", [result intAtIndex:3], soft); + XCTAssertFalse([result next], @"no more than one row returned"); +} + +- (void)checkSamples:(NSArray*)samples name:(NSString*)samplerName totalSamples:(NSUInteger)total accuracy:(double)accuracy +{ + NSUInteger samplescount = 0, targetcount = 0; + NSMutableArray* samplesfound = [NSMutableArray array]; + PQLResultSet* result = [_db fetch:@"select * from samples"]; + while ([result next]) { + ++samplescount; + [self recentTimeStamp:[result numberAtIndex:1]]; + if ([[result stringAtIndex:2] isEqual:samplerName]) { + ++targetcount; + [samplesfound addObject:[result numberAtIndex:3]]; + } + } + + XCTAssertEqual([samples count], targetcount); + XCTAssertEqual(samplescount, total); + + [samplesfound sortUsingSelector:@selector(compare:)]; + NSArray* sortedInput = [samples sortedArrayUsingSelector:@selector(compare:)]; + for (NSUInteger idx = 0; idx < [samples count]; ++idx) { + XCTAssertEqualWithAccuracy([samplesfound[idx] doubleValue], [sortedInput[idx] doubleValue], accuracy); + } +} + +- (void)waitForSamplerWork:(double)interval +{ + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * interval), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ + dispatch_semaphore_signal(sema); + }); + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); +} + +// MARK: Test administration + ++ (void)setUp +{ + NSError* error; + _path = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@/", [[NSUUID UUID] UUIDString]]]; + [[NSFileManager defaultManager] createDirectoryAtPath:_path + withIntermediateDirectories:YES + attributes:nil + error:&error]; + // No XCTAssert in class method + if (error) { + NSLog(@"Could not make directory at %@", _path); + } + NSDictionary *version = CFBridgingRelease(_CFCopySystemVersionDictionary()); + if (version) { + build = version[(__bridge NSString *)_kCFSystemVersionBuildVersionKey]; + product = version[(__bridge NSString *)_kCFSystemVersionProductNameKey]; + } else { + NSLog(@"could not get build version/product, tests should fail"); + } +} + +- (void)setUp +{ + [super setUp]; + self.continueAfterFailure = NO; + NSError* error = nil; + _dbpath = [_path stringByAppendingFormat:@"/test_%ld.db", (long)++_testnum]; + NSLog(@"sqlite3 %@", _dbpath); + [UnitTestAnalytics setDatabasePath:_dbpath]; + _analytics = [UnitTestAnalytics logger]; + _db = [PQLConnection new]; + + XCTAssertTrue([_db openAtURL:[NSURL URLWithString:_dbpath] sharedCache:NO error:&error]); + XCTAssertNil(error, @"could open db"); + XCTAssertNotNil(_db); +} + +- (void)tearDown +{ + NSError *error = nil; + XCTAssertTrue([_db close:&error], @"could close db"); + XCTAssertNil(error, @"No error from closing db"); + [_analytics removeState]; + [super tearDown]; +} + ++ (void)tearDown +{ + [[NSFileManager defaultManager] removeItemAtPath:_path error:nil]; +} + +// MARK: SFAnalytics Tests + +- (void)testDbIsEmptyAtStartup +{ + [self assertNoEventsAnywhere]; +} + +- (void)testAddingEventsWithNilName +{ + [_analytics logSuccessForEventNamed:nil]; + [self assertNoEventsAnywhere]; + + [_analytics logHardFailureForEventNamed:nil withAttributes:nil]; + [self assertNoEventsAnywhere]; + + [_analytics logSoftFailureForEventNamed:nil withAttributes:nil]; + [self assertNoEventsAnywhere]; + + [_analytics noteEventNamed:nil]; + [self assertNoEventsAnywhere]; +} + +- (void)testLogSuccess +{ + [_analytics logSuccessForEventNamed:@"unittestevent"]; + [self assertNoHardFailures]; + [self assertNoSoftFailures]; + + PQLResultSet* result = [_db fetch:@"select success_count from success_count"]; + XCTAssert([result next], @"a row was found after adding an event"); + XCTAssertEqual([result intAtIndex:0], 1, @"success count is 1 after adding an event"); + XCTAssertFalse([result next], @"only one row found in success_count after inserting a single event"); + result = [_db fetch:@"select * from all_events"]; + [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassSuccess]; +} + +- (void)testLogRecoverableFailure +{ + [_analytics logSoftFailureForEventNamed:@"unittestevent" withAttributes:nil]; + [self assertNoHardFailures]; + + // First check success_count has logged a soft failure + [self checkSuccessCountsForEvent:@"unittestevent" success:0 hard:0 soft:1]; + + // then check soft_failures itself + PQLResultSet* result = [_db fetch:@"select * from soft_failures"]; + [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassSoftFailure]; + + // finally check all_events + result = [_db fetch:@"select * from all_events"]; + [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassSoftFailure]; +} + +- (void)testLogRecoverablyFailureWithAttributes +{ + NSDictionary* attrs = @{@"attr1" : @"value1", @"attr2" : @"value2"}; + [_analytics logSoftFailureForEventNamed:@"unittestevent" withAttributes:attrs]; + [self assertNoHardFailures]; + + [self checkSuccessCountsForEvent:@"unittestevent" success:0 hard:0 soft:1]; + + // then check soft_failures itself + PQLResultSet* result = [_db fetch:@"select * from soft_failures"]; + [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassSoftFailure attributes:attrs]; + + // finally check all_events + result = [_db fetch:@"select * from all_events"]; + [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassSoftFailure attributes:attrs]; +} + +- (void)testLogUnrecoverableFailure +{ + [_analytics logHardFailureForEventNamed:@"unittestevent" withAttributes:nil]; + [self assertNoSoftFailures]; + + // First check success_count has logged a hard failure + [self checkSuccessCountsForEvent:@"unittestevent" success:0 hard:1 soft:0]; + + // then check hard_failures itself + PQLResultSet* result = [_db fetch:@"select * from hard_failures"]; + [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassHardFailure]; + + // finally check all_events + result = [_db fetch:@"select * from all_events"]; + [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassHardFailure]; +} + +- (void)testLogUnrecoverableFailureWithAttributes +{ + NSDictionary* attrs = @{@"attr1" : @"value1", @"attr2" : @"value2"}; + [_analytics logHardFailureForEventNamed:@"unittestevent" withAttributes:attrs]; + [self assertNoSoftFailures]; + + // First check success_count has logged a hard failure + [self checkSuccessCountsForEvent:@"unittestevent" success:0 hard:1 soft:0]; + + // then check hard_failures itself + PQLResultSet* result = [_db fetch:@"select * from hard_failures"]; + [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassHardFailure attributes:attrs]; + + // finally check all_events + result = [_db fetch:@"select * from all_events"]; + [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassHardFailure attributes:attrs]; +} + +- (void)testLogSeveralEvents +{ + NSDictionary* attrs = @{@"attr1" : @"value1", @"attr2" : @"value2"}; + int iterations = 100; + for (int idx = 0; idx < iterations; ++idx) { + [_analytics logHardFailureForEventNamed:@"unittesthardfailure" withAttributes:attrs]; + [_analytics logSoftFailureForEventNamed:@"unittestsoftfailure" withAttributes:attrs]; + [_analytics logSuccessForEventNamed:@"unittestsuccess"]; + [_analytics logHardFailureForEventNamed:@"unittestcombined" withAttributes:attrs]; + [_analytics logSoftFailureForEventNamed:@"unittestcombined" withAttributes:attrs]; + [_analytics logSuccessForEventNamed:@"unittestcombined"]; + } + + [self checkSuccessCountsForEvent:@"unittesthardfailure" success:0 hard:iterations soft:0]; + [self checkSuccessCountsForEvent:@"unittestsoftfailure" success:0 hard:0 soft:iterations]; + [self checkSuccessCountsForEvent:@"unittestsuccess" success:iterations hard:0 soft:0]; + [self checkSuccessCountsForEvent:@"unittestcombined" success:iterations hard:iterations soft:iterations]; +} + +- (void)testNoteEvent +{ + [_analytics noteEventNamed:@"unittestevent"]; + [self assertNoSoftFailures]; + [self assertNoHardFailures]; + + // First check success_count has logged a success + [self checkSuccessCountsForEvent:@"unittestevent" success:1 hard:0 soft:0]; + + PQLResultSet* result = [_db fetch:@"select * from all_events"]; + [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassNote]; +} + +// MARK: SFAnalyticsSampler Tests + +- (void)testSamplerSimple +{ + NSString* samplerName = [NSString stringWithFormat:@"UnitTestSamplerSimple_%li", (long)_testnum]; + + // This block should be set immediately and fire in 1000ms. Give it a little slack in checking though + XCTestExpectation* exp = [self expectationWithDescription:@"waiting for sampler to fire"]; + [_analytics addMetricSamplerForName:samplerName withTimeInterval:1.0f block:^NSNumber *{ + [exp fulfill]; + return @15.3; + }]; + [self waitForExpectations:@[exp] timeout:1.2f]; + [_analytics removeMetricSamplerForName:samplerName]; + + // The expectation is fulfilled before returning and after returning some more work needs to happen. Let it settle down. + [self waitForSamplerWork:0.2f]; + + [self checkSamples:@[@15.3] name:samplerName totalSamples:1 accuracy:0.01f]; +} + +// Test state removal mostly +- (void)testSamplerSimpleLoop +{ + [self tearDown]; + for (int idx = 0; idx < 3; ++idx) { + [self setUp]; + @autoreleasepool { + [self testSamplerSimple]; + } + [self tearDown]; + } +} + + +- (void)testSamplerDoesNotFirePrematurely +{ + NSString* samplerName = [NSString stringWithFormat:@"UnitTestSamplerDoesNotFirePrematurely_%li", (long)_testnum]; + __block BOOL run = NO; + [_analytics addMetricSamplerForName:samplerName withTimeInterval:1.0f block:^NSNumber *{ + run = YES; + return @0.9; + }]; + + [self waitForSamplerWork:0.5f]; + XCTAssertFalse(run, @"sample did not fire prematurely"); + [_analytics removeMetricSamplerForName:samplerName]; +} + +- (void)testSamplerRemove +{ + NSString* samplerName = [NSString stringWithFormat:@"UnitTestSamplerRemove_%li", (long)_testnum]; + __block BOOL run = NO; + [_analytics addMetricSamplerForName:samplerName withTimeInterval:1.0f block:^NSNumber *{ + run = YES; + return @23.8; + }]; + XCTAssertNotNil([_analytics existingMetricSamplerForName:samplerName], @"SFAnalytics held onto the sampler we setup"); + [_analytics removeMetricSamplerForName:samplerName]; + XCTAssertNil([_analytics existingMetricSamplerForName:samplerName], @"SFAnalytics got rid of our sampler"); + + [self waitForSamplerWork:2.0f]; + XCTAssertFalse(run, @"sampler did not run after removal"); +} + +- (void)testSamplerRepeatedSampling +{ + NSString* samplerName = [NSString stringWithFormat:@"UnitTestSamplerRepeatedSampling_%li", (long)_testnum]; + __block int run = 0; + [_analytics addMetricSamplerForName:samplerName withTimeInterval:1.0f block:^NSNumber *{ + run += 1; + return @1.5; + }]; + + [self waitForSamplerWork:3.5f]; + [_analytics removeMetricSamplerForName:samplerName]; + XCTAssertEqual(run, 3, @"sampler ran correct number of times"); + [self checkSamples:@[@1.5, @1.5, @1.5] name:samplerName totalSamples:3 accuracy:0.01f]; +} + +- (void)testSamplerDisable +{ + NSString* samplerName = [NSString stringWithFormat:@"UnitTestSamplerDisable_%li", (long)_testnum]; + __block int run = 0; + [_analytics addMetricSamplerForName:samplerName withTimeInterval:1.0f block:^NSNumber *{ + run += 1; + return @44.9; + }]; + + [[_analytics existingMetricSamplerForName:samplerName] pauseSampling]; + [self waitForSamplerWork:2.0f]; + XCTAssertEqual(run, 0, @"sampler did not run while disabled"); + + [[_analytics existingMetricSamplerForName:samplerName] resumeSampling]; + [self waitForSamplerWork:1.3f]; + XCTAssertEqual(run, 1, @"sampler ran after resuming"); + + [self checkSamples:@[@44.9] name:samplerName totalSamples:1 accuracy:0.01f]; +} + +- (void)testSamplerWithBadData +{ + NSString* samplerName = [NSString stringWithFormat:@"UnitTestSamplerWithBadData_%li", (long)_testnum]; + + // bad name + XCTAssertNil([_analytics addMetricSamplerForName:nil withTimeInterval:3.0f block:^NSNumber *{ + return @0.0; + }]); + + // bad interval + XCTAssertNil([_analytics addMetricSamplerForName:samplerName withTimeInterval:0.0f block:^NSNumber *{ + return @0.0; + }]); + + XCTAssertNil([_analytics addMetricSamplerForName:samplerName withTimeInterval:2.0f block:nil]); +} + +- (void)testSamplerOncePerReport +{ + NSString* samplerName = [NSString stringWithFormat:@"UnitTestSamplerOncePerReport_%li", (long)_testnum]; + __block int run = 0; + [_analytics addMetricSamplerForName:samplerName withTimeInterval:SFAnalyticsSamplerIntervalOncePerReport block:^NSNumber *{ + run += 1; + return @74.1; + }]; + + // There's no point in waiting, it could have been set to some arbitrarily long timer instead + + notify_post(SFAnalyticsFireSamplersNotification); + [self waitForSamplerWork:0.5f]; + XCTAssertEqual(run, 1, @"once-per-report sampler fired once in response to notification"); + [self checkSamples:@[@74.1] name:samplerName totalSamples:1 accuracy:0.01f]; +} + +- (void)testSamplerOncePerReportEnsuresSingleSampleInDatabase +{ + NSString* samplerName = [NSString stringWithFormat:@"UnitTestSamplerSetTimeInterval_%li", (long)_testnum]; + [_analytics addMetricSamplerForName:samplerName withTimeInterval:SFAnalyticsSamplerIntervalOncePerReport block:^NSNumber *{ + return @57.6; + }]; + notify_post(SFAnalyticsFireSamplersNotification); + [self waitForSamplerWork:0.5f]; + notify_post(SFAnalyticsFireSamplersNotification); + [self waitForSamplerWork:0.5f]; + [self checkSamples:@[@57.6] name:samplerName totalSamples:1 accuracy:0.01f]; +} + +- (void)testSamplerAddSamplerTwice +{ + NSString* samplerName = [NSString stringWithFormat:@"UnitTestSamplerDisable_%li", (long)_testnum]; + XCTAssertNotNil([_analytics addMetricSamplerForName:samplerName withTimeInterval:3.0f block:^NSNumber *{ + return @7.7; + }], @"adding first sampler works okay"); + + XCTAssertNil([_analytics addMetricSamplerForName:samplerName withTimeInterval:3.0f block:^NSNumber *{ + return @7.8; + }], @"adding duplicate sampler did not work"); +} + +- (void)testSamplerLogBadSample +{ + [_analytics logMetric:nil withName:@"testsampler"]; + [self checkSamples:@[] name:@"testsampler" totalSamples:0 accuracy:0.01f]; + + id badobj = [NSString stringWithUTF8String:"yolo!"]; + [_analytics logMetric:badobj withName:@"testSampler"]; + [self checkSamples:@[] name:@"testsampler" totalSamples:0 accuracy:0.01f]; +} + +- (void)testSamplerSetTimeInterval +{ + NSString* samplerName = [NSString stringWithFormat:@"UnitTestSamplerSetTimeInterval_%li", (long)_testnum]; + __block NSUInteger run = 0; + + [_analytics addMetricSamplerForName:samplerName withTimeInterval:1.0f block:^NSNumber *{ + ++run; + return @23.8; + }]; + [self waitForSamplerWork:1.2f]; + [_analytics existingMetricSamplerForName:samplerName].samplingInterval = 1.5f; + [self waitForSamplerWork:2.5f]; + XCTAssertEqual(run, 2ul); + [self checkSamples:@[@23.8, @23.8] name:samplerName totalSamples:2 accuracy:0.01f]; +} + +// MARK: SFAnalyticsMultiSampler Tests + +- (void)testMultiSamplerSimple +{ + NSString* samplerName = [NSString stringWithFormat:@"UnitTestMultiSamplerSimple_%li", (long)_testnum]; + + XCTestExpectation* exp = [self expectationWithDescription:@"waiting for sampler to fire"]; + [_analytics AddMultiSamplerForName:samplerName withTimeInterval:1.0f block:^NSDictionary *{ + [exp fulfill]; + return @{@"val1" : @89.4f, @"val2" : @11.2f}; + }]; + [self waitForExpectations:@[exp] timeout:1.3f]; + [_analytics removeMultiSamplerForName:samplerName]; + + // The expectation is fulfilled before returning and after returning some more work needs to happen. Let it settle down. + [self waitForSamplerWork:0.2f]; + + [self checkSamples:@[@89.4f] name:@"val1" totalSamples:2 accuracy:0.01f]; + [self checkSamples:@[@11.2f] name:@"val2" totalSamples:2 accuracy:0.01f]; +} + +- (void)testMultiSamplerOncePerReport +{ + NSString* samplerName = [NSString stringWithFormat:@"UnitTestMultiSamplerOncePerReport_%li", (long)_testnum]; + __block int run = 0; + [_analytics AddMultiSamplerForName:samplerName withTimeInterval:SFAnalyticsSamplerIntervalOncePerReport block:^NSDictionary *{ + run += 1; + return @{@"val1" : @33.8f, @"val2" : @54.6f}; + }]; + + // There's no point in waiting, it could have been set to some arbitrarily long timer instead + + notify_post(SFAnalyticsFireSamplersNotification); + [self waitForSamplerWork:1.0f]; + XCTAssertEqual(run, 1, @"once-per-report sampler fired once in response to notification"); + [self checkSamples:@[@33.8f] name:@"val1" totalSamples:2 accuracy:0.01f]; + [self checkSamples:@[@54.6f] name:@"val2" totalSamples:2 accuracy:0.01f]; +} + +- (void)testMultiSamplerSetTimeInterval +{ + NSString* samplerName = [NSString stringWithFormat:@"UnitTestMultiSamplerSetTimeInterval_%li", (long)_testnum]; + __block NSUInteger run = 0; + [_analytics AddMultiSamplerForName:samplerName withTimeInterval:1.0f block:^NSDictionary *{ + ++run; + return @{@"val1" : @29.3f, @"val2" : @19.3f}; + }]; + [self waitForSamplerWork:1.2f]; + [_analytics existingMultiSamplerForName:samplerName].samplingInterval = 1.5f; + [self waitForSamplerWork:2.5f]; + XCTAssertEqual(run, 2ul); + [self checkSamples:@[@29.3f, @29.3f] name:@"val1" totalSamples:4 accuracy:0.01f]; + [self checkSamples:@[@19.3f, @19.3f] name:@"val2" totalSamples:4 accuracy:0.01f]; +} + + +// MARK: SFAnalyticsActivityTracker Tests + +- (void)testTrackerSimple +{ + NSString* trackerName = @"UnitTestTrackerSimple"; + @autoreleasepool { + [_analytics logSystemMetricsForActivityNamed:trackerName withAction:^{ + [NSThread sleepForTimeInterval:0.3f]; + }]; + } + + + [self checkSamples:@[@(0.3f * NSEC_PER_SEC)] name:trackerName totalSamples:1 accuracy:(0.01f * NSEC_PER_SEC)]; +} + +- (void)testTrackerMultipleBlocks +{ + NSString* trackerName = @"UnitTestTrackerMultipleBlocks"; + @autoreleasepool { + SFAnalyticsActivityTracker* tracker = [_analytics logSystemMetricsForActivityNamed:trackerName withAction:^{ + [NSThread sleepForTimeInterval:0.3f]; + }]; + + [tracker performAction:^{ + [NSThread sleepForTimeInterval:0.2f]; + }]; + } + + [self checkSamples:@[@(0.5f * NSEC_PER_SEC)] name:trackerName totalSamples:1 accuracy:(0.1f * NSEC_PER_SEC)]; +} + +- (void)testTrackerAction +{ + NSString* trackerName = @"UnitTestTrackerOneBlock"; + @autoreleasepool { + SFAnalyticsActivityTracker* tracker = [_analytics logSystemMetricsForActivityNamed:trackerName withAction:NULL]; + [tracker performAction:^{ + [NSThread sleepForTimeInterval:0.2f]; + }]; + } + + [self checkSamples:@[@(0.2f * NSEC_PER_SEC)] name:trackerName totalSamples:1 accuracy:(0.1f * NSEC_PER_SEC)]; +} + +- (void)testTrackerStartStop { + + NSString* trackerName = @"UnitTestTrackerStartStop"; + @autoreleasepool { + SFAnalyticsActivityTracker* tracker = [_analytics logSystemMetricsForActivityNamed:trackerName withAction:NULL]; + [tracker start]; + [NSThread sleepForTimeInterval:0.2f]; + [tracker stop]; + } + + [self checkSamples:@[@(0.2f * NSEC_PER_SEC)] name:trackerName totalSamples:1 accuracy:(0.1f * NSEC_PER_SEC)]; +} + + + +- (void)testTrackerCancel +{ + NSString* trackerName = @"UnitTestTrackerCancel"; + @autoreleasepool { + [[_analytics logSystemMetricsForActivityNamed:trackerName withAction:^{ + [NSThread sleepForTimeInterval:0.3f]; + }] cancel]; + } + + [self assertNoEventsAnywhere]; +} + + + +- (void)testTrackerBadData +{ + // Inspect database to find out it's empty + [_analytics logMetric:nil withName:@"fake"]; + [_analytics logMetric:@3.0 withName:nil]; + + // get object back so inspect that, too + XCTAssertNil([_analytics logSystemMetricsForActivityNamed:nil withAction:^{return;}]); + + [self assertNoEventsAnywhere]; +} + +// MARK: Miscellaneous + +- (void)testInstantiateBaseClass +{ + XCTAssertNil([SFAnalytics logger]); +} + +- (void)testFuzzyDaysSinceDate +{ + NSInteger secondsPerDay = 60 * 60 * 24; + XCTAssertEqual([SFAnalytics fuzzyDaysSinceDate:[NSDate date]], 0); + XCTAssertEqual([SFAnalytics fuzzyDaysSinceDate:[NSDate dateWithTimeIntervalSinceNow:secondsPerDay * -3]], 1); + XCTAssertEqual([SFAnalytics fuzzyDaysSinceDate:[NSDate dateWithTimeIntervalSinceNow:secondsPerDay * -18]], 7); + XCTAssertEqual([SFAnalytics fuzzyDaysSinceDate:[NSDate dateWithTimeIntervalSinceNow:secondsPerDay * -77]], 30); + XCTAssertEqual([SFAnalytics fuzzyDaysSinceDate:[NSDate dateWithTimeIntervalSinceNow:secondsPerDay * -370]], 365); + XCTAssertEqual([SFAnalytics fuzzyDaysSinceDate:[NSDate distantPast]], 1000); + XCTAssertEqual([SFAnalytics fuzzyDaysSinceDate:nil], -1); +} + +- (void)testRingBuffer { + [self assertNoEventsAnywhere]; + for (unsigned idx = 0; idx < (SFAnalyticsMaxEventsToReport + 50); ++idx) { + [_analytics logHardFailureForEventNamed:@"ringbufferevent" withAttributes:nil]; + } + + PQLResultSet* result = [_db fetch:@"select count(*) from hard_failures"]; + XCTAssertTrue([result next], @"Got a count from hard_failures"); + XCTAssertLessThanOrEqual([result unsignedIntAtIndex:0], SFAnalyticsMaxEventsToReport, @"Ring buffer contains a sane number of events"); + + // all_events has a much larger buffer so it should handle the extra events okay + result = [_db fetch:@"select count(*) from all_events"]; + XCTAssertTrue([result next], @"Got a count from all_events"); + XCTAssertLessThanOrEqual([result unsignedIntAtIndex:0], SFAnalyticsMaxEventsToReport + 50); +} + +- (void)testRaceToCreateLoggers +{ + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + for (NSInteger idx = 0; idx < 500; ++idx) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + UnitTestAnalytics* logger = [UnitTestAnalytics logger]; + [logger logSuccessForEventNamed:@"testevent"]; + dispatch_semaphore_signal(semaphore); + }); + } + + for (NSInteger idx = 0; idx < 500; ++idx) { + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + } +} + +- (void)testDateProperty +{ + NSString* propertyKey = @"testDataPropertyKey"; + XCTAssertNil([_analytics datePropertyForKey:propertyKey]); + NSDate* test = [NSDate date]; + [_analytics setDateProperty:test forKey:propertyKey]; + NSDate* retrieved = [_analytics datePropertyForKey:propertyKey]; + XCTAssert(retrieved); + // Storing in SQLite as string loses subsecond resolution, so we need some slack + XCTAssertEqualWithAccuracy([test timeIntervalSinceDate:retrieved], 0, 1); + [_analytics setDateProperty:nil forKey:propertyKey]; + XCTAssertNil([_analytics datePropertyForKey:propertyKey]); +} + +@end diff --git a/supd/Tests/SupdTests.m b/supd/Tests/SupdTests.m new file mode 100644 index 00000000..ed617a7b --- /dev/null +++ b/supd/Tests/SupdTests.m @@ -0,0 +1,757 @@ +/* + * Copyright (c) 2017-2018 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import +#import +#import "supd.h" +#import "SFAnalytics.h" +#import "SFAnalyticsDefines.h" +#import + +static NSString* _path; +static NSInteger _testnum; +static NSString* build = NULL; +static NSString* product = NULL; +static NSInteger _reporterWrites; +static NSInteger _reporterCleanups; + +// MARK: Stub FakeCKKSAnalytics + +@interface FakeCKKSAnalytics : SFAnalytics + +@end + +@implementation FakeCKKSAnalytics + ++ (NSString*)databasePath +{ + return [_path stringByAppendingFormat:@"/ckks_%ld.db", _testnum]; +} + +@end + + +// MARK: Stub FakeSOSAnalytics + +@interface FakeSOSAnalytics : SFAnalytics + +@end + +@implementation FakeSOSAnalytics + ++ (NSString*)databasePath +{ + return [_path stringByAppendingFormat:@"/sos_%ld.db", _testnum]; +} + +@end + + +// MARK: Stub FakePCSAnalytics + +@interface FakePCSAnalytics : SFAnalytics + +@end + +@implementation FakePCSAnalytics + ++ (NSString*)databasePath +{ + return [_path stringByAppendingFormat:@"/pcs_%ld.db", _testnum]; +} + +@end + +// MARK: Stub FakeTLSAnalytics + +@interface FakeTLSAnalytics : SFAnalytics + +@end + +@implementation FakeTLSAnalytics + ++ (NSString*)databasePath +{ + return [_path stringByAppendingFormat:@"/tls_%ld.db", _testnum]; +} + +@end + +// MARK: Start SupdTests + +@interface SupdTests : XCTestCase + +@end + +@implementation SupdTests { + supd* _supd; + id mockReporter; + FakeCKKSAnalytics* _ckksAnalytics; + FakeSOSAnalytics* _sosAnalytics; + FakePCSAnalytics* _pcsAnalytics; + FakeTLSAnalytics* _tlsAnalytics; +} + +// MARK: Test helper methods +- (SFAnalyticsTopic *)keySyncTopic { + for (SFAnalyticsTopic *topic in _supd.analyticsTopics) { + if ([topic.internalTopicName isEqualToString:SFAnalyticsTopicKeySync]) { + return topic; + } + } + return nil; +} + +- (void)inspectDataBlobStructure:(NSDictionary*)data +{ + if (!data || ![data isKindOfClass:[NSDictionary class]]) { + XCTFail(@"data is an NSDictionary"); + } + + XCTAssert(_supd.analyticsTopics, @"supd has nonnull topics list"); + SFAnalyticsTopic *keySyncTopic = [self keySyncTopic]; + XCTAssert([keySyncTopic splunkTopicName], @"supd has a nonnull topic name"); + XCTAssertEqual([data count], 2ul, @"dictionary event and posttime objects"); + XCTAssertTrue(data[@"events"] && [data[@"events"] isKindOfClass:[NSArray class]], @"data blob contains an NSArray 'events'"); + XCTAssertTrue(data[@"postTime"] && [data[@"postTime"] isKindOfClass:[NSNumber class]], @"data blob contains an NSNumber 'postTime"); + NSDate* postTime = [NSDate dateWithTimeIntervalSince1970:[data[@"postTime"] doubleValue]]; + XCTAssertTrue([[NSDate date] timeIntervalSinceDate:postTime] < 3, @"postTime is sane"); + + for (NSDictionary* event in data[@"events"]) { + if ([event isKindOfClass:[NSDictionary class]]) { + XCTAssertTrue([event[@"build"] isEqual:build], @"event contains correct build string"); + XCTAssertTrue([event[@"product"] isEqual:product], @"event contains correct product string"); + XCTAssertTrue([event[@"eventTime"] isKindOfClass:[NSNumber class]], @"event contains an NSNumber 'eventTime"); + NSDate* eventTime = [NSDate dateWithTimeIntervalSince1970:[event[@"eventTime"] doubleValue]]; + XCTAssertTrue([[NSDate date] timeIntervalSinceDate:eventTime] < 3, @"eventTime is sane"); + XCTAssertTrue([event[@"eventType"] isKindOfClass:[NSString class]], @"all events have a type"); + XCTAssertTrue([event[@"topic"] isEqual:[keySyncTopic splunkTopicName]], @"all events have a topic name"); + } else { + XCTFail(@"event %@ is an NSDictionary", event); + } + } +} + +- (BOOL)event:(NSDictionary*)event containsAttributes:(NSDictionary*)attrs { + if (!attrs) { + return YES; + } + __block BOOL equal = YES; + [attrs enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { + equal &= [event[key] isEqualToString:obj]; + }]; + return equal; +} + +- (int)failures:(NSDictionary*)data eventType:(NSString*)type attributes:(NSDictionary*)attrs class:(SFAnalyticsEventClass)class +{ + int encountered = 0; + for (NSDictionary* event in data[@"events"]) { + if ([event[@"eventType"] isEqualToString:type] && + [event[@"eventClass"] isKindOfClass:[NSNumber class]] && + [event[@"eventClass"] intValue] == class && [self event:event containsAttributes:attrs]) { + ++encountered; + } + } + return encountered; +} + +- (void)checkTotalEventCount:(NSDictionary*)data hard:(int)hard soft:(int)soft forcedFail:(BOOL)forcedFail +{ + int hardfound = 0, softfound = 0; + NSUInteger summfound = 0; + for (NSDictionary* event in data[@"events"]) { + if ([event[SFAnalyticsEventType] hasSuffix:@"HealthSummary"]) { + ++summfound; + } else if ([event[SFAnalyticsEventClassKey] integerValue] == SFAnalyticsEventClassHardFailure) { + ++hardfound; + } else if ([event[SFAnalyticsEventClassKey] integerValue] == SFAnalyticsEventClassSoftFailure) { + ++softfound; + } + } + + XCTAssertLessThanOrEqual(((NSArray*)data[@"events"]).count, 1000ul, @"Total event count fits in alloted data"); + if (!forcedFail) { + XCTAssertEqual(summfound, [[[self keySyncTopic] topicClients] count]); + } + // Add fuzziness, we're not testing exact implementation details + XCTAssertEqualWithAccuracy(hardfound, hard, 10); + XCTAssertEqualWithAccuracy(softfound, soft, 10); +} + +- (void)checkTotalEventCount:(NSDictionary*)data hard:(int)hard soft:(int)soft +{ + [self checkTotalEventCount:data hard:hard soft:soft forcedFail:NO]; +} + +// This is a dumb hack, but inlining stringWithFormat causes the compiler to growl for unknown reasons +- (NSString*)string:(NSString*)name item:(NSString*)item +{ + return [NSString stringWithFormat:@"%@-%@", name, item]; +} + +- (void)sampleStatisticsInEvents:(NSArray*)events name:(NSString*)name values:(NSArray*)values +{ + [self sampleStatisticsInEvents:events name:name values:values amount:1]; +} + +// Usually amount == 1 but for testing sampler with same name in different subclasses this is higher +- (void)sampleStatisticsInEvents:(NSArray*)events name:(NSString*)name values:(NSArray*)values amount:(int)num +{ + int found = 0; + for (NSDictionary* event in events) { + if (([values count] == 1 && ![event objectForKey:[NSString stringWithFormat:@"%@", name]]) || + ([values count] > 1 && ![event objectForKey:[NSString stringWithFormat:@"%@-min", name]])) { + continue; + } + + ++found; + if (values.count == 1) { + XCTAssertEqual([event[name] doubleValue], [values[0] doubleValue]); + XCTAssertNil(event[[self string:name item:@"min"]]); + XCTAssertNil(event[[self string:name item:@"max"]]); + XCTAssertNil(event[[self string:name item:@"avg"]]); + XCTAssertNil(event[[self string:name item:@"med"]]); + } else { + XCTAssertEqualWithAccuracy([event[[self string:name item:@"min"]] doubleValue], [values[0] doubleValue], 0.01f); + XCTAssertEqualWithAccuracy([event[[self string:name item:@"max"]] doubleValue], [values[1] doubleValue], 0.01f); + XCTAssertEqualWithAccuracy([event[[self string:name item:@"avg"]] doubleValue], [values[2] doubleValue], 0.01f); + XCTAssertEqualWithAccuracy([event[[self string:name item:@"med"]] doubleValue], [values[3] doubleValue], 0.01f); + } + + if (values.count > 4) { + XCTAssertEqualWithAccuracy([event[[self string:name item:@"dev"]] doubleValue], [values[4] doubleValue], 0.01f); + } else { + XCTAssertNil(event[[self string:name item:@"dev"]]); + } + + if (values.count > 5) { + XCTAssertEqualWithAccuracy([event[[self string:name item:@"1q"]] doubleValue], [values[5] doubleValue], 0.01f); + XCTAssertEqualWithAccuracy([event[[self string:name item:@"3q"]] doubleValue], [values[6] doubleValue], 0.01f); + } else { + XCTAssertNil(event[[self string:name item:@"1q"]]); + XCTAssertNil(event[[self string:name item:@"3q"]]); + } + } + XCTAssertEqual(found, num); +} + +- (NSDictionary*)getJSONDataFromSupd +{ + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + __block NSDictionary* data; + [_supd getLoggingJSON:YES topic:SFAnalyticsTopicKeySync reply:^(NSData *json, NSError *error) { + XCTAssertNil(error); + XCTAssertNotNil(json); + if (!error) { + data = [NSJSONSerialization JSONObjectWithData:json options:0 error:&error]; + } + XCTAssertNil(error, @"no error deserializing json: %@", error); + dispatch_semaphore_signal(sema); + }]; + if (dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 5)) != 0) { + XCTFail(@"supd returns JSON data in a timely fashion"); + } + return data; +} + +// MARK: Test administration + ++ (void)setUp +{ + NSError* error; + _path = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@/", [[NSUUID UUID] UUIDString]]]; + [[NSFileManager defaultManager] createDirectoryAtPath:_path + withIntermediateDirectories:YES + attributes:nil + error:&error]; + if (error) { + NSLog(@"sad trombone, couldn't create path"); + } + + NSDictionary *version = CFBridgingRelease(_CFCopySystemVersionDictionary()); + if (version) { + build = version[(__bridge NSString *)_kCFSystemVersionBuildVersionKey]; + product = version[(__bridge NSString *)_kCFSystemVersionProductNameKey]; + } else { + NSLog(@"could not get build version/product, tests should fail"); + } +} + +- (void)setUp +{ + [super setUp]; + self.continueAfterFailure = NO; + ++_testnum; + + id mockTopic = OCMStrictClassMock([SFAnalyticsTopic class]); + NSString *ckksPath = [_path stringByAppendingFormat:@"/ckks_%ld.db", _testnum]; + NSString *sosPath = [_path stringByAppendingFormat:@"/sos_%ld.db", _testnum]; + NSString *pcsPath = [_path stringByAppendingFormat:@"/pcs_%ld.db", _testnum]; + NSString *tlsPath = [_path stringByAppendingFormat:@"/tls_%ld.db", _testnum]; + OCMStub([mockTopic databasePathForCKKS]).andReturn(ckksPath); + OCMStub([mockTopic databasePathForSOS]).andReturn(sosPath); + OCMStub([mockTopic databasePathForPCS]).andReturn(pcsPath); + OCMStub([mockTopic databasePathForTLS]).andReturn(tlsPath); + + _reporterWrites = 0; + mockReporter = OCMClassMock([SFAnalyticsReporter class]); + OCMStub([mockReporter saveReport:[OCMArg isNotNil]]).andDo(^(NSInvocation *invocation) { + _reporterWrites++; + }).andReturn(YES); + OCMStub([mockReporter cleanupReportsDirectory]).andDo(^(NSInvocation *invocation) { + _reporterCleanups++; + }).andReturn(YES); + + [supd removeInstance]; + _supd = [[supd alloc] initWithReporter:mockReporter]; + _ckksAnalytics = [FakeCKKSAnalytics new]; + _sosAnalytics = [FakeSOSAnalytics new]; + _pcsAnalytics = [FakePCSAnalytics new]; + _tlsAnalytics = [FakeTLSAnalytics new]; + NSLog(@"ckks sqlite3 %@", [FakeCKKSAnalytics databasePath]); + NSLog(@"sos sqlite3 %@", [FakeSOSAnalytics databasePath]); + NSLog(@"pcs sqlite3 %@", [FakePCSAnalytics databasePath]); + NSLog(@"tls sqlite3 %@", [FakeTLSAnalytics databasePath]); + + // Forcibly override analytics flags and enable them by default + deviceAnalyticsOverride = YES; + deviceAnalyticsEnabled = YES; + iCloudAnalyticsOverride = YES; + iCloudAnalyticsEnabled = YES; +} + +- (void)tearDown +{ + + [super tearDown]; +} + +// MARK: Actual tests + +// Note! This test relies on Security being installed because supd reads from a plist in Security.framework +- (void)testSplunkDefaultTopicNameExists +{ + XCTAssertNotNil([[self keySyncTopic] splunkTopicName]); +} + +// Note! This test relies on Security being installed because supd reads from a plist in Security.framework +- (void)testSplunkDefaultBagURLExists +{ + XCTAssertNotNil([[self keySyncTopic] splunkBagURL]); +} + +- (void)testLoggingJSONSimple:(BOOL)analyticsEnabled +{ + iCloudAnalyticsEnabled = analyticsEnabled; + + [_ckksAnalytics logSuccessForEventNamed:@"ckksunittestevent"]; + NSDictionary* ckksAttrs = @{@"cattr" : @"cvalue"}; + [_ckksAnalytics logHardFailureForEventNamed:@"ckksunittestevent" withAttributes:ckksAttrs]; + [_ckksAnalytics logSoftFailureForEventNamed:@"ckksunittestevent" withAttributes:ckksAttrs]; + [_sosAnalytics logSuccessForEventNamed:@"unittestevent"]; + NSDictionary* utAttrs = @{@"uattr" : @"uvalue"}; + [_sosAnalytics logHardFailureForEventNamed:@"unittestevent" withAttributes:utAttrs]; + [_sosAnalytics logSoftFailureForEventNamed:@"unittestevent" withAttributes:utAttrs]; + + NSDictionary* data = [self getJSONDataFromSupd]; + [self inspectDataBlobStructure:data]; + + // TODO: inspect health summaries + + if (analyticsEnabled) { + XCTAssertEqual([self failures:data eventType:@"ckksunittestevent" attributes:ckksAttrs class:SFAnalyticsEventClassHardFailure], 1); + XCTAssertEqual([self failures:data eventType:@"ckksunittestevent" attributes:ckksAttrs class:SFAnalyticsEventClassSoftFailure], 1); + XCTAssertEqual([self failures:data eventType:@"unittestevent" attributes:utAttrs class:SFAnalyticsEventClassHardFailure], 1); + XCTAssertEqual([self failures:data eventType:@"unittestevent" attributes:utAttrs class:SFAnalyticsEventClassSoftFailure], 1); + + [self checkTotalEventCount:data hard:2 soft:2]; + } else { + [self checkTotalEventCount:data hard:0 soft:0 forcedFail:YES]; + } +} + +- (void)testLoggingJSONSimpleWithiCloudAnalyticsEnabled +{ + [self testLoggingJSONSimple:YES]; +} + +- (void)testLoggingJSONSimpleWithiCloudAnalyticsDisabled +{ + [self testLoggingJSONSimple:NO]; +} + +- (void)testTLSLoggingJSONSimple:(BOOL)analyticsEnabled +{ + deviceAnalyticsEnabled = analyticsEnabled; + + [_tlsAnalytics logSuccessForEventNamed:@"tlsunittestevent"]; + NSDictionary* tlsAttrs = @{@"cattr" : @"cvalue"}; + [_tlsAnalytics logHardFailureForEventNamed:@"tlsunittestevent" withAttributes:tlsAttrs]; + [_tlsAnalytics logSoftFailureForEventNamed:@"tlsunittestevent" withAttributes:tlsAttrs]; + + NSDictionary* data = [self getJSONDataFromSupd]; + [self inspectDataBlobStructure:data]; + + if (analyticsEnabled) { + [self checkTotalEventCount:data hard:1 soft:1]; + } else { + [self checkTotalEventCount:data hard:0 soft:0 forcedFail:YES]; + } +} + +- (void)testTLSLoggingJSONSimpleWithDeviceAnalyticsEnabled +{ + [self testTLSLoggingJSONSimple:YES]; +} + +- (void)testTLSLoggingJSONSimpleWithDeviceAnalyticsDisabled +{ + [self testTLSLoggingJSONSimple:NO]; +} + +- (void)testMockDiagnosticReportGeneration +{ + SFAnalyticsReporter *reporter = mockReporter; + + uint8_t report_data[] = {0x00, 0x01, 0x02, 0x03}; + NSData *reportData = [[NSData alloc] initWithBytes:report_data length:sizeof(report_data)]; + BOOL writtenToLog = YES; + size_t numWrites = 5; + for (size_t i = 0; i < numWrites; i++) { + writtenToLog &= [reporter saveReport:reportData]; + } + + XCTAssertTrue(writtenToLog, "Failed to write to log"); + XCTAssertTrue((int)_reporterWrites == (int)numWrites, "Expected %zu report, got %d", numWrites, (int)_reporterWrites); +} + +- (void)testMockDiagnosticReportCleanup +{ + SFAnalyticsReporter *reporter = mockReporter; + + // Write the log + uint8_t report_data[] = {0x00, 0x01, 0x02, 0x03}; + NSData *reportData = [[NSData alloc] initWithBytes:report_data length:sizeof(report_data)]; + BOOL writtenToLog = YES; + size_t numWrites = 5; + for (size_t i = 0; i < numWrites; i++) { + writtenToLog &= [reporter saveReport:reportData]; + } + + XCTAssertTrue(writtenToLog, "Failed to write to log"); + XCTAssertTrue((int)_reporterWrites == (int)numWrites, "Expected %zu report, got %d", numWrites, (int)_reporterWrites); + + // Now clean up... + [reporter cleanupReportsDirectory]; + XCTAssertTrue((int)_reporterCleanups == 1, "Expected %d report, got %d", 1, (int)_reporterCleanups); +} + +- (void)testFakeDiagnosticReportGeneration +{ + CFUUIDRef uuid = CFUUIDCreate(NULL); + CFStringRef uuidString = CFUUIDCreateString(NULL, uuid); + CFRelease(uuid); + NSString *temporaryDirectory = [NSString stringWithFormat:@"%@%@", @"/tmp/", (__bridge NSString *)uuidString]; + + NSTimeInterval validityInterval = 2; + SFAnalyticsReporter *reporter = [[SFAnalyticsReporter alloc] initWithPath:temporaryDirectory validity:validityInterval]; + [reporter setupReportsDirectory]; + + // Write the log + uint8_t report_data[] = {0x00, 0x01, 0x02, 0x03}; + NSData *reportData = [[NSData alloc] initWithBytes:report_data length:sizeof(report_data)]; + BOOL writtenToLog = YES; + size_t numWrites = 1; + for (size_t i = 0; i < numWrites; i++) { + writtenToLog &= [reporter saveReport:reportData]; + } + + // Ensure the right number of reports is generated + XCTAssertTrue(writtenToLog, "Failed to write to log"); + NSArray *directoryContent = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[reporter reportsDirectoryPath] error:nil]; + size_t reportCount = [directoryContent count]; + XCTAssertTrue(reportCount == numWrites); + + // Ensure the count stays even after cleanup, as they are not stale + [reporter cleanupReportsDirectory]; + directoryContent = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[reporter reportsDirectoryPath] error:nil]; + reportCount = [directoryContent count]; + XCTAssertTrue(reportCount == numWrites); + + // Sleep for twice the validity interval + sleep(validityInterval * 2); + + // Cleanup stale reports. We expect everything to be gone at this point. + [reporter cleanupReportsDirectory]; + directoryContent = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[reporter reportsDirectoryPath] error:nil]; + reportCount = [directoryContent count]; + XCTAssertTrue(reportCount == 0); +} + +- (void)testSuccessCounts +{ + NSString* eventName1 = @"successCountsEvent1"; + NSString* eventName2 = @"successCountsEvent2"; + + for (int idx = 0; idx < 3; ++idx) { + [_ckksAnalytics logSuccessForEventNamed:eventName1]; + [_ckksAnalytics logSuccessForEventNamed:eventName2]; + [_ckksAnalytics logHardFailureForEventNamed:eventName1 withAttributes:nil]; + [_ckksAnalytics logSoftFailureForEventNamed:eventName2 withAttributes:nil]; + } + [_ckksAnalytics logSuccessForEventNamed:eventName2]; + + NSDictionary* data = [self getJSONDataFromSupd]; + [self inspectDataBlobStructure:data]; + + NSDictionary* hs; + for (NSDictionary* event in data[@"events"]) { + if ([event[SFAnalyticsEventType] isEqual:@"ckksHealthSummary"]) { + hs = event; + break; + } + } + XCTAssert(hs); + + XCTAssertEqual([hs[SFAnalyticsColumnSuccessCount] integerValue], 7); + XCTAssertEqual([hs[SFAnalyticsColumnHardFailureCount] integerValue], 3); + XCTAssertEqual([hs[SFAnalyticsColumnSoftFailureCount] integerValue], 3); + XCTAssertEqual([hs[[self string:eventName1 item:@"success"]] integerValue], 3); + XCTAssertEqual([hs[[self string:eventName1 item:@"hardfail"]] integerValue], 3); + XCTAssertEqual([hs[[self string:eventName1 item:@"softfail"]] integerValue], 0); + XCTAssertEqual([hs[[self string:eventName2 item:@"success"]] integerValue], 4); + XCTAssertEqual([hs[[self string:eventName2 item:@"hardfail"]] integerValue], 0); + XCTAssertEqual([hs[[self string:eventName2 item:@"softfail"]] integerValue], 3); +} + +// There was a failure with thresholds if some, but not all clients exceeded their 'threshold' number of failures, +// causing the addFailures:toUploadRecords:threshold method to crash with out of bounds. +// This is also implicitly tested in testTooManyHardFailures and testTooManyCombinedFailures but I wanted an explicit case. +- (void)testExceedThresholdForOneClientOnly +{ + int testAmount = ((int)SFAnalyticsMaxEventsToReport / 4); + for (int idx = 0; idx < testAmount; ++idx) { + [_ckksAnalytics logHardFailureForEventNamed:@"ckkshardfail" withAttributes:nil]; + [_ckksAnalytics logSoftFailureForEventNamed:@"ckkssoftfail" withAttributes:nil]; + } + + [_sosAnalytics logHardFailureForEventNamed:@"soshardfail" withAttributes:nil]; + [_sosAnalytics logSoftFailureForEventNamed:@"sossoftfail" withAttributes:nil]; + + NSDictionary* data = [self getJSONDataFromSupd]; + [self inspectDataBlobStructure:data]; + + [self checkTotalEventCount:data hard:testAmount + 1 soft:testAmount + 1]; + + XCTAssertEqual([self failures:data eventType:@"ckkshardfail" attributes:nil class:SFAnalyticsEventClassHardFailure], testAmount); + XCTAssertEqual([self failures:data eventType:@"ckkssoftfail" attributes:nil class:SFAnalyticsEventClassSoftFailure], testAmount); + XCTAssertEqual([self failures:data eventType:@"soshardfail" attributes:nil class:SFAnalyticsEventClassHardFailure], 1); + XCTAssertEqual([self failures:data eventType:@"sossoftfail" attributes:nil class:SFAnalyticsEventClassSoftFailure], 1); +} + + +// We have so many hard failures they won't fit in the upload buffer +- (void)testTooManyHardFailures +{ + NSDictionary* ckksAttrs = @{@"cattr" : @"cvalue"}; + NSDictionary* utAttrs = @{@"uattr" : @"uvalue"}; + for (int idx = 0; idx < 400; ++idx) { + [_ckksAnalytics logHardFailureForEventNamed:@"ckksunittestfailure" withAttributes:ckksAttrs]; + [_ckksAnalytics logHardFailureForEventNamed:@"ckksunittestfailure" withAttributes:ckksAttrs]; + [_sosAnalytics logHardFailureForEventNamed:@"utunittestfailure" withAttributes:utAttrs]; + } + + NSDictionary* data = [self getJSONDataFromSupd]; + [self inspectDataBlobStructure:data]; + + [self checkTotalEventCount:data hard:998 soft:0]; + // Based on threshold = records_to_upload/10 with a nice margin + XCTAssertEqualWithAccuracy([self failures:data eventType:@"ckksunittestfailure" attributes:ckksAttrs class:SFAnalyticsEventClassHardFailure], 658, 50); + XCTAssertEqualWithAccuracy([self failures:data eventType:@"utunittestfailure" attributes:utAttrs class:SFAnalyticsEventClassHardFailure], 339, 50); +} + +// So many soft failures they won't fit in the buffer +- (void)testTooManySoftFailures +{ + NSDictionary* ckksAttrs = @{@"cattr" : @"cvalue"}; + NSDictionary* utAttrs = @{@"uattr" : @"uvalue"}; + for (int idx = 0; idx < 400; ++idx) { + [_ckksAnalytics logSoftFailureForEventNamed:@"ckksunittestfailure" withAttributes:ckksAttrs]; + [_ckksAnalytics logSoftFailureForEventNamed:@"ckksunittestfailure" withAttributes:ckksAttrs]; + [_sosAnalytics logSoftFailureForEventNamed:@"utunittestfailure" withAttributes:utAttrs]; + } + + NSDictionary* data = [self getJSONDataFromSupd]; + [self inspectDataBlobStructure:data]; + + [self checkTotalEventCount:data hard:0 soft:998]; + // Based on threshold = records_to_upload/10 with a nice margin + XCTAssertEqualWithAccuracy([self failures:data eventType:@"ckksunittestfailure" attributes:ckksAttrs class:SFAnalyticsEventClassSoftFailure], 665, 50); + XCTAssertEqualWithAccuracy([self failures:data eventType:@"utunittestfailure" attributes:utAttrs class:SFAnalyticsEventClassSoftFailure], 332, 50); +} + +- (void)testTooManyCombinedFailures +{ + NSDictionary* ckksAttrs = @{@"cattr1" : @"cvalue1", @"cattrthatisalotlongerthanthepreviousone" : @"cvaluethatisalsoalotlongerthantheother"}; + NSDictionary* utAttrs = @{@"uattr" : @"uvalue", @"uattrthatisalotlongerthanthepreviousone" : @"uvaluethatisalsoalotlongerthantheother"}; + for (int idx = 0; idx < 400; ++idx) { + [_ckksAnalytics logHardFailureForEventNamed:@"ckksunittestfailure" withAttributes:ckksAttrs]; + [_ckksAnalytics logSoftFailureForEventNamed:@"ckksunittestfailure" withAttributes:ckksAttrs]; + [_sosAnalytics logHardFailureForEventNamed:@"utunittestfailure" withAttributes:utAttrs]; + [_sosAnalytics logSoftFailureForEventNamed:@"utunittestfailure" withAttributes:utAttrs]; + } + + NSDictionary* data = [self getJSONDataFromSupd]; + [self inspectDataBlobStructure:data]; + + [self checkTotalEventCount:data hard:800 soft:198]; + // Based on threshold = records_to_upload/10 with a nice margin + XCTAssertEqualWithAccuracy([self failures:data eventType:@"ckksunittestfailure" attributes:ckksAttrs class:SFAnalyticsEventClassHardFailure], 400, 50); + XCTAssertEqualWithAccuracy([self failures:data eventType:@"utunittestfailure" attributes:utAttrs class:SFAnalyticsEventClassHardFailure], 400, 50); + XCTAssertEqualWithAccuracy([self failures:data eventType:@"ckksunittestfailure" attributes:ckksAttrs class:SFAnalyticsEventClassSoftFailure], 100, 50); + XCTAssertEqualWithAccuracy([self failures:data eventType:@"utunittestfailure" attributes:utAttrs class:SFAnalyticsEventClassSoftFailure], 100, 50); +} + +// There's an even number of samples +- (void)testSamplesEvenSampleCount +{ + NSString* sampleNameEven = @"evenSample"; + + for (NSNumber* value in @[@36.831855250339714, @90.78721762172914, @49.24392301762506, + @42.806362283260036, @16.76725375576855, @34.50969130579674, + @25.956509180834637, @36.8268555935645, @35.54069258036879, + @7.26364884595062, @45.414180770615395, @5.223213570809022]) { + [_ckksAnalytics logMetric:value withName:sampleNameEven]; + } + + NSDictionary* data = [self getJSONDataFromSupd]; + [self inspectDataBlobStructure:data]; + + // min, max, avg, med, dev, 1q, 3q + [self checkTotalEventCount:data hard:0 soft:0]; + [self sampleStatisticsInEvents:data[@"events"] name:sampleNameEven values:@[@5.22, @90.78, @35.60, @36.18, @21.52, @21.36, @44.11]]; +} + +// There are 4*n + 1 samples +- (void)testSamples4n1SampleCount +{ + NSString* sampleName4n1 = @"4n1Sample"; + for (NSNumber* value in @[@37.76544251068022, @27.36378948426223, @45.10503077614114, + @43.90635413191473, @54.78709742040113, @52.34879597889124, + @70.95760312196856, @23.23648158872921, @75.34678687445064, + @10.723238854026203, @41.98468801166455, @17.074404554908476, + @94.24252031232739]) { + [_ckksAnalytics logMetric:value withName:sampleName4n1]; + } + + NSDictionary* data = [self getJSONDataFromSupd]; + [self inspectDataBlobStructure:data]; + + [self checkTotalEventCount:data hard:0 soft:0]; + [self sampleStatisticsInEvents:data[@"events"] name:sampleName4n1 values:@[@10.72, @94.24, @45.76, @43.90, @23.14, @26.33, @58.83]]; +} + +// There are 4*n + 3 samples +- (void)testSamples4n3SampleCount +{ + NSString* sampleName4n3 = @"4n3Sample"; + + for (NSNumber* value in @[@42.012971885655496, @87.85629592375282, @5.748491212287082, + @38.451850063872975, @81.96900109690873, @99.83098790545392, + @80.89400981437815, @5.719237885152143, @1.6740622555032196, + @14.437000556079038, @29.046050177512395]) { + [_sosAnalytics logMetric:value withName:sampleName4n3]; + } + + NSDictionary* data = [self getJSONDataFromSupd]; + [self inspectDataBlobStructure:data]; + [self checkTotalEventCount:data hard:0 soft:0]; + + [self sampleStatisticsInEvents:data[@"events"] name:sampleName4n3 values:@[@1.67, @99.83, @44.33, @38.45, @35.28, @7.92, @81.70]]; +} + +// stddev and quartiles undefined for single sample +- (void)testSamplesSingleSample +{ + NSString* sampleName = @"singleSample"; + + [_ckksAnalytics logMetric:@3.14159 withName:sampleName]; + + NSDictionary* data = [self getJSONDataFromSupd]; + [self inspectDataBlobStructure:data]; + [self checkTotalEventCount:data hard:0 soft:0]; + + [self sampleStatisticsInEvents:data[@"events"] name:sampleName values:@[@3.14159]]; +} + +// quartiles meaningless for fewer than 4 samples (but stddev exists) +- (void)testSamplesFewerThanFour +{ + NSString* sampleName = @"fewSamples"; + + [_ckksAnalytics logMetric:@3.14159 withName:sampleName]; + [_ckksAnalytics logMetric:@6.28318 withName:sampleName]; + + NSDictionary* data = [self getJSONDataFromSupd]; + [self inspectDataBlobStructure:data]; + [self checkTotalEventCount:data hard:0 soft:0]; + + [self sampleStatisticsInEvents:data[@"events"] name:sampleName values:@[@3.14, @6.28, @4.71, @4.71, @1.57]]; +} + +- (void)testSamplesSameNameDifferentSubclass +{ + NSString* sampleName = @"differentSubclassSamples"; + + [_sosAnalytics logMetric:@313.37 withName:sampleName]; + [_ckksAnalytics logMetric:@313.37 withName:sampleName]; + + NSDictionary* data = [self getJSONDataFromSupd]; + [self inspectDataBlobStructure:data]; + [self checkTotalEventCount:data hard:0 soft:0]; + + [self sampleStatisticsInEvents:data[@"events"] name:sampleName values:@[@313.37] amount:2]; +} + + + +// TODO +- (void)testGetSysdiagnoseDump +{ + +} + +// TODO (need mock server) +- (void)testSplunkUpload +{ + +} + +// TODO (need mock server) +- (void)testDBIsEmptiedAfterUpload +{ + +} + +@end diff --git a/supd/main.m b/supd/main.m new file mode 100644 index 00000000..a8f7b24e --- /dev/null +++ b/supd/main.m @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import +#import "supd.h" +#include "debugging.h" +#import +#include + +@interface ServiceDelegate : NSObject +@end + +@implementation ServiceDelegate + +- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection { + NSNumber *num = [newConnection valueForEntitlement:@"com.apple.private.securityuploadd"]; + if (![num isKindOfClass:[NSNumber class]] || ![num boolValue]) { + secerror("xpc: Client (pid: %d) doesn't have entitlement", [newConnection processIdentifier]); + return NO; + } else { + secinfo("xpc", "Client (pid: %d) properly entitled, let's go", [newConnection processIdentifier]); + } + + newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(supdProtocol)]; + supd *exportedObject = [supd instance]; + newConnection.exportedObject = exportedObject; + [newConnection resume]; + return YES; +} + +@end + +int main(int argc, const char *argv[]) +{ + secnotice("lifecycle", "supd lives!"); + ServiceDelegate *delegate = [ServiceDelegate new]; + + // kick the singleton so it can register its xpc activity handler + [supd instantiate]; + + NSXPCListener *listener = [[NSXPCListener alloc] initWithMachServiceName:@"com.apple.securityuploadd"]; + listener.delegate = delegate; + + // We're always launched in response to client activity and don't want to sit around idle. + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5ull * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + secnotice("lifecycle", "will exit when clean"); + xpc_transaction_exit_clean(); + }); + + [listener resume]; + [[NSRunLoop currentRunLoop] run]; + return 0; +} diff --git a/supd/securityuploadd-Entitlements.plist b/supd/securityuploadd-Entitlements.plist new file mode 100644 index 00000000..d8708bea --- /dev/null +++ b/supd/securityuploadd-Entitlements.plist @@ -0,0 +1,18 @@ + + + + + com.apple.accounts.appleaccount.fullaccess + + com.apple.authkit.client.private + + com.apple.private.accounts.allaccounts + + com.apple.private.ckks + + seatbelt-profiles + + securityuploadd + + + diff --git a/supd/securityuploadd-ios.plist b/supd/securityuploadd-ios.plist new file mode 100644 index 00000000..b84a889d --- /dev/null +++ b/supd/securityuploadd-ios.plist @@ -0,0 +1,48 @@ + + + + + ProcessType + Adaptive + Label + com.apple.securityuploadd + UserName + _securityd + GroupName + wheel + EnablePressuredExit + + ProgramArguments + + /usr/libexec/securityuploadd + + MachServices + + com.apple.securityuploadd + + + LaunchEvents + + com.apple.xpc.activity + + com.apple.securityuploadd.triggerupload + + Priority + Maintenance + PowerNap + + AllowBattery + + Interval + 43200 + GracePeriod + 21600 + RequireInexpensiveNetworkConnectivity + + NetworkTransferDirection + Bidirectional + + + + + diff --git a/supd/securityuploadd-osx.plist b/supd/securityuploadd-osx.plist new file mode 100644 index 00000000..6bff9bae --- /dev/null +++ b/supd/securityuploadd-osx.plist @@ -0,0 +1,46 @@ + + + + + ProcessType + Adaptive + Label + com.apple.securityuploadd + EnableTransactions + + EnablePressuredExit + + ProgramArguments + + /usr/libexec/securityuploadd + + MachServices + + com.apple.securityuploadd + + + LaunchEvents + + com.apple.xpc.activity + + com.apple.securityuploadd.triggerupload + + Priority + Maintenance + PowerNap + + AllowBattery + + Interval + 43200 + GracePeriod + 21600 + RequireInexpensiveNetworkConnectivity + + NetworkTransferDirection + Bidirectional + + + + + diff --git a/supd/securityuploadd.8 b/supd/securityuploadd.8 new file mode 100644 index 00000000..d46e270c --- /dev/null +++ b/supd/securityuploadd.8 @@ -0,0 +1,9 @@ +.Dd October 10, 2017 +.Dt securityuploadd 8 +.Os +.Sh NAME +.Nm securityuploadd +.Nd Keychain Metrics Uploader +.Sh DESCRIPTION +.Nm +Lightweight on-demand daemon to upload keychain and keychain syncing metrics. Split out from the main keychain daemons for security reasons: we do not wish to give our daemons access to the network. diff --git a/supd/supd.h b/supd/supd.h new file mode 100644 index 00000000..478dbc81 --- /dev/null +++ b/supd/supd.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import +#import "supdProtocol.h" + +@interface SFAnalyticsClient: NSObject +@property (nonatomic) NSString* storePath; +@property (nonatomic) NSString* name; +@property (atomic) BOOL requireDeviceAnalytics; +@property (atomic) BOOL requireiCloudAnalytics; +@end + +@interface SFAnalyticsTopic : NSObject +@property NSString* splunkTopicName; +@property NSURL* splunkBagURL; +@property NSString *internalTopicName; + +@property NSArray *topicClients; + +// -------------------------------- +// Things below are for unit testing ++ (NSString*)databasePathForCKKS; ++ (NSString*)databasePathForSOS; ++ (NSString*)databasePathForPCS; ++ (NSString*)databasePathForTLS; +@end + +@interface SFAnalyticsReporter : NSObject +- (NSString *)databaseDirectoryPath; +- (NSString *)reportsDirectoryPath; +- (id)init; +- (id)initWithPath:(NSString *)path validity:(NSTimeInterval)validity; +- (BOOL)removeFilesFrom:(NSString *)directory olderThanSecond:(NSTimeInterval)seconds; +- (BOOL)setupReportsDirectory; +- (BOOL)cleanupReportsDirectory; +- (BOOL)saveReport:(NSData *)reportData; + +@property NSString *databasePath; +@property NSTimeInterval reportValidityPeriod; +@end + +@interface supd : NSObject ++ (instancetype)instance; ++ (void)removeInstance; ++ (void)instantiate; +- (instancetype)initWithReporter:(SFAnalyticsReporter *)reporter; + +// -------------------------------- +// Things below are for unit testing +@property (readonly) dispatch_queue_t queue; +@property (readonly) NSArray* analyticsTopics; +@property (readonly) SFAnalyticsReporter *reporter; +- (void)sendNotificationForOncePerReportSamplers; +@end + +// -------------------------------- +// Things below are for unit testing +extern BOOL deviceAnalyticsOverride; +extern BOOL deviceAnalyticsEnabled; +extern BOOL iCloudAnalyticsOverride; +extern BOOL iCloudAnalyticsEnabled; diff --git a/supd/supd.m b/supd/supd.m new file mode 100644 index 00000000..b053f5c0 --- /dev/null +++ b/supd/supd.m @@ -0,0 +1,1499 @@ +/* + * Copyright (c) 2017-2018 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import "supd.h" +#import "SFAnalyticsDefines.h" +#import "SFAnalyticsSQLiteStore.h" +#import "SFAnalytics.h" + +#include +#import "utilities/debugging.h" +#import +#import +#include +#import "keychain/ckks/CKKSControl.h" +#import + +#import +#import +#import + +#if TARGET_OS_OSX +#include "dirhelper_priv.h" +#import +#import +#import +#import +#import +#import +#import +#import +#else // TARGET_OS_OSX +#import +#import +#import +#import +#if TARGET_OS_EMBEDDED +#import +#import +#endif // TARGET_OS_EMBEDDED +#endif // TARGET_OS_OSX + +NSString* const SFAnalyticsSplunkTopic = @"topic"; +NSString* const SFAnalyticsSplunkPostTime = @"postTime"; +NSString* const SFAnalyticsClientId = @"clientId"; +NSString* const SFAnalyticsInternal = @"internal"; + +NSString* const SFAnalyticsMetricsBase = @"metricsBase"; +NSString* const SFAnalyticsDeviceID = @"ckdeviceID"; + +NSString* const SFAnalyticsSecondsCustomerKey = @"SecondsBetweenUploadsCustomer"; +NSString* const SFAnalyticsSecondsInternalKey = @"SecondsBetweenUploadsInternal"; +NSString* const SFAnalyticsMaxEventsKey = @"NumberOfEvents"; +NSString* const SFAnalyticsDevicePercentageCustomerKey = @"DevicePercentageCustomer"; +NSString* const SFAnalyticsDevicePercentageInternalKey = @"DevicePercentageInternal"; + +#define SFANALYTICS_SPLUNK_DEV 0 + +#if SFANALYTICS_SPLUNK_DEV +NSUInteger const secondsBetweenUploadsCustomer = 10; +NSUInteger const secondsBetweenUploadsInternal = 10; +#else // SFANALYTICS_SPLUNK_DEV +NSUInteger const secondsBetweenUploadsCustomer = (3 * (60 * 60 * 24)); +NSUInteger const secondsBetweenUploadsInternal = (60 * 60 * 24); +#endif // SFANALYTICS_SPLUNK_DEV + +#if TARGET_OS_OSX +static NSString * const _SFAnalyticsDatabasePath = @"/var/db/SecurityFrameworkAnalytics/"; +#else // TARGET_OS_OSX +static NSString * const _SFAnalyticsDatabasePath = nil; +#endif // TARGET_OS_OSX + +@implementation SFAnalyticsReporter +- (NSString *)databaseDirectoryPath +{ + return _databasePath; +} + +- (NSString *)reportsDirectoryPath +{ + static NSString *_SFAnalyticsReportsDirectoryPath = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + if ([self databaseDirectoryPath]) { + _SFAnalyticsReportsDirectoryPath = [NSString stringWithFormat:@"%@%@", [self databaseDirectoryPath], @"Reports"]; + } + }); + return _SFAnalyticsReportsDirectoryPath; +} + +- (id)initWithPath:(NSString *)path validity:(NSTimeInterval)validity +{ + if (self = [super init]) { + _databasePath = path; + _reportValidityPeriod = validity; + } + return self; +} + +- (id)init +{ + return [self initWithPath:_SFAnalyticsDatabasePath validity:(secondsBetweenUploadsCustomer * 2)]; +} + +- (BOOL)setupReportsDirectory +{ + NSString *databaseDirectoryPath = [self databaseDirectoryPath]; + NSString *reportsDirectoryPath = [self reportsDirectoryPath]; + if (!(databaseDirectoryPath != nil && reportsDirectoryPath != nil)) { + return NO; + } + + // Note: securityuploadd is not sandboxed on macOS, so we can operate in the system reports directory at will. + __block BOOL result = YES; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // Create database directory if needed + NSFileManager *fm = [NSFileManager defaultManager]; + NSError *err = nil; + BOOL ok = [fm createDirectoryAtPath:databaseDirectoryPath + withIntermediateDirectories:YES + attributes:nil + error:&err]; + if (ok) { + // Create reports directory if needed + ok = [fm createDirectoryAtPath:reportsDirectoryPath + withIntermediateDirectories:YES + attributes:nil + error:&err]; + if (!ok) { + secerror("Reports directory creation failed with %@", err); + result = NO; + } + + } else { + secerror("Database directory creation failed with %@", err); + result = NO; + } + }); + return result; +} + +- (BOOL)removeFilesFrom:(NSString *)directory + olderThanSecond:(NSTimeInterval)seconds +{ + NSDate *olderThanSecond = [NSDate dateWithTimeIntervalSinceNow:-seconds]; + + NSFileManager *fm = [NSFileManager defaultManager]; + NSDirectoryEnumerator *dirEnum = [fm enumeratorAtPath:directory]; + NSString *fileName; + int64_t totalSize = 0; + while (fileName = [dirEnum nextObject]) { + NSString *filePath = [NSString stringWithFormat:@"%@/%@", directory, fileName]; + BOOL isDir; + if ([fm fileExistsAtPath:filePath isDirectory:&isDir]) { + if (isDir) { + // Do not remove sub-directories and their contents + [dirEnum skipDescendents]; + } else { + NSDate *creationDate = [[fm attributesOfItemAtPath:filePath error:nil] fileCreationDate]; + BOOL isOlder = ([creationDate compare:olderThanSecond] == NSOrderedAscending); + if (isOlder) { + totalSize += [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil] fileSize]; + [fm removeItemAtPath:filePath error:nil]; + } + } + } + } + return YES; +} + +- (BOOL)cleanupReportsDirectory +{ + NSString *reportsDirectoryPath = [self reportsDirectoryPath]; + if (reportsDirectoryPath != nil) { + @autoreleasepool { + [self removeFilesFrom:reportsDirectoryPath olderThanSecond:_reportValidityPeriod]; + } + return YES; + } + return NO; +} + +- (NSString *)createReportFilename +{ +#if TARGET_OS_OSX + NSDictionary *problemReport = nil; + // We do not have our own CrashReporter key, so we make our own. This causes the default report extension to be ".diag". + // See: https://clownfish.apple.com/index.php?action=search_cached&path=CrashReporterSupport%2FCrashReporterSupport.c&version=CrashCatcher-938.3&project=CrashCatcher&q=&language=all&index=LoboElk + problemReport = @{ + (__bridge NSString *)kCRProblemReportProblemTypeKey : @"supd", + (__bridge NSString *)kCRProblemReportAppNameKey : @"securityuploadd", + (__bridge NSString *)kCRProblemReportDescriptionKey : @"analytics", + (__bridge NSString *)kCRProblemReportNoUserUUIDKey : @YES, + (__bridge NSString *)kCRProblemReportRoutingKey : @"anon", + (__bridge NSString *)kCRProblemReportSubroutingKey : @"security_uploadd", + }; + + CFURLRef outputPathURL = NULL; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + // TODO: Use Need a variant of OSAWriteLogForSubmission() that returns pathname for the log file + CRStatusCode status = CRSaveProblemReport((__bridge CFDictionaryRef)problemReport, &outputPathURL); +#pragma clang diagnostic pop + + NSString *outputpath = [(__bridge NSURL *)outputPathURL path]; + return outputpath; +#else + return @"temporary_path.supd"; +#endif // TARGET_OS_OSX +} + +- (BOOL)saveReport:(NSData *)reportData +{ + @autoreleasepool { + NSString *reportFileName = [self createReportFilename]; + if (reportFileName != nil) { + NSURL *path = [NSURL URLWithString:[self reportsDirectoryPath]]; + if (path != nil) { + NSURL *absoluteReportName = [path URLByAppendingPathComponent:reportFileName]; + [[NSFileManager defaultManager] createFileAtPath:[absoluteReportName absoluteString] contents:reportData attributes:nil]; + return YES; + } + } + } + return NO; +} +@end + +#define DEFAULT_SPLUNK_MAX_EVENTS_TO_REPORT 1000 + +#define DEFAULT_SPLUNK_DEVICE_PERCENTAGE 100 + +static supd *_supdInstance = nil; + +BOOL deviceAnalyticsOverride = NO; +BOOL deviceAnalyticsEnabled = NO; +BOOL iCloudAnalyticsOverride = NO; +BOOL iCloudAnalyticsEnabled = NO; + +static BOOL +_isDeviceAnalyticsEnabled(void) +{ + // This flag is only set during tests. + if (deviceAnalyticsOverride) { + return deviceAnalyticsEnabled; + } + + static BOOL dataCollectionEnabled = NO; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ +#if TARGET_OS_EMBEDDED + dataCollectionEnabled = DiagnosticLogSubmissionEnabled(); +#elif TARGET_OS_OSX + dataCollectionEnabled = CRIsAutoSubmitEnabled(); +#endif + }); + return dataCollectionEnabled; +} + +static NSString *const kAnalyticsiCloudIdMSKey = @"com.apple.idms.config.privacy.icloud.data"; + +#if TARGET_OS_IPHONE +static NSDictionary * +_getiCloudConfigurationInfoWithError(NSError **outError) +{ + __block NSDictionary *outConfigurationInfo = nil; + __block NSError *localError = nil; + + ACAccountStore *accountStore = [[ACAccountStore alloc] init]; + ACAccount *primaryAccount = [accountStore aa_primaryAppleAccount]; + if (primaryAccount != nil) { + NSString *altDSID = [primaryAccount aa_altDSID]; + secnotice("_getiCloudConfigurationInfoWithError", "Fetching configuration info"); + + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + AKAppleIDAuthenticationController *authController = [AKAppleIDAuthenticationController new]; + [authController configurationInfoWithIdentifiers:@[kAnalyticsiCloudIdMSKey] + forAltDSID:altDSID + completion:^(NSDictionary> *configurationInfo, NSError *error) { + if (error) { + secerror("_getiCloudConfigurationInfoWithError: Error fetching configurationInfo: %@", error); + localError = error; + } else if (![configurationInfo isKindOfClass:[NSDictionary class]]) { + secerror("_getiCloudConfigurationInfoWithError: configurationInfo dict was not a dict, it was a %{public}@", [configurationInfo class]); + localError = error; + configurationInfo = nil; + } else { + secnotice("_getiCloudConfigurationInfoWithError", "fetched configurationInfo %@", configurationInfo); + outConfigurationInfo = configurationInfo; + } + dispatch_semaphore_signal(sema); + }]; + dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, (uint64_t)(5 * NSEC_PER_SEC))); + } else { + secerror("_getiCloudConfigurationInfoWithError: Failed to fetch primary account info."); + } + + if (localError && outError) { + *outError = localError; + } + return outConfigurationInfo; +} +#endif // TARGET_OS_IPHONE + +#if TARGET_OS_OSX +static NSString * +_iCloudAccount(void) +{ + return CFBridgingRelease(MMLCopyLoggedInAccount()); +} + +static NSString * +_altDSIDFromAccount(void) +{ + static CFStringRef kMMPropertyAccountAlternateDSID = CFSTR("AccountAlternateDSID"); + NSString *account = _iCloudAccount(); + if (account != nil) { + return CFBridgingRelease(MMLAccountCopyProperty((__bridge CFStringRef)account, kMMPropertyAccountAlternateDSID)); + } + secerror("_altDSIDFromAccount: failed to fetch iCloud account"); + return nil; +} +#endif // TARGET_OS_OSX + +static BOOL +_isiCloudAnalyticsEnabled() +{ + // This flag is only set during tests. + if (iCloudAnalyticsOverride) { + return iCloudAnalyticsEnabled; + } + + static bool cachedAllowsICloudAnalytics = false; + +#if TARGET_OS_OSX + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + /* AOSAccounts is not mastered into the BaseSystem. Check that those classes are linked at runtime and abort if not. */ + if (![AKAppleIDAuthenticationController class]) { + secnotice("OTATrust", "Weak-linked AOSAccounts framework missing. Are we running in the base system?"); + return; + } + + NSString *currentAltDSID = _altDSIDFromAccount(); + if (currentAltDSID != nil) { + AKAppleIDAuthenticationController *authController = [AKAppleIDAuthenticationController new]; + __block bool allowsICloudAnalytics = false; + dispatch_semaphore_t sem = dispatch_semaphore_create(0); + secnotice("isiCloudAnalyticsEnabled", "fetching iCloud Analytics value from idms"); + [authController configurationInfoWithIdentifiers:@[kAnalyticsiCloudIdMSKey] + forAltDSID:currentAltDSID + completion:^(NSDictionary *configurationInfo, NSError *error) { + if (!error && configurationInfo) { + NSNumber *value = configurationInfo[kAnalyticsiCloudIdMSKey]; + if (value != nil) { + secnotice("_isiCloudAnalyticsEnabled", "authController:configurationInfoWithIdentifiers completed with no error and configuration information"); + allowsICloudAnalytics = [value boolValue]; + } else { + secerror("%s: no iCloud Analytics value found in IDMS", __FUNCTION__); + } + } else { + secerror("%s: Unable to fetch iCloud Analytics value from IDMS.", __FUNCTION__); + } + secnotice("_isiCloudAnalyticsEnabled", "authController:configurationInfoWithIdentifiers completed and returning"); + dispatch_semaphore_signal(sem); + }]; + // Wait 5 seconds before giving up and returning from the block. + dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, (uint64_t)(5 * NSEC_PER_SEC))); + cachedAllowsICloudAnalytics = allowsICloudAnalytics; + } else { + secerror("_isiCloudAnalyticsEnabled: Failed to fetch alternate DSID"); + } + }); +#else // TARGET_OS_OSX + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSError *error = nil; + NSDictionary *accountConfiguration = _getiCloudConfigurationInfoWithError(&error); + if (error == nil && accountConfiguration != nil) { + id iCloudAnalyticsOptIn = accountConfiguration[kAnalyticsiCloudIdMSKey]; + if (iCloudAnalyticsOptIn != nil) { + BOOL iCloudAnalyticsOptInHasCorrectType = ([iCloudAnalyticsOptIn isKindOfClass:[NSNumber class]] || [iCloudAnalyticsOptIn isKindOfClass:[NSString class]]); + if (iCloudAnalyticsOptInHasCorrectType) { + NSNumber *iCloudAnalyticsOptInNumber = @([iCloudAnalyticsOptIn integerValue]); + cachedAllowsICloudAnalytics = ![iCloudAnalyticsOptInNumber isEqualToNumber:[NSNumber numberWithInteger:0]]; + } + } + } else if (error != nil) { + secerror("_isiCloudAnalyticsEnabled: %@", error); + } + }); +#endif // TARGET_OS_OSX + + return cachedAllowsICloudAnalytics; +} + +/* NSData GZip category based on GeoKit's implementation */ +@interface NSData (GZip) +- (NSData *)supd_gzipDeflate; +@end + +#define GZIP_OFFSET 16 +#define GZIP_STRIDE_LEN 16384 + +@implementation NSData (Gzip) +- (NSData *)supd_gzipDeflate +{ + if ([self length] == 0) { + return self; + } + + z_stream strm; + memset(&strm, 0, sizeof(strm)); + strm.next_in=(uint8_t *)[self bytes]; + strm.avail_in = (unsigned int)[self length]; + + + if (Z_OK != deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, + MAX_WBITS + GZIP_OFFSET, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)) { + return nil; + } + + NSMutableData *compressed = [NSMutableData dataWithLength:GZIP_STRIDE_LEN]; + + do { + if (strm.total_out >= [compressed length]) { + [compressed increaseLengthBy: 16384]; + } + + strm.next_out = [compressed mutableBytes] + strm.total_out; + strm.avail_out = (int)[compressed length] - (int)strm.total_out; + + deflate(&strm, Z_FINISH); + + } while (strm.avail_out == 0); + + deflateEnd(&strm); + + [compressed setLength: strm.total_out]; + if (strm.avail_in == 0) { + return [NSData dataWithData:compressed]; + } else { + return nil; + } +} +@end + +@implementation SFAnalyticsClient { + NSString* _path; + NSString* _name; + BOOL _requireDeviceAnalytics; + BOOL _requireiCloudAnalytics; +} + +@synthesize storePath = _path; +@synthesize name = _name; + +- (instancetype)initWithStorePath:(NSString*)path name:(NSString*)name + deviceAnalytics:(BOOL)deviceAnalytics iCloudAnalytics:(BOOL)iCloudAnalytics { + if (self = [super init]) { + _path = path; + _name = name; + _requireDeviceAnalytics = deviceAnalytics; + _requireiCloudAnalytics = iCloudAnalytics; + } + return self; +} + +@end + +@interface SFAnalyticsTopic () +@property NSURL* _splunkUploadURL; + +@property BOOL allowInsecureSplunkCert; +@property BOOL ignoreServersMessagesTellingUsToGoAway; +@property BOOL disableUploads; +@property BOOL disableClientId; + +@property NSUInteger secondsBetweenUploads; +@property NSUInteger maxEventsToReport; +@property float devicePercentage; // for sampling reporting devices + +@property NSDictionary* metricsBase; // data the server provides and wants us to send back +@property NSArray* blacklistedFields; +@property NSArray* blacklistedEvents; +@end + +@implementation SFAnalyticsTopic +- (void)setupClientsForTopic:(NSString *)topicName +{ + NSMutableArray* clients = [NSMutableArray new]; + if ([topicName isEqualToString:SFAnalyticsTopicKeySync]) { + [clients addObject:[[SFAnalyticsClient alloc] initWithStorePath:[self.class databasePathForCKKS] + name:@"ckks" deviceAnalytics:NO iCloudAnalytics:YES]]; + [clients addObject:[[SFAnalyticsClient alloc] initWithStorePath:[self.class databasePathForSOS] + name:@"sos" deviceAnalytics:NO iCloudAnalytics:YES]]; + [clients addObject:[[SFAnalyticsClient alloc] initWithStorePath:[self.class databasePathForPCS] + name:@"pcs" deviceAnalytics:NO iCloudAnalytics:YES]]; + } else if ([topicName isEqualToString:SFAnaltyicsTopicTrust]) { +#if TARGET_OS_OSX + _set_user_dir_suffix("com.apple.trustd"); // supd needs to read trustd's cache dir for these +#endif + [clients addObject:[[SFAnalyticsClient alloc] initWithStorePath:[self.class databasePathForTrust] + name:@"trust" deviceAnalytics:YES iCloudAnalytics:NO]]; + [clients addObject:[[SFAnalyticsClient alloc] initWithStorePath:[self.class databasePathForTrustdHealth] + name:@"trustdHealth" deviceAnalytics:YES iCloudAnalytics:NO]]; + [clients addObject:[[SFAnalyticsClient alloc] initWithStorePath:[self.class databasePathForTLS] + name:@"tls" deviceAnalytics:YES iCloudAnalytics:NO]]; +#if TARGET_OS_OSX + _set_user_dir_suffix(NULL); // set back to the default cache dir +#endif + } + + _topicClients = clients; +} + +- (instancetype)initWithDictionary:(NSDictionary *)dictionary name:(NSString *)topicName samplingRates:(NSDictionary *)rates { + if (self = [super init]) { + _internalTopicName = topicName; + [self setupClientsForTopic:topicName]; + _splunkTopicName = dictionary[@"splunk_topic"]; + __splunkUploadURL = [NSURL URLWithString:dictionary[@"splunk_uploadURL"]]; + _splunkBagURL = [NSURL URLWithString:dictionary[@"splunk_bagURL"]]; + _allowInsecureSplunkCert = [[dictionary valueForKey:@"splunk_allowInsecureCertificate"] boolValue]; + NSString* splunkEndpoint = dictionary[@"splunk_endpointDomain"]; + if (dictionary[@"disableClientId"]) { + _disableClientId = YES; + } + + NSUserDefaults* defaults = [[NSUserDefaults alloc] initWithSuiteName:SFAnalyticsUserDefaultsSuite]; + NSString* userDefaultsSplunkTopic = [defaults stringForKey:@"splunk_topic"]; + if (userDefaultsSplunkTopic) { + _splunkTopicName = userDefaultsSplunkTopic; + } + + NSURL* userDefaultsSplunkUploadURL = [NSURL URLWithString:[defaults stringForKey:@"splunk_uploadURL"]]; + if (userDefaultsSplunkUploadURL) { + __splunkUploadURL = userDefaultsSplunkUploadURL; + } + + NSURL* userDefaultsSplunkBagURL = [NSURL URLWithString:[defaults stringForKey:@"splunk_bagURL"]]; + if (userDefaultsSplunkBagURL) { + _splunkBagURL = userDefaultsSplunkBagURL; + } + + BOOL userDefaultsAllowInsecureSplunkCert = [defaults boolForKey:@"splunk_allowInsecureCertificate"]; + _allowInsecureSplunkCert |= userDefaultsAllowInsecureSplunkCert; + + NSString* userDefaultsSplunkEndpoint = [defaults stringForKey:@"splunk_endpointDomain"]; + if (userDefaultsSplunkEndpoint) { + splunkEndpoint = userDefaultsSplunkEndpoint; + } + +#if SFANALYTICS_SPLUNK_DEV + _secondsBetweenUploads = secondsBetweenUploadsInternal; + _maxEventsToReport = SFAnalyticsMaxEventsToReport; + _devicePercentage = DEFAULT_SPLUNK_DEVICE_PERCENTAGE; +#else + bool internal = os_variant_has_internal_diagnostics("com.apple.security"); + if (rates) { + NSNumber *secondsNum = internal ? rates[SFAnalyticsSecondsInternalKey] : rates[SFAnalyticsSecondsCustomerKey]; + _secondsBetweenUploads = [secondsNum integerValue]; + _maxEventsToReport = [rates[SFAnalyticsMaxEventsKey] unsignedIntegerValue]; + NSNumber *percentageNum = internal ? rates[SFAnalyticsDevicePercentageInternalKey] : rates[SFAnalyticsDevicePercentageCustomerKey]; + _devicePercentage = [percentageNum floatValue]; + } else { + _secondsBetweenUploads = internal ? secondsBetweenUploadsInternal : secondsBetweenUploadsCustomer; + _maxEventsToReport = SFAnalyticsMaxEventsToReport; + _devicePercentage = DEFAULT_SPLUNK_DEVICE_PERCENTAGE; + } +#endif + secnotice("supd", "created %@ with %lu seconds between uploads, %lu max events, %f percent of uploads", + _internalTopicName, (unsigned long)_secondsBetweenUploads, (unsigned long)_maxEventsToReport, _devicePercentage); + +#if SFANALYTICS_SPLUNK_DEV + _ignoreServersMessagesTellingUsToGoAway = YES; + + if (!_splunkUploadURL && splunkEndpoint) { + NSString* urlString = [NSString stringWithFormat:@"https://%@/report/2/%@", splunkEndpoint, _splunkTopicName]; + _splunkUploadURL = [NSURL URLWithString:urlString]; + } +#else + (void)splunkEndpoint; +#endif + } + return self; +} + +- (BOOL)isSampledUpload +{ + uint32_t sample = arc4random(); + if ((double)_devicePercentage < ((double)1 / UINT32_MAX) * 100) { + /* Requested percentage is smaller than we can sample. just do 1 out of UINT32_MAX */ + if (sample == 0) { + return YES; + } + } else { + if ((double)sample <= (double)UINT32_MAX * ((double)_devicePercentage / 100)) { + return YES; + } + } + return NO; +} + +- (BOOL)postJSON:(NSData*)json toEndpoint:(NSURL*)endpoint error:(NSError**)error +{ + if (!endpoint) { + if (error) { + NSString *description = [NSString stringWithFormat:@"No endpoint for %@", _internalTopicName]; + *error = [NSError errorWithDomain:@"SupdUploadErrorDomain" + code:-10 + userInfo:@{NSLocalizedDescriptionKey : description}]; + } + return false; + } + /* + * Create the NSURLSession + * We use the ephemeral session config because we don't need cookies or cache + */ + NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; + + configuration.HTTPAdditionalHeaders = @{ @"User-Agent" : [NSString stringWithFormat:@"securityd/%s", SECURITY_BUILD_VERSION]}; + + NSURLSession* postSession = [NSURLSession sessionWithConfiguration:configuration + delegate:self + delegateQueue:nil]; + + NSMutableURLRequest* postRequest = [[NSMutableURLRequest alloc] init]; + postRequest.URL = endpoint; + postRequest.HTTPMethod = @"POST"; + postRequest.HTTPBody = [json supd_gzipDeflate]; + [postRequest setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"]; + + /* + * Create the upload task. + */ + dispatch_semaphore_t sem = dispatch_semaphore_create(0); + __block BOOL uploadSuccess = NO; + NSURLSessionDataTask* uploadTask = [postSession dataTaskWithRequest:postRequest + completionHandler:^(NSData * _Nullable __unused data, NSURLResponse * _Nullable response, NSError * _Nullable requestError) { + if (requestError) { + secerror("Error in uploading the events to splunk for %@: %@", self->_internalTopicName, requestError); + } else if (![response isKindOfClass:NSHTTPURLResponse.class]){ + Class class = response.class; + secerror("Received the wrong kind of response for %@: %@", self->_internalTopicName, NSStringFromClass(class)); + } else { + NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response; + if(httpResponse.statusCode >= 200 && httpResponse.statusCode < 300) { + /* Success */ + uploadSuccess = YES; + secnotice("upload", "Splunk upload success for %@", self->_internalTopicName); + } else { + secnotice("upload", "Splunk upload for %@ unexpected status to URL: %@ -- status: %d", + self->_internalTopicName, endpoint, (int)(httpResponse.statusCode)); + } + } + dispatch_semaphore_signal(sem); + }]; + secnotice("upload", "Splunk upload start for %@", self->_internalTopicName); + [uploadTask resume]; + dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, (uint64_t)(5 * 60 * NSEC_PER_SEC))); + return uploadSuccess; +} + +- (BOOL)eventIsBlacklisted:(NSMutableDictionary*)event { + return _blacklistedEvents ? [_blacklistedEvents containsObject:event[SFAnalyticsEventType]] : NO; +} + +- (void)removeBlacklistedFieldsFromEvent:(NSMutableDictionary*)event { + for (NSString* badField in self->_blacklistedFields) { + [event removeObjectForKey:badField]; + } +} + +- (void)addRequiredFieldsToEvent:(NSMutableDictionary*)event { + [_metricsBase enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { + if (!event[key]) { + event[key] = obj; + } + }]; +} + +- (BOOL)prepareEventForUpload:(NSMutableDictionary*)event { + if ([self eventIsBlacklisted:event]) { + return NO; + } + + [self removeBlacklistedFieldsFromEvent:event]; + [self addRequiredFieldsToEvent:event]; + if (_disableClientId) { + event[SFAnalyticsClientId] = @(0); + } + event[SFAnalyticsSplunkTopic] = self->_splunkTopicName ?: [NSNull null]; + return YES; +} + +- (void)addFailures:(NSMutableArray*)failures toUploadRecords:(NSMutableArray*)records threshold:(NSUInteger)threshold +{ + // The first 0 through 'threshold' items are getting uploaded in any case (which might be 0 for lower priority data) + + for (NSArray* client in failures) { + [client enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + if (idx >= threshold) { + *stop = YES; + return; + } + if ([self prepareEventForUpload:obj]) { + [records addObject:obj]; + } + }]; + } + + // Are there more items than we shoved into the upload records? + NSInteger excessItems = 0; + for (NSArray* client in failures) { + NSInteger localExcess = client.count - threshold; + excessItems += localExcess > 0 ? localExcess : 0; + } + + // Then, if we have space and items left, apply a scaling factor to distribute events across clients to fill upload buffer + if (records.count < _maxEventsToReport && excessItems > 0) { + double scale = (_maxEventsToReport - records.count) / (double)excessItems; + if (scale > 1) { + scale = 1; + } + + for (NSArray* client in failures) { + if (client.count > threshold) { + NSRange range = NSMakeRange(threshold, (client.count - threshold) * scale); + NSArray* sub = [client subarrayWithRange:range]; + [sub enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + if ([self prepareEventForUpload:obj]) { + [records addObject:obj]; + } + }]; + } + } + } +} + +- (NSMutableDictionary*)sampleStatisticsForSamples:(NSArray*)samples withName:(NSString*)name +{ + NSMutableDictionary* statistics = [NSMutableDictionary dictionary]; + NSUInteger count = samples.count; + NSArray* sortedSamples = [samples sortedArrayUsingSelector:@selector(compare:)]; + NSArray* samplesAsExpressionArray = @[[NSExpression expressionForConstantValue:sortedSamples]]; + + if (count == 1) { + statistics[name] = samples[0]; + } else { + // NSExpression takes population standard deviation. Our data is a sample of whatever we sampled over time, + // but the difference between the two is fairly minor (divide by N before taking sqrt versus divide by N-1). + statistics[[NSString stringWithFormat:@"%@-dev", name]] = [[NSExpression expressionForFunction:@"stddev:" arguments:samplesAsExpressionArray] expressionValueWithObject:nil context:nil]; + + statistics[[NSString stringWithFormat:@"%@-min", name]] = [[NSExpression expressionForFunction:@"min:" arguments:samplesAsExpressionArray] expressionValueWithObject:nil context:nil]; + statistics[[NSString stringWithFormat:@"%@-max", name]] = [[NSExpression expressionForFunction:@"max:" arguments:samplesAsExpressionArray] expressionValueWithObject:nil context:nil]; + statistics[[NSString stringWithFormat:@"%@-avg", name]] = [[NSExpression expressionForFunction:@"average:" arguments:samplesAsExpressionArray] expressionValueWithObject:nil context:nil]; + statistics[[NSString stringWithFormat:@"%@-med", name]] = [[NSExpression expressionForFunction:@"median:" arguments:samplesAsExpressionArray] expressionValueWithObject:nil context:nil]; + } + + if (count > 3) { + NSString* q1 = [NSString stringWithFormat:@"%@-1q", name]; + NSString* q3 = [NSString stringWithFormat:@"%@-3q", name]; + // From Wikipedia, which is never wrong + if (count % 2 == 0) { + // The lower quartile value is the median of the lower half of the data. The upper quartile value is the median of the upper half of the data. + statistics[q1] = [[NSExpression expressionForFunction:@"median:" arguments:@[[NSExpression expressionForConstantValue:[sortedSamples subarrayWithRange:NSMakeRange(0, count / 2)]]]] expressionValueWithObject:nil context:nil]; + statistics[q3] = [[NSExpression expressionForFunction:@"median:" arguments:@[[NSExpression expressionForConstantValue:[sortedSamples subarrayWithRange:NSMakeRange((count / 2), count / 2)]]]] expressionValueWithObject:nil context:nil]; + } else if (count % 4 == 1) { + // If there are (4n+1) data points, then the lower quartile is 25% of the nth data value plus 75% of the (n+1)th data value; + // the upper quartile is 75% of the (3n+1)th data point plus 25% of the (3n+2)th data point. + // (offset n by -1 since we count from 0) + NSUInteger n = count / 4; + statistics[q1] = @(([sortedSamples[n - 1] doubleValue] + [sortedSamples[n] doubleValue] * 3.0) / 4.0); + statistics[q3] = @(([sortedSamples[(3 * n)] doubleValue] * 3.0 + [sortedSamples[(3 * n) + 1] doubleValue]) / 4.0); + } else if (count % 4 == 3){ + // If there are (4n+3) data points, then the lower quartile is 75% of the (n+1)th data value plus 25% of the (n+2)th data value; + // the upper quartile is 25% of the (3n+2)th data point plus 75% of the (3n+3)th data point. + // (offset n by -1 since we count from 0) + NSUInteger n = count / 4; + statistics[q1] = @(([sortedSamples[n] doubleValue] * 3.0 + [sortedSamples[n + 1] doubleValue]) / 4.0); + statistics[q3] = @(([sortedSamples[(3 * n) + 1] doubleValue] + [sortedSamples[(3 * n) + 2] doubleValue] * 3.0) / 4.0); + } + } + + return statistics; +} + +- (NSMutableDictionary*)healthSummaryWithName:(NSString*)name store:(SFAnalyticsSQLiteStore*)store +{ + __block NSMutableDictionary* summary = [NSMutableDictionary new]; + + // Add some events of our own before pulling in data + summary[SFAnalyticsEventType] = [NSString stringWithFormat:@"%@HealthSummary", name]; + if ([self eventIsBlacklisted:summary]) { + return nil; + } + summary[SFAnalyticsEventTime] = @([[NSDate date] timeIntervalSince1970] * 1000); // Splunk wants milliseconds + [SFAnalytics addOSVersionToEvent:summary]; + + // Process counters + NSDictionary* successCounts = store.summaryCounts; + __block NSInteger totalSuccessCount = 0; + __block NSInteger totalHardFailureCount = 0; + __block NSInteger totalSoftFailureCount = 0; + [successCounts enumerateKeysAndObjectsUsingBlock:^(NSString* _Nonnull eventType, NSDictionary* _Nonnull counts, BOOL* _Nonnull stop) { + summary[[NSString stringWithFormat:@"%@-success", eventType]] = counts[SFAnalyticsColumnSuccessCount]; + summary[[NSString stringWithFormat:@"%@-hardfail", eventType]] = counts[SFAnalyticsColumnHardFailureCount]; + summary[[NSString stringWithFormat:@"%@-softfail", eventType]] = counts[SFAnalyticsColumnSoftFailureCount]; + totalSuccessCount += [counts[SFAnalyticsColumnSuccessCount] integerValue]; + totalHardFailureCount += [counts[SFAnalyticsColumnHardFailureCount] integerValue]; + totalSoftFailureCount += [counts[SFAnalyticsColumnSoftFailureCount] integerValue]; + }]; + + summary[SFAnalyticsColumnSuccessCount] = @(totalSuccessCount); + summary[SFAnalyticsColumnHardFailureCount] = @(totalHardFailureCount); + summary[SFAnalyticsColumnSoftFailureCount] = @(totalSoftFailureCount); + if (os_variant_has_internal_diagnostics("com.apple.security")) { + summary[SFAnalyticsInternal] = @YES; + } + + // Process samples + NSMutableDictionary* samplesBySampler = [NSMutableDictionary dictionary]; + for (NSDictionary* sample in [store samples]) { + if (!samplesBySampler[sample[SFAnalyticsColumnSampleName]]) { + samplesBySampler[sample[SFAnalyticsColumnSampleName]] = [NSMutableArray array]; + } + [samplesBySampler[sample[SFAnalyticsColumnSampleName]] addObject:sample[SFAnalyticsColumnSampleValue]]; + } + [samplesBySampler enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSMutableArray * _Nonnull obj, BOOL * _Nonnull stop) { + NSMutableDictionary* event = [self sampleStatisticsForSamples:obj withName:key]; + [summary addEntriesFromDictionary:event]; + }]; + + // Should always return yes because we already checked for event blacklisting specifically + if (![self prepareEventForUpload:summary]) { + return nil; + } + return summary; +} + +- (void)updateUploadDateForClients:(NSArray*)clients clearData:(BOOL)clearData +{ + for (SFAnalyticsClient* client in clients) { + SFAnalyticsSQLiteStore* store = [SFAnalyticsSQLiteStore storeWithPath:client.storePath schema:SFAnalyticsTableSchema]; + secnotice("postprocess", "Setting upload date for client: %@", client.name); + store.uploadDate = [NSDate date]; + if (clearData) { + secnotice("postprocess", "Clearing collected data for client: %@", client.name); + [store clearAllData]; + } + } +} + +- (NSData*)getLoggingJSON:(bool)pretty + forUpload:(BOOL)upload + participatingClients:(NSMutableArray**)clients + error:(NSError**)error +{ + __block NSMutableArray* uploadRecords = [NSMutableArray arrayWithCapacity:_maxEventsToReport]; + __block NSError *localError; + __block NSMutableArray* hardFailures = [NSMutableArray new]; + __block NSMutableArray* softFailures = [NSMutableArray new]; + NSString* ckdeviceID = nil; + if ([_internalTopicName isEqualToString:SFAnalyticsTopicKeySync]) { + ckdeviceID = os_variant_has_internal_diagnostics("com.apple.security") ? [self askSecurityForCKDeviceID] : nil; + } + for (SFAnalyticsClient* client in self->_topicClients) { + if ([client requireDeviceAnalytics] && !_isDeviceAnalyticsEnabled()) { + // Client required device analytics, yet the user did not opt in. + secnotice("getLoggingJSON", "Client '%@' requires device analytics yet user did not opt in.", [client name]); + continue; + } + if ([client requireiCloudAnalytics] && !_isiCloudAnalyticsEnabled()) { + // Client required iCloud analytics, yet the user did not opt in. + secnotice("getLoggingJSON", "Client '%@' requires iCloud analytics yet user did not opt in.", [client name]); + continue; + } + + SFAnalyticsSQLiteStore* store = [SFAnalyticsSQLiteStore storeWithPath:client.storePath schema:SFAnalyticsTableSchema]; + + if (upload) { + NSDate* uploadDate = store.uploadDate; + if (uploadDate && [[NSDate date] timeIntervalSinceDate:uploadDate] < _secondsBetweenUploads) { + secnotice("json", "ignoring client '%@' for %@ because last upload too recent: %@", + client.name, _internalTopicName, uploadDate); + continue; + } + + if (!uploadDate) { + secnotice("json", "ignoring client '%@' because doesn't have an upload date; giving it a baseline date", + client.name); + [self updateUploadDateForClients:@[client] clearData:NO]; + continue; + } + + secnotice("json", "including client '%@' for upload", client.name); + [*clients addObject:client]; + } + + NSMutableDictionary* healthSummary = [self healthSummaryWithName:client.name store:store]; + if (healthSummary) { + if (ckdeviceID) { + healthSummary[SFAnalyticsDeviceID] = ckdeviceID; + } + [uploadRecords addObject:healthSummary]; + } + + [hardFailures addObject:store.hardFailures]; + [softFailures addObject:store.softFailures]; + } + if (upload && [*clients count] == 0) { + if (error) { + NSString *description = [NSString stringWithFormat:@"Upload too recent for all clients for %@", _internalTopicName]; + *error = [NSError errorWithDomain:@"SupdUploadErrorDomain" + code:-10 + userInfo:@{NSLocalizedDescriptionKey : description}]; + } + return nil; + } + + [self addFailures:hardFailures toUploadRecords:uploadRecords threshold:_maxEventsToReport/10]; + [self addFailures:softFailures toUploadRecords:uploadRecords threshold:0]; + + NSDictionary* jsonDict = @{ + SFAnalyticsSplunkPostTime : @([[NSDate date] timeIntervalSince1970] * 1000), + @"events" : uploadRecords + }; + + NSData *json = [NSJSONSerialization dataWithJSONObject:jsonDict + options:(pretty ? NSJSONWritingPrettyPrinted : 0) + error:&localError]; + + if (error) { + *error = localError; + } + return json; +} + +- (NSString*)askSecurityForCKDeviceID +{ + NSError* error = nil; + CKKSControl* rpc = [CKKSControl controlObject:&error]; + if(error || !rpc) { + secerror("unable to obtain CKKS endpoint: %@", error); + return nil; + } + + __block NSString* localCKDeviceID; + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + [rpc rpcGetCKDeviceIDWithReply:^(NSString* ckdeviceID) { + localCKDeviceID = ckdeviceID; + dispatch_semaphore_signal(sema); + }]; + + if (dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 10)) != 0) { + secerror("timed out waiting for a response from security"); + return nil; + } + + return localCKDeviceID; +} + +// this method is kind of evil for the fact that it has side-effects in pulling other things besides the metricsURL from the server, and as such should NOT be memoized. +// TODO redo this, probably to return a dictionary. +- (NSURL*)splunkUploadURL +{ + if (__splunkUploadURL) { + return __splunkUploadURL; + } + + __weak __typeof(self) weakSelf = self; + dispatch_semaphore_t sem = dispatch_semaphore_create(0); + + __block NSError* error = nil; + NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; + NSURLSession* storeBagSession = [NSURLSession sessionWithConfiguration:configuration + delegate:self + delegateQueue:nil]; + + NSURL* requestEndpoint = _splunkBagURL; + __block NSURL* result = nil; + NSURLSessionDataTask* storeBagTask = [storeBagSession dataTaskWithURL:requestEndpoint completionHandler:^(NSData * _Nullable data, + NSURLResponse * _Nullable __unused response, + NSError * _Nullable responseError) { + + __strong __typeof(self) strongSelf = weakSelf; + if (!strongSelf) { + return; + } + + if (data && !responseError) { + NSData *responseData = data; // shut up compiler + NSDictionary* responseDict = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error]; + if([responseDict isKindOfClass:NSDictionary.class] && !error) { + if (!self->_ignoreServersMessagesTellingUsToGoAway) { + self->_disableUploads = [[responseDict valueForKey:@"sendDisabled"] boolValue]; + if (self->_disableUploads) { + // then don't upload anything right now + secerror("not returning a splunk URL because uploads are disabled for %@", self->_internalTopicName); + dispatch_semaphore_signal(sem); + return; + } + + // backend works with milliseconds + NSUInteger secondsBetweenUploads = [[responseDict valueForKey:@"postFrequency"] unsignedIntegerValue] / 1000; + if (secondsBetweenUploads > 0) { + if (os_variant_has_internal_diagnostics("com.apple.security") && + self->_secondsBetweenUploads < secondsBetweenUploads) { + secnotice("getURL", "Overriding server-sent post frequency because device is internal (%lu -> %lu)", secondsBetweenUploads, self->_secondsBetweenUploads); + } else { + strongSelf->_secondsBetweenUploads = secondsBetweenUploads; + } + } + + strongSelf->_blacklistedEvents = responseDict[@"blacklistedEvents"]; + strongSelf->_blacklistedFields = responseDict[@"blacklistedFields"]; + } + + strongSelf->_metricsBase = responseDict[@"metricsBase"]; + + NSString* metricsEndpoint = responseDict[@"metricsUrl"]; + if([metricsEndpoint isKindOfClass:NSString.class]) { + /* Lives our URL */ + NSString* endpoint = [metricsEndpoint stringByAppendingFormat:@"/2/%@", strongSelf->_splunkTopicName]; + secnotice("upload", "got metrics endpoint %@ for %@", endpoint, self->_internalTopicName); + NSURL* endpointURL = [NSURL URLWithString:endpoint]; + if([endpointURL.scheme isEqualToString:@"https"]) { + result = endpointURL; + } + } + } + } + else { + error = responseError; + } + if (error) { + secnotice("upload", "Unable to fetch splunk endpoint at URL for %@: %@ -- error: %@", + self->_internalTopicName, requestEndpoint, error.description); + } + else if (!result) { + secnotice("upload", "Malformed iTunes config payload for %@!", self->_internalTopicName); + } + + dispatch_semaphore_signal(sem); + }]; + + [storeBagTask resume]; + dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, (uint64_t)(60 * NSEC_PER_SEC))); + + return result; +} + +- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge + completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler { + assert(completionHandler); + (void)session; + secnotice("upload", "Splunk upload challenge for %@", _internalTopicName); + NSURLCredential *cred = nil; + SecTrustResultType result = kSecTrustResultInvalid; + + if ([challenge previousFailureCount] > 0) { + // Previous failures occurred, bail + completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); + + } else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { + /* + * Evaluate trust for the certificate + */ + + SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; + // Coverity gets upset if we don't check status even though result is all we need. + OSStatus status = SecTrustEvaluate(serverTrust, &result); + if (_allowInsecureSplunkCert || (status == errSecSuccess && ((result == kSecTrustResultProceed) || (result == kSecTrustResultUnspecified)))) { + /* + * All is well, accept the credentials + */ + if(_allowInsecureSplunkCert) { + secnotice("upload", "Force Accepting Splunk Credential for %@", _internalTopicName); + } + cred = [NSURLCredential credentialForTrust:serverTrust]; + completionHandler(NSURLSessionAuthChallengeUseCredential, cred); + + } else { + /* + * An error occurred in evaluating trust, bail + */ + completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); + } + } else { + /* + * Just perform the default handling + */ + completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); + } +} + +- (NSDictionary*)eventDictWithBlacklistedFieldsStrippedFrom:(NSDictionary*)eventDict +{ + NSMutableDictionary* strippedDict = eventDict.mutableCopy; + for (NSString* blacklistedField in _blacklistedFields) { + [strippedDict removeObjectForKey:blacklistedField]; + } + return strippedDict; +} + +// MARK: Database path retrieval + ++ (NSString*)databasePathForCKKS +{ + return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"Analytics/ckks_analytics.db") path]; +} + ++ (NSString*)databasePathForSOS +{ + return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"Analytics/sos_analytics.db") path]; +} + ++ (NSString*)AppSupportPath +{ +#if TARGET_OS_IOS + return @"/var/mobile/Library/Application Support"; +#else + NSArray*paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, true); + if ([paths count] < 1) { + return nil; + } + return [NSString stringWithString: paths[0]]; +#endif /* TARGET_OS_IOS */ +} + ++ (NSString*)databasePathForPCS +{ + NSString *appSup = [self AppSupportPath]; + if (!appSup) { + return nil; + } + NSString *dbpath = [NSString stringWithFormat:@"%@/com.apple.ProtectedCloudStorage/PCSAnalytics.db", appSup]; + secnotice("supd", "PCS Database path (%@)", dbpath); + return dbpath; +} + ++ (NSString*)databasePathForTrustdHealth +{ +#if TARGET_OS_IPHONE + return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory(CFSTR("Analytics/trustd_health_analytics.db")) path]; +#else + return [(__bridge_transfer NSURL*)SecCopyURLForFileInUserCacheDirectory(CFSTR("Analytics/trustd_health_analytics.db")) path]; +#endif +} + ++ (NSString*)databasePathForTrust +{ +#if TARGET_OS_IPHONE + return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory(CFSTR("Analytics/trust_analytics.db")) path]; +#else + return [(__bridge_transfer NSURL*)SecCopyURLForFileInUserCacheDirectory(CFSTR("Analytics/trust_analytics.db")) path]; +#endif +} + ++ (NSString*)databasePathForTLS +{ +#if TARGET_OS_IPHONE + return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory(CFSTR("Analytics/TLS_analytics.db")) path]; +#else + return [(__bridge_transfer NSURL*)SecCopyURLForFileInUserCacheDirectory(CFSTR("Analytics/TLS_analytics.db")) path]; +#endif +} + +@end + +@interface supd () +@property NSDictionary *topicsSamplingRates; +@end + +@implementation supd +- (void)setupTopics +{ + NSDictionary* systemDefaultValues = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle bundleWithPath:@"/System/Library/Frameworks/Security.framework"] pathForResource:@"SFAnalytics" ofType:@"plist"]]; + NSMutableArray * topics = [NSMutableArray array]; + for (NSString *topicKey in systemDefaultValues) { + NSDictionary *topicSamplingRates = _topicsSamplingRates[topicKey]; + SFAnalyticsTopic *topic = [[SFAnalyticsTopic alloc] initWithDictionary:systemDefaultValues[topicKey] name:topicKey samplingRates:topicSamplingRates]; + [topics addObject:topic]; + } + _analyticsTopics = [NSArray arrayWithArray:topics]; +} + ++ (void)instantiate { + [supd instance]; +} + ++ (instancetype)instance { +#if TARGET_OS_SIMULATOR + return nil; +#else + if (!_supdInstance) { + _supdInstance = [self new]; + } + return _supdInstance; +#endif +} + +// Use this for testing to get rid of any state ++ (void)removeInstance { + _supdInstance = nil; +} + + +static NSString *SystemTrustStorePath = @"/System/Library/Security/Certificates.bundle"; +static NSString *AnalyticsSamplingRatesFilename = @"AnalyticsSamplingRates"; +static NSString *ContentVersionKey = @"MobileAssetContentVersion"; +static NSString *AssetContextFilename = @"OTAPKIContext.plist"; + +static NSNumber *getSystemVersion(NSBundle *trustStoreBundle) { + NSDictionary *systemVersionPlist = [NSDictionary dictionaryWithContentsOfURL:[trustStoreBundle URLForResource:@"AssetVersion" + withExtension:@"plist"]]; + if (!systemVersionPlist || ![systemVersionPlist isKindOfClass:[NSDictionary class]]) { + return nil; + } + NSNumber *systemVersion = systemVersionPlist[ContentVersionKey]; + if (systemVersion == nil || ![systemVersion isKindOfClass:[NSNumber class]]) { + return nil; + } + return systemVersion; +} + +static NSNumber *getAssetVersion(NSURL *directory) { + NSDictionary *assetContextPlist = [NSDictionary dictionaryWithContentsOfURL:[directory URLByAppendingPathComponent:AssetContextFilename]]; + if (!assetContextPlist || ![assetContextPlist isKindOfClass:[NSDictionary class]]) { + return nil; + } + NSNumber *assetVersion = assetContextPlist[ContentVersionKey]; + if (assetVersion == nil || ![assetVersion isKindOfClass:[NSNumber class]]) { + return nil; + } + return assetVersion; +} + +static bool ShouldInitializeWithAsset(NSBundle *trustStoreBundle, NSURL *directory) { + NSNumber *systemVersion = getSystemVersion(trustStoreBundle); + NSNumber *assetVersion = getAssetVersion(directory); + + if (assetVersion == nil || systemVersion == nil) { + return false; + } + if ([assetVersion compare:systemVersion] == NSOrderedDescending) { + return true; + } + return false; +} + +- (void)setupSamplingRates { +#if TARGET_OS_SIMULATOR + NSBundle *trustStoreBundle = [NSBundle bundleWithPath:[NSString stringWithFormat:@"%s%@", getenv("SIMULATOR_ROOT"), SystemTrustStorePath]]; +#else + NSBundle *trustStoreBundle = [NSBundle bundleWithPath:SystemTrustStorePath]; +#endif + +#if TARGET_OS_IPHONE + NSURL *keychainsDirectory = CFBridgingRelease(SecCopyURLForFileInKeychainDirectory(nil)); +#else + NSURL *keychainsDirectory = [NSURL fileURLWithFileSystemRepresentation:"/Library/Keychains/" isDirectory:YES relativeToURL:nil]; +#endif + NSURL *directory = [keychainsDirectory URLByAppendingPathComponent:@"SupplementalsAssets/" isDirectory:YES]; + + NSDictionary *analyticsSamplingRates = nil; + if (ShouldInitializeWithAsset(trustStoreBundle, directory)) { + /* Try to get the asset version of the sampling rates */ + NSURL *analyticsSamplingRateURL = [directory URLByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist", AnalyticsSamplingRatesFilename]]; + analyticsSamplingRates = [NSDictionary dictionaryWithContentsOfURL:analyticsSamplingRateURL]; + secnotice("supd", "read sampling rates from SupplementalsAssets dir"); + if (!analyticsSamplingRates || ![analyticsSamplingRates isKindOfClass:[NSDictionary class]]) { + analyticsSamplingRates = nil; + } + } + if (!analyticsSamplingRates) { + analyticsSamplingRates = [NSDictionary dictionaryWithContentsOfURL: [trustStoreBundle URLForResource:AnalyticsSamplingRatesFilename + withExtension:@"plist"]]; + } + if (analyticsSamplingRates && [analyticsSamplingRates isKindOfClass:[NSDictionary class]]) { + _topicsSamplingRates = analyticsSamplingRates[@"Topics"]; + if (!_topicsSamplingRates || ![analyticsSamplingRates isKindOfClass:[NSDictionary class]]) { + _topicsSamplingRates = nil; // Something has gone terribly wrong, so we'll use the hardcoded defaults in this case + } + } +} + +- (instancetype)initWithReporter:(SFAnalyticsReporter *)reporter +{ + if (self = [super init]) { + [self setupSamplingRates]; + [self setupTopics]; + _reporter = reporter; + [_reporter setupReportsDirectory]; + + xpc_activity_register("com.apple.securityuploadd.triggerupload", XPC_ACTIVITY_CHECK_IN, ^(xpc_activity_t activity) { + xpc_activity_state_t activityState = xpc_activity_get_state(activity); + secnotice("supd", "hit xpc activity trigger, state: %ld", activityState); + if (activityState == XPC_ACTIVITY_STATE_RUN) { + // Clean up the reports directory, and then run our regularly scheduled scan + [_reporter cleanupReportsDirectory]; + [self performRegularlyScheduledUpload]; + } + }); + } + + return self; +} + +- (instancetype)init { + SFAnalyticsReporter *reporter = [[SFAnalyticsReporter alloc] init]; + return [self initWithReporter:reporter]; +} + +- (void)sendNotificationForOncePerReportSamplers +{ + notify_post(SFAnalyticsFireSamplersNotification); + [NSThread sleepForTimeInterval:3.0]; +} + +- (void)performRegularlyScheduledUpload { + secnotice("upload", "Starting uploads in response to regular trigger"); + NSError *error = nil; + if ([self uploadAnalyticsWithError:&error]) { + secnotice("upload", "Regularly scheduled upload successful"); + } else { + secerror("upload: Failed to complete regularly scheduled upload: %@", error); + } +} + +- (BOOL)uploadAnalyticsWithError:(NSError**)error { + [self sendNotificationForOncePerReportSamplers]; + + BOOL result = NO; + NSError* localError = nil; + for (SFAnalyticsTopic *topic in _analyticsTopics) { + @autoreleasepool { // The logging JSONs get quite large. Ensure they're deallocated between topics. + __block NSURL* endpoint = [topic splunkUploadURL]; // has side effects! + if ([topic disableUploads]) { + secnotice("upload", "Aborting upload task because uploads are disabled for %@", [topic internalTopicName]); + return NO; + } + + NSMutableArray* clients = [NSMutableArray new]; + NSData* json = [topic getLoggingJSON:false forUpload:YES participatingClients:&clients error:&localError]; + if (json) { + if ([topic isSampledUpload]) { + BOOL writtenToLog = NO; +#if TARGET_OS_OSX + // As of now, data is NOT logged for transparency on macOS, yet we upload anyway. + writtenToLog = YES; +#elif !TARGET_OS_SIMULATOR + // We override the output here and always assume we write to the log. Data transparency will be fixed in F. + writtenToLog = YES; +#endif // !TARGET_OS_SIMULATOR + if (!writtenToLog) { + secerror("uploadAnalyticsWithError: failed to write analytics data to log"); + } else if ([topic postJSON:json toEndpoint:endpoint error:&localError]) { + secnotice("uploadAnalyticsWithError", "Succeeded writing analytics data to log -- proceeding with upload"); + result = YES; + [topic updateUploadDateForClients:clients clearData:YES]; + } + } else { + /* If we didn't sample this report, update date to prevent trying to upload again sooner + * than we should. Clear data so that per-day calculations remain consistent. */ + secnotice("upload", "skipping unsampled upload for %@ and clearing data", [topic internalTopicName]); + [topic updateUploadDateForClients:clients clearData:YES]; + } + } + } + if (error && localError) { + *error = localError; + } + } + return result; +} + +- (NSString*)sysdiagnoseStringForEventRecord:(NSDictionary*)eventRecord +{ + NSMutableDictionary* mutableEventRecord = eventRecord.mutableCopy; + [mutableEventRecord removeObjectForKey:SFAnalyticsSplunkTopic]; + + NSDate* eventDate = [NSDate dateWithTimeIntervalSince1970:[[eventRecord valueForKey:SFAnalyticsEventTime] doubleValue] / 1000]; + [mutableEventRecord removeObjectForKey:SFAnalyticsEventTime]; + + NSString* eventName = eventRecord[SFAnalyticsEventType]; + [mutableEventRecord removeObjectForKey:SFAnalyticsEventType]; + + SFAnalyticsEventClass eventClass = [[eventRecord valueForKey:SFAnalyticsEventClassKey] integerValue]; + NSString* eventClassString = [self stringForEventClass:eventClass]; + [mutableEventRecord removeObjectForKey:SFAnalyticsEventClassKey]; + + NSMutableString* additionalAttributesString = [NSMutableString string]; + if (mutableEventRecord.count > 0) { + [additionalAttributesString appendString:@" - Attributes: {" ]; + __block BOOL firstAttribute = YES; + [mutableEventRecord enumerateKeysAndObjectsUsingBlock:^(NSString* key, id object, BOOL* stop) { + NSString* openingString = firstAttribute ? @"" : @", "; + [additionalAttributesString appendString:[NSString stringWithFormat:@"%@%@ : %@", openingString, key, object]]; + firstAttribute = NO; + }]; + [additionalAttributesString appendString:@" }"]; + } + + return [NSString stringWithFormat:@"%@ %@: %@%@", eventDate, eventClassString, eventName, additionalAttributesString]; +} + +- (NSString*)getSysdiagnoseDump +{ + NSMutableString* sysdiagnose = [[NSMutableString alloc] init]; + + for (SFAnalyticsTopic* topic in _analyticsTopics) { + for (SFAnalyticsClient* client in topic.topicClients) { + [sysdiagnose appendString:[NSString stringWithFormat:@"Client: %@\n", client.name]]; + SFAnalyticsSQLiteStore* store = [SFAnalyticsSQLiteStore storeWithPath:client.storePath schema:SFAnalyticsTableSchema]; + NSArray* allEvents = store.allEvents; + for (NSDictionary* eventRecord in allEvents) { + [sysdiagnose appendFormat:@"%@\n", [self sysdiagnoseStringForEventRecord:eventRecord]]; + } + if (allEvents.count == 0) { + [sysdiagnose appendString:@"No data to report for this client\n"]; + } + } + } + return sysdiagnose; +} + +- (NSString*)stringForEventClass:(SFAnalyticsEventClass)eventClass +{ + if (eventClass == SFAnalyticsEventClassNote) { + return @"EventNote"; + } + else if (eventClass == SFAnalyticsEventClassSuccess) { + return @"EventSuccess"; + } + else if (eventClass == SFAnalyticsEventClassHardFailure) { + return @"EventHardFailure"; + } + else if (eventClass == SFAnalyticsEventClassSoftFailure) { + return @"EventSoftFailure"; + } + else { + return @"EventUnknown"; + } +} + +// MARK: XPC Procotol Handlers + +- (void)getSysdiagnoseDumpWithReply:(void (^)(NSString*))reply { + reply([self getSysdiagnoseDump]); +} + +- (void)getLoggingJSON:(bool)pretty topic:(NSString *)topicName reply:(void (^)(NSData*, NSError*))reply { + secnotice("rpcGetLoggingJSON", "Building a JSON blob resembling the one we would have uploaded"); + NSError* error = nil; + [self sendNotificationForOncePerReportSamplers]; + NSData* json = nil; + for (SFAnalyticsTopic* topic in self->_analyticsTopics) { + if ([topic.internalTopicName isEqualToString:topicName]) { + json = [topic getLoggingJSON:pretty forUpload:NO participatingClients:nil error:&error]; + } + } + if (!json) { + secerror("Unable to obtain JSON: %@", error); + } + reply(json, error); +} + +- (void)forceUploadWithReply:(void (^)(BOOL, NSError*))reply { + secnotice("upload", "Performing upload in response to rpc message"); + NSError* error = nil; + BOOL result = [self uploadAnalyticsWithError:&error]; + secnotice("upload", "Result of manually triggered upload: %@, error: %@", result ? @"success" : @"failure", error); + reply(result, error); +} + +@end diff --git a/supd/supdProtocol.h b/supd/supdProtocol.h new file mode 100644 index 00000000..fd051cf3 --- /dev/null +++ b/supd/supdProtocol.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import + +@protocol supdProtocol +- (void)getSysdiagnoseDumpWithReply:(void (^)(NSString*))reply; +- (void)getLoggingJSON:(bool)pretty topic:(NSString *)topicName reply:(void (^)(NSData*, NSError*))reply; +- (void)forceUploadWithReply:(void (^)(BOOL, NSError*))reply; +@end diff --git a/supdctl/main.m b/supdctl/main.m new file mode 100644 index 00000000..0307de74 --- /dev/null +++ b/supdctl/main.m @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import +#include "lib/SecArgParse.h" +#import "supd/supdProtocol.h" +#import +#import "SFAnalytics.h" + +/* Internal Topic Names */ +NSString* const SFAnalyticsTopicKeySync = @"KeySyncTopic"; +NSString* const SFAnaltyicsTopicTrust = @"TrustTopic"; + +static void nsprintf(NSString *fmt, ...) NS_FORMAT_FUNCTION(1, 2); +static void nsprintf(NSString *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + NSString *str = [[NSString alloc] initWithFormat:fmt arguments:ap]; + va_end(ap); + + puts([str UTF8String]); +#if !__has_feature(objc_arc) + [str release]; +#endif +} + +static NSXPCConnection* getConnection() +{ + NSXPCConnection* connection = [[NSXPCConnection alloc] initWithMachServiceName:@"com.apple.securityuploadd" options:0]; + connection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(supdProtocol)]; + [connection resume]; + return connection; +} + +static void getSysdiagnoseDump(void) +{ + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + NSXPCConnection* connection = getConnection(); + [[connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + nsprintf(@"Could not communicate with supd: %@", error); + dispatch_semaphore_signal(sema); + }] getSysdiagnoseDumpWithReply:^(NSString * sysdiagnoseString) { + nsprintf(@"Analytics sysdiagnose: \n%@", sysdiagnoseString); + dispatch_semaphore_signal(sema); + }]; + + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 20)) != 0) { + printf("\n\nError: timed out waiting for response from supd\n"); + } + [connection invalidate]; +} + +static void getLoggingJSON(char *topicName) +{ + NSString *topic = topicName ? [NSString stringWithUTF8String:topicName] : SFAnalyticsTopicKeySync; + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + NSXPCConnection* connection = getConnection(); + [[connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + nsprintf(@"Could not communicate with supd: %@", error); + dispatch_semaphore_signal(sema); + }] getLoggingJSON:YES topic:topic reply:^(NSData* data, NSError* error) { + if (data) { + nsprintf(@"Logging data we would have uploaded:\n%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); + } else { + nsprintf(@"supd gave us an error: %@", error); + } + dispatch_semaphore_signal(sema); + }]; + + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 20)) != 0) { + printf("\n\nError: timed out waiting for response from supd\n"); + } + [connection invalidate]; +} + +static void forceUploadAnalytics(void) +{ + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + NSXPCConnection* connection = getConnection(); + [[connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + nsprintf(@"Could not communicate with supd: %@", error); + dispatch_semaphore_signal(sema); + }] forceUploadWithReply:^(BOOL success, NSError *error) { + if (success) { + printf("Supd reports successful upload\n"); + } else { + nsprintf(@"Supd reports failure: %@", error); + } + dispatch_semaphore_signal(sema); + }]; + + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 20)) != 0) { + printf("\n\nError: timed out waiting for response from supd\n"); + } + [connection invalidate]; +} + +static int forceUpload = false; +static int getJSON = false; +static int getSysdiagnose = false; +static char *topicName = nil; + +int main(int argc, char **argv) +{ + static struct argument options[] = { + { .shortname='t', .longname="topicName", .argument=&topicName, .description="Operate on a non-default topic"}, + + { .command="sysdiagnose", .flag=&getSysdiagnose, .flagval=true, .description="Retrieve the current sysdiagnose dump for security analytics"}, + { .command="get", .flag=&getJSON, .flagval=true, .description="Get the JSON blob we would upload to the server if an upload were due"}, + { .command="upload", .flag=&forceUpload, .flagval=true, .description="Force an upload of analytics data to server"}, + {} // Need this! + }; + + static struct arguments args = { + .programname="supdctl", + .description="Control and report on security analytics", + .arguments = options, + }; + + if(!options_parse(argc, argv, &args)) { + printf("\n"); + print_usage(&args); + return -1; + } + + @autoreleasepool { + if (forceUpload) { + forceUploadAnalytics(); + } else if (getJSON) { + getLoggingJSON(topicName); + } else if (getSysdiagnose) { + getSysdiagnoseDump(); + } else { + print_usage(&args); + return -1; + } + } + return 0; +} + diff --git a/supdctl/supdctl-Entitlements.plist b/supdctl/supdctl-Entitlements.plist new file mode 100644 index 00000000..271f6e35 --- /dev/null +++ b/supdctl/supdctl-Entitlements.plist @@ -0,0 +1,8 @@ + + + + + com.apple.private.securityuploadd + + + diff --git a/tests/secdmockaks/Info.plist b/tests/secdmockaks/Info.plist new file mode 100644 index 00000000..6c40a6cd --- /dev/null +++ b/tests/secdmockaks/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/tests/secdmockaks/mockaks.h b/tests/secdmockaks/mockaks.h new file mode 100644 index 00000000..8390d5d9 --- /dev/null +++ b/tests/secdmockaks/mockaks.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef mockaks_h +#define mockaks_h + +#import + +@interface SecMockAKS : NSObject ++ (bool)isLocked:(keyclass_t)key_class; ++ (bool)isSEPDown; ++ (bool)useGenerationCount; +@end + +#endif /* mockaks_h */ diff --git a/tests/secdmockaks/mockaks.m b/tests/secdmockaks/mockaks.m new file mode 100644 index 00000000..044d1d4f --- /dev/null +++ b/tests/secdmockaks/mockaks.m @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2018 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import "mockaks.h" + +@implementation SecMockAKS + ++ (bool)isLocked:(keyclass_t)key_class +{ + return false; +} + ++ (bool)isSEPDown +{ + return false; +} + ++ (bool)useGenerationCount +{ + return false; +} + +@end + +kern_return_t +aks_load_bag(const void * data, int length, keybag_handle_t* handle) +{ + *handle = 17; + return 0; +} + +kern_return_t aks_unlock_bag(keybag_handle_t handle, const void * passcode, int length) +{ + return 0; +} + +kern_return_t +aks_create_bag(const void * passcode, int length, keybag_type_t type, keybag_handle_t* handle) +{ + *handle = 17; + return 0; +} + +kern_return_t +aks_unload_bag(keybag_handle_t handle) +{ + return -1; +} + +kern_return_t +aks_save_bag(keybag_handle_t handle, void ** data, int * length) +{ + return 0; +} + +kern_return_t +aks_get_system(keybag_handle_t special_handle, keybag_handle_t *handle) +{ + *handle = 17; + return 0; +} + +//static uint8_t staticAKSKey[32] = "1234567890123456789012"; + +#define PADDINGSIZE 8 + +kern_return_t +aks_wrap_key(const void * key, int key_size, keyclass_t key_class, keybag_handle_t handle, void * wrapped_key, int * wrapped_key_size_inout, keyclass_t * class_out) +{ + if ([SecMockAKS isLocked:key_class]) { + return kIOReturnNotPermitted; + } + if ([SecMockAKS isSEPDown]) { + return kIOReturnBusy; + } + + *class_out = key_class; + if ([SecMockAKS useGenerationCount]) { + *class_out |= (key_class_last + 1); + } + + if (key_size + PADDINGSIZE > *wrapped_key_size_inout) { + abort(); + } + *wrapped_key_size_inout = key_size + PADDINGSIZE; + memcpy(wrapped_key, key, key_size); + memset(((uint8_t *)wrapped_key) + key_size, 0xff, PADDINGSIZE); + return 0; +} + +kern_return_t +aks_unwrap_key(const void * wrapped_key, int wrapped_key_size, keyclass_t key_class, keybag_handle_t handle, void * key, int * key_size_inout) +{ + if ([SecMockAKS isLocked:key_class]) { + return kIOReturnNotPermitted; + } + if ([SecMockAKS isSEPDown]) { + return kIOReturnBusy; + } + + if (wrapped_key_size < 8) { + abort(); + } + static const char expected_padding[PADDINGSIZE] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + if (memcmp(((const uint8_t *)wrapped_key) + (wrapped_key_size - PADDINGSIZE), expected_padding, PADDINGSIZE) != 0) { + abort(); + } + if (*key_size_inout < wrapped_key_size - PADDINGSIZE) { + abort(); + } + *key_size_inout = wrapped_key_size - PADDINGSIZE; + memcpy(key, wrapped_key, *key_size_inout); + + return 0; +} + +int +aks_ref_key_create(keybag_handle_t handle, keyclass_t cls, aks_key_type_t type, const uint8_t *params, size_t params_len, aks_ref_key_t *ot) +{ + return -1; +} + +int +aks_ref_key_encrypt(aks_ref_key_t handle, + const uint8_t *der_params, size_t der_params_len, + const void * data, size_t data_len, + void ** out_der, size_t * out_der_len) +{ + return -1; +} + +int +aks_ref_key_decrypt(aks_ref_key_t handle, + const uint8_t *der_params, size_t der_params_len, + const void * data, size_t data_len, + void ** out_der, size_t * out_der_len) +{ + return -1; +} + +int +aks_ref_key_delete(aks_ref_key_t handle, const uint8_t *der_params, size_t der_params_len) +{ + return -1; +} + +int +aks_operation_optional_params(const uint8_t * access_groups, size_t access_groups_len, const uint8_t * external_data, size_t external_data_len, const void * acm_handle, int acm_handle_len, void ** out_der, size_t * out_der_len) +{ + return -1; +} + +int aks_ref_key_create_with_blob(keybag_handle_t refkey, const uint8_t *ref_key_blob, size_t ref_key_blob_len, aks_ref_key_t* handle) +{ + *handle = NULL; + return 0; +} + +const uint8_t * aks_ref_key_get_blob(aks_ref_key_t refkey, size_t *out_blob_len) +{ + *out_blob_len = 2; + return (const uint8_t *)"20"; +} +int +aks_ref_key_free(aks_ref_key_t* key) +{ + return 0; +} + +const uint8_t * +aks_ref_key_get_external_data(aks_ref_key_t refkey, size_t *out_external_data_len) +{ + *out_external_data_len = 2; + return (const uint8_t *)"21"; +} + + +kern_return_t +aks_assert_hold(keybag_handle_t handle, uint32_t type, uint64_t timeout) +{ + return 0; +} + +kern_return_t +aks_assert_drop(keybag_handle_t handle, uint32_t type) +{ + return 0; +} + +kern_return_t +aks_generation(keybag_handle_t handle, + generation_option_t generation_option, + uint32_t * current_generation) +{ + *current_generation = 0; + return 0; +} + +kern_return_t +aks_get_bag_uuid(keybag_handle_t handle, uuid_t uuid) +{ + memcpy(uuid, "0123456789abcdf", sizeof(uuid_t)); + return 0; +} + +kern_return_t +aks_get_lock_state(keybag_handle_t handle, keybag_state_t *state) +{ + *state = keybag_state_been_unlocked; + return 0; +} + +static CFStringRef staticKeybagHandle = CFSTR("keybagHandle"); + +int +MKBKeyBagCreateWithData(CFDataRef keybagBlob, MKBKeyBagHandleRef* newHandle) +{ + *newHandle = (MKBKeyBagHandleRef)staticKeybagHandle; + return 0; +} + +int +MKBKeyBagUnlock(MKBKeyBagHandleRef keybag, CFDataRef passcode) +{ + if (keybag == NULL || !CFEqual(keybag, staticKeybagHandle)) { + abort(); + } + return 0; +} + +int MKBKeyBagGetAKSHandle(MKBKeyBagHandleRef keybag, int32_t *handle) +{ + if (keybag == NULL || !CFEqual(keybag, staticKeybagHandle)) { + abort(); + } + *handle = 17; + return 0; +} + + + +const CFTypeRef kAKSKeyAcl = (CFTypeRef)CFSTR("kAKSKeyAcl"); +const CFTypeRef kAKSKeyAclParamRequirePasscode = (CFTypeRef)CFSTR("kAKSKeyAclParamRequirePasscode"); + +const CFTypeRef kAKSKeyOpDefaultAcl = (CFTypeRef)CFSTR("kAKSKeyOpDefaultAcl"); +const CFTypeRef kAKSKeyOpEncrypt = (CFTypeRef)CFSTR("kAKSKeyOpEncrypt"); +const CFTypeRef kAKSKeyOpDecrypt = (CFTypeRef)CFSTR("kAKSKeyOpDecrypt"); +const CFTypeRef kAKSKeyOpSync = (CFTypeRef)CFSTR("kAKSKeyOpSync"); +const CFTypeRef kAKSKeyOpDelete = (CFTypeRef)CFSTR("kAKSKeyOpDelete"); +const CFTypeRef kAKSKeyOpCreate = (CFTypeRef)CFSTR("kAKSKeyOpCreate"); +const CFTypeRef kAKSKeyOpSign = (CFTypeRef)CFSTR("kAKSKeyOpSign"); +const CFTypeRef kAKSKeyOpSetKeyClass = (CFTypeRef)CFSTR("kAKSKeyOpSetKeyClass"); +const CFTypeRef kAKSKeyOpWrap = (CFTypeRef)CFSTR("kAKSKeyOpWrap"); +const CFTypeRef kAKSKeyOpUnwrap = (CFTypeRef)CFSTR("kAKSKeyOpUnwrap"); +const CFTypeRef kAKSKeyOpComputeKey = (CFTypeRef)CFSTR("kAKSKeyOpComputeKey"); +const CFTypeRef kAKSKeyOpAttest = (CFTypeRef)CFSTR("kAKSKeyOpAttest"); +const CFTypeRef kAKSKeyOpTranscrypt = (CFTypeRef)CFSTR("kAKSKeyOpTranscrypt"); + + +TKTokenRef TKTokenCreate(CFDictionaryRef attributes, CFErrorRef *error) +{ + return NULL; +} + +CFTypeRef TKTokenCopyObjectData(TKTokenRef token, CFDataRef objectID, CFErrorRef *error) +{ + return NULL; +} + +CFDataRef TKTokenCopyObjectCreationAccessControl(TKTokenRef token, CFDictionaryRef objectAttributes, CFErrorRef *error) +{ + return NULL; +} + +CFDataRef TKTokenCreateOrUpdateObject(TKTokenRef token, CFDataRef objectID, CFMutableDictionaryRef attributes, CFErrorRef *error) +{ + return NULL; +} + +CFDataRef TKTokenCopyObjectAccessControl(TKTokenRef token, CFDataRef objectID, CFErrorRef *error) +{ + return NULL; +} +bool TKTokenDeleteObject(TKTokenRef token, CFDataRef objectID, CFErrorRef *error) +{ + return false; +} + +CFDataRef TKTokenCopyPublicKeyData(TKTokenRef token, CFDataRef objectID, CFErrorRef *error) +{ + return NULL; +} + +CFTypeRef TKTokenCopyOperationResult(TKTokenRef token, CFDataRef objectID, CFIndex secKeyOperationType, CFArrayRef algorithm, + CFIndex secKeyOperationMode, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) +{ + return NULL; +} + +CF_RETURNS_RETAINED CFDictionaryRef TKTokenControl(TKTokenRef token, CFDictionaryRef attributes, CFErrorRef *error) +{ + return NULL; +} + +CFTypeRef LACreateNewContextWithACMContext(CFDataRef acmContext, CFErrorRef *error) +{ + return NULL; +} + +CFDataRef LACopyACMContext(CFTypeRef context, CFErrorRef *error) +{ + return NULL; +} + +bool LAEvaluateAndUpdateACL(CFTypeRef context, CFDataRef acl, CFTypeRef operation, CFDictionaryRef hints, CFDataRef *updatedACL, CFErrorRef *error) +{ + return false; +} + +ACMContextRef +ACMContextCreateWithExternalForm(const void *externalForm, size_t dataLength) +{ + return NULL; +} + +ACMStatus +ACMContextDelete(ACMContextRef context, bool destroyContext) +{ + return 0; +} + +ACMStatus +ACMContextRemovePassphraseCredentialsByPurposeAndScope(const ACMContextRef context, ACMPassphrasePurpose purpose, ACMScope scope) +{ + return 0; +} + diff --git a/tests/secdmockaks/secdmock_db_version_10_5.h b/tests/secdmockaks/secdmock_db_version_10_5.h new file mode 100644 index 00000000..a48f2a78 --- /dev/null +++ b/tests/secdmockaks/secdmock_db_version_10_5.h @@ -0,0 +1,169 @@ +const char *secdmock_db_version10_5[] = { +"PRAGMA foreign_keys=OFF;", +"BEGIN TRANSACTION;", +"CREATE TABLE genp(rowid INTEGER PRIMARY KEY AUTOINCREMENT,cdat REAL,mdat REAL,desc BLOB,icmt BLOB,crtr INTEGER,type INTEGER,scrp INTEGER,labl BLOB,alis BLOB,invi INTEGER,nega INTEGER,cusi INTEGER,prot BLOB,acct BLOB NOT NULL DEFAULT '',svce BLOB NOT NULL DEFAULT '',gena BLOB,data BLOB,agrp TEXT NOT NULL,pdmn TEXT,sync INTEGER NOT NULL DEFAULT 0,tomb INTEGER NOT NULL DEFAULT 0,sha1 BLOB,vwht TEXT,tkid TEXT,musr BLOB NOT NULL,UUID TEXT,sysb INTEGER DEFAULT 0,pcss INTEGER,pcsk BLOB,pcsi BLOB,persistref BLOB NOT NULL,UNIQUE(acct,svce,agrp,sync,vwht,tkid,musr));", +"INSERT INTO genp VALUES(1,540009245.94961404799,540009245.94961404799,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'8382da59a29b55be466989dfa2aebd753d64c29e',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'0300008006000000280000003aa6d8ef67454036a5400ffa795e8da6a8c0415f8eac42c453a55193b984e5b0ffffffffffffffff6d1db45fd916e0eea6e4d6461652236de8eb2b06f4d46f97f44d142cd7889e5b300f067bd4b05d2885b079437f47fac2a95a5fbd65ef3fc907f93b10f7df6aadfa5fb481d2af38fd042703d255fbb6883646147c34f06def5424c3c261ada76dee25aa1347e50869ea0285b6a6f6aaf9bacd6f88044dea72b1b7eda52f15c9c504cd8d589f7a1871c2b69b4a18f7f274a4a67ce7a96bbc7c20497cbdae1ac51b716d71edd274e275df5fc5687d0ee77748c6345538508a8b575287b85cffc8f6d108046c65c45ef33fcf728bdc451f0013b736daa0329ebb99dd60f49c','sync','ak',0,0,X'9606421eed00b577e315aa2f1cb355b42dfcf455','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(2,540009245.95954704282,540009245.95954704282,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'5aae321010aed69c632f05d26ff25a3264daf9df',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000fed80c22727d56ebcb7642031807e29b886a45f7367bc57c39dd4ff0c87a2147ffffffffffffffff432a9bab1064e002f1829613adc70b526bd34b18bfd2e80bbd5dfd6242aa83294f94554607ae0095f564e92748bd1fe95cb0a5669d475a755c54ae2aa6776f79911acb5271539e7f3616c4424a1fc9f8629558138d51f7da0cec0e6fb1890fcd7a331059b727368d36cb635c5dcbb9aa09a132528d871b3c3fa4e6f57047c314995523818e722049732acd5aa58db7a2f638eb11bb38219f44837e0a69e63efa3ea8a2cea9d37bd92830212803770d4f08f93576be06390f2f7f31b9a33a95959695d5b879485a39aff82795705b01e266c14e7c1a5f3aaf14ee328ba8','sync','ak',0,0,X'465af1664ec91a1b3e40961935d62f1d0f51f431','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(3,540009245.96500504016,540009245.96500504016,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'4872b599a64f42a50c2bb8190f4a3053f8f68b83',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000f03a72b4037f8e2566b5abd12b3fd63fdb8b7b686f58d74264db2c57741758a5ffffffffffffffffc56e4643d616e47c39de15202aaa6a7728282a53da54199b3fc9a118131a3e244d75bf98681bee9201fd2d564a9e14f9232ac9ff5bcaa61b9bd9338a171a3fcf7bf726dd618fb22e45537850b65e4bb817e7c4986484c9ae2c5fe19864f5bdd485720ae0a452a942a9b0f1c69a2be72c51bb25861c9141532e57e76be84086345ef5ac55b0edcf24f0fafcffe303b7309cb42d8f782d79829cc814a9855b8d2d8a60c2c4cbae8ee74b6e9638b09c64cdb5957ffa5da290cddf37babf88494aeedd52d2926cd479d4727f384fd57b1a5dc4ac3eac751abbbdb7dbab5e49','sync','ak',0,0,X'db56704c6d1961215f3cb01153997cffd5923bb2','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(4,540009245.96904194357,540009245.96904194357,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'7c93f04b766453571932dd9f62fc2ec2e6fff1bd',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000333ae41a218d6acd22d392f6051eea737b9e4a72e1a82dad9bb987b11bfa46feffffffffffffffffed5f369356888535aa502a458fb9fcd53dd06b43dc7e3012d6a69b15a184f828d7c163404ae16f07ed3344b50e909d146e4a16bb503f03a76c707e0943386616d1224dad995205297d9562e1e3ae676ec5d33a38d94ee276910b54d0dbe032673b3630dc868352c83d24c265b46e3800accec6e2071d28d1551e9b933a09f482cd6be09f2499fbcff37e224c237734d9148dda5decee75a4a997647964299cc090fda9a1dd5ab9df91227beb9d67dd539905a1b1d5bba1e2970e79c5dbab3449d62efa35d247cc4801bdb5b9d4bfbee3e9d82c87d9f7ed1abb1a54e9df','sync','ak',0,0,X'8194c6d9143186d4a3dd9c91bd4ca336807ca149','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(5,540009245.97303295135,540009245.97303295135,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'c9304138ee216d27ad7e02188309e730eae3c88c',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'03000080060000002800000034a5f9344d362336bce4e70edac9832c3914b78d5332a5e4bfeeb6382fdc1adfffffffffffffffffe5356b12f073d4982a140267127bb47de510b91b8b9ac1b22fd563a4dfde6ab7ca2c3cd9c30c5fdb9f879f8f768ab8ea9fc8f62ac1a8f2ad0418674d0afd5e5aa359a8f8e8a862ef6465c2693330d09cbd165fc56dc7003f0174fd8554674da790bdf311b16cd81c68904a36801ff3eca33aa8522966ed7a30a31e576b850af4091f937e8cbdbad37a9dafcf8271e353bb8105351f2e0c7725e467b57e3fecc18a210958fe65976de9c9b9b8317e8d77397ba605f79172042aab81e25e76ef0672f07c326d80d2ed8b769d381102869eed906d7218a784f3d2cff93394','sync','ak',0,0,X'29b024b51b20557236b0ffba807e7439b260906d','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(6,540009245.97699296474,540009245.97699296474,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'eeb4d0c9c2cd4376e4790e8afa7e80514b2ddb03',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000010cbc193247a8174b7368cb5215386128e054ca5f582eaca931796a5b1abbd7ffffffffffffffff2a73831c0172d2e39809b75adbd999224ff6f123fc00de6316a65e9cb31ce29dd63772036bed62e97528ce65592d991590e1ef738cc428b96b54eab0798b477ad981a301ede7fa8cb4a8d83a165b8fde9e57ff60b245b553217678f2b8193b0130093acbddca9a95ee6909b6275210012e57b2bfbbc85ce21f0ceed5253a48faf3c13bc7fd5bf521c1a54954b72f1fc1a953bc1daca5147c537724211e4fb6cfbc9dd11d8cc57436aa47e0cf864fe64f39ceec1944e4b533f8d4f8fea2fa6dbca6b46ea0c95a78238a4d14cf6f553dea440b28c0ae2bfd3a4d90f63def','sync','ak',0,0,X'e0009e99650e1c3e16a99b661ba78024ebd03e98','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(7,540009245.98067498207,540009245.98067498207,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'c5bd6ce0d501326fa6a0aec020542fc94cff130b',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000100b9dedff390f782856d382411dd00b328185a25a878a57d34904ee13603f85ffffffffffffffff2820cdc6b257aa66bb1098308a8282a0bdb2c1a62621d0e050042535de7070a6140073e7aca0c6dff260cbf90931ed530a49f4030c176b16c72e8f1428021aece0b4c41378e66d7b997f2ec4a7d25d8e9f34b5e04ed1224df1fde1d493dfcb5ebb621ed361db51ee406c2bf45cf15a3f2154a09ec089a1481fda3c0c236407665a7de081eecbd055cd963c364de000b274bf753158eadc8b9637140d22502f1c1ae15f3be15af72f9078d07724b799e0bca1791f6ed12be050d13cd173adff0abc87c36cd282812bae25e732bd89053a9eeb4393d2991810cd2eb72275','sync','ak',0,0,X'f2434775aa80960763f972b24e880056436a8365','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(8,540009245.98510801791,540009245.98510801791,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'2a6383e0e35bc696730fd84da42d4c7123e8fbf1',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'03000080060000002800000078ca5addb75af33904cf214f7b59f583d5ec3b21358d9af12109793e1adf2c57ffffffffffffffff28ba59afec9308cd00aada0f04e2a9c3ce18d3a50eece6cb12afd497d05fa9d86c1c5927f7c794ba199eb768ed48c888b8bfa29b997f0b2f2ac2a5d2f0ee2e0c87f2f8ac872a692a1f437de244e2772f8b3ce83e296a728a1fa4b3a05c2a4e8b930ed2aa9e4fc2d2576010ac42eb7110c79a57f0c228774902648c5e80b7bf9a14b2ca75fc76c39d5a10eeb3e7c4243a752ba502408ca2a4e43480778a4510fb90875ed39740dcecf45547f647a6c46d2fa630042278bc2acf01f51333c1edb2c7538b6061cbc6d5df0a2a819df97ee0bec3d6e19ac20a1f55ae5a81fa','sync','ak',0,0,X'014037894870b7772d48317e1970d33b59d2e953','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(9,540009245.98908996584,540009245.98908996584,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'a58a2dceecafe55cd69bc0824b050eecf0044f3a',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000d74cd676be86b1d01a4824f64952f4f9543128e31fc79d9023efa713b0545a56ffffffffffffffff7c4f0cd5daaa8404fbdcce3c3cf316abb81a2758f45337e905cfca0367b77475e4f7709ebfc8af53dc2820527f3ee5a9c544233ead690e9b2f54467fb39fc9929a9ad46d55083e3b430891f2d4eb71d28c7eb949cae6c592be94fc31720b6f6da5af9c18a5d41ca018b10ff7ee4889e70272c15c2453e31caf766c5fde3e6a9c1d37eae6b92dea67e40cf31178c98cfda69b0336f8c66c4181409b6ac0f92a66f45835aa66ff7d93cd9a6831cbd7aa38cbf1cb946a2ae59a8791c17a99bc647f1d0535eff7fc5e2b250f5900869508b75ab315f121ee8eaf15ba98','sync','ak',0,0,X'cf5df2df2ac4bbcf15a1d123b4ebda4b1ba044c7','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(10,540009245.99284398554,540009245.99284398554,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'e54afb2c10a7241d5305558d00fa9a63170adc8d',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000df7f87f28510d41c02269279cb124582e1a0c08497cab0ec6382616e8f8a7864ffffffffffffffff67b8dea891cc92bbafa73c119d022ac7e6122d50ea4431467fe7a862afa4bb485f5caf64580951f7b088d8b33c80feb3de5e4964f58b9e2d2d11c437d822c270def058a37b1630e72f51cabe11d9d5d5bb3297223a73363b33ac418407b12bd17f7316dee7b4c1156f3256f7cca083669823a9d8c3aaa6b63442b1da10514983ede00edf5e80868946fff7cf8396cc97c658ef4f621a1244c8ee457a7d2ef339e2d359ecd35f087faf98f2d45043d7eea899a217690ca32e55dad5b92d61634ad368b6064eae4a4a4e09a1ec784eb6643f11978301eea2801628a9b9c9','sync','ak',0,0,X'19347fe868dee17bf9d53435628b3e65e6465534','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(11,540009245.99883902074,540009245.99883902074,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'dd2cad2f1e45d7c4a7ad157b9f3b3ae503c69783',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'03000080060000002800000019f693e9260a0c2446d03f4074c775433f8cefbd9f4f505e78b5d8e9d4953215ffffffffffffffff19595f3de4d67cc15262fe104b9dccd8147c5c77452501e0d4eb06f263d973bb9a704d858afe788cdb59326cd80e9d1f0efaa580edac7ba55863c55a07da0cc78db79e3635252f6e4419926089a4236f273171179c7499aa9bb7f1e7d588deeb23ece5d8e0a7ac2f4ddf842d6ce5ea22499f2c867b5dc5f47013236eab19e36c93957a07c2a929ac11f82366656df094beab2fa07cd974f8e268e06fa4eb26a3bd918279d36e565151764e63d927e67ce631188c022d32a4dcbd599c65011548bacfef2fcd2186ee346b8d6a22a711cd5f4a1508d2bf2332f1a7a0c8ed3b','sync','ak',0,0,X'7fe2c9e56d13085e8e0cb985702cac582f3b85d3','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(12,540009246.00752496719,540009246.00752496719,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'e62d275c52a9542c792b5dee3fa10c886182d0c7',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'03000080060000002800000026f6dd4ccb424644dfbf0d2db960b04d4645b3f68ab3899e7b1d3adf8391afe9fffffffffffffffff6509376b61ee8920edc67fcce8fc9ed0c32878790078791ca1cdb7c290fa8c6a3eb8202bf456145dc18b515e750ab9566933558235611ab8ff45fab0766cfd0fe7c963797ccc7756b0ac2bcd82b3064de9b27802a715346c78fcc87b59f41521a96480c031674d6f8bdc52e05e65a2cbd63db9aacfbbfc667d9d0a443a9cde6321425ff358579d0699be7e153255647c8e7bafe563969752eb9c068c95d62cf6bdaeef20cc55f9723bc023eef47db1ff126ceb213761201ce4653a9206b84349d5edee0735761c5270e8676b0db9e1cce696c7552c5833718a18f69d4a9','sync','ak',0,0,X'5ba5995b1170c31766f42815c6db013b2a209027','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(13,540009246.01104497908,540009246.01104497908,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'ca8e8c88bcdd512029792ebd515c8f72a26bc372',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000a41baf094862b049b2fe6cae59e5705d744a6c4156ee32a26d1925a0fafa820affffffffffffffffdfe1c50a5f8f68ac7bad4caa88208ddd5a315609dfefcc4ce3f446117cd85e2c98ef020cb65919a42ea29e4f1ebce17af330cb35effb5a843d9e1e7712e7c12e4b8e9a964d64e2aee956b20e092e7545beaa90931169ac8155dea04f16a2178d6ea4b48d03e8a6f56b7fe5abb5e952c37f0940272b8b550380ae1d4b5c2e310528323568437e31afda02d21a49aa04bf3115075424da8f213f2df72dd090c2c911fd977ea8e712f935ef28d88c4168946208efd0e53ae0ae480bd92877930dbd94dd4c49be679801f79caad5873386183808abf6eaf730808c06821c729c','sync','ak',0,0,X'dd102ed52a178411e634f52c4f6c6bfb22b33198','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(14,540009246.01563894747,540009246.01563894747,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'3e988a865d4b20cd337fc4e675d986d8b5e47080',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'03000080060000002800000007df07212155ed960e619dfce4680f98fb776f3af6c3e8840c6ea7004cbfb13affffffffffffffff4f28f9306b5400f60c6c18e1fe7f2fe9839274a73b0d28a9833aefd22535fb71fbadbcf7c35ef9c7457d488d4a8ac9e8989f7affb1d534986b1e09194d6b212e01951855a4fe5385f8114eabdf7045c21d488e5360464e59f979ef2b6f8c9082cf62a7ea6091c725494dfddb32fe7ab6e440defd652938fc18afaf1e2341ee42f44ea28d8c32a5a7bf01ab52dfbac39e55572d874d3f8f1aff69f9a003f7b32040616a6e2de302c8742e230a17b512cd417490b5cc8953524a35a8afc4ac86ec37e8b4e41a4cfa4659a54608004fb904b6541cacba23bbe35e1f393a7daf','sync','ak',0,0,X'eb8d4a9dd3bbb1a4c9b748bf66c4f223fcd81cdd','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(15,540009246.01945900918,540009246.01945900918,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'848b91f19350904eec92e211f378cfb180f044d7',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000388ecbd28481b5690eb559e4e6d2c4c4c0d2f4e0f58784ff25bc6579e2938670ffffffffffffffffcd855236922ce10cda23969ee07b41e867cb4cdf845bde81cb3e49e8b5d4f12ad092630befcb16e679913939b34d3dcf3cc58f39d1f01b0b1a6555395b0849a03c4178c2059a75ca37fa3006980c769a477c4fba601501de495219ca467985ced76c7c005bec33033a57ec9056cf10990c02f4272a7bdf363e8260580d4a5352fee5e7bf214f373b286e26baf869697756bc9320ce071bce02bb5a49ddbd36e566650eb569554c409192e28ed77c4c826dba03aabb82fcd628f9a607fd5ab6cc5713f59db08d8c7329455df0a2a39b9588a3d3c847fad00b7728539bcffe','sync','ak',0,0,X'ede27d9bb278ad679e007ad8f64b68bc7d17106b','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(16,540009246.02373099325,540009246.02373099325,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'2d355d53dd86109d8946cc385d4e612799949a9a',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'03000080060000002800000046aab1b63efd4741847d88abbc315302f5676b8018f85a8615d88a96f3b9d4d1ffffffffffffffffeb12a3c6fe77e2a632ee611ade6fc64d12e0a63159863d7792503a97abd2bd6eb605fd317016f3c8cc81003b535cdb497948a862b819c371dc23f448da4dcf66fa75cb235df5ba8d086521c0292464db68e6bb339df98849daa90d589086f3147e605123336cb025041f46b806ac23e4a655757878d110962e96498b4269f3a21659872caf430741c738ade294b40d0fd97c23c10696c622299656cea133322d0a1b5457bb2d54b279ab95f0f1b9a466999646beb77d124894f4e50ea1a7c63ebeab07c19a86286ddc23f10a05dc891f5fd14fbca1ce74eac070e0bbc71a','sync','ak',0,0,X'064e731d3e677c837de05ae105b5f5e79fecc0bb','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(17,540009246.02740502356,540009246.02740502356,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'e9c5538b19dc0af4955ed3abdea0ab1827bb510d',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000c908fdff3a41c6de36487f1c8bfad9069f617536a4ef2e54ae344614dd1939aeffffffffffffffff46e76da3d8ae70564686863f1566a2ae2b727982d9b36ff7a4ba0498a9f7a89ab1562cd8c5dd6fd7f499cb3a2fc989bc48059c9a61fac52bd03298304cef0b997c30ce95b3fa9b1e4ed24052019d8c06c8df8fb2bc5de4214c3615e5a9f0b86209a074c5fcd7961398e87135d31b18e414629ccc132a61c7f5d706e994b8ff267a317857a36268b2bbfa7f9e59156d791b737d7f9dc979c712ea71ef2f03f113b2356b438123a68fc747eb2472a737dff167883ed5b9c121fabd70ba740b305e547e9d5b5b09d324ac58c3c146b806debdf31f48b3fbefaaef83eab27efa','sync','ak',0,0,X'9b0b25ad12cdf94fa248f877c6802645986729ae','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(18,540009246.03106105325,540009246.03106105325,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'6384e8ebbd7b08d9e8f5f25c207b5db3bea3fde0',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'03000080060000002800000093b97b5d3b79973652b07b15cacbc990c5d3288c7326b9db25e1dbd3df4f1de5ffffffffffffffff80e8ec8057b8c60c69b7d4fcb862fd5bf9e84000ae94ee1e0fb807174c83b4af17372e9729e6557fe69bcda161c7031ff1ecff9442e4783d4436ea45b7addd051cea1706b27d93e65ad559437a5fa3601209e4e23e401647b09b8b836b8b7cfcead4d4d9bb3b24c5c47c3b4000fac61fff5da191680b5b0dc3562e716a3dfcc665ec6588a4d8d70f07d1d65bddbed8abef9aad5be34954734435315934eb5be1a4de0b2a5d28957c8f4a47e687e7f580fd4ebc90dcf7f30dfc2068f0a49607f42c2ba9c73353d739fd07227d37cfbceab73837deb14ea326fe1d6ff5e95a','sync','ak',0,0,X'b83757a8e52e2502a2eb604322ee87f2cc298779','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(19,540009246.03506100176,540009246.03506100176,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'e29530802ccf90dc256fa5b247487074a1b5100a',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000b6433d250303dd30033868240d785d8bb5b235522c19f05c9074717ab528c49affffffffffffffff722594202e4609bdaec66c529c0d60e96cc4424eea8c739341f652ae8502f4aa435061dedf2ac879a5c5610de80cc8bb9cba22a60e8d3ba3f728425847b388808505574e6c505f9e2756e4218877d8dcb31829b25081c6012708c02db495dbff67d061365217dbcd09fef56024456c6bfa4b98b542f52dff2d977eb2f70219cd27e5abdb19b5e28d7806ba7c39bae21440a4fc4bec46538ec19b5ecfbb8d190d17157960e8cb21e8a9d38538f167e02c3eb1b73a51d50d275bf7ca3b206030cd1428880c51e0240975d8b7cc3782eb58513c2175af7b8072ef6174fdc560','sync','ak',0,0,X'daf523c6580d71580e31a3936e997f682a702f8a','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(20,540009246.0390599966,540009246.0390599966,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'84182bc7bda9bac9ff3e6496511884f90f573b84',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'0300008006000000280000001d0f77962162a1df9b4e0315b2083084217578d8c6e54fcf6fc4bc8df8ebc00effffffffffffffff51b1b49445813c16875090510cbbdcb5619cca1c239c633001d28c4628655bbc8347adb6edcab1bd48e8027571a3bb4c96cf231975604302666c4d12eb5e90a2803f9dd5e5336675e3bdd179f34e12ea969312aa3f471b0800e38f49060fa7136c71d0ba24164d9999efa4298447ce9c1168841a198382b275167b99dc6b7703e6fa044914791de625daa4e50dc7dea72105f7ca8195ffa6d973050699a37302688b46c6a94029f364a0691dd2e9d316c5c8a400f4e09e7b802f3b202e790cc87f89bc06da3b4fb8bb8829b7c5dc84d67a796d846b148b42cf9bc5b5','sync','ak',0,0,X'2111c6975ba46a7b4be18438cb4dcd60ecd58999','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(21,540009246.04271399974,540009246.04271399974,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'fd3b25de8b7936d68251083799bc37899591cd92',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'03000080060000002800000031f1f25faede3227e172f92649184c66afe60b2afb8faa45cd84e0c01f09303effffffffffffffff98f9094a91cd8526db74bec5d53ac2f858360952b557e73713a9a57a074263e80d42660ff9719294095efd76c868be6f232c5bcfcb398824d51b7a2503c0a2b3362660bcb02177bed89a9a48815eb33fed927cb2e66af873ddfd3bb156a39fd5abf60d1158dbaf1cf63dd58dab9aadca82b571e85f5ad294d3fe346cf6a121440aeb8c8c53d05b926ad1a57c4c98130493ca04676afa09767bc09bae57f6a64be7bf0bb25111108d754ad46ac159170ea5fbc536880714672f32d806e7bb6ef8b7573e16ff4158dae08d2c1d5e0f46b04d0f218fc38775671c0bb5aae949','sync','ak',0,0,X'e2a22915b25aa87d70721ef02dac4b65ca83c763','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(22,540009246.04644501207,540009246.04644501207,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'166994f82033c7f123770fd93a4ca5be1ef65cd4',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'0300008006000000280000003eba0ada457dd11d98c5eff89c2be18c58c7f56a5a1b11fbe9bb88175cb35f8cffffffffffffffff9b0a96d3f2635faae49f0e03e8fc27d9791483a2c4b0f30174131982d0f4e738cb3d289f37d6c311a5b152920742aa242bd46c08b22a864931ab55c9c35908a486a73e56aefbf555bab7b2b62322026e20cac5585eae5a0ba59f5094e3eea041bf0dc9158290d708a240def28a5c990972b75206544b53ee30a80360d2c6b19a28d35f6dd9255ecd03e30585023f950c34992b1b6bc488c59792e5d0750364b2eac9586ebe9c680c18f7c0a5d4a303412d1fbe15b5dbd3f7afbf4c9f158c3fa7d616130eb3e826e4e419adfd7b3e773a95417c5c6b397c2dd650409b6d93','sync','ak',0,0,X'c9069fa763684b884561b332b43c8e4d7b421961','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(23,540009246.0500359535,540009246.0500359535,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'fe441bf8ed28ee3f57594bed1e7e32dafcf598de',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'03000080060000002800000079ed9dd821eda407329291bd377b25325f1832c70b354c37ee8bbe06c5beb188ffffffffffffffff1d9040d1d8a706817fa2f11c9d00dcc27a68cda36153dce1cb497a17f9c0e27dbdd595c7df0beb82361cfeeea9d45d9b7247e6b0ef1c99d21c460b2d56ba85d0cf2edd732fcda6a2315765aa3c20387a9d444c2e44e6c260d64ad2c4c499611e1e13d1dea16e615363f569be1a1b428b495434573c15e80c7116bbdd93c5ca77213eed47de7014d9829f695465f1697643d1863eeee681d2d973a77e7ac417b2184a4e7bc054841fb0e8f11c5eba3df57a2df8f1a5dff2a3469854f42370c8925020a105da93ef54ddff78a4061467a36e9eb44aa762c19e42d67224dce5','sync','ak',0,0,X'963e55dc2b9f20af288c3ac668dc63cb977a02d9','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(24,540009246.06836700437,540009246.06836700437,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'215abad1bcead4124197850dee86ce1e8a87e7af',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'0300008006000000280000006c1f41825815f257ca6372249f01b45036cdc751dbd926d85a06d0e0db699e1affffffffffffffffd1791f6f4a1976976da6fd5cd2cb539bbc219567de638ec2a8f294a4056f5f60ebe6056acbc23b6444293656031a508c1b2bf2c20b61a8902fd6fb2f746996ac520da159cb6b82b137743a9000d77c93235ddf48efe1c286473b03928f10ee67e39e9fb579dd9c3778cf6104889d4fb8df1744de2585d932ea62e6305ae7bb2a5a207453e34697086fd415885ef805eca7864e56f10d6c723f3da17595a86ad877dccea58cada27dbb563381b900e93881d48a2d43d4a665801933466ed38d67cffab0d1a1f2147ba320c060f4a633c6bba7340384b82decb4e6728ca1c3','sync','ak',0,0,X'72f52b8d9cbde9b80f3a289ab6f7e174c3c6d237','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(25,540009246.07308697701,540009246.07308697701,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'298c1e15fc3964aead90dc076a13679e14a2ac2c',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'0300008006000000280000004bb209bc16910ca296541b38d67f7ca1f675fe5b2265fbd1bd80e5863e3d2044ffffffffffffffff79f1a89e94bfc3c27d8e238bdfa441dd2739e4d46577f36a9192678dafdec8276503c5e1f42d779baa68f0289b8e41402b260fe84dac87cfac349f79c3c1b663c5c0a9f614305a4810f4d1a21ac9d30d1903f0f0ea77a544bec49c84da9109025d391220e8c7c111476fa77d68a80388a3ca8bcf0b16984a8fb077e87c163582be970d999194e283c078beca893bfa8f3c7dd4fc67652c767518de06a3bb87cb72ffe7a0e6c78478e8aa6dfb8f2d32a33eb5e0fb0fd3650a26b1323c0b1cc45e33fb4eed360590cee6a014b89a11550af12bada506fe727be9c94cb9c9a6','sync','ak',0,0,X'21f34fed5a4b46a2661562af9062656da7d8ea9c','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(26,540009246.07746100423,540009246.07746100423,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'bbb92bd8956ce7ea51e3b5a52770f63878e8e935',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000607c37b5240275af50a4bef5fa8a876aa7502c0f0afb132426390cf452ad88ffffffffffffffffff28f2dbbfdff39bdf32899676854a3aa0e52238eb2823488d310597342e71bf8541bde80e7eddd8916baeb102f3359df3db3843bbc0588b223a8a901cea598d718b54417b35a5d3afd8ae47165c9fc5ba46a44edecab2da7a736a96ebe5e74bd4e9c57104594c6a99b9430979fafd58672f66fa848b8895cd7ff3f36ff1dbc3cc3ebbb8d63e2873d8d251d699c4403bc2739f3c8b8ac28ccef0265cf1147f557bb1b17aecab035c65799eac5d491a93005552cb789d58226b6233e6f62ce57e61b3d01b1989cbfdf77089ac1cfa306710a42f580633c89b1828b499542b36','sync','ak',0,0,X'88facef56a3d4b6e564da7dc286c68f4719270e3','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(27,540009246.08136796952,540009246.08136796952,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'9ff2f7c4b27e2d78a8d00d1989a41896dc3e3691',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'0300008006000000280000001395f10a95872f2cb8f7bb740403d3d5daf6cdcfcd2e0dd915d81786ab1b59bcffffffffffffffff2e26e36d9f973ef41685f520fe218bd0477945500196867e1a1dacc35a8e348de80cb921c70d3d05eed4bdb070c8c6cc7f309cc9cb3e6d9c10a9cff8c70809217617047bc99a3e779454f5d6d8cba071b500db671e44651dc0c1fe791d323cacdbad75518e49f073a3ca4b798f4b2e10b85a1b7793c539b7db1e7410d0cf42ab4a65e83c86184d73c79c336577717b76dc1fa701d63a88979380a89a5f73a78e2404bfe349c24e6a3b215dca8521f18bf73246e54503986c7bc5229fd192061ee224f7a1782bfbcf4558e83c27b743e826c23832ec65900563de164ec33c','sync','ak',0,0,X'f0973208d33e467e4b0813858d22c799b48fe79f','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(28,540009246.08478295804,540009246.08478295804,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'f1fd3a0e76155cead83c6fba2a82fb56350df259',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000ccb381b7635074bd24f70511d7f6be4a133f94862ccebe48e5c378952c64372dffffffffffffffff691c40d07dc45276276f49eed47c12f3fbe9ca71d7331861e20e4cd16bb95b880c7821c32fef4b84060e98bcceed100a5e6d57888ebb84423fdda8295796cddfa1b48c86c2d8cef98abe9ccd895f6bb3a9147a34200cab6fcd37ad9f311aac23223088e689555eea2e03b908efe347deff926eac98fe634f1884488820d3645f5b699ccaab603eaae68da649b872ed8794aafaaf1532073f8409dd3937298e2cababe89a4a9bf16aae65c080619f05a1026eace4a5956d7e17afba3df4c3eb60a003dac1acf5dc06324ff36cd0138b67cd96df0b57e836acc72fa172de30','sync','ak',0,0,X'dc591988007f260a636861192c80c483bd957123','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(29,540009246.08790004254,540009246.08790004254,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'457ca81200fc6ef89b19fa8c5687fb3afcc28fd8',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'0300008006000000280000002c4e3519fb054d2a23e6c525061d2513cbff9b15acc4dac42cef667457ec8b52fffffffffffffffffee39a69e50c522bd06f53f36a305e664c31598d115ea31f832b92d9db8d4b1a295640bde3246b2795cbca34651b5af1dd2f5da9bce168f9b47bbf7ad0e790ddeb22e648a82381ca9e877dceb89ba718938a797af58075556cd1f17b606d3bd4b625168058206c2426baae58a1d25e2aa0740b5a8db0b3d9c987bde7cba59a42291c478bcf1bd7d8aeb80271b6eabb824a07fc85fabf0d0d5bd5cdca6b8b41e0d4a7966b042e1faf60be3118a7119169077478aab0086a8c670eb92989733d79df80168200f1a79c33a705e4108a08f6e77e7120482d5d8a0452','sync','ak',0,0,X'6a2af463ea21cc27aeab8dd374436f185c297924','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(30,540009246.09233105183,540009246.09233105183,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'0b3028c40099176e838e81ead36f67ad18928d48',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'0300008006000000280000004b4c4c273000e4bca1693d8548582038c63ad8653eb9aa73c3ad1e76f5dc0fb4ffffffffffffffffa77afd4b131e57080333cbda89bcc90ef0b4f2ce860d5e0023831f26ef83fa29f8d20aab3a80611d64b3a256dbd8495ad3b906b5f18336e4816ff825a35fb33a714d2ade4a1b3ff52ab52a15a4f9c4613af6c218da7cb4dbc817e54d52d6105eceaa46b28ee4ed5c1cdefe947263e72cfc7ec3a7f07d29c8dbd1fe571cdb6485622569a6ae17fe4d43e489de84fea7282e327757a530f2e0aa74dc19d2a756895f5d13f3c0e09f67f20d3edc107a36023959acd8c94a90f75bee1372f23a5abbbdf0502658255716da26bfc3281a6ef20e4bba3279933c7c28a250a13a01','sync','ak',0,0,X'dccb82d6d4775ef77809ca0020d03d03a4cc3679','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(31,540009246.09653496743,540009246.09653496743,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'7cb537d6c581482a1c1192a904a2baeb68622b14',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'0300008006000000280000007350fc643562ecc25943bb3d9243f5c054ba1b1cf75afe812b3f3b07213a8b92ffffffffffffffff88609d1daa302e80908ec745a3d053dd05bce0a447b005c1c5512b106f76f7319b7083a7e5ad542b73f6e8f98cd44dde01a7fa3a358763ce17bff030fe76f13fd7c50ec82505b6d54ffcf1e2262b807edda5e50b4d3c8190bc96e6a2febb3f1be3d68be132bcc2cd3192cd782c7c4e75cf3ae99bda4a34c668dee15476e2eb3e2e8a33cc24a6f402bb71f9cb4468ebd7124363b7cee20c0fd5e798cc1d401d5f5a29e5a03a1b7a324e434aa19bff6d205d1085bb367221d0275522b7f3537f61bc44ba336bb5bcceb9d13da1820bf5f05f792ee6eb2ef5b80ac3c3f794ee','sync','ak',0,0,X'40bf8eb16fa28a2d22cb819e95bfc567520f60ce','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(32,540009246.10136699678,540009246.10136699678,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'9fa550e31db22b3968b29876e892efd739b7cbb4',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000cc991923c11cf3d9175a04658ee1f5e335074a6ac6283bd6479499530286f551ffffffffffffffffb43ecba3279e004f958c51ff4d581c3c054e82146efbd2326fb647bdd49c5f7936adc63357a2d86bf8d6a37387a707043800356a2ad4e83133692be5ab2efcd0189da7e9233430aee4296fbe16d89b84e061f129cfc6660d88c1ef704f1c79b76d3a3b763724e01f10c3e4b85ae58da682e2e904000bc98421fdbbd961f8597686273a1c4548640f686d1eb10a48e0a9a575c6cca1581e92b620dd01d7a8a94ca9f3094dd430bf32d0cc806a3c463863b3186e9ce52cee9a0a947441623ed4bd84d0afce3baeb1138be2ced6a8bb1d40b69b68d4110aecbc6e87324fc430','sync','ak',0,0,X'fd691e6048602d19dd155a88f142156b41a01305','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(33,540009246.10513496397,540009246.10513496397,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'481b02e558337bcaed9d54209d530e17d408e0cc',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'0300008006000000280000007db92007511383867241723797a9ccd4d28889c93351963f219f21810faa5d4affffffffffffffff869c81a43f39f42b416b7b4bb3852c9109bfe2ef54b96ffac148237cd02f657ee49c40b6e27a5b4a4d8fe75016696c808b1543d1599bdf035dc456281b6c812c8cfd2139a7487b0ca057d248970d97c45b914fb9e222a2ed4ca29f800f0c559714d24dc2853d23f56a703b8b0db1603d33db0b62e5d1f71b61ddeed4f29ce4175552b5de0a00a3e767262fabf1c4d630310d4cec1697053ebfc433a10ab733d330fe79f0663fa853ea0ea062e97fe47012b364829cafc63f7d44fc2c23fa9af3a8e8ac0784bd24e5fe1f0bb062861cddff94b77aac1897c1be41f9eae1e0','sync','ak',0,0,X'4cc770007795860f7af697ac327c2a512a56e5c5','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(34,540009246.10805094241,540009246.10805094241,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'c39bd8c7d03d60d6c9d46810e92d40ff2fa727f0',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'0300008006000000280000000501649f3f054c956f5b15bc501cc7ad8c8dab2aed0c14190f4f43bdf1ea772fffffffffffffffff8dc5fc06ce90205fb10eb00b4c268726c423400d21fc1c5856dffe7f0cea407571850b42b6eb0914617e98e70134dc6cc75b0ecaacff04932516f2ad17c0ed17ddbf37b362f6ce5266e3dff6550c302b4374d7e8b375c062aeae5567a745bb583a806c76f799554ca3df2b28e4b966ee93a77b068bb290b67b5af90b2b9acb5e99a535ad4472cbc83fe0110790e634061c3d7de2a6f1ca7e95bebf198231933dda7b23339054a69e4368ba46081bd7ee1a5bbb38294e9b6b0bffad5cd48fdc6d5d43b394ffb986db2c7502d0d3f9f18a0facff89c9ba2f2aafe0e87d4cd6','sync','ak',0,0,X'4416e3caf3305aeb56c7d82f5213a75cc2dbace6','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(35,540009246.11151099206,540009246.11151099206,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'fa9163eaa8e20394509f96572cd9904a455a9edd',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'0300008006000000280000004fcbc521042b2d24892b38ecb7e7f0a0715e0e768df8577f090224a99e52fec4ffffffffffffffff95c7ecb4264c8f0bdb76638376bd633e3880cda4b1d8b0d754e6c4018f1d2f04ac9971141dc5379a110054c82e8a0b0b13f5d9246a38d61b9acc4cd44b00d0ff6655d46ec84e6da6dbc7543077c2c00e1446ebe4d6804304ad9c760a47167b220238b35f07cd6eaf3ce70b20d83771acf84f505149221b9f2fe066dbb9a96f9a5bfb4a357fa036fc66eb5ded7f8231114483db87a7adf0e49a18548661f8ed24d4c0d1c0a5d31b2985f103afb366ff6531a517c050445b56fa545fdde7aa20cb2c45f82985964f0f28ead79dbd1bedacd5db05575be3721e6dc5a8f927a1','sync','ak',0,0,X'd741b608a5935373789035097ce5089534e0a615','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(36,540009246.11565101146,540009246.11565101146,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'c146e972cd43db30fcbe92ac84bb6759546a6a97',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000905342763f215c0a9a984fd678d89060ccc669650f5c1a4d9db6cc90b623d87cffffffffffffffff424bb5434cad764c0e4af92170782c292eb15316acad1ff9bd4d328fb9a39196e9dc0ce0877046f2c64a645147b1d9726059ddb2ff6d55cc37a9d474e8a51e93c412077e6dc0885dd57654c99bc96964bbd091310f573af8285c7db75dfe08e033916a411bed4f88c837adbcb49d9cdb5c3d1951662330cc1ed11dc75ddfa8aa0a9c33902bae6ce7baec8c51398cde632422d63b3e158217c928975cad15bf97bcae9c4a3c5cb69df9083d7ea9d5ebdc746fc886c37b2019aebeaebd002c1a7af053219253482fe604834b508153f477c08d540a78b5e9b3c8c3269062ad','sync','ak',0,0,X'70ea352c55c79851cc41a1c5982731a6abae7577','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(37,540009246.11884999274,540009246.11884999274,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'10d55ff7665a76399dd3b9bc325e080075e2ca80',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000eb64cd0cde58b64f05b37d4310d83fdd5f6b37e38041459d018b1723b5a28cefffffffffffffffff8595b53084d082cde671f8e32d5a1db5535de1a97e6e8630c5547ed82ba323a47c1853c5d67792e9fdf32346164f6e74f7e28b2674754ce893798b74f1d68652512f15489ff028f47647fec837e4dab7bf5dae93bc2830a9715602107efa63dfe37c8f9ff7ae9f37f13fff61e3bdb93a369fbabd5f34bd02c5b49c17f078b2fd12c9bde7d398d884a18d50c262b3d48115ca26da6426a894c6174cfcd5e0f05fdc3e717cce3c6707503ffe43c5a0472a9ea8da315ca4c3e5f4a53df6b329ee1bdcb08df38bbfe0fd4126cc13c26947d90d71ddfde103a97b54cc431b','sync','ak',0,0,X'10fa113010c1fa7cc8d78e530fa1a7268c38ad23','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(38,540009246.12437605858,540009246.12437605858,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'ae3d912d9c06192d7a912b5ca7813cf6fe85c363',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000cee7c95d6d334478b08e52bb9bf596648f680c686649049fab2db6e980629f6effffffffffffffff5768e69ee03ad4d33b19b82b4c8d853885e78db47b41a26a27fdbfb705bd77f9938b7aaaf20dd4f0f0550b2e9893f9b45bb39b73c13145cf7ac36c2be5713f7462b2b987b7f9cfa4e3f039924bc798c80245189b845577888b9957ac0186ceda93dfbbb9944dbd07f9320781eddd3bee15561ba673996c0b916a0266538b63fc1d1b18fbcf603521491466ec6b9b99b75b054a2d52705ba8f236f754c076940a9d109ccb85d9f3b708c3ab9c9a9e206eda19d42524316fd92978703976603f8ac575d5265f34466866ef9122d1c8044efab107861e5ee185394c06f9cf4d','sync','ak',0,0,X'4e6ab77f90390aca3cdfbd67e65641d94b56d912','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(39,540009246.12985503675,540009246.12985503675,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'cb26c3b4e982f9215562a5638e21368325e320ae',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'03000080060000002800000013eb07449f06d26474b303078921e5c00234dad3bb626387f47c24d365ee267cffffffffffffffff43f2ec6d496b16ce8f1f3a2d0cf51b68894dfa21dfc99b903d9d66de25fbe11c275040aa867962ea3860b51c029bc3f821fa42f2108e6425e67ba2b496b5a7e8ad43ffb37249985a3fe3c19ca2e4f6d4bb3c2b649ee1257f6e0e5e7da835a834ed520ee748696427d1e7d10a14e393408ab873600b2820e9ce18f689cd91227546d2518e161d5c8d4fcbcb344704524d07ce0bc5709b7608d2a46017cb545244de5744c50227fcf9706c9a1a29b6780e5f65e273aa8e1be043d7ba07a9797631c87b05c9ed4069bc7399fa448e94c473399f66c9693147c265d700fab2be','sync','ak',0,0,X'f3f13c555913aec22beddf172c5e8e846cd6a6ad','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(40,540009246.13457798959,540009246.13457798959,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'2a2f3bc6c0b0fa2c7d67857bba536c8286992ef5',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'0300008006000000280000001fa895844938c23e78b2fc7c8121d1ded5ef9e23a297de40c23f7f4297964c10ffffffffffffffff7d9e1fd229e1ae5f470932419ed3074e6776b690467a913cb972d6c3497493c872f34113232a21370470c9af51fc2650a675bd62e7b8c134b9e12a7a89436173c99113729084a64f1bc79cab4769bda9cea67f872121d5fd73dffc424df3a409355de87f2d6c3785c327f19a880c85b30fe9eeaeb175ac68548b23b65b1dc22da8758c7d131a1b7cb7f5700f871f842b42ce2cffb42ef37f33c31184df916a74210f0d9e07ba6f76c3567f8886fcb981c0ee0b10972df721e8f58181c6a76faa9324f99726da68398b68b130471f35f5d518dbc7e59ce2d27801815201c1','sync','ak',0,0,X'b48fc42bb7d984027c070247342e0ea560d40af7','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(41,540009246.13815200329,540009246.13815200329,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'aed7b09246a7e6fb7d12fcb5131cdfe5133f1ea5',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'03000080060000002800000006b85d74fdf19f68bca707aedd0304e8be229a0ad1a84f03ef9fe31ca0164fd9fffffffffffffffff7d6a3af6b7973a3827c703e365dcd3bfc5ffa2db339e5d44dd8ee3aa60b962d609552872a69b3164fb8d6a52ddb4121d22d29dcfccd848d88f8363a2c7144a2fa3114f671997d5ec60228bcf0aa71f25d59b3156363ab5c2d9fc21618fb6706b978732f3fd3ef1e56851c207496bb3bcef74b3fded822fc0b79f6c739c8e5985f0453702b4c8d206a1d2a69e116e68d4b566b6b46198f48c711a0f9fdda8569a80ed35193e9402472128425bc83a8b5f11f818b38ebf73b79c72256104476a81fbf00e7cee48d9e435bfa62f234e80b5d20dd8536251cb4ca89c37ae1c3','sync','ak',0,0,X'a4b63a617ea4b0ca502a01737075ceadd8ee978b','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(42,540009246.14087796211,540009246.14087796211,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'ffa6ae40a6afe4e6c9c676fa122bce8529992a5a',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000ece8f63a005e529b422a473b1aa791c95bd2fa861fc383863b254b6ada78f311ffffffffffffffff5f845e150333311755a4044c51ba874ca3c43400942eba9f14bc2da369e2d80ca281c9d43bcbc3a0398a75892c7779e20a3cc2097eec79f6fd39d260448b4e9b6d566ce3551e11ab291c17767bfe5aa9f644cc75d0b8337e56d9bf3c4c09b75ade0648ff2d0773e0964391487cbba01ae22dfff5462b6e96c2fefffab2685c44b9e3c99baa2283870ab24e5a58aa933f436ac91ef4507b85ec8c70209d91e0d70f9d7ce6d5585a17595594c84449bd29ea98486e06141693683981acf8e2bbf6e538749c3bb9f707a1fb0a16cf4c2787dfc2afc82195c1252b7529747d23','sync','ak',0,0,X'205053fd3a4ff552a332844a1d4e8dc57cd87ddd','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(43,540009246.14429497718,540009246.14429497718,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'a3d2b38f6e49125112a1804deece91e421f965e4',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000acbe8f196252107eb0710213824e1728e25af217b6e86a6c980c9b96ddf08c1ffffffffffffffffff8633d67b0816e4e7a2e328996e0c972d5d7c0ae2b98ce3e6d6a1978fac1d6cfa2dabb67cc5c22fd5d5f5c6673ce264ac553538dccbfbc907d586f888cd4eb10280f66c2ae555caddd2b4161cc5bb8b40641eab92b45ea6d01c283764fb58c745d38c8fbbaceb4dcd25df50f24bcca615ced354628c93b267e526c90705b5f7249519c78eb61061f8ead1760bd2724af14c9d3f1720c2e95825dc96a7aff0072e4c208932008c99bd92987f3573a6ea0c1ca5865c1d8b3635601516d358504625f19ee4fad35598dc657ac10869c4e7c51c356b6f6764fb6276638f6b925','sync','ak',0,0,X'a99fa6b8bb1a577e641ceaac6d42dc133f808965','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(44,540009246.14734101296,540009246.14734101296,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'a726f509119981ebbfeef50afe3118f653c171c8',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'0300008006000000280000009c805cfe08a7f97697e2b44bdcb1ec5528614fe7353549885d6f0be1c22a5c0affffffffffffffff32b0d2e5fff3341787b135c4b9a78efa9a96a87cec39c513525bb3e14f66cc82622f0124dda52bbdb44947b6854e25367dc02b3246985ecf1694ceea15729029bb86ff6605ba2eb3d8141054df7792eac3a025f1961e777a8e965d909676b7054f5a79ec8ad3d6edc10c8c17bfc402d2a1b24c06453bd1af07578a15a635cabe4cc851e35740894a7e7f7b0ac043aa57914c85d424edbcc569e1364fd6b18e0e1334972c06d253758ef2e3f665cd186c607552bd7639dd32623a861c91e6d540811b99e12a2c850e8b4bf2378f9519d7c6b511521d54d06eef10b0b9b082','sync','ak',0,0,X'017b6c1fda8f9ce1743e6c2fe2bf2258ef7989b7','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(45,540009246.15040802956,540009246.15040802956,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'c932b839c200a4b2d2dae9f543d3cf16e7fe9b11',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000980f3b8f00ddb2a079e93cfd435436b00f08f88f101834f4262de73c560d56cbffffffffffffffff8a1534379b3d4c4a9d1a99093560229e653f2911bfe9970b0fd028a09240ed03f4a72b2e76dd8a8a8022692fa5fb9c9b67ed5a402732f980eaa22b53e42df70b1ea858d39599f641d211dc745141d86b99281c029ba08205aaeb5fc3bcbd49ee12a1c5d7b6e29b602d58a35f769451831bb113269e13ee83731d757b3c365caca7c56c885a4364f8cba2cb701f24557aa15e7167cfc777aad1e3d45f141946ec583ff71630685258c91e5f50124fd4f9e8646c7dbe522df10f5a0a7475730e710cead70d60321912159ca9697c0e03e1006f9d02e25f7e2fe021e68da313','sync','ak',0,0,X'b85a6e345f2e091959d44faf1ed4ed06bc5d0eb3','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(46,540009246.15337598322,540009246.15337598322,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'218039970958276aa9280c9c38e67cb945818af7',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'03000080060000002800000070de334bc93720f3071104b02fd776113f5904c674a57558ac1114549a6d089afffffffffffffffff56651d147cf18cc584562bd1c3932af147762a507863635a01d388cde2ca6147b38c450cf42254cacce12d210a413a0821fc4b93468642a4d391c4d3045f956132ce60e70717b8c9d2dcdd74f77f5ac8bcfb3898a9b39beccfc6f51d658721aa992528a99682d62bf6e8de487a1c291e5359812ab6bf69f55e26566b2ab4bb9ceb0513314afd9963e6507cbc8005b021924d90d32c7a3ff19eb73d9a48988d3661db916cd6a410f6a7138dde5d229799405201833b7a799be9ea72d96fd855a78d688ff2f6e239a114bc433aba69c8b35d00c68301734ae82c1cf5e7a42','sync','ak',0,0,X'e3e79af64959c52963cb5f90d94cc7baa0afd741','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(47,540009246.15662097929,540009246.15662097929,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'b62ddddaa3d03b92122817af746791c7e6e86be4',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'0300008006000000280000004cb5f37926091210edf1d042d0186ba7e21ec7f706c7bcfad2fb38e736617357ffffffffffffffff7a4e286409d4e50d06183eda805e49464880ca9b7457f69b46d8718c1d8149c926c8a6f58b6fd329bc641391db3ab6eb21b681f70b4b2e5a51c2570f8481ec4d5ae8e39cc9530979f7fa8e19ab65b4701c7d0c6e01e06037aebf6787eeefcb841e5e7c7da1c236c20c52d9bbcbe9ed589d9da3ccf30b5861cdf8503522a589e0e4973a03fd8a24e55aeb2ec7174f196ff4a190c94275e9487f001fa2952988c0cc91e7754d6e82843b35b07d841cc97ca7894b571318c6452ddd38523da4deed9ad3655f2692c76df9762eb5c8112b54fd950563da225b37c005650dcfb5','sync','ak',0,0,X'931f503216aec2276cf4de013c8e17bdee01340c','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(48,540009246.15953397752,540009246.15953397752,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'28c7da70aa2baa1ba58d752eeca3e605eecc5806',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000269239d0792d33cc3ba5fa68f8d767f2c8db3e4e1f3bddb680baed083fb70e9dffffffffffffffff81389ea97f06441b683bb62ae06f88ca5c40f5cc7db5fd4accfc65e96739e1db20b13fe153beec620959c0993747effde1581c36513f329a2c47051b628861099185df63bf55071c69e0d739b3a6242794422b1bf980ccf46cc01e5c17ca7bee3ad0102c3e459845562c6438f377463727e1e7a98736bc452c008cc51c817b80061a4363e78c4ccaf278054bd3e28d29ea64a06db5cd3440e612db1b9271dacff57aff31064bee6c9e2b5c05450377cc37c68e6a1065511fa46a154f042749df9411499d6f27d48c69786fda878397e7ed40132b868df29a2f4fe350ffcc','sync','ak',0,0,X'73ffce8e3a24faace335fb57857cfe01bb112a62','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(49,540009246.16241300106,540009246.16241300106,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'9bad040aca6d5538965effb516a6af074bd9b95a',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'0300008006000000280000004e79bf61bb34b6a707449f4ab545707c3f32103e781fe7d4ab86518078dcab22ffffffffffffffff47ffff0dc56a1a4166acc4ebd6032b791ccde9607dcb08c1fbbc88393a43820c9cf82e37cb3bfbf4482db8052c1dfe5c79260d5c1e6eb60de8665cf7fdb52e315e6c401004e625c42bda3ff85d18ea8156ddee1d827d23afe0f691f2043d3eacae3ec6ebbdc514f21dbfff234fcd05da1ca5716412af4a5bc423fc1c272872877e2ea10aafde799e0e8f264180a2f66bf7eb19ade170fba6c60c80f3d8e0aaf212c4dfb89aa531332a82193c6b31e2bc509a08cafbc3addbe63cd4f17559fa82147e519805bff87ca79560eeb0c890dc77a8631521667414d065d9bf0512','sync','ak',0,0,X'5bdf5602f319d6fa9a48899ef41b099359c4b727','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO genp VALUES(50,540009246.16554105282,540009246.16554105282,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,X'c836ab78de836bb61f6e95ad145322eef78ac34a',X'60b0f62a25648e85ca93fbb508de87c5537a7a38',NULL,X'030000800600000028000000b38cc4c21b52e5847764fdca1a8de78e169c8f8818de9a76a717c5460f2bff0dffffffffffffffffef59d8614872a04f39f4996c41fd1edc52fce6a1f0e4d1540c62cb93e60974e4d193205cc0f26c1ed7abe0af03f15361b47902550f43d4dad57a9f888af7753999b9a5c2fd68a8709880534e814eaad0fe357924d63de8d088fcdd9e45c9457dc5d23c4ecf6fcb563a5e78dc63de703dbec694521d3695ad3cc568b1ba66488f360464aa9721fc80bbd6fbfd34d371a7f99a225b39a8942867bd14cb255ad00ddfac6147218e2a9d1d0c9ddca36de321df9e249ae9d966c44d03de515b0ec4eed5e7dd0bb5635bf6b8ce3854d47c0f806bfd6c64e4e8e86996ec0925b776','sync','ak',0,0,X'5e9787515348cc4321af5861ad0249d687f3dee2','','','',NULL,NULL,NULL,NULL,NULL,'');", +"CREATE TABLE inet(rowid INTEGER PRIMARY KEY AUTOINCREMENT,cdat REAL,mdat REAL,desc BLOB,icmt BLOB,crtr INTEGER,type INTEGER,scrp INTEGER,labl BLOB,alis BLOB,invi INTEGER,nega INTEGER,cusi INTEGER,prot BLOB,acct BLOB NOT NULL DEFAULT '',sdmn BLOB NOT NULL DEFAULT '',srvr BLOB NOT NULL DEFAULT '',ptcl INTEGER NOT NULL DEFAULT 0,atyp BLOB NOT NULL DEFAULT '',port INTEGER NOT NULL DEFAULT 0,path BLOB NOT NULL DEFAULT '',data BLOB,agrp TEXT NOT NULL,pdmn TEXT,sync INTEGER NOT NULL DEFAULT 0,tomb INTEGER NOT NULL DEFAULT 0,sha1 BLOB,vwht TEXT,tkid TEXT,musr BLOB NOT NULL,UUID TEXT,sysb INTEGER DEFAULT 0,pcss INTEGER,pcsk BLOB,pcsi BLOB,persistref BLOB NOT NULL,UNIQUE(acct,sdmn,srvr,ptcl,atyp,port,path,agrp,sync,vwht,tkid,musr));", +"CREATE TABLE cert(rowid INTEGER PRIMARY KEY AUTOINCREMENT,cdat REAL,mdat REAL,ctyp INTEGER NOT NULL DEFAULT 0,cenc INTEGER,labl BLOB,alis BLOB,subj BLOB,issr BLOB NOT NULL DEFAULT '',slnr BLOB NOT NULL DEFAULT '',skid BLOB,pkhh BLOB,data BLOB,agrp TEXT NOT NULL,pdmn TEXT,sync INTEGER NOT NULL DEFAULT 0,tomb INTEGER NOT NULL DEFAULT 0,sha1 BLOB,vwht TEXT,tkid TEXT,musr BLOB NOT NULL,UUID TEXT,sysb INTEGER DEFAULT 0,pcss INTEGER,pcsk BLOB,pcsi BLOB,persistref BLOB NOT NULL,UNIQUE(ctyp,issr,slnr,agrp,sync,vwht,tkid,musr));", +"CREATE TABLE keys(rowid INTEGER PRIMARY KEY AUTOINCREMENT,cdat REAL,mdat REAL,kcls INTEGER NOT NULL DEFAULT 0,labl BLOB,alis BLOB,perm INTEGER,priv INTEGER,modi INTEGER,klbl BLOB NOT NULL DEFAULT '',atag BLOB NOT NULL DEFAULT '',crtr INTEGER NOT NULL DEFAULT 0,type INTEGER NOT NULL DEFAULT 0,bsiz INTEGER NOT NULL DEFAULT 0,esiz INTEGER NOT NULL DEFAULT 0,sdat REAL NOT NULL DEFAULT 0,edat REAL NOT NULL DEFAULT 0,sens INTEGER,asen INTEGER,extr INTEGER,next INTEGER,encr INTEGER,decr INTEGER,drve INTEGER,sign INTEGER,vrfy INTEGER,snrc INTEGER,vyrc INTEGER,wrap INTEGER,unwp INTEGER,data BLOB,agrp TEXT NOT NULL,pdmn TEXT,sync INTEGER NOT NULL DEFAULT 0,tomb INTEGER NOT NULL DEFAULT 0,sha1 BLOB,vwht TEXT,tkid TEXT,musr BLOB NOT NULL,UUID TEXT,sysb INTEGER DEFAULT 0,pcss INTEGER,pcsk BLOB,pcsi BLOB,persistref BLOB NOT NULL,UNIQUE(kcls,klbl,atag,crtr,type,bsiz,esiz,sdat,edat,agrp,sync,vwht,tkid,musr));", +"INSERT INTO keys VALUES(1,540009246.19841694832,540009246.19841694832,X'3c585604e87f855973731fea83e21fab9392d2fc',X'9a08110bc764be9db9bc110742ba7e9a378f3d09',NULL,1,1,1,X'995a7134b96d07759386b20c4b450f7d275b7391',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000d9d8cb6901c0890249dc4125dcafcb4e00b820680f2c170af363cb9de8617a33ffffffffffffffff1f6c1d8abc39bc95cbf8b622523b5934e56156d052f1e481fe1d6c19a84e7be8776a09594830e7c29414e076bcd1d49a0dc768b99c833fbb4cb9129e052c107729858ebbed9af65c49978c332f7ac820ff963de358dd37c8b331df2cff5e19af60293fa32da1abe755e87af9928d79fff0ee19ebf4474b76ca1cbacf57966e06fe1eca6960b5c2926c889e985609884c17b7a0b2efa2a18d87b8e2016193b569e276bcb612a02280e31c13454ba1c53dc8c3a1c6c38a4875b6676ea291d22bd48ad8c1f9fbe9145ed17c99875eb14591bbc5df24e31d17b8ee019a6edebd602ab600f888bbf21cbfcfc6df9942bc0626a10ef3912a7604d247361f8f07e8e834e7be89b350dee08fd4d17d172d10ef008478a04705a278d6149f940c7470ed5613bb47018c02f00d29078f57484de7861d21a2108ab7e6fd116d8fe7928f9940ccad9e49df85eeebe1f0f6963bd35d03086d1807d92e5c9e0d0909dd18552054fff9858535af562dc95d606dea981447b48335a7b9b8133042c6d6404db569f1a43c2eb73090401774e322e6bbcf4fb16e8172aeecd55025d8227779e818528313a86d8c04f4e56bc3655a114a19da2f4f2097dbf2530f6128f0759b2aef873626d4d3b3c9b6cc122f9b1a0a0f81294130699f3f7d326f5356a3855b859bab2aa45400567f2fb2581331aef32d7a202c672a6bc45e0499aab35ef797361dba2beef4a0a796e4504f21a63e14fd2917b84c486c477da3d234a167a0d18a560e0ecea21e7ea9eebfa6f094b6c2633e98504f25428f7e9b18761d6a807a077244ff7ee75be7fa5a5543286dd87ab6723b77dbb23226996c5514a5831169b44b5c4325a8fae72d000a31cfb81bd593b9fe77478c35453f4a59d148b7013d86d29510e0817e8999312b56b727b05959ed222b20f24191e594e8d526728a2d4c2389c244b56dcfcf5d0c61da8ee03d270c027cdcb4b865f4747256659b663bc00be96b0740cada9df7ad39657683dd2af0bc6fa65d7125c7d4d9fcac05dabde572c47968710ec6f4da2b55539b5ba695400e92981e714e8685b80da2c70bd236a2baf1e1e3edbdd7944ee21fb05767c1617dd4df9dcda549ed1230c6f7c63b101eeec5f73158b28c831af5fd34a7875caefd6b096b6bb25e5cf5b865bc424f6cb3bd8bb6e7750a6b2c36793b0fca7765e1aa99ee53ebbac5f464b83edccd272f7574c7c1dd1463c08088b63c3727dd8e50008e0c705339f3311cb5be1c4f9e4a5d0309271492d3c0c357fd058464cccf97f777989641a2fa2b1a9eb65f78e1e6b38d0ec8c941ad33b26b6f1c586600db37455e84449fa5ee0dc235acc5f63470b5cabab8086cf6c7301f010629cb8e9957a75356823d7f6ae20ee238cb7409ebfddf0f056d3cc7c1c07e009cdeb6c56a0fcba426a745d77a637bc5dc13447c5474ad81601ac9810feec0605b038b0436d576da3c4aaa0c868ffa9d851fa6ed487c471a76e5b5fb498e19ff3922677209520fef0699f7b75cfcdfdfce79734881692b6c7ab37cea375634e1c780f95d146a01d81aabd517965ada68dca900d4c52169ae29bca20642996184','sync','ak',0,0,X'da54fd644fcef9c37d7ef945244ac15d2877fdc9','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(2,540009246.23930704592,540009246.23930704592,X'3c585604e87f855973731fea83e21fab9392d2fc',X'b32091dc8a67b6dfe720a532ca08683fa798431f',NULL,1,1,1,X'257ffd4973c8ecf11a6be35871f6c9c243fdd1cc',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000a0294251278f4316ec77109ed0a2ce3ba57938d6270107c4f4b65f8c7c67bd52ffffffffffffffffab4bf8cebc002fac883febdcd95cce5af390712a0e1fdae16a90f9c852f65fb47f77d7871ee9d5cbb6de7712fe814c2614e15ea63a8e08feb17d8e6efa6e6c42b88fb43947c756d2894bd8ab0e383af4b8a9d5fbc9b44a4ad5b923fcae155ec1d213b512cb924645c99a21ed6c40717896553511f07fbdb69b47e25cf61376f027dfd12ecd5fe81695ae2a7000768910a3866797acdbc0ef7afd73d9430e8f81327e501091471290ce4e59b104297247589b26dadcd4071343a6b381d824cb7b42d35df20b30ec5921ad45641ba6ed62bb51e0e954ab4bf3cc6eb83515d39e29d5645f82829d04433323836d593a9368ca5b572fd23a8c98be029ab089a28f6ce12cee9db97c16d1b0b50554b8a090c85e09a3d94fdcea7bf7a66907e55f03a699afc65d4775f0a269c777977e5effd7bcf5a7d2efc965d0d43d5352e367c53245f7707aa6e07687d598c5b73d367a23940223582da9e62f97fae53ac2ebe22c1dac615fdcfe6268eb559dfd277fd5339e74f5e9be70633d6081dc71776e6bda8a34463f8b1f2aaf53824fb8ac1a97ce0c4ab6fe105c3c8fe46c8a216823afac1dcc9834cc4507230fd77a94cb6fbbf5388100027eaf716298944ffbaea07a2157b49f1679dd0ec36ff71cf04091dd6de178e23738ea1566cbadd0d379c26f51abea16431a7e72425f574a9261bb1e18ddb87fa29100db70d77fa7f3c1e24a73b6f32f4ee3e904abfbb9a27bc700128a9000c781ce6931f905df1b510799a291cc0c78156e2046ffde04283f7f0d3b173c769df1decb521d81ceaf60cbb99a650d57cf7d6a5f89ce13b74cd55534f55716417a3a5e300a07206825081d70afd17b037319e119deb89733a7b7da4e6b453256c1140aa17d7963cf15945cc68f507fa1aab53ebd69515915ce4946357c2583ab8f88d3404e058e4902bad948e7dbe83b29b76cd54a2f75359a4af83d471e3f77a7bafa12746abb8e9b1b0e3ab5ac147cec356b4490e2aea80b94fcbf24ef49bdbf8dbffe94d427450055833183ca45a6eb0382998fe4b6257b89c4621012ac7b375a244ebaa4c902aa1452747201064640f95947ac14e60e75e970dd347d6651344861f8d973bfb8c05d737de01187e714074a48f77d332b76caf373e695b7aa8d74b0773e4ef103ed0c44434c2ca7873b2c7bf77464f79bf26552b5c076b628f5eb73459a58ec99bb1440dc8a53e2b380f8df117ef12e0f1ae1a2e00ca557f13eca771b9c98969040678a33df014a4cfdf74819c1c3cade75276d75cd08b1fa66fd9680c7ee8eaf76b55ccb3e5a1b147df419c079a035ebf0690aefa9ca01ca8c2a2659d88085fe118b41b8eb1c87a4c4cb49ae5846808a614ef1588efafadf155876d142da0700e5a8c44118c62296940c2cb819a42c499050a3de8d83faf6842d419284f860d330c239322dd863484528035ad50ef4adee3dbbfadb0bc5c5cdb9bc42c0363eba929e3203db6e047904ede891e24249631b61d4a0e575fb958be9842a352ae3235228a5a4d4077a4e10dac8b2b0cbc0b2fae23aea411ed189e48a7a8637e2de9303af489008bcb24e0abc812c','sync','ak',0,0,X'ec6e682433ba2e89a300f211303359809cf1a198','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(3,540009246.37129604816,540009246.37129604816,X'3c585604e87f855973731fea83e21fab9392d2fc',X'5dd8ad384c6356517e17af4755efbfbfdab3ace6',NULL,1,1,1,X'c150fb6a2a8c2419b9e96e7f7e5bd32b944108a8',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'0300008006000000280000002814bf69fed3af30c35a1301e831c31fdb981a5969b9b5fee18ff6cee5c76e8cffffffffffffffff74d317c525ec4735c9709d08f6385f62e3302c1f42324514df4b46a21049e2c0075a65913de66d463cc9eafbfb6545b94ee7b94048be87013f0331b1bcd2c6eaf2e3caecae22a3a09652c8195ea666d609a1fec92821f308b3dfa76ec7b226c4ff68177fb1dba75310142eaa386e85b143bb1311cceac9783c7b35d77cce4c472a938acd9dea9f002d5f249a1f998876ff94c7d2b89a5aa03f10028c639e0285ad82406e67ff38a0c7932bc0825b6c8e258a0ee4df5f1da8e08bde9a5938f747cd6d7805896b51dac95b480cc5b9b12d6c3278a767ae3ac1e811a781d74102b352274f755f3beea8556ae6f2ab876c0b966ad3d88cd6f12e86472949fee19bb6bf252bd1b58db1c2d0fc7b42fe2e57e8e51565a5278cc821694b780b6b60370c48daa99ed393e9e224173f526e9cde2160803c42bbf4b5743a261e95044d3ac7f4261ce89b847a59f6a1d16a2996e1cabecc4b97a5202905175295a557b8ecdcec70a1aea2527b7d14c8b6a8d3e881bc2119d65156fecc3e497bc1dfbfc7bca7727608e6c5e89e568ad70b43e416e2e7ec374006fa127281321fe06939fd885399d36d9d9a068d566df26254825d9172dfc36eb6c258728af9a0659080826e5a762f2ff9800936a92623bf5bc9f39fd32a99fd942df59afa887444d6fc8def7f8fe51b2e5f8827106a875196337fafff81607339aba2b735d5213c34b011f2cfe117f35b0ecb012507ceb5090ccd5b0e1900baa591948ceb2913bac43e1d98302b03db3ecfd821ddd67717b8fe1664ce40f9e4f9d2b780533ac26ac0247c874329344e6dad9004c8a6c61d48028a9e6a21d6b8e0a823c795ada2a00193fd78a412b0b4ddad3f02d1b25735720b97206e40e77bff94cad4f21046873813126d189e70756391f1e9dc9bcd21be7d3fb41360aed37e691efb29e80e10e12f40e41530354ac8b9b5397fbddfb4410ca607141e64c369b9502ec8f5c4ad64c05dfbf6c17d2151cab569aa187068497293725e03f43fcf156f3945a04579876ad03512475c8c908d597cf46229a4ec159948ab0fb566015aec0f86de2dcc8b00b368f49fa00c465bc0926e00f07e8ae7d89f2eb26df2fb549a276fae2850b9185fc194af4407bba1aea01cba802cdb23df59080a8c92e5e08dadab57233bac20168e4373c4d6f71a52e63b1c7d60085327a6058957457ef8163a313dffe83e0aa19a04b98ed119dc5e3724edd21d27d0180c9cebf638299e934240c89593a90e5107aa528079d043dd2849b588cd39a81a1fdad4515a02a430c52b36a7b85244b16119f0f94174b43d11a21513a25d235fc621a58aebc0fb4cf58950f3e35af43b0a1ea9a1d15741b053ff12d34beb1fbe45e46430875b50071cd2c14978af95550a1ef5fd5b80c5d81c7a2060691688bc3df0df982baa16a0a3dff01c245c826ea7418c18d0cb583746fd7a85771e622b36c2155c247a1cdf6dc66e03f2d72d2cc4fdd1fe538ae33482beae52acdd02b2d1cdbf2eb45ca5e2e89097d0a798500d1836fbdf2334c693aa5b5bd4bbfb74e5981948268f5cbf7f5c0d57d75a9ae1d66e640571034f78','sync','ak',0,0,X'26f896467e5b2b947c042f98916b41e11499d49c','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(4,540009246.39969503878,540009246.39969503878,X'3c585604e87f855973731fea83e21fab9392d2fc',X'f804b06b15c1ed1c561a3310eb36ffc10e88cde4',NULL,1,1,1,X'9d2647ea7ee5c3a92fd7864a1c1ab436daa9ebd2',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000c6bbbc21cb16083b7d3e2322efa3db4259177597bc364d0825ae7bc95d55db2affffffffffffffff74e7802d9adea9e03160a3b608e9f3ad921cd130ba441f91a713b23c028261e15a0d0c53965828ac49e0173a5bafe4237bdf039c145633cca616805ff783cc30634717fe850fa9130a1a380d275611d144a19ad9aa92117be49fd25008187fb030bd80b7544d029f558f0dd98fcfd5a493411d7ad50dcc5f001333ae3447ada8d20dc96ebcadba1cf1e1e586f0ddf969bdfde7acbdfecbe0049e4bd825c1fa7d965faf6259767e273de4fd42e989194f7f41df999008b6a7daf8527c720325ed59a298b3948dc8d7888e58c7890c760ba6b813e9c5ca040816c383eb7f19ff8f9923b073e4bae0709f61135690c82d3b4c5c08194ac2bc1483c595c5b0df674cf2a6fdaf9d37809577286044a535a48a0bc36711fa17a6cf019baca5dbc0c7755c27ac205445a2032e624674d73df0dfa50f0eebfc2b5c0e80ecc2c27f392b9633d7651094419533a7e83f1b5c5323aa0d1d3cdb5122cff3de052bfec503c7107c8a6f94389310790073b8b7a89b355583ff07a1fe99c302a9262120a0c153e130f4be462d08c9ebe07ffeba2faf41821974a5f3aa7162d4f4866e5a5b50e49b3f27a7c4b18d1903b2625b0e98ae3651ca69906c2da2c974a9bd2f0ba43c0bc43330abcca2c666b49e51e66d3b63bf6100843bd1e44ce2f16251d4dbe8ab7753602aabf3a32d3b61208e7726ec3d303ff05aee7f4d4826545f950d75fb1b5bca86d65966a68373d5d1e8cb4df16b8a3dcf9f63b904a7d30e21a624d4639e067293c596bfa178cb7ddc7d196e08153a6cd33886b91da870df7705d124e11418b98046e1afd2caa143429e37f6624b3bf97df8de7a7d535928bd08b115bf8e6b97b035c0b31c72c400601d78fde0f982e2e7473fc53dc203843042c86b43f0cb5db0c5b45a9b475cfb6b231f26f01bfd9642e7d463cbe1a9f4641de496d2e75092756274cb7d2bb4ec35aac72fc77db33639c6126f0632d5ca8d68b84e9dba010fd866f67f90f9601f2f0e61f7cd303b4e3ed27b97dfb8aaaa45cb2b9a64b3895966c5354e64b7ff178ec95eb1537290823369c83900b36d8425d9b978992485694322637290ebac932323f0d6a0dc984168551cf4e345ab4b7b4cafd5635bc31f7db5bcc338d79dbcab26e12c40f4c6bf6c2c4a1165cc1d7e757e05c058dfe505ba4e4912381e8cea4846460f4c48b32254da6c243f5d88c5a7eb9e3588194e4ac09277ffc83cbd71de087d2e9a11683fa71fa5e56fa0677ce873262c396c0edabebbc68e089236e47d96db930d81728815c9bf0d2380a86dc7960f629c32d7be1c0db60b74492c8c14b980960bef1abf2748370834b0eab98b88ad75338e942fa30433d03ed2de645be843acc0556ea4904e6c57073aa131588302535bb269868b122fe324ef51634c8293969b49a1f9a73a2146d30ef43f4bf051f36e06d98bf25bcd99c720b5442994ba9f4388d93420e1d6fb0a33ed639547af09db4a8cee8ccc056778f5273956d1c1e38eee15e558f17062f2b87689f178e5d59d63849fe173b68bcb015c45a53639a2163d12a0bc2b0f8fa22314214ff3011e7ac45c68475dd47c3ca8','sync','ak',0,0,X'6bf3cda6ec4d6a0ea59a3d9e79b1f39f9873c381','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(5,540009246.42938804625,540009246.42938804625,X'3c585604e87f855973731fea83e21fab9392d2fc',X'018dd86054c8c7ffc3c08d3138504c7d9c240b16',NULL,1,1,1,X'29c843d85c52ffca384eabd2b73a1dd4e16ff128',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000f292712363b137d0d0fcbff2c232e0add96e07840e5908d303adde064c330a4dffffffffffffffff7503bfed2da36a72d24b32fd863b120e8bb29f6d13d441854af23a438e00987c7c69457862e31e51e783f2e031a617ab17dbb044702ad93720ed91038112c33f6241080477cf003302fbbc1150b89868b6d104c54dcf34f4aaf83aec5e795a7c17d835bfb42c25e5c1e9bb7ddd6f191be1274e9029470a58de22b0e61c8236316af8698043d2deabb52f99445944f93c47ef556962c15216824bb78ffb21a8ba2701b9fa2894c2771ce0491f573147473f2f7dded38b5cf183f974e95bf5a81671c1552495bb52a0017f39c9199626cd6e6aba066cf77341742d5f7190beeff114899ff869a1ecb91b5fddee5043b4ba43c9c9e96f9dfec9cd2b1c0c80be51e26efd83a0433322a590425ccf20c03e8fed93ce425af27c7130b58db4a3c9cb818808fcc4b615c8945c671694f6c5daed7abff2f1cfacb922b774b8ab3c171b5dd62121aed934bf62aa0988877a108f3858cf768fcba4e835dff71c1826904580ad50dec3d99ab56170a2997484994a6697cd28a26a94323cdd6eacc336fb5bb850d2783ab1b0219160db933ced5c9f3991ae547665ce71d9fe3d1182591c35e81f22d697b59afe9111a3e4eb93ef0a84c402b97439f08016d5b95dcf7d70f3f5ee58bb5a59c55dff944d974c000764a49773579c082fdaa9cbd9808120a867ca2e8e0b7fd290b6183e2ca4389e056f9263c5858c923bd3ac3982b83f0b229425352cadbcbd00f066458c8bd13c5afdb90dc7ee85af206e1c014a13d0ae150bea96cae93c07a9bc093a912db59ea4341cfeb47d7183ff7bfb67627db00a98efafe091a90c318da65bbaa81bd644dc25a32185cd6450a5df0c85e528e46d6c93b05edd5500c7722e019093afb366d451f342cf341b44afa87d4ec96da09cf1aa2c0bfb4bb0105f297de407af9483be7bf7afbac4a22b2f05b0dc8e1355111d4745835c4f9b598dadebbd08d63f466c6a1a1a6e97d6ca614523b219ffe52498a806e981685adbad37d67e5dccb22a1e8a2cb3bb4386837455126e5bbc3e465186775c8e67e3e4b2b2654478b1db8ffd6c08b25dd03f8d4393cd7a53e01d54699180d01e6705757bad6a66b79739ec76ac3fa0efc1894727dbc1e35c68c5cae071daa35ed482cbb14c7b02557caae7dd8d7fbe0a5315347f3fc7674207e2063955768f1923966a91fdc621d19b41218a9f71b066c69222bdb9ec192bc0003377293d87460943cd17760da4082d29c0e7b80057f8fcc5d92a5171405a44200368cc43d3abeb6d15de97b03276c8e34c91139d89c901b07d6b19d8eaef7a078fdb5a37c9b24cbf898d0e2f7d015ff3547893e67821af6061dbf923c250c8906666fb23ece8db12dc4280590bf7c55f9ff3c31c583b4ae9d053d856063143d44acf77b06c4857abbc16a8f6c9fa7377ccd8b7f00a9f96fe2122e52fe33a19bfe3d66812d32945552b244672a1067e2c9123f6f732247dbd16215d77ae6e5ee851eb338fe70cb27faa78297ff648c0e8d906945a5f34e61b656b6eceb1bb27cdc1c550ac2b158f22d17f46e5aedb14e308d1aa184f7418b828ff3b44bd3fe52f70574214e8eb9f715065a3','sync','ak',0,0,X'5006f57e748dcd926d86fea7e31d8b9f8c0244ef','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(6,540009246.47465705871,540009246.47465705871,X'3c585604e87f855973731fea83e21fab9392d2fc',X'6bb46c6a660006ace3a0dd504e9f63f59975e1b1',NULL,1,1,1,X'03edbbcad1ffe196e6b840c412501beecab97f98',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000921cea45b77fe548e229bdc4406ea86bb035a5dd1254e5aaf49f86df83ce70d8ffffffffffffffff86943b0296919559b7eeab90141e12db8cf64711a3834b069dd987fd42ba4e6873e807406eb3be7e0481cede80717f97e9f007bf2af8010170f601e09f8c24fb39c02b97d5da9473507114d4c5c01db4d99496106937deffa73825486eded41b1388ef89650209dc841b07f53d8768f5aa8526c91f34772250e35247bfbb0d96c8dae75f7442b484bb72a145f719a1ffa6a87c2010815b8cad84faf11eca3fcad27ee41e77adabdadb8527b2f0cf77f078c3a87751a14b6d92c453bf5a57a882480794fb978ba2568a4ed864c97c012999ab7a2ba547f796d6d825b5b465bde443d660fb102d9831c62cd3ef59cf6e612d52718197511b1e548ec25ae65abe560b1d9fea2f25e15c36d48c304db740a3ba18ddcfff4c6d36be068fb8610d04914ffdd70f7d17ec58f8beda6aa7257f65b7b3e2c933d7e13d1c5117c2c212408430abc2254eda4b81d6343c95e0a29cdee3d79fd686d953ae7fe06b34d736fee2a4ca42e7afa037e54299ad2a332871347c874e23b01266f38f217077813b7a387c5d3ea71af302d6e7f2c9375d33d2540b5e61dbb3984c646a4df60d5fec7e3e5dbea40973cefcfacf8b19d4dd6d44f97fe573f3759313b790b97a720a61cdcc01acaaad1488cc0db6c87ea8f39082ee3cbb2a51816428993e8faf2257492fed7f961cb176596786e9919056c4ccc5816f867b8c7cafbdacaeae67bbcc778a3fafc894abe8b2a009e463c83c9f2d2316ccb81e5d5f949f620e204d7e112d642e6185ef81f1a7ee9fece3e8d2843b5c2926f1cb567b57e16fd6e66a7582fa4b70c0472f2a89fe5c29d124adc5b4232fcc257196344369aeb8bd575d03dc25361950ef402b551439700916067717d024b5ba6b54eab960eebdcb9ddd12bb13604a127c2a00ff5d27c73f43220f6baa7e4a5e457065d2b733ec34fb152b1cd7e2dcba7de0d53af572d1b8ec518fc9ec2317bccfcbec0baebdd33e32ddcce199ae3cbc356f020f0781e76400709e8658b2b551b60a2ecca72c92050ef597dea9900822796bb4f842e0e2105f38b28b4883521488b843a8164979237798eb1cd9bedd29d8b1f07b0b10518c7b43e7880cd80ebc1457ed20b29b699c200147b7dde900b48d714e5526b7f7cd982ea79915483009a64ff3be46f66d1c602c44800e72fe17dc902ea4b0166aeb3a73e75dd3a6177ddd7b7444dc581f0066542a7f7f50f8ef75d80fd097346bff3a08dc0672e17ec4031b11169db1269328b5845dbc42dced1a77219ca2f1d5aace201ebce1a643860e29b33e539c469dda3634fd0fd467c89667300ee5f075b0d7be0f5e6f5010b424ad539b77898b994c1e82a85918ed3b7436640363b5032eb44c4cc709ce43175ad8a715f513ddc0387aed61f3d3c5fc600b5f0d51cd5d6d915f296caba8669c251ca4d9c6cbdb62bf51857121256f7d419257b8c72f27e7320a6e6ab54d8919123ee9658c564345588c60b033801226d9e7ca20a380479c0647b74ac7ada676f80100354387fffceabb93ee5571b6dd084f0a1872f7fc30d091ca59f4d08b5529a7d1bcead55f8faa14ed444f5cc3ed48928d9765','sync','ak',0,0,X'3ce68f65039af6401bb7a0e2e0162814367e7822','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(7,540009246.5564240217,540009246.5564240217,X'3c585604e87f855973731fea83e21fab9392d2fc',X'262e1af502bea4f046b08007fbfb3e5469a2dfd5',NULL,1,1,1,X'b48a60c1e64af32847e1ee7193d5b88bc569f9ad',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000ebfd867ce4524712986412b226b31b6856123b1b680c23cd95afc1b8067a39adffffffffffffffffac98d92822c74a5409afbec794ef4ba4669bef490b7ad47f32ba1c74380589a0976bffef0191b1d8d5325739137e751fb1ce24eb802bfb2ed4ab34e5666cd5bf321dc7f09a2d3f3bffb3e068e788915d18b80e9a7f53dbe8a4372a35b1540345940ab2bc73ebff9f856373f078e2f1ea7626b3e596a736506c0eab230f52c6a41c6f520ac9f33e7b577a07982c4b7c07c4854298f14eb79279434eadb9b01422f3eba47fbdfac591a4e5a53bef806069e189aa68e43d599d05d8d1931bcb112af97aecdc09db21a32f6d4cc8ba137b9a13b605b95a7e95bc45df96bcfe58672164d666e6d3ccacdc7b76f12020b78282186d3393384b13fe9ea445b33dd4d11273dc2f00b1e9460729b1d49ab3f03a01bf5fe4433448f38060b6347f8e0077b1b2a451fb107150eb7a242033a185f0aa2074f921f53c162a7d5bac6c7d5be24481cde216140c62c2563ea86082ef5dcc696666357de02f53838e317ac35972e67eeb07ed12139972aee39c5edcef301aa417d4f6f3ba89d9794bd8884f9a567cfedef2b9c288ec4ca7722efedc09b4d41233762a3743617e871085e5b8ee09f05c2d67e7fdd1fb01dda108877227b8e06b865383e0df19dadb35eef0880e5a50a5887c28b884c55176aa12776b2eb22531c50a930c29f74b493147a420eb2a4405086911fd833d89da702d96e02f14e89b77f6d118d222f021a4a7df73e84e39eed95e7d8a4fcf47e590bc5867ca4ca5eec708826eb7e30c3a11a4719e0186cf4b9b1c9467a174196ac42bce8f4b12f493b306293b050ecd61dfb15377ad912ae009df81922ee19b474f565627dc0c53dc11752f4ed8372a55451ff008a20f88ed8cd526b84dbf82f0eb0cd26381438f71fc4deb16188326722e6bcb0152cc8bc4eb7655afbbc14a449275127ce919bcf9a15a909892b1c4a02877a2ea2e5578297b70ea9f1398eed051e79250700215e85558a1d593cfac24c847d99c28b021cf46a070079fe3eacd12673a301e7035d5ff5a0bf28ce20d0b2cb854930dc91930d7e5987df5f915c2996eebe4ad75fce264f618f665d87117a0886a587899da788c2ddf018d6a7312211e57d5aa6a553c7106a37ac8be8a50be41cbb2146220dd321d4a0b1ae880de684b3aae55c5f806f65e0277cd6f476fa4d45698bff992cf837ca940a5ccb2a84e4d565a493c424402e427f0ca89efeab37d731446c8c0acbc75c0d6f9ac1658b2c1227f70fa25309983fc396161c38798ee814087b18d9eea9d098b941c715cfa6f578d4e885afcc8ae5d003f4c99fe10d09db534d6939abd8cfc8e20e24cbd464b07bd12c9111653738c6ceffa329e967bd1bfdc9a61c80e7d223746e136c6318f547a5c01a93387972ace245ab2d61515889f765c375e5c6bc09c67524e5223d61a0e6d27461173c4116acbb91aa1157186e81cc5922de611f4de44a3d45addfec705fa84e589a0044f522b7d8c96e1d9a4d7a0ea2c79d10e51924cf6f7b1151f7e5f84061ca2ee8b31bc37acba2c5f316e0e754e4cd7f2bc6087a0094dc28c06f50fa92de2f4c3c02dc6cf5fc62bb5652221afa9668c63aea141ee','sync','ak',0,0,X'594fa5c4cfcc578b953b01cee110e06fa2f9dc36','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(8,540009246.58500099183,540009246.58500099183,X'3c585604e87f855973731fea83e21fab9392d2fc',X'4bd0fe69c51752bd66e2860cf51e030062b0e32e',NULL,1,1,1,X'95ab20914a5317e37e2d72dc26dd3ce8fc8c39ba',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000a8ad54fee4a485b7ba6611fbc2e1441949c4ec1a9f10352dd49471ecb61d7dd5ffffffffffffffff32980a58e608c9cee1d405977aeafa80a1bfcbfdd79492680e3d9a5f6883dedb8ad6a5c222c1452a9f7d195ea2e5e7b11d3ab09f69cfb27115c079bfb8844a8ce63a7b016ac60e6c1a92f08b2961d1f0008140ef33c92620c105d6831fa610f989f85915a45cd50fd9ca8f570af0f99d58bd697b19479597c4c2a1df709bc235c3680f818c17ab7ad28350d8103386dccabce6d94d98c699282242ebe86acdc777fa96c42734bcfd2ff9aceb0d29c0a9c88a18724768e819878d7ce3d6968001674c4c0f9d180a5e2f7fbefee2ecf406bd582e02a75e1d8f49df8d88d6e661034b87dec6d3217fcf9d426a5640338bb38c159604ca74bdb5aeae0ff1771ad350914b14386b7f4938de3a4952f42ca5919d46bf1c85c6fda568db3b58d1c26dde50f9814e051320082ef3ad7d1b8cd57dcf62d82727b4693a7808c89334c9a0e117973f0eb38b75e9489ee2846f189d6296f2eadd00b730609c944a4610b6d0666ed93e89ce9a6770886db9a845814a5ac149a37c6b09654565047aa5b439cb48823191d6d5f7ac4e7069865770e3f7f779f5f01e9a152258b639b75efce9cf4f86e64584962f4d4851ae6d47349f9c75df08e377d1b623e141202ad448c97598e1a98d83061189b129abe0374fbe52c5fe30495e179c0c64b90653857e61378669d0eda1cd327e1c84362ebe011993583a99de3b390c2c70e0ef373b865a2c42105a0b4e63965dd286022018d95a84263167e63f9840ec4fc0940a467239ed6cc3b63617c155ad5f96251c74fc3d64635c5f249b3fbde672f9327eaf09f0bba2836206f867e4ef7b2d177dd872b55a0d9cfb7a24bc5b2016a115bd512c3898e91e445cb08a023c684f834a3a81482c8d52c7b599720ce8efe3c430a70c24401828eb4c15051a6a5124b30e17fab9dd98917c2f4064bb848e0e0ff904e65c690f2f981c0934729430b9cfaff0c7ffe5fc4d80d5ce9113d1ec61b901e02b6e19ad2d4a2ef77c465bc97ff0c990ddd9cea6ee81a623fc21bf301cbb8a814cb9009329ea77b9cb8688b67f813fd6bebe612760a5a793e9d6c7b13fe2344f3dbd6a8e3b6cb398f7705cf27dd0a47a59fe229038fba98c2edca155f15407b9cffd4db21dbd7a0337d452ed2c7e33b21e3b4bdde58f87f706b574a0b4d1da5b64b89d3e5f86938256872e261e13d5ff3222cb7495a81df3f7c0c34dbf7dfd922c945d0424968a58a3ae55bb8b852d3067f7f4cec5f0f2f3c0318d2298708814c5483274dfe0b71facd4bb0f6f27d012331ae724fa72b440f77a44b027f7d7671ba9f43508a419deed4b2f4cbe3b51aaab4d489b91a2ff5aff3c6152341133c7a2b005e0a60e05a8539c9d3abd5cec5ccfe0b149c9944a85105076721b9757713bcd26322b88c0340912deb5667fe616630df80d2cd11a678dd97abf65455f3bf2bf4f3850c8d3053b958f528a07466413175ff4083c574cbc4db366011a8b8a1a35c37e6e468df282597c6d0e8b79feb44b667608520e51d4871d2ed3732fe85f2d3b38dedd44add4d265a705659733889ecaa724befb6e71271d54b9759847b42a27a5224e26069c0a3451','sync','ak',0,0,X'7af71ab0e26e44708e819d1e85a917324a4c4f25','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(9,540009246.62409603596,540009246.62409603596,X'3c585604e87f855973731fea83e21fab9392d2fc',X'0dc979403e4c0ac4d59fc55b01f01eaa78012f42',NULL,1,1,1,X'39de145b5758fe1fcbed02b5f338c57572c9128c',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000efd9994a52c5a1dcce75d0f442be01e32e44785a5431509d3b2950bbb638fcc9ffffffffffffffff08d888cd3c537fc01f11d9071c2fbfa127d84a83d87f52fbedb45d3a8279cacc39dc523ccd18f88fba71bdc08dde9f8d5f192a4b8db18be713703b26b6d84376b496a19f46aca5648888e5200525184f7f6e1b31b30398f790b075e41ed4f53f2c6196a9b00688042d823e2e11a040fc719a20cffc89b219e6daf65b0a4badbd1958b81248700fd112bf29561e04e897b8f54483f0ce0d1303e0e3784f04ac4c02afb0019f86fd90d41a57cf252bf6dde6ca56ab9b12bbfcd7d73ea7f5084bf3a4a7b319409150fae7c0fb2940e2c492fba94e2899c53939b88b69d97f8c732e82adc83d5ba4c170c454e0687b9a7d885944e94c70b989f2af1591860f779dd929d28cf6e6721cab48eb9a7f9974cfc4595d9fff94322a3cbab861877829db9b247dcedec53f3899e1c8e316485da74dc0ca9e847cc300ab2e06bf1517669f770817c0ba3ab9571eb4cfd406aad5bba4a0e9b9b16f647d36a80f3079df60b171f84fa9e4243b58ecdb757baa83071d7c5f55d1b85c6ade766a9237768303571b97b1ad826a01aa4cd4461fec09831337741eaba1fdf7c566812479a80423645eadda33ab589f419b680c2f0b09399bd01e0d422e0090ec19bb5f162c07a01b381bdd2bf42567a761005abd1b624dfd11ae88037b88a7b5f6d78d536f171318492c6baf605350cc8de078b604256bcb544c76a8afcc80e8d988b278197345747fb620edf0dd12e4e0f2a3ac4440c7da08711509ec1700b4ebe3054e7991dfba7e04c226532afa831778a9cfc69118145caf5068de695ffe3e89b9ebf699c39fba216972bcafaf7aa70361c06ec75b1e95b99dc05af05a2cd4c1396b044dd3e0274b6f443e53211217a0c24e6dadd4983988c7d4435d4678a23410649b08f3fad0e8749f486d7e7ef37f47098c469a665d3c79c6f87f2aefa38150dc921d59f4c06931673b18fa236c6bc1f463452893b5cbb9b6fadab23968962ee1efc0f87b223a3424917440813579257389792cae09df518fea9c773156a77c72921922aea13d20038c15104e50481b0196e57adf3efb9e0d745f57160fc1b9fcc3adfcfc5f32b63b93f3526ff84a277ce64755aef8e0bfb30adba8f7ac3466f6323ccbb464aeb42c7f3d81d87f3a6f6f9e129b6eae770609c82e35377a7b48bc29b6fbc46efa4975a83f6bebb0f6b4ce958db9c84dc60a3515ef205e100dd91cd7cb525b9c0fef8420fda974450a11d40ea3b853c2a311ee371b1f31d15d420c0f5630bdf7732cd77a677fe54f5d28bb091d9b327b2186148416b59c54ce62e6bf232cd33b75516852f09303b84920486b091072f635cef16c0e753c750ae06aa4b89eeb4d8a7db9becbc754459b15a96360763cfb23a84da5970fe4dc8f454d5d0b081459fcfc5d5bef625b9e19b83537b52c6b8ee1d75c9892dd4a052069515957bd8fcaed62856c3d54f892d91ce705e69d4c8d03c3787d31e67b8fabeb093f4e2f88c4b999e61b04b53ecb97b1b4053550bd6655e76c88d5581e88925788cfb2f4c68983f542253cab77f35de221bef39e8756f4b512dea3729733a9cda046973feb9b35175a17349c','sync','ak',0,0,X'9e8592af94c8cbac2f09073b195e90612e9e80db','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(10,540009246.64887404442,540009246.64887404442,X'3c585604e87f855973731fea83e21fab9392d2fc',X'e0238c695e5197661c44e400525566a3b238b704',NULL,1,1,1,X'52d7905d087d8c90f678d08dc95225a110fd7566',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000e65cce4228b2285910a0b006c58d94cfcb829043f41f5ec0e7d71bad2fe8baffffffffffffffffff1d6bffa39e12e66de043dab4a4191a377fc584c3366de16946b5bb02bb9381e16448f7c96b0ebf215ae3ed3c0d22851e997c3672fa8023b033387524c9bd01f6df646aad91edd3d5eb2956152cbc863c25cd6823c6a073363279e0ed65d0fa133e74d1c5037044cd65715ebc4bf215480300adc452faadc93508a47c91bddeda402d88bbe88e67a2d9b14508066233b44c0a3559f73ddb533010a5c448ec6976e89bd02930acfd6f544b7a0e6ab4d9882a8b4c578319b081db2c7410962a0e3fbb3aeff82574193235477c67a4e63072420beea1d5bc7665afa1f2f76a97a13f999f7a2d1d9226b2f83a72347996e7b243760bf58fda4b79046959c61b2d39d5db1316053cf37aad3a8bad735eb54882a7d14c64d382395ed7ba6b9dbb9ef51fec11abe36e8696c8ff6467b87ce24c4e38e662cc4fc3f82eb3090b92f8b2d1c4bb09dc9f554e3ad27109d6e2757a4e44dc3a2c156efc2eeccf37f286c0a7f143815444fafd0912b4ad461fc28cbc825ca84f8d5c68e468837c4c428e68fd4a718874c4604fa314387aec3f89411975a10a4391c92a0ab7a1b22a46c92385b82574770e4de226304ad6ffe21cbb3b7d45d74a771f9b412b6316431177264cf01ccdb568ea7b80c00a8995bad5afe39c71400c88e8bc728aca964caffa28f9a67ad40c7b23fa6e1c19ac72706a3b5c4b6807b41eb63910491d9e5b9b9360d0fde4599c361d20f7e0d4f1ac535fa60be7d5209d28ecfb73a0686c49ccfc9495cb6238b97b4817d46bba40d50bffccf1efe233b4b2a03d0ab2563aadc2880807d620e241fe22361f171c1e5f7b0df1870c45e81c57700f7ab3c89132248cab9fd78439fc14258174f3dd3948673ff9ac4281f2a47170cf6f4dad20bdc382f912cce5d32a066bcbdedf649c04353e21ca089dfeb97c8db9068444b8438aeb3393e646f8e422cdcae9e3073f4d93a5662609755f3aade37c52d996aefcef27566cfde65d86e48aafc4594bfde6552d818c73f311d75c693751644ab40db44c77842ee81af35a0e47d7f906103b12b16cbea2b2f503be56157b02a357318a6f9e27db0146489876baf4f6b57df86501bcba60fb00276422571df9f0c648881b07ed139219125d5422ede2cb7b846c3084029380e54b1e3cb372486ec13848350a7019a7ed54c9b0d1a654a3102ec75f484bc79bba5453b01d1688b860cfec9f2de4adf7be11c19cca69ffcfd0ee6d94446f89cc91d9665f43dc9d8f473e09b60263426bd5f45a80b7d38261216a14355d4365806a58e2ee5f4fc3570519e355a039fc2965b1f50c3a4f874a90fa63bc9fee9b69068cf706ac6f07c6f776d57b9666f885c2c6adca2fcbe4d19a20d5c89c9929659f43873b6f2ce16296710d20f9a703903d82f2b2aca908c7df8c4c73640858528f4991d740314d0f2630d17b8f7bd9dfc33040ebd102fce8976203690232215a5e85e05628a5d74df0914b113ddef4b986aaaf8c2545864027b0dc10d7f20df06bba7b732be31fb92cf1b12599d2aa654ab17a234213b45350ff97769add404600368712d5f40f6640e9f4a1cd43a6dba9dbe8df83ec17','sync','ak',0,0,X'b11a5e4479be7474514b85339907e6ad87474acb','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(11,540009246.67430794238,540009246.67430794238,X'3c585604e87f855973731fea83e21fab9392d2fc',X'8a3c27dd0b49b6a2781f838a22b08adc3ce81161',NULL,1,1,1,X'1ddd508da6d6e9781fda3588051503051b71fef5',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000252c36c18abf3264b71946dcd50957ce931034c00bf70f3e4a02121e99c4ad9cffffffffffffffff997953bb38268436cec229174cef2de61b33c460510ff053c5b7b413ff78efadc966f6afdfa8f4f7185744a11a4d0ef165cc0bd15696076618a296a7a3bdd55b4db8c20a3c12a2ab73daddf98497d0356b7b6eb6ec78dbb4fe67e26a9eda3770930644b038a77bd6aa759391f29c865d9438b2065d2c505da9b35191cba115dddfb2f47304ddf830f8549ed15b2d920895eb1cb3c29218c924f57dd7401c6bfc411d0d93dcafaa0b01da9249b37a04c001f2f2d65bf245ae276f45571ca9d2953826a43d4d65e3952ca42348687c8460a2f4aa835ec2909a6f15c013ac4eea850b157786aa83e17c91bd4600e547e3939403fe3a34575b40b5fdf8cc2f3cacace103bb26da62035065adb6bec536c526fa0fe10c3969fb103438761c934e86bd83e895e714d2f5d26e9469385c6709d15f26f0ef98b0503356bbd2054ed787ee902594d56f5a5a7b530db75e9ac5836ebaa7fcd231f034f7d14e409c744bacc3915456aa2f3e1427d6828f689c555aa37c64fffb56e48f395bec602a4ab6caa8c0e823e0dfd45bd56a284d9f9443069b16572c127fa191591010ce5714b460454ba536d85496c40e749731c2d6081eb9eddf78bd42c4b92bdfa68cece0ec57dcc3c21e67778f110397eb06ba4066fda376d57fc31d0bde24b12c89dbc0d83926770cecc1ba06721730d71b0fd11fa518d8fd6665a770e6d1770b73aa860f21588778f551aa0af79c27fb50c6ead25e1ff863294e33c87d17e524af416a0093abe8a66aaf9beee50485b899124ee897a94d80f11d30e0768488aedd5aeeb123bf70e06052a6493cd5a647c49a935ace80d3244c156f254952b7f6afa2ad725819a11a884d5889cebe2b51d28e5a01ba531818b8d757e556cf59fecb499084c490e78940006a722c74fc7319e9eda569dfaaf5b94aae555d2e74ffcb09024692b5b8496afbbeedb58626c9cb04bda22990a46ecd1ad49b1bbcdead4d48809ea735d5587eed78efbb90ff88c2e6c8bfcf10d86046d1867c7bc7b345e62b084b704bfe528fce33a9210ff89cbff4468861e8ecc8a7513630c25b6b072fbcbc0f5332254ab5dae732b5c0ee0591313a9f172eeb1edebb9915287f5d83c0058e700d1ef58086d77c39b4fdd187ca3fdf0642a9ab57beeaa1b399c7f7ac4eb85aeb0a88418e2891d3835b6e7b30402f1c8a57b08b30c3b70776f48e392a3e28af25ad40a93ac599e63f82cc84e5ecb9dcde3fb8f8454a75fff9ae0b801e57763aeac3ebf4263c545b5ffd6f5bb950bf695c5bba0681227eabc159c7c7669bc7fa7575f20f49b5f9adcb27a874891e4ff68927908ec4d8bd9274606589e3f816b4b150028fb10433e38975b6dbbdeaf4a8de03e8515c90fe880c83700ffc562d9402be28f42cd96874bb6a5ee1893f030e33416ffcdc26e5f261b7847983170882209f80bff41eb8723624eca9ea748af81e190b360a173418630af585c7c9573a1f2c9332cc1fd8893e8d18ab7ae5c27bfee48e430a5d0efccf5806403b523436679bc65fc7957b520c2984c821382763becd2e078e5b245b0f8ef2628817f69eec218c6a9a841921bd95a4','sync','ak',0,0,X'cadd9f1646dc72442cc10fcb357f7f54f270f790','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(12,540009246.70574796198,540009246.70574796198,X'3c585604e87f855973731fea83e21fab9392d2fc',X'99926c00cc6487bad3ffa563ca6959256bdaf622',NULL,1,1,1,X'68b8756a797c8a826b13de6a7a29ebeaff03f40d',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'03000080060000002800000094da37ec2a695d8b8e908460697a45078fc562a4d5e901e4cdecb748b61cc9c2ffffffffffffffff0f78c3c81b036eca6066233142cbd2ecef327235c8b2b1b0105bfa64be9820e197ffec179d246732a35366e417ec3c9e2bbf049a2fe3f40f433915dbb409a429b576a018ad807ea19481e28865ff8abf3e3e78e237df1e13cd30be553c339a4638dc6758917f5c54d017a1753c5c93ebcb8ebceb72f955715555c502922a499591c2ba33165ee3eda901b8f45a911469ffad40faf563323456d6a1e4aaf1b88140e6e20d903f386e9e485ea73b349b97a54a65b8b4a4f873e63b293aa3f9d45ef2c8829a2b4c2ce875205432c4178386f22270df6cc34cde1a86970cd0e9d7587105f1c33fe4b0007a5c358f0c451a296eeffe53f4cf385c2d36f8915b94c91d2ebd8480211d6cdfe03e61e60bf276001a16be472d2b652d87f4f9abdfff8df6ebfa729b5cb3b1e0e52dac4f4b3a671d0cce46f08ad35d2b3531aa9daf84a7d3b77e7cecace6a6dc671fff038f0b8083b08b6098a1363a59b7b681b304e06d18a4e2abcf441c31ebcf5327e3ed27ee391cbe1e6c1caec6344c7eb9552f4727e0c28b1172d15d915242f0ee7d85576a1f9ab2ff67eae65389fc538d0bff99e3eba958a452b6921ef66287b102f9996ce9f1b399ce1bdd380b2c5b1187562af1f977b6a018a2cd96e5ac6a02ea4d400f1838835825a27c175dc19726240226ad93a121d849029b1570a43ce762e8dc58b5c36b924a23100c9ac2d8745a2f06679e12d13de76d25a92b4d0f2c4e1814ab32932d03837969fa9199e587bfb63cfc4794eaca66374d30cd2a59e154960e9c2ff31ef6eb103912b63510efb96f91648ed07ca21fdac297d7729e6bbfbeb3ef347d47872cc0a0b5ec6a3af3a49a926009e376e8916086464b2a17d7004bff908edebbbafb7d30347a789b1fe8f89c6a310769c5c322553c24cbbfcd616d06137e62b4e16957a9260ec0ac132d1d9d56881a3660172f3320641e55d1f9332d3bf02f9ace90eff66108e7a0489566d65e5996fc57084a23949b5f3ea4446645265ac7b66f2461653622b16001205cdcc1e171eef71856a5f210a1d3543366df16dd3b93406caa5673eb1254974f94fdfdbb04a88e5ec4c18206a11df909a60d9777a5a0ea8951aa0eda0e1c911530776aee91a404c7b8f00159c2f1e9aed4f6f7098daac0a2e44129a2ce7c019385c8a63518e58bfc3fa9c25009b63fd045b748d9f3cc7bd61e052f6bb10554378b0d7b33235a5aafa0ff367cbcee0a51e3c258560aedd39edde4f4013acf5b82270f98b498c91886ff36d99ac44aedb539481889f39a055b9097d726f7f6bd7522c2d3e0f157f4ceff80019d08d196ebf89eef006889a0f6e95c445ecc6999540230ec27b4faee9a5495fe0158e1bdb1e0f953644611b1aa872baae09920c433de0ad3c54ebb16463a4f13be9aeb513b24bcbf88327edb2e6211ac3b29152c894ff75cfcdce4323d75de0148d764bcd4ce81651a42ba18db1b98f5e08702ef5dc144397f3f45b766b967f80ad55cd26915d83bd332ed32993d095bc48725436a6a21f37bf2a431f920372095410b3708d88c05c185a0be95dd4b36041f6a08e3631401326e1571a7db267b','sync','ak',0,0,X'2331cdb16e45bd3843d864c67d0d4a2393884354','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(13,540009246.73491597174,540009246.73491597174,X'3c585604e87f855973731fea83e21fab9392d2fc',X'1cd61447d253b48953bc8aa52d3f64dee114ca08',NULL,1,1,1,X'94f5e9aa2bfc33247255010863960c302c01bd5c',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'03000080060000002800000070a5634ad60486ba094347e63156dbe1059a7d9b65bbf824f33d2978da956a1bffffffffffffffff9f9f96fc298ea78aa9de2b6e43c00e21f05793f4c8b16e52c4625233087a3d33dc900e08383e79a9061871b833c61fe3c232de9f029e11667f01f9c3ee7a4c7c2c45e00d4d82c4e0c75748981f0ba943ad6a9d9729deefd5abae0a413e4db7a22caadc9233fbfb2acb2c76ff1511d0f60fec3aaa45e65c5ec6ba273dc9cacccd144b1cbef951780c74be134b39673db9f4966280e007d5db7e2a9aee2b5def9b3be4253a9073a3676ac581cfbc4c33ce926204ea20085d099767b4a289a8222438d051bd85ef88f076bb7f82d8313f94952d5e2904f500776042ce5b62905ecd52e4089e9b4c452c033eca496453a1a6e48569a33490101adf95cacd509af108ffef97626503c8dcf51ee4045370d07b21febe23c5537783cce6bfd426457bd1fe942d8432979f4d8d2321f3274c1935956511ce54bedc9787a813c8f210610433b9e366b66794897e58f1fdde488cd5720de6a0a95020d538167cc386477779527c18fd8f33f632b348747ba17eb28d49cb9a8cdc14cee5a35f67682724a45271965774673a177c3f25596df5916331a8dd218d2428e07e9003b6f6252aeec4b1ebdc3139e629012e0d7d5292cd0d4a8431a847d2043315064f9f12e4499ce656346bcf4994fd6864915e88ad0bfabf4b930cdf8d295c75eb1ce3118906b4cd81eb8cbe6833d92ef8dfb2bb98237e47dacf23a2e9ba32fd92abaef3338410eb9772356f8cf2fb0c5c4612815ef04f62ca7043bfae05b532198135d7e24724be3f0910689af52227360a1d65e30e90e798049dda58662f5483424dd244ecbf42c40368d1c1eb655ab04fd88043087e14e6808228a3384b75faccdf77a585319837095e7d261f1b8346915157ff89503c0ecd3b3ffeb7f765ea2ceb77221d11b49ce85eb6f318a9119bb5cb00f6f7a6ab2809a86789a3ff10deb0fe181aff5f0832ba9f372392ce6c29f21642386caf615e4d2fad860fb995bd0100b65db4cb883f67ec7d7f497d207c01991f3faad6b9e9efecf2f6984ba47e51f9768f326db93cadf092e21b8a3b89dce4bcf891b5af9558c50313b428772ee48c6c2398b204ed2587ebb9366907d1d72d88014b1621143d9b25c4afb540b1f04450cc04200a300cbc9ce81a0c73fbf033d601790b93d5f5691c2124d0a9fdb852b373ec2be84b8cefd732a38d75162006e6ac1c96def556c694378b79fb29a9de5767db6059f58f20c2ba26277891f2762aa676b4ad61c266e7c450bc1ca49cb7a654e128733e0d7ff8b433cf4d3c89e26dd183f85882deceaad655ba09653dc2588cce367d3fc2ebab2228e3f57e36c05eaf125e47a5641cfbd30398591b314af327e3966e5428e1e2f41ba45f6b86560a863cefcdd5da288e0dc455d66812b8481ab6bee2d63a9ddfaae46441c329ed00a4bc0a48fa6d13790384b716c8661339f455280982abd7135def86649829b3f6cc9916311c07ac0667b6af66ceae27a2dcb0d83b7c7caeae84e33a2ee0ce7dd1ddef2e79d9ecc2af17c19dd48cb4d8c6b836f37892893576d7f9498c5c057053cf5fca3cbcd4c988c4b8f2d80f96188c4283c4e760348134c78c83','sync','ak',0,0,X'3cc443ced2bf56033659abba66111a35d49f8909','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(14,540009246.79443299768,540009246.79443299768,X'3c585604e87f855973731fea83e21fab9392d2fc',X'd6d71e32ac73fbfce32b8ecb609562ffbec8c808',NULL,1,1,1,X'b00e2051154eb453baf26feabe2950ea8accadc0',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000ce7c7cadd473c790759959afc4fc014f9218eaf3b59b026d2af65c8a2f6df0d6ffffffffffffffffd8f7ad4b6be5d80e872954a61edb4bc118857de425f7f464f69c91caa411cc563c47ab511ebf639eb87b37944e0f5200d9b9c22ededb8617fb9a57c1be6a706a790f0ad145c759070ca24577f9389d592465e9c5fb4b348efdc9d0b0b5a043a2a388afd28f6c0a5053d9ab4a81e33aa906f46cc691ccf80ad9306adf6574b68a0ec2cc6545448a092b8e1920f0fbd01d1008b0430306e77485fe5e7d5ccab2e28b1ac4311f9009601ab451fc7498fcc2a7dfa6f4fecfa92c0f44968ad4c69eb9bfac39215de653c6ed8f764f86349f9893383f41b733c025bea01ae74c8e78ec9ac9fb15d9e061e1830f8860436dde2efe75000a42eadfba4d555270fa24c37c29b7ff416a1a001c7c9ccd5f0fc709a9906351f81008a182f4ff740bae00e74d1869cac785889d4dd34208bbdd16ab7be1c38e615743c023db2dbdcc1be06b6b79adc2c42e4223fec7275733c51226c70315b0fabd54cedc14e2612f80a4dba4824fed54a5a04363e333ec3d5af27505e5afa1d9d96fcbf57391ca67da157b5c21846ef0ec97fe2669b72d534606551a8bc44a799478a5efad61b224173000a1a773013114a8bacd5f2393dd72f40c3a8ac03e067a9c64639069df8a1becc81b379c93624cd7c3e579287757dfae5553ef31e638fa8e315adf6284c8077e6361bdeef99f73f89e12a7d492e33ada87725edb0c2c0c24e49ceabd61372519e6ffb389f51d01b3654d9d47aacba3b7e30d465e3cd87ff4f4896cf9cb3d5530417c80367f2a457fead9d38af826517576957cb0de56b946ddbe09a9b797639090435d403f1051eef6bd3f2da8f2f659971eea86d00eb84f5a89231acd741c531e228a3a5fbcddde0248d893aa59cf1d809bc92f16721330c683173a4c4e50d73b80904316bec24cf46d5e00327dc61c2bfb609444aa8e0bcf937e9c0d585d917e70208653a9b20186ae057610bd41748f9fc75df0c56304466301d610b3c58bceb7164cf144bd521658bf34bd099e957850cab44b3d765952b4ea9051df32e023946896b3be627f81b8bf9e357ba90167a535b5503b9e7eca7a9540bf73573b19889a86d58e8f5218c70eabafebc0e4ee6de896f4af1178cd209762bfd3aaf6cb4ccf9a37b0948e670776f7c352e8e01e3c039b3ceae1a236998b166273322b3bb5884a8262f4b533fccb77b229a4605a8dcb7c3b5992c589d113f9d431fb9356fa9f073e6f96f4b9c00cbb56d34b6c09c9e9067c23038d0d86ae555e86fc87c7570b4d4ced4a4be205eb9107a04fbca047d0abf6c811a42431b943d49d0d5a2df83e8904116e1e0b316c3ea2b47018e7b337c80f57ccf9f841502e5564f69d7ce0f5b1900b513c2e072901b61980420529e02aa10d5c8e84f05711baf4dc095a79588fd336bae05abd054ac5898745a6460359d6e45139c8d1aaa3cc019891b03c66845ae8f6591b7cc8d8d64f0efdf75f2c935081d6f51d2b70ee0bc88dbef7f3457d40b8794cd48704786554e94d2d5c7d9e6edff977cdb4da2d31a8416ff2a1bbcdca177d6b365b8d1dd5bca569b8ada36abecf3fd5bcf43a559834e69970d09cee6d6eea4c','sync','ak',0,0,X'ec376cffefd33a8990c84e35e5f926cd2e90e9cc','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(15,540009246.87818598747,540009246.87818598747,X'3c585604e87f855973731fea83e21fab9392d2fc',X'de2e183ef552d8b9b32534d4d438f537da3997e7',NULL,1,1,1,X'e9d5b00c90767132e38bf7b69f4bd5bd34c4f3e9',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'03000080060000002800000012e00a3c32c30bf8286d63a9171e05b0998f03c0d0214e825a160eb684be8f8affffffffffffffff98db3b56e2efc9be0d3c63feed615842a7b7093ec6d8cd7205bd930940ef5ac11ddd9fff55f27aefa4f8a89304887615e7b0e65e5edef868af3ec53d5e9b88820de08361e4a42fe3c58f40fc3fd02d424ba984593f92ebe451ca54dc44de7b09589e8c386efb6d9ffd32cff2efa8ab91260e1cad30ce00544444dff46df7ca238817c40d0ed219cbf32daabb854420ddbaedc0ff59a94c496a3182dd6669cf1281c2ee600356948bc0765a1c73d869a1138bb453b3862ced8d0e75bfb6e9dcd4cb78a3c87531eca102b3295237e8152d50e5e746cc9e17bf5adaa4eff62b59b013cfc32d15bb177f81dfd297992fe6206907cb5b6d3bbd070f169804a65a24a23b7607e10acd6a03b598fed5a22ba824f11730f1b1a28e6484e937855f496a960171c471b0e9911427127be475f0c7d2b3ff1711a934890e56db9a8e6a0e10b41a43b472f4e96f789c8e6cd5275bfa7a4b4f186626b45d597b66d7c57ef418765a749ac36b196983866870ca30c4413e5b316cb89fbcaecc649c41cb93482c7eb268a87ceb61cbe6a809dc9cd024593fdca7bea494d56d0802d3f1ec6d1a286a2a23cfaf913e921785162692d3b0ecf4ff743d18bffb564370340e0d02722e4e54d475878adfcb50ca0e0c60a05af809dc9b1f9a2eda2c9fd7b198c2f92f9af4380bfa5062b6bfba941405c9081cce03cfe4bf0f3ab6c6cbb2de68c7fe31df6003537bb8088f620cdc36612c470c63c1494da4324acc8330c66c336ef5b64e75e00fe590a526f679711070f42ebf5f0e4731155b4f8a5adf2eb54ffa57a2f963c71ece7250b961a186f5b7402675ff0c043b7b845b970260064f91533ef7c667276eead846eb3edfc910bed2dabe6131e5d666ed059b08ea9d588b4618967ec7ec6fe7e5bbe75f2e004e016b8d5513457f6828c944f0e7721262207ec0fba8a1c71cbaa96d319d244154d2e089d9f62c5046c5be9a43928f0c492aae51d317635786c9cad2b2e79faad8b9600d2b4d88a87bfe84236d57b8110f0d10ff858e9eb099e7f2d22ae785036dc4f022c86758e2c8608ad2639b10be89cfb04f31aa1487c3974144540c0e17ef79e08ed64da572cec3e39f931b2eb78ecb234d49999499ff2afb80f8d794ba908cc85f4e4a64ebf818a7a76fb231353d8dbbb4b66f18cd507c5dd5982248930e3c43fe49d9c81c2063a808677fb4b22b57f635945e97c434e80e335f25696a8d00bd66ee9eddde08deba16f4481107c94bb102db408744100796cee87d6373ba1fde645183813166061905e25837c24678cffa4eeac8c2826ba94a03480bf7d893a8fae9aa0692f8bdff11e0aa4af0fcb981eccf997291b476ab63245ba42c8f5b19279ffe5cb1c706283b576ce6bb7eda10585077886dd36b7ca9919fa76330901c8c8d0178d0714b294b32feae5f57e8cd56203da19db4198e46e7af7d70c1106a6b19382782719c94c6cc60b6ec4dbea595827dddcb6e4c1753a8a0f9c8980033ecdab4c4cc6e054b126476e2909b3037f70e8ddd9148bc7f1725f7f4cf7d2da45918d0da09119a491ee9f9e7e3b89fb0ee10fa8a9d8d937a5b173d','sync','ak',0,0,X'e51577625cc24d8a92a0d52f0710f23a63ad36d4','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(16,540009246.90006196497,540009246.90006196497,X'3c585604e87f855973731fea83e21fab9392d2fc',X'c727925ff3c0bc23e34770128d8e6e8c888acbfa',NULL,1,1,1,X'f42e53045ad197594ea67e54ebc104ad794f39b5',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'0300008006000000280000000ec371220d8afc8dc993cb4bbf1f396f9ffc0d60cda6e04ac177550568437cafffffffffffffffff2d1b99be501960d66d6142881d265a9c9f8c3b873cc468404386ff83aceb55b97395db222b1db1d6f18c35380cf0413947cbc19fe2ff83a4add617c637a39ea1d4182226dea74da3edf07d69807c588059caee4cced38a85a74200c932cf8c7983c2ae16ff442702d031b9c9a311964f949805e67110c948d61b51a49a70ea0b641c8ede38b07c3d837ae099d0d2c503d036204edbd419ac2cdbc8edc2878208cb27238fa9e739d692208bf2c0601dd82e1a80745273a5c79990537c1363888fc4a3a1454b350ba0549e76d08b32c88a3f73888ec3742cfe4e9a77b2872e08709dc03ac3effb15e16c6e4f649e2981df8adbeb903e4dcc870be0101704473bff9e86dd4c31830c5818277ac7bcc37f58a4a74e4013c2c07c4f02f080ba924a41bc6bf77f85b3f9dd0e0cb5a2629b88e3850d7bb45770741440d41c77bb617b6a866de40289da3d9c354f26b46ac2eca03e5650cf38c790450679eed7d5f0b18778ca4536d9b224fd57493979028be627a05485319cefdc381bddc6e5d42e675b07cd8e52e589bbef6e17e99b59d8ea196ef55c31fa559fdd60a0ce3020a2d4df96336845569e97dfcf75240980d925d13e27e0af2fc3af104594d6b29c281599433369c7fea86ea69bbf877f3761abe62f1fad7d201fd9ffaf906f5c3a87e26cb28606469aabb27c1452480dc972765d7ccf3a94ebaf35e77b56ed688f2753851736016d247cd9ea10a3e22232bcf387f9739c2f5f75853a06181885566b662059a346c5f216717d43cff1e2fffcf85314260ac830239a87308151946ea1b9e439336bac8474ec5c03270728493ec3141b29a36b11bbdfe86e6a9900cfedab7611c4f823dd57bc3dc2871bde0d3da2ee284dea18c643a70cbe46b60e5f3180434ab56dd6a25e73ef45174a1f52f3a38d43f160c0ea274306ded203790bd40a8807fa7c31b48d1cabb22e10c9b16290fc1e5cea6703793f3879a44f5e35f09bb6bb3d101f37facf9f4d194f2e60cada58e40ff6b07a067a4f0098eda9caab32894d68f4106e99eaa455c18e75b92b16c080de340bb748ae033b05cf00df5dc07ee80462810eef675a77f1988a5ea0c3a051296746849244a2ee98b92d856737f92bc401ea3dda0137728c25309419568a36e72f1c16290d05339e4e9f75743282aad178c2a2f060f55beda8af053b662226c22a8e41a4e4ac613d4ef1849866db8718d73f89cc2a03ce1cca7038e1b3fd2a80a9e3bee60ae6b7620b75546db19387fa7655049aff44ef29222184790547695bf7e2c8f85b9530605bed662cfe2b4783836deea4172d5b52a9c2fba2845642c19f334a6e47ea632c9f57eb1a648a60169503f7ec865cc20acb0f77ea2b99c1d3636096f7f67a15ce3f76c4acde9366fd1ec87df14665104114418fdcedc247275f2dbe19bd08e1efce078214a2175739e560d6520abfdc32c8cca062158ec14b4e306a0920e7bafb878fb7ac6f169993314f0a0da34447dce108bfaf0f75f08ea302273022981c0517d7714f413c3e237e42f00589a56bb0906a8af684a186f11a6faba38d3b432bfa4a744e920d6959be8f4f28c8','sync','ak',0,0,X'8feda9df7a3732a248294712fa0d545497057d76','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(17,540009246.95946598053,540009246.95946598053,X'3c585604e87f855973731fea83e21fab9392d2fc',X'95c1942ec25cdd1d06cc5c1964fee94fa5c9d034',NULL,1,1,1,X'39c7f4b9ce90d7bf91bc71f072dc98841f12f208',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'03000080060000002800000045f3d0cfef9c4bc8dad0741804555b7be39e7dd41bc6d8ccafb9cf5dacb223b9ffffffffffffffff71f762ca54659c29e922f061122d2037e0c9f302b6792a608fd28b7bc4e86620fa3a3f6cbb8df60f73e1a7927e455611c053f5822723054a7892f14148e6c7f3aebc653b7e76584f6d8d0b6243cd381b2b06b27a2e54eacb7e06ef36c8c30ffc7ea70d76398740da3bfbbfd4bfd0bf0ed97e602773d2f1cee500d2ff9a729ebccd28dd80bcabbf59654f11ca351c55da15a3e1493d43cca94f082b8289d51644916a75c9cdbfa5b1199dd7a0d7a5bcfc6509f4c7624836adb3f043c4da983b7dca4c0959bd55b1af79cafb86e0864ccbf3f15847d89f6e9f05c8a94af180d29ae641a43585ffb71b1cd4ec3e7cf9f1dd6176a0d04258875fab5c70454ca35c47784e7fcc107c4aa62ee08cf244ad9727b18000b59e0224437a7ad0d9fe9176af36fb4ba37a503396a0ed7f81d19fafe4db50a1da71912afdaf0e33ec13f28af1adc5d165ba125a71ec89e13ab035d001920e1f183161faffd06a24a056c4bab384b5902b3d72bdd4c9c32eab467bbaaf74d980144b60391508cedd56107edd965ba709c582193f45a6c805b68e29d4faef6c6a20cf93f27ff1dd516c5b59a607b9ae0ad53951c2bbeee1821eca555876e9288f4515e974e351724d78d53f2df17a6a3cfea8998cecb3a043b0d40aa24977fb3630c5d0f9fd439c86af4a6fcdf483ccf3b1c029d0d0b85e7f3442567fa066de8c79f103bd82bcf84a60804a92084a5866aa4ae4338061dbbfd842c6ae049b9430c2f149b975b9553be18dec3c0997507ba587d241311fd3d7d3e43abe72e0fd4826b0ac29093f0060685653a5087834bcc2296e45597288a34cea196b305685285bad0f3c41330880042cea3fca16858507e14edeee7d3293438e0eb184505599e0cf4701f6143f5003a22e77f4049df964af037e2c08996768e1d4e8716151f3f085786b2b2a27eea0130763c089a039fdcd68accb3fb695de4d1ed6809d035d0b3bc3774c4471c56e393a0d618b89717882a203c0945805e974fd3e88903e8122e700fce2416ed66cb50ae631927986fec2ed57cb73700bd2d5aee8834dd42c6731a4c2068030cb34150f23a385314677253ff26db15ba2648e139d7fff40b1d5170c8c951488146be74b4246e8aa3b1954662e81e346432729f973b2bc60ce2b8f9dfcd535aeabb74a4ce7e95b83050f651c0b0b7dbe75180f4e569389a31afc2d39404a81528aeb06bab88572858ab7ab089748b0f49e1e40a796a997a76b5ac9841b025ab535673925bbab70392056109283a517cc9b66885d2a9f05cd4fb9dc48b226da16da2bb3e5d6fa994dfe66ddbf27843bb95c69d5f619f2f835e5de4a406bdb9bcfef5209380ac49a5ac74dd5e097ca5457fbcf652fa704311aa0cc95718aa12a32c519494ded2e22e585e19f057063fa16b27226b5cc5b419a5946ed864b95f563da507bb5c691d3aa6835e975234c2d5351004b28f761fc257af30fdb64858e01129581043e7979711d06812627a67b01c0c3c0d63977dc6d29513f666f728c65fc2d22042db747bc16e1ebf2f56b5bad81a588d53872e0672eaff67a6c79eb2e0caa65e4af7f00ac3454afd0cb34','sync','ak',0,0,X'cfb198fa5cbf210ba4f4b9aa532921045e6a4c37','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(18,540009247.00499796865,540009247.00499796865,X'3c585604e87f855973731fea83e21fab9392d2fc',X'b018d2c8b2c5e6cc4e5733ee02972e5f1852cfda',NULL,1,1,1,X'28a63458ee8badf52d3a68747c618cba5ffb8a19',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'0300008006000000280000007b538f0c8b0f1b7b257673fbdefea6625276916d93ea21b49888908f4140d313ffffffffffffffff51dc340e9ee93a6c05d693843483be5481157a35b4007b8de3fa7075c9837f62dc2ab6e44cddf731f06dd1c23069349c9589faf90844f743826db3567f199810bc715cea72f411d9711111f629b5312d283cde3195efae93e19131ce52da52046568403c34b6d384bef1b3baafa5a19f39da16b2906386b30c08dfd84a6fdd2b59c2d719f94c7dd77850353cfc698b9e1e6a012117b07a1a4820b952298e38df0759e568a7be11083230a176e0ce922d07d2ae3fde1e220e4c11aea70da56b4f54133f2198beb928a179990f44e5bf5a88b32a7a3d64f83c0dc14b586d330a022093609a6816cdabc9ffefe3f6330454034617e34fd1090dec042d0810dea915b5b859517976c183459495291c18034f937cc0b0b77f94de3c6a39cf616ac6bde0f8a8d4fe14fe0d87f920ed472ead87ba65da24fb9dfa87a5f10bdc2be270658a3013e358133621d413de486c416bb273403a65bb362c9da609e7a9869ba81e7e0a0aef08cbe02d2cb68761481753145aeb1de6cb6f568a70a30ef77cc14e924f780b7307b0f78ddbb8cc98f674c84853a6ba7f55d17a13b3553a5af09fa2bc83e22fb6d233c54a62e5be62fdf2b9309bfb4a9f563a1538dce21c2c3fbdbfb6e2d50ca722b47ee036504e1f5b51ae598cfe8c1cb662e75ff565a09edfdcc3c5289bc4e054c1132db6473586073701627adc6887e92e242eb7c782a19a1df7f730da1b196c03b75a360f0dc6d598ef8e2a72e187f150939819d654ec6b9fa5c1c8ba276c0afa03992beea44eecfa4256598f8ebb6cfd9a701b293ab795be68f8e29c2c99cee9a6629e74943db0132fb2458cfe99a0a9490fb76fc3494fe6fbbb249993c45f723f7c91f4472744676ad2ce8d91dfb987e106eb878bd5221f1a6157a38649db491ac9b3e6bf5bf637d1d06b85ea88f3da0201cc766b41d08b7ff94512e24b5711f915f7412633b37891de9912dc79a6e9241b994051d69a668cab8b96db8f9aa9ba3e86e822881e49f6e3735c33fa67ae6093d3a7d1c41ebfddb6244e26ac0397f080c3c99f5c86beb549db9fda4f98a94f22967343509ae14250e98aa50b6ce65fe35e9f525e42a0900c2a08c1f4ed33a5d0ec7f70a843fa779eb0e3180b814306b4e247bb6744d3d46ee234dbc77cb196f5ad4f763eab5622791c36820bbcb21b4313baae9f4f3718555faa5cee44461ee906a0fef58a20cec46e81ed4946d022f308b48268e91f430cb5916953364a3236e6279ffbae6de0f84dbbcf4f1b1a1848feec46f847bed0a1b8d32194f3dd2f37173447db983bc42e196a4f8c15e5cd534a1a71957cfa7357699b14eb641e4f1cfb7d04448b68899dc0262c8690041dc19d6a5f915a2c69bb30503b4329a1d439ee7ed79e4bfa2a5dfe7f4db31facf4f40525cde343475a7c56b443d28d16189ac76992f6e26a66d83270a771d2dd3bef353cbaef622495a4830411707c5c7fae13bd132523b055089ce01f914e58eb316d5907cd94a19d7237d5ecd230428dd7311079297ff848a18a0c5bfca1915ddd003540143107ed740bb49b1a3b6e59a564862cdb0d30ab2f949684a89291','sync','ak',0,0,X'00322ab0f66ed08e824b78787d0a5db68d7f3749','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(19,540009247.04253399372,540009247.04253399372,X'3c585604e87f855973731fea83e21fab9392d2fc',X'85f1272c37315b8ef6b3793378efa3d7feaacee5',NULL,1,1,1,X'aea3aa45414620fc26ee5ebedb6adb044e02f224',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'0300008006000000280000002a26b2b67cdfe6e9a4cd040f4ccd8fb95887df6cce59964ca3434022a69d5908ffffffffffffffff3442b1417d53973c0ebb28fbd87653058ae0dd46a80dcdab52eb0269460263ce8bf95597d5544d6a988a8db929b5daf28174b21f7bd05ee3cd7445c6db8d606fc111ce1515f51696260e2fe771d975a4cb84af400f8a6b592800010fa1679058d0e0549b05e10ea13a45bc1f9ff564f066a2c7093398abd51a7daadc1529c897593f93a0361ca43a51a948f9bf2ddbb92afc2b5557229ed54413c570a5d9d07d4ce0c3ae5a1b384146e67fe0e080cdf0d7b97f8c6b4bd38338e4ad0040f1f2b67bbfda367590f80189df7e8c4bcc7398a7823e8539b2ebf21b0c01e8d7a3d8a646b84f2092f8aa37e79816e5f0e0939b72c56ac9eb07c02b69dee7609f744fa9fd6048b85f59cabb8747904791535f9a87d1e8419aeea6d828c7f2115eb2c1354efe16648e1fddfc026fd6e4b9ee416858d4a3fd744b0d2aba839a58b0891485812dc0bbf3894a3425785d88052ed946077bdfcf2d475e5b897c3ba167d6be56b68e41413a6a8ddae15cb93feb3edb5eeeac671d958a9cc09b7994cfb742a5c5ff8f66c031eb4f28df0f966e6f88c026e37bf955366b1e642627a740cda0aae513e9533db6cc3bca51e033b04992741dab39693d1744e85b67d5d7d111828c3d71aa76797ce912bff8b23ac92871f3d970fd682083f35ce9b63a977b27f2170d0bb8af50b05542c6683475dae9ff559404c5c59f2d46cb08ab09b670d33bd77dc0facad74e24681ab19c8c126f276ad9476ce31f4a40333537776a4ffce9d16fe72e48691fb572723278c563006937a1c52e57a6cfc42871a873bfdae0253660ecffa45d6c88d786d2e77e00d1a7295a442f8a867318024118c7986f34d96dc2ea02496ddec08104efaaf8d87d89bee13f0e3196578ad815856ef2d0a887644f158f4f6a6317a90c77b3948227ed3540f9e1ca7592184a41cb2096291845d1251c57ca73a91814f91c4344bf6aa2e4218fccb107e5c2051cd085228d04ce2fd3f5a20db9cdd59d17b2f553ae85ab467bba484a34efd327b11292f0a37af578f90a001c684990c76d7c0d9b4b3c87435784ee48abb1bb3a22c09de4b6f604ec954e4d1e9e9d0219edad3beb5a5d3eb5e60bba096860c56352be7fa8d5130179a4101375b5623139eaac2c42a5e0780ca432d45794313a051914d269f7383175fb33d44519a44c41b8562b31ad86beba430b633a4c423c9dbb3015e2fc009fa5a096f521177e00e4ed91d668cc4dc0fe843221f90398d786da96700a15b63620c1340b2946e619edc881a688284348c86a4e7fecda9227e5ecfe0f35a5a62532e31eaa73904048baa71aa50908150da1bda73822ece105f29c1e26e134ef2bb5c96cf79d632120159eb68a8ef1f156edc6121d6f231da2f6d94f2b200e6fae16afbd61508a74280c41f3608509556914c88fc9d78661a86fff8c7b812afda974cb82fa5284ddbc03a9c279e053ad4447829f34a5d1bc3e9e6ad0501276ac228fabe9d49479031cfe29f424946dd4539d72a648660b50c43f41ac3e7c9faa2e2a60ad933fbbf923cc0d4940be2936b301bc99e1f8166a4dedd1994939df5eb7669c21aa209d3b07e1','sync','ak',0,0,X'27762b9c292eebc71a0d051fbe3987fb4a711467','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(20,540009247.08044397829,540009247.08044397829,X'3c585604e87f855973731fea83e21fab9392d2fc',X'5d309930ebb5e6a23bd5f273e0196a01b121d601',NULL,1,1,1,X'3118b0467d90e3646a8a0dc0f4109c9be8eb4a5a',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'03000080060000002800000008833cc64694103851bd358d479739ce17f345a6631674bd03d7395673819730ffffffffffffffffb7215b0db81a2e576188e9111d97870382755dbe414c31fd9f98e98a240231c0aeadb71e83fb0b6e6e9b263c5b6dde20e64929cb040ace678018335492f447c55d71c8bd4f56c0b9a65ae23b7f2ab8eaece99d320d5ca2234c9b3c118a0ce3ba6ff24fecb800391f3ef2e3e067c6aa0a6bbd377f0cd1b9ce1e2eefa6d8d60c5b8f47d0f5b58f84f884cee928ae208cef902369d096ce627bbd4e847b74cc511601f267fccee84c6e36b6b6bd3f5d1047a68e6557df3a7d27258e264aab78e8eab360bb48f55114d552d440d566a4f932d3bc573ed5a7dd0e32ff8ae91e5a37c92d994739dfb8c4b5976cc1619c5fcad9528ce32a5d15ccbe5568fcdc47eb791c2d206619a94dd546a5788e61056d62845fe24a9ac594a81b7b3c83e08cd6202cfa016ad688391a6c7a690b507e29abb941eca6a409418ff7cc310e7cf5111afd9765464fb981103b8469c915f4b6c161ad609d3d6304261fd2c2c3dc9ed0eb241aabd987f555e3137f2e44d1ea5ac948ebd7749182af43dfe8bd66739b9de4e00741cfe971491c77bf8554a73eac5d977ffb4ceb7d60ef8ca668e57fd8132744cbf98aab90dba4f223459bc3aac39a3f43f6fc29102b8db5eeadd929e69d8fa50a74fcbf34840da377650b5682b043e0475eab81dd00dde09aaf5879be7dc21011e5f9d8609a8ad8edf45c23337eb82ecabb704e24277def615247587eaa24dcfd98ae6421f62397bb7ca1f8ba15b8a6394bad48387c38eb823d7b7e2e309f34cd54872b4f4ed467943972a24e25df8275f5c81c0756ff17db6e9765df739a7eac287fd54e269522adaef953fa15150f3b0a6ffafdb5aba44103f7e2bf8e77a876caba374e3fa8408eb268e608b0d172524ea14b7c2d878c134e5c5b4bfedd85acda451e73b5f26d05ade767f6b49e6e9576cef285f093f703934ae3f70ad4a7a763dff7f8e7f0a1d94ecd58b4c4bc949c71486f06d8f8ce7992430bcadf269d106ea02b3981c4359ba98f6506863a0cbf5adca2b6b764816e419eadc071d844ac31221606f8e74f5b7539dffb6c447b874a0ed5dda8ecf92247ffa8c19926977ca7e14936afdbf7439ef2482e4d8818b5ef52bd483813f1e2fb017351b09e92f9ae5882c2c2dcf59641fb325250652057255a908f7f77399172dc8fcd1a2ed5a02691bc6271137087e8e259ef3772696ab85e0d2650eab1986d01b37775be7302d1b6dcd60c14c4148567f76c76d9672f6361e08f415cd5baf9bbb0a47eeaa5fdd9cb678b742d0373ee7c672322e03c8d67b5baf3c315d9d080b47763ec8ee895b50b7536c7a276b84678ac55e52faf3701758a598fc4a1627bf4154f10fa516985da47b46f86c2c67a7c1971a1d33ec3da49f973efd97e51673797f94cdf2c82031a3ce44fe4dd712cac9022232f7e0335772906ee5d91547ed4edb68607aa913e69a1d91cc8e42d14917e0cf37bf70ee527e6e4ae3b86bd14ca355bb8d895fe25d7a3f7cbe7f9c43c1b55d8efa6c30e88c624f8dd4d1ae96850b5900923e39a369c781f631759ed82437895e7bca3cb4cd0d0de03697a8c37eb48f6601db22b68d46e4e1e46','sync','ak',0,0,X'9bd9160eae87fac9b111ed46456393c9cdb13e30','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(21,540009247.12179398535,540009247.12179398535,X'3c585604e87f855973731fea83e21fab9392d2fc',X'3ac8effbce88c398e9efa76029d262d3c702afea',NULL,1,1,1,X'd9efd5793aa25b09cf99c63551014c2637b79f7a',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000842ce074d9b389977a96105c788fa19cee9071cd5cecf8369d77fe3a89bead90fffffffffffffffff9e6a045db57f17987dc3c7c8d96d62fc67816fb195abe27138f3ac1290074cb8357fdd6830ec9057979b98ee698322c736748cf67577ae84e4a6bbb059a424ec24aa9ee562a0898aff5eb876b64eced3fe1175a2f01aaf3ceb008e951da84cd723ae77af6ee1510d5a152ccabd1c4977d394e4ef260439672dc054e5acb2baa4bc8f1ddc1df786cda94ccf39beaa46d5d610297b7ba76762a337029f93ad7724cb555c42c5c3988535f71f50a77987a95743e021fd335e640f62eeb9378f71e1d03f50437c7b8053e5f39bd434dd640e495fc9f0d43702867288424e97f247d02a7771faa6a2b3dd58c1a485a1ff0746bddf0e92946998f5bb7e069d6d5399f74007c78d31079283cb00dcb26b6dddfd91429a7baa6fb328cb9fc3b030773494b7506d28a5b77843764d049080ba2d3608bde8ce2356e408711b8dcb988b2afa677dc781acde030f44f45fc8aaa59907cc87a9bbf962fa6cdba1e3bca26e25e130030831803979daabbbc801df335da78e4370c81b10e29f193a55dc448fc78bea090365dce7dc9e37941dd521804cbd8d24126e449f01f1c4a1365c8910cc0ca0739245bb23799e2bf24ff3c1b337f03816a74bb138b1a965a57e032a8ae438035ca17cf27e3e3299e1a63d4fb9a8a64c252e9e37ad58a662739ec959480d3b444ebdb4a7d9ed847c1ebe3083e8a481c301bb45f2124d8c443c2a7d115d839516f0f3f92472d28e5d23fa9c8c3db9bb69a50248d71d9b1926e9cc6ecde20daca22c0cacbd8c61b162e138393890a14b767fd16dce34041e5b6c31668c3126510193c88b1aab157abf0252b3c19ce19f6b3b62eb8d8576015aeac8936e5d6bebd08073d45e0d50362a8a57f5d712b7d76f89e89e86a0c3f806f68d9f6105e1810f55939ba869a451ee89eb4c00b3050035f14a7c78f986e59af37ff4ce221891ab6480347f6cb0b7773838f2b97ea63e2a29939e8ea7c6269782dec2862b1535bf94662e8a01d2b7e2936c0c0927e703decd132f390556e1b0d9ba8f5a8c289c4ecaec69fd7eadbaaca35ebeaf2f16a5bbff9eee1355b612802adf4334635e8e8dd62954e4f9ef39ad09c77ea5f3e21a86b5d618f38a8fbe257581fe35e4e471d06df02157d8c611031c1dec87eb730ed3a251bf0ce227a2c7d2019602ca0c6d9ffad49536001f115b8e5fffb6a7a37909abad6782661b9fcf89a9efc86921d996c9dd62f8efc8ed099effc2ddd19533d689ec13277140982315c8fa588a8ba9af071d9ec613b912504f17af96fc722c5cc21294f1b6b697b5c38c0dfe3a10456f65a0d6949252b3a6b064c59cedb56966a424fb451e919ff57b6b45c4ddcbffceaaa3bc9c3c822fdc2896a05260037e48253b9c44010bbe8a01e33323633ff68f3c822b52ee475efa3d8390994b68c237f6f95dc0d8cf2d57f5b195cca455978812f26d01615b55bd986364703bdae0c1edb955b142b73c7746fb82c7ed145044675618f2a697ff1b64ddc65336b7b8682695283f944068bd920168a48c242454ada236f0e377787d0fa4c73a2c3a466987242f61e529d6a002d3118b7b9c3205510e39fe509b6','sync','ak',0,0,X'd174b86fa2498449ec83f43b3c901ad85d497a03','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(22,540009247.16436302661,540009247.16436302661,X'3c585604e87f855973731fea83e21fab9392d2fc',X'957330d9e82f1403efa5a03d4edecf0c4820a289',NULL,1,1,1,X'a34fe8a5828aa708591faa49ee0f0402483ddaf0',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000384251995b760a5128a43f2c03eb9727c50f8066c5a0175e394012bc49e3f646ffffffffffffffff7d9760b597a1b516992d3037fd2901a926a2d7ac2b188e461af0bc7d0e8455f9d4cecf4b604a753eda7bc6a52bd36f704e1a56e62c15496b0ceeb90791c53e6a1cfd3ac3ea0028883e6e4b5591c4a81d860a6873d26bed7e91622b9f43619390a40eba24a95e26655f3f19fd8d3e254974b6704ae4214d2ba32dd32eb0bc70567262e918ed82af0bbf1a7c1b4526adfc34cb9dd0dc552d5c6dcb779bcc0e77d8639dc89b4482b16814f7a0e3a22bfec66d6468967cc20613e716082f5ccad130e5660eb6aad9836089fcd3ce38d9f9e4e0b1dfae2573354f015abc84de50abea832267239c682889dfdbaed0cf4d33c528fb57c8b21f4d24227b303e21364963ec2e15fbd642d87866479eb89ce1e615672e2d96ec990b2128b9c45c4ebd5a07067a8b8c19e45a4305e4901aa1457289044db4df3e1d71bf130913143608bd82b63dac78a8d2f472063bc13d26946fd0a6246bb696d67f7e66fe1cb22eb387db074cfd8b692f34eae5e2f94f63edec1015e9a32aeb0f359f5f400be20a945545fabe7e6dffb8eaccf90e03ffecfe1bf800f5141ee7e84af4f200b71a62cca9a5f2c5c585a4ba3a0ea749e56e72de9027b683af46fadc4eb6d1d50de3b5a7bbaa1d05fda00a488d9e1fc8a2bc0a774d1c7cbfc94c18f6986f83decf61b393cdc0a9fa9a604200d8af62f5690de6caf4357920cd48ff18107fa525f3b860b34e43b2d1d023e8a6a65ec2b7b7577c42a07b1fa3d5565af7d328399db4c5f82402d63bd5c66a4fcddc44238bb5deaa7ded022e73d491bfae8149c1f1545e1e193bf6d593017b55baf094a5e8486544837cac127ddad0395bcff758aea15f03998364a29e6ba29c2830da8e6a34bdac46afff3846ade81a530f9101bb78ab7503eef1a0d5b5d547e96bc4175699ead89ee711fc68d65cea755560dbc2577cb2417cbf26508ff46ff9c770dc2b791d506731b65abc02f92edfca7fc95a9a6bbb17881d35454aa8ab0e2197a73213387c0e7f2f5bc01c04ec97a0076ddbeb83f8d0e1b81042dd6b8216d517c43393110ff25923de6a44dd517ada7eca4a4e04523ae3bafd0022cf78504b3a74d53ead78fff458f801a474512fc16228417dcc21a65512a65abfc7a0f703fa22fca005f3919329fd3cea9ac6f17808f61a20f59e84830092fb4b93ddf6458d3f2156f2a4e5810eddb2cfdf6a57c9129f77d956a1acc961dc81485b4e088f99d3634431a380b3e68a1e542aed32b2c7987cd0ad6d0b9d177c4e09d4198916710680228666374af619270c5a3111c3f985aeae5d0427633e2f0c602ee362e8721fdd012874f2ebf8cd13486e895a83286309e737c857cf435d5a09638dcb775127b231b4dbf1bfaaf486b06875ee6620e166678c4da4b2e9aa392e6aa384ee2d11574bff5f173176935c032084fc5c49f84adda28a2f0046329bb52d50834ba8dc4a8f727895bf8ac8e12b976ba60f5dfb48d34beb3f55c7860d54982574d9026101d1f913be312cbfb7530a65a5cbc8876a1b25db0d3882c28b04f83ffc53680c17bd3bfd56fe7dc1dcd68a70570bd079464e12e35af57a20f3cee82674','sync','ak',0,0,X'9bf4a29ae10aaece4780711b68632d06b9a439ac','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(23,540009247.18998897077,540009247.18998897077,X'3c585604e87f855973731fea83e21fab9392d2fc',X'710c2658f862c7870b58d8855fba915c1b1bcdc5',NULL,1,1,1,X'9bee8e45100a88deda6685f204309fcb347e367b',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000fef063a3238856a5f2d40ca5ba4b77406a8bc4a1436798c8c46f779c99634104fffffffffffffffff8ed89a8568414a8a56ea9690a8d289dd420eaa91acd9a4806576113d4cd35ba821ba47b30da230a50df303249aa090a0d272a2893811e3c154c5db81a5e72b82a5d4e25adcf8ee1c4e7df92a2b9acdf25f5d430f7875bb5b90f9ca10b4fabc8de7612b8ce1ad7f20c2391fb448951b809b7554c96ac044b96b986e76dbdd4161938241b27d1faba9a622d226e8f43807093a477c2b63f1c0c72c44b1d7b62b83913349acb3f979ec8f5b2aee4f23263725a4361e5a43ba3d15e5f2f04e1db3bc8b091a7b6165c13c7beeef5bcafb9c8b8d986916380ef3f7e246251535f9944da2a737a30ad367bed889b2d48c8dd3174c5addf73050310b4843acafeda10b7c565347bef6715461a2fea5f836f10deaae4f798f726404368342df83164d43b9b840c520cab92834033d22828bc9a4e9d25930b1b979a88b0b188a00e855c7fd3dfd61916fcee50a8372b94782794f085ff2533e47ef78e42e7b1104beadbfacd291504d9d71887e1eed967a2cb9d123e58f8d71e2984bf6d00d233329f2f5e2eeae5e295f648ed6e989c75efe8f8c366b2f8bfe0fbf33646095a561e6f5b73762a2cde6068894b35936b551639986350460245e77e38d2ab44ec8ff22c003cce1e82c83e8849a5c8c869a703d6a79d9b234348cc242e1761cef2a58418a2798c418139cf2ca7c2e4c15233babb0bd60558bd1466096d715537c5ff28808d0f2081405eac186f182a37f837c49c8e454edc340bb58df7d59d41749828a7c742405e8834840c6dbc6b0f9e8610071dca1d4fe385950791865665ed6058825325d4e768a9d4241a5789694b3cd0b5387b18c1ae1aae7bddd74039d657081a40dbe5059fb936c58dd6de71fa24fe12cc361a019d3e978edbeee17249e189e9bf8f3cf810400ad01fa015e01436152c9ce61781822b11be786984357ad39f89d1300454fce146bdb39b95b6ddf249f9dbfcd7b1315a244342a6eccfca5d0b51b42d3f42d016ae55c93ce73a9b50d3d0b965de86e433e9e95606e5c1ad85f21163c8656852b34770b3cd16b4c4cc99127aeddd387758b71e77db5ae6d41f824432742585447a2d83f42b0c693e92d7de03fb11f11b72bd14818942b2ca2cb15f480bef4ae05b64b89cc3d57da35a82af42cf814f550bb428c860d01c48a0809f5985b124d09187fd57eb6ef159043bf6d13568e72f285e6c7db673e9981ea08fea387ba56bbe1a76137cfef95cc8fba2db9d919155cc4cbed1069eae65156f1c2cc7ffa7a0d7ef7ec2eb7569b2077798931de2bfafd2686acd29fd7e14ed72caf0667487da296f7476f09aa022508f499b59626da8776bcfd7c1207768779d6fc47973f6d572d8571441d80413582df4377fef8fdda086570fcab0e5b94b9a18829f4a11aae9ef7c638a1e0d191dd0f511316738cfd81d0c424e64f8fbc08566086409e844ff346e093945a2f8d855188aa23f3a9ef7925c4b344ca2505da5b09934885fb1fec812afbd9db5be2c623a9d348e046d048aeb93eda4e51fc3eb535fcb0759cca00c2d80fcfc2bbdb0db630128e9869ccaa4c0ef5cb91f3ebe13210b65c331d397d61a3b14','sync','ak',0,0,X'56bc1afd7780d09b9929061adadb3c4514f2118b','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(24,540009247.27961099147,540009247.27961099147,X'3c585604e87f855973731fea83e21fab9392d2fc',X'8fc97d86cc2fd379f724adcfdda1aecc16e79290',NULL,1,1,1,X'9b9df5bfae51d08338d2fbe56aa394ce5c2fdb33',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000a2ce3044c6956d3fdfdc3e9c643e327199813a1e173e33bb4dc3da1726670ed6ffffffffffffffffcd5078b4f8ee84eb31b5fc0cbaaad1f8b3d5e9df7bdbf77f6b217486e96eb6155765ebfc7b30e60609b28e8ee92f85c8c6baeed66043e91ec9a16adaa3306c78d9719587e41fe2c50ea94949940a538e9f268528e2feee3789616d6e61646f12714307a3927b958e22580e0a481337c4eec05d913f0747a8273780743ed5d89d94332fabed1a77bb0301a864d92719836ad693a625397a572f8e42eb69b5baa14ad832e01b9405c2ba0a856cb69f604bbaa94d7bb7fd0edbdf2cce4345f1c459e3d7376c0fdf23aaf73515e87c1f2152c525be00beb0eb93a30907e3e85d023fdd59ac06e446166fdb09f93a0e0a9e6716335d1a96a733ea35b9d33c38b61d29358c35211e968582b10f74c00f5443fcf3a3a7c1dfb609f20e24d2e9416e064b5b3acf5857806b61abc30ef875596f8eac1a14fb2ecc6f7b741397eaf28327c705a52fbb9ce7618f0fed4d875e856a149f50f98a9785ab3bac6418dc4768164f42a7db0821a8287971b04fc0d3bd394d04b7cd8e42c3dd41629c7a8b091da9eaf872b0e0694772083dc68a1821ce4abf75cbc5e05cc20df56e40e56223b1a33eb48d4aaa79f0eb053fb3c2750a6f91e1338194a2409e32eca214d1ac151c7d594361469ddf774bb7123dd00acbda316cdb0f897f489ffa4a08eaa8136881d59e57d505849142ec581d28a662906bc484d57bc9f0c59fbeafb4a93f162e9a4227f4b0c5ed725f4ea78d1aa28fd626849eac9067d2fd1e024df60005b8d40f12287371914d66201015a0cae103c7b70ba3181a5cb8a5541054e047b76d2b201f472e616a3696a03d5e71268dd0fb041762a7ec966c1cb6d355599b893434138d1a6c10a97641e534727f41ba1d257d5a3b5a7327b838e3f677c449278889c0d5ba9308d26d15ff9f609a8d0a236de4296b447f09b76fb1df5204110f2ca31c57903f15852912678e0322889cfe1748ebc2da0ae3673a90b8c2f50836c3a607413ce0d01a738907f4c58f567ebc378d7336e6c76601ce440ab315486a0bcd1af59abea2818f389af2e204ab1af99f6fdfa076e5bcff301b3371e5e044e61b7eedc28f2f36d5813002fe3d628c33a9d9309b12ab38dc1a2231bd4da587f4f1db9059a66af6f260f1d87302ac3430ef2a43e89c3c6db38f95893798eff4cb068fa9e8a88ec87f1f64c5949607deb8d61c60149c509e5ea75ac30103c9cc369261384de168140b16f2185b6c6d6b0303949fc2e676b4b0b8922db9caf876dc317f564ecfcfa4650b3873ff2415ff57a811a94e41b5493eea5bc16b190b8ace6fea6dcd019f5432580a07b09fa117cd99e2f275f29139e80e431f634d122fa06be5a52ba88374e9389ca2701f1133be4ea3cf38c871bf4dacfbc795cc8d8c59053fd68832f476fa9ecb99f1a78becf7e63b274ae86db57a7fa853beb1859147b78ccd6ebbc1564b9c7011010d07cccd12ddea92c23f219415440c2987771f946e63ec7e9b7b929a92932f3e870e43063287d93d591881bb347f8bcb41efe557fe11d76970811004d0f3286d921c38bd4903fd813f1d9e470b704ffb38168a8c41fea449c42d605ab0d9ea','sync','ak',0,0,X'af1d6e44dce0738fe366984fe06db8d9e5fcf007','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(25,540009247.33149302005,540009247.33149302005,X'3c585604e87f855973731fea83e21fab9392d2fc',X'6c3f524d5765aa8d2bb9a1d88340101d08852482',NULL,1,1,1,X'0f2099865d8dacb7580d9a26b8bab208b06ff443',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'0300008006000000280000002a5bdec7c55cdfcab8b64fba6d7a4f07ce020cdbaa81ff44c49751fbe9314f1affffffffffffffffc9d9659d857f364b2cb96bf67b900b7371a312bff5e900c537b283d81bf4f189dc57abba4526842be69d114b903441b6f9130811399b4dc04a1e6453407cb762bc81b6b9870e1a32b798744e704ccbbf5d4e745943931e571ec5b8cac1d203c979060ffdbd00526e448d383c5ef68220af4479f0ab2f3d7e2fa0c376c2a0f14c5f8b97134485304c9306cd7b4efb9250a1fb1cf822273aa348b726e7b4d8942332e12ba81700c27896a100d24beff4a38e2c519c6b03890a5cadd415091003c51819abc642259942f2a10299296904535059fc6291cf77a63ef0f3faa785ed1d3ea894f156f2297cbabeb2affa882f3f2f40a38ae8b1629d96d9602c50de53fd213f61dbf8308d3dd4e30b437334845447da7402933e7d34d68ab3572a3a98d553b5f250fccf744db801733322f593ba4cd0bb25608d7903ac7bb7c9645085d356d7fd58ae815d83171a3290e4b289a77b78a29a0852d004c3feae13d105ec0aa373de0878978fad0dbd0c1004458aa848f8d7847d2d7787205dee3735fb37231ba603fe02ca6d8157ba54a59d4caa54586f28a2fafff65667ec0d413f6305419a38f77cf8f0a73ee7d304709eb049e5b324fd90243e6d9f5274243b76832cac7d4ad3cfea63772fe5db2f71b24c6d5877a0a1541da10cc1c195900ab47f6c12f1918188cf850bd96e27fcfb0d16a7a5d36771db0f64262565db0d2605f91033a8938309cbf2a9326ac514a1f957665a318c622ce9bb3886633e250b61bf5d305e34a86e50d2401b494092de18711e14431a64bbbfa4da1b091b0cc081e3d9e55f44ba1c5a7273151031b12ee8ccd035b39c450521bc7f20fa358bdf5f44a5b24dea7ebff774672ba35e414539f3bf53b64cf155aceecf3da303bf359ac47773c22f146979945abdcc49b6739b93685f1723ac0feb5a77539d27b8e0f4ddad92bb8b26534f0eb74211e3986a5a5f8dee790d70f9ce780cffbe779dd4b66b9a64fc6ccf6fbdcd4138cc53720a4e2c4a1c5c8d705061b98760b96239896c2e1cdeedc325c8872e46f2a2975ff147ecc862845b7156a373ce5452ae44a39ba743cf6216cf85046de4f62415bb5afd06c71f139a5b9a214191808b05c7b3563326bed2a4af2027b4f34865f5baeabbbd383cee9bb924540f90b43670b156b2e481409fe762dd9ce7b2389c611bc050358af484fb038365b099b857ab5dfbaaf3353e5cad55b3f1f55c1eda242ff880d86f932cfcbe00e946356c4355b26dbe8220b6d13243a606f747bf628c95af9b8310af421f15354a059db9ff9f7b2d5c1fc8bc951b906270bd733d4b75a1ed428c922c7d51c0db920cae48194332609b9a288db30afc099d124bd5b313373fcfa83c22b59d1cc66a63cb5951a865b65e634e21fa79d1e0c040a0fb77c5a418729b1b0529cb38eadbcda1715c509e886c9de788c74a4bd9be9c52f7e9ff22abea7e43ec1469b48dcb4d66f1b5e3a18cbb1e804be99380ccb42c302094f008f5757f9e3be5f959a4904fbf3de47a52d3f8906792597d3261cc9c543aed43c6d52e96cbc0d5a75677cb12d951dea620af5c645833ba565cfecd2b93d830','sync','ak',0,0,X'f3b866ee440d3a13017ac0545cc5cc15ef1a7a7f','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(26,540009247.43573498723,540009247.43573498723,X'3c585604e87f855973731fea83e21fab9392d2fc',X'a13c665b1d7a66756287e5bfcda960f5193f903d',NULL,1,1,1,X'e3129d56ed171509107139a75c5680598ad5b73f',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000a5da16429ca05d84a9260efe276bbb71ca85b8ba9e7186bd1e46e48e5f8dafffffffffffffffffff4edf62f7db218f9a5ee690f42b777e7fba1177cc020fbcc4dcf42fe68e1a5e521a92662bb0ddfa836d6c987ac7dbfcdabaebc5f8134e94caba7bcff2d4b7b6e868cec3af7595f34f8f1e53628084943109a4dc0b7931649d5d9bb3cfcc9529035488726a4e2f02a15774c1be1e1bc72dffa7d8c2969f43311e8036629bde37f77fae972d2dd5a48910a425c0f805cca3a27dedc26617f7229cf63c4cb19a3eb2e5118570b5ac8213b066ba1752248d78a9866501abb7acb402888d7ce48ea607d2d3934cc240ff436e38f39b466ff6766aad7cb190097c279d38fb0e741a50a689462739af2e6da1ddc4f95dbfbb9dc0be6e6e862f02e08db7388aa561e0a737f222430b1136cf52b7f4fd1c9e61e0f03808a3700a70c093dc9d7f41e6cdc8eab7d427e18b3d7885e7ad41b5a665af34ee9c616902e2dc29216ffbe13aeea1768b1800370263b42459a60d22a7e57b648a1917be1944b3e02ac1ad79bb3b283f71555bc0d93caf8b4b6d9e3e6ab5eed5737ca0566f22d48418c1c5b789d3472b32e52308b21461fdb70a184096333cd4edb4de546e1e54af321debb263cda290dacd9d47efbc18f408db262f046afcd6304a50e16c565e07f3686532349d5e47045aa234b925cf90c0f63dd0a6d9e1f3928b06946ccadbcdf0284bce0a9c9704596ceab544d012a4f2cc192a841f61796aad12a718981ff3761b3e2f000a52250ba574c6a37e3a3f177d1e62bf570d2fe618779080cd712c85ee23053d571bc82ef172f1e239d26ddfba7822238faa08f0ae029a570f4aa1e5d03d109b6f0cc84ed2ae30fe5d213b7e3958033da0f8be901b3beb67c5dfa974fb788426fcefaae0251572bac7334c9fe8f368d0b8fcfb5cceb065b14d1f7f720ca60fd3fca303b51f2154b7b0426a545e2505fdbb436969ef691e00511ea671855ec9fd8fcb147f469416f892b96eb4b8fd44795e48b5c90bc1a5e9af43c3197a11a4fc88ee7965baafeb0e46d907bb12f8c50d1dbe8569c2aeca0eabf5a9b01d41c529f70291637c8f91823ed9809f8bbd46e5bd6aec44b0b8c245c8ad87d0de0c93f9ab0de89200fba6581e17f5239390db7b1e7bb24170c958ccb171b3e12297664a95c4a7330606942617b1655f545bea6332e76a66137e887c2676397d75cbae2d1789a3c47e81c898d55e59e7563ffb6aeddb818b51f49b27800c76e2b5389135b96a0cbc5ff2ca70cbd182a82a72d6973023f2931d5acd23ed251be6838ad9af485798c5e23ad7bb186d190e5a557454a331ad1d815f62c3efd871802659199c536b782302f756c56382d5a7ceee9290001647f5c14b7fceb1c58462215d78948527ec3cb3538531a37ba951dee8186545b4ea1e565e1ce73500db8c1539cae06ba1323d02e05137c6a07bab4bacdb94780215e4928920a9f2d579812495558bf75dd780ad977946ed89d055a818ffa9d886767683af67e21238d3c0a87d33ea633a2458331ec8c36910078bf97f80ef8c82f061772e6c7670063ee268020d8c4f7c4b9456e9d02afcc1357abe8f688f1ea9fdb0ee26b1450cd184e03afd1c96c6161ab2a634110c17','sync','ak',0,0,X'45e395f9a296ffce30d5e163a478659aafec9550','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(27,540009247.51279902459,540009247.51279902459,X'3c585604e87f855973731fea83e21fab9392d2fc',X'61877464b2d2af5c48e1133c86224f9544d915f6',NULL,1,1,1,X'363309dfbe8b48fc943cfc5a7e326a4deda4316c',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000d01cd3ba424c3579b6cf93b422a9000a9dae2b28f30ab53a649840eb4e03e579ffffffffffffffff34bc6e0e54ebe68109ca84a04e26c0378c882333820c745ee16ac9fb8db6ad47b45b0d0f4c080fcee6adcee407a1b69af65c19b4682047dbfd240a962b8db1e90fdddea16e7d44fa6e0722d2862c33fd03be806af0520cdcc8e9e52647560a651c7097bed6d4c60a449cc7d615b5c5278aa420e3ae6a5aa57b23aa57a68591d885e748a999ad487ccb29f10c33a865500698a338137dd2f2a56999c856e72e8edb20ac4ae09f2406fef15c83cf257ec54274b2553623f047538e47b6a5ab292d22c999a7f7ab07ad08790bc460facef6df2e1cdc763f402e0d7cd63abee159c52e1f13272afb97485facea9cd6879cbc13a7769e6e9521246dbf56a4b4fa15580b73ecb88df237bf776044f17ae3db10ef9680777a32bc61ede8f3a994f667ec8101cfd9c2c50444f14fbaa5da00d61e2e6bd81c5aa7cc6bb493e31719a6c5ee95ef53583a4151f501386ef309f68a2930d1dac3d275f2ad472721577db211d95f4e9d88f7dcfde0f4e1ac6e49b72bef25b424cdc758cac33b55b9aef64c333dbeb10f9acc600273ac867b00ac25d0e93ef3e4684b102751d95111fd5cb3922450c6aa07cb07508fde267ea965f0ab6c031a5cee8b71ceedeffe6bac4d83534653b01f6745bab0d90c3bd4dbbe498cc9be8f13b8fd51f8c5f69defe98b4647dad6a761578d6624deaf18ed433178f5b327d696f3279fa5e1ff4789ee05adeb066592125ca39a763d76a8f9f7ebe4423a915e46efc0e5930aa5c944c25967399b8356e168d3aed9427e693144a63b6ba515e5c27e038e7a228042955ae2ca21bac1b053b63914c04d7fb44df6851dfa9f63d1f0270a15791de513c7e63bb1d59f997654c9da312d8caad9da74e37ac5f77a184596e44d9a209dbc55819b08287cfda5a247cbef94ea371b3849aee7266bd6340117f628bc23f3dbc82ac6d6f874ed7663fc7f153382bcee72ea73d4f3d55853c5215f744759de890a139deb8a408da434935a135dab36f1066d9f9c6831b75b8fb65db413c680f7d2d54f338233891fc8243d06c5c1957159ba73c66b10e6bfe6faa0d3e9118248b031e41e11b81a9dfa09f873b037fd3e65d76971f2698d8a8955b49e2ad21c1413e78d2b1ac73b0f32a4ee44f369ff10606370b316e762611aac73236b5862594ce98238aad3d06544e6d12efe5574b717f7ab450912a8fb00dc18eaeeedffb5e7226b505b657401eb84b3e780b08ff145d4ca773f8bf5f08f6067e2ba06c4a0d97d2630b5c90184d0ccaeb3d7cbfbfacd20a772bb4cf2ea055db93c51c6f6b925850526fed869f3127b2718af544667c6f9c65329883a41f9c2b59d007dbd1bf0a11e66ba6d7d25cb71c6e4316436677d9cbbfba4e365515c5a8706796556811dd1a6f6a30a27675c9b73eeb266b75f9815f1c1a63e7d92ac01a2430855b1045967c20388cccf622e88c31083d914bf774d11628fc470828614315dbdb9170b360169a0c65ab7dc1eb4c3aeaa05e1bdeca1a32c25ca21c520d7da5fc2bc976e742dbb4eb2b68a67c08d878c98a30aaacbd72d1761ce7b14b8c83d59ee72c30c940f36f9071dd59f57257d76','sync','ak',0,0,X'd8554a7ae56f7411a7ce8515718054fbadf9e87c','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(28,540009247.6053160429,540009247.6053160429,X'3c585604e87f855973731fea83e21fab9392d2fc',X'7ae3392d2cb9aabe4368c004ed31718e60d6eaf4',NULL,1,1,1,X'35048287b477459d153daaef3b216169fb8eb8d3',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000f1f9c5b78e5dfbad069152cc57cdc051b774afe84f7f04b87af37bf8dcccfce9ffffffffffffffffafbc13265a3115c6881f13864ad7832a97e22219b6a37a2c5e215d5385172637644d357dcadf374161b2e668ab0659ae15bbdaa748621f33a803c6eab17f19847a7d67e27ef14bc77175dda3e0ef7e81f5b67d4a4e4053f955eb0acd71d466f78624ce637d42582ff22a6f69108b99892eeb3bfe7fbce212d429bc03fb70478f43798e40fe94dd46f680e26c0af4c6c73f4f645c2b32dfd1c3288e686807e056c7b4c6e2d721a836d62e90f3020acd74ddba74cc1879bc46f43eebfc61176c32e82cbbdde86772b7ab6a1637f2dca1bdf96aefc8906db21a7d9f65b55a2db4367d599c54a3b46e00388731c91bf70953035d0df402ab3a5d0419a3a4578ee36fd580da4dc3b6042f6908081cb10a19b58519e3f0736f6ba4f446db078dd27d73b37a45a93c67aeb32cf0b792f3758dc05a40aadbfd2559b81ac5a1a8ff5ef37786dff1e47487150c3c79a049a6cdee84c7a0b09ed70381749bc1e7cdcc5d4e0142e8ed6871b6fb7970d18c28082d6013a56799eb72978b87aac1507f8bb9ad5f2e9d9d97daf4dd69be330bfc3a711eb6b758b3ff5543fdfdc7c5d4edd5f25d5312b869aa342f82daf5a503a6b51fc906a693e28e529d05f29af2a889c08baec8a4a45c358ba1132f0655134cb615e9ed1c2e53072de3cfcae661e4e443ce5e24bb3c9ec891857a98b0d78c14770c5a4d330777d7341d884a345bd416d86a6d2d6709b65217f70805501bf13cf111f16018406477bb4c04099f53bb5f6e7e6b15ceb50eed28a3a0fa0e082c81e1a6ba55d9b9925e096f26eb52df4e45fec5e448cfc082617c9b9744fa69dc1f7e3add545139760c7be1e5df5757f9d855b994a629a57c382eb4ab0397b96eaf0fc6582f5ab46dd599c7e5a31821ca3da2a1cdbbe3f00b1fbf2b5a7b1c86be0f38a141ad8ca87db8cc91ea0ab5a027fa7b98109fe46092b4eed1586c293c816cdf7383ef2c58925271941ad7693fd527c3ce2dc404d8191be7c50dd34596ef749440ddcb21449da019b37d6cd744918a200af1e8e93468c912d9c33bd5f12fd31235f468735b2ae2fddbb9b716345b789c07dbc1912104fd42b5ebd4f8513e3c1ba8d236c9e1d8ece71dc82c239fe2b8fd7747bb198cc4c330c02b5349d4df4ea88a59718fade0c06504ae8949521ea7a503877c698e84d9a2d593ff3b574cd41c06f20e8eccecfa71ce7cfbba99959fa6a10fefbae7d15604fdc8d67862eb853bd696b972380d073feb6e3b1e89e1198fed59e76364735cc2d2ea5bf28cda4e03fc8536eb876d506ffad4b20c72248ad858924c4e0d47700a1d849e9119bcf1a2177236f0278d374ac182d9bc79a9e1f2ce63d3ae13893f8e478a370d08f08e7609b8763d1b5f6212a29ed05e5dffc3a73ae4c8fcd575bccfb0ddbbf07830c5d288eae4da8acb5af3f4d47d2038f02db44a58f2053a04eb3e1bd6c3908b8304f4f1e1e00b97f41e8524fdb008627fc2d940a7cc4fc09965dee240ac435127236998637f6ad3252d22f07d01f808a809e42c03719646a4ddb6fb554aafc8c6ab340ec7df233b93f0385d23f962efab4f72babd86b0ff8c636e6889ad','sync','ak',0,0,X'0a644505d4611c840c5dc53d0343bd5d703abf5d','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(29,540009247.67837095259,540009247.67837095259,X'3c585604e87f855973731fea83e21fab9392d2fc',X'aca29d0e4c943c6b98a80641a9d972484a2b1f68',NULL,1,1,1,X'f82340c2bc035a2cf71f837c2243ef5ef416a412',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'0300008006000000280000000867586306762ed702b49db58ef2b32869966027b21fa38fc3b4f92dd1583157ffffffffffffffffee52c5f4fc6885ce88f2bd1d34d59451aef21aed3a52ba0020f5f9784849c97d7cc44b9156b6320c34369822e99d74aaa6a842c685b1ffb524f6c3fd5212121185944d5298d37fa36bfcda1a28d4a387d8fd0b4b373bbfecbd687c54ee7b196abd4440c37b13597bbf16cfef77d838a78d19d22f43034f58cc7bfe627e976c4c3be71b0a398ad80e1521847f9d046dcc85a775b3784a0445fc9982b42f8ae02383476392f7ac7f753b6bbad9e3fbcef9ce65d98ff36d9da0e09cfb46f82381613cdfe5043107d6ce35abee3486e5aadcd7e6501cd60a62f9370dbb578c14c0db45927474acd7746936a0bc14ffe46fdcdfb77fa8dde4ed29a3ebc3f43463f281a76e5daa99498b22493fb4417b4fe30f683ee3793af1b53af0984bf432730cfe410283aeb14fae1f2cda55d98d21d372a0df4b82cf7e1700263330b44c02e1b81807a77b2a2adf767a27e42ef926b6f058c938565d4a7aebc968d86b55153320df19b6018d647b883c9b8c7ba61ae814e745deed1eb0ce4a80978af148dc2148be0421739eefcc9e8e8fbdb8031a7cadf86f70aeabdd211cfe7e8a7550b5c68a77da0beda45517bf64afc3d1365a450ffb84e917a007c3bbd14a3b6e2b30b65f4e3dba836a8b986a1f906e06dc56aced1acfded02f7fb883a96b27d82d1e22f0013314da60d856975316a6be3a57ebd2c3a0ae12c5c3221dd6d12f6febe74c0442e58b793202b8331bbc28f5f5abaafc70abb897823c7474f211ced1a29b78ba1f21da11b8ef5cf0d4dd58898e0116aa3c2e5f53b3193d56ba24f82eb1fe7a4db0771c0798b8048b5561ba1f1d2ef8514a502ce784da46b39a304c90c80ad0e2dde5217c3e82244f51e30700575b8c13ce30e4df24c79051896ce1213b9db6a4d24bd01ddb0e44fbb1b3e522fab2ac50364d47d611b388e3549c0a138549d5cc0c0bb413a4108e1842ef9c4dedd1396932d1969f41b44c48231a696c5503cb20ca253c9d3c1870fad9c4ec487c266ddb74f97b85543ac863049ef9cee235319b397f254ec682f493ce0e1ef1d0f68fc40ae48ed7f7e8257f9c3a78d0c94c11811ab81b6db4c13ba33d82065d09e2f530c926e9c335b45db3a6ff09cf2f448c294b6dc6f17a38a9afda51813a1a76f8873f324bb8030afdb4161bddc0a07841a3ffd5b5c9e8756237b2622c2a1263735854546a3dec4b8317a3571e282b6d6a3d47227c833102c0127041be5008f3335edc12a9c5bb408aad568dda2438c3c71cfb9f6f077116c4a0baa053ff7d93f732e5b6a04a0656698f9fd74592a33f0807b47ca256a8c89b4d02e8c16e36f1355d963363b6cd458d654142878ec68762c24a14b4c16b0733f2c658e0837e646dee2bb95b6a72bebf6dbf661f847dc29f2f51b7ccbfc9aa8d39a6d04d89dcb6f2b079906062a3b3f996d1a9a52bd9c8772c0507e384d8eaf6e36b7f6c6a57b83a3f92183a2dd73428f588663fef35ceaf042ddd2b827d033a607c1a6b95f903fe3dbdd397ad336c31c65b784109586977859f5967ad677ba62f376ef13aa45b7838d7108157dc42a7931770952041d4049724c2c29a5be7','sync','ak',0,0,X'9a62a1b9229c383af39c199bdbcf10b382f55a9e','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(30,540009247.70696198942,540009247.70696198942,X'3c585604e87f855973731fea83e21fab9392d2fc',X'5e5d549e52b459dae5c4caefc0f48ae4bc693c2b',NULL,1,1,1,X'ad2af702eb0c7fd45ea13986b60338b8c5ca058e',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000c0a7d7efcd8a20b86a43d43afd009b9482ad1989af4c81d87fba6c7cf55eed2dfffffffffffffffffdcd665548a5803c623fff5d0e9fe39d5c5cb9343d756568c262c91eae5f16ce0a8bc58879b29358006d20bee303e137538d05115f1d70717ac0fc602e0ddf86a9329e7f82426e039193a0905ea78961c7129b6fd10fe3067b54f2e43e449a9e2c68f66797cd88a2a60c75eddd12b7530f8c8bee6be2093ba896be7513037001c8b5d16e9b2775fe08de64af87f42e7eb99c5d8ca8cf43752afd5f7686ea32071235299dc4d706589c7d00633cd2f92e7c9c13e506dbdcedf2060b5cf8a278a6e20b5a91798887f545912a3c836885684b3ba72e13963eae8423ab1fdb4fcc1e6111c9dbd9cc496640dc2fcb75a3d5748e3d9c20f3873bac5670c9df2599a0a4666924c8b6f490d0c9a12d3cda9a3df508d7fca79bf3535e027a971d2730dc24617f67311080da889d7e8c8fbfb8bf67b2ca9d2c90f84737d502de682698f69bf7405afa9e7b4bae3972ae6b887a899478489a03761e7be41e9160858ba6945f03acf7242c1695586c9efbb8fecddfcbbd46733628a8df08205bb3e4209f106ef92eb7e0c3fdeceaa7a41523704cf668b7592a2c71e5fd2d94a744f1d226bb5ab5c025aa1320856a8dc4b071d6f78ae0fcd1baaff41d51ab44354a96fe3be7202e1b9437b283961fb761e370266d98f3e429b39019b5d33cc4422ab004ef63278ef480b562c5dabf5ecc84df7f0c667f9da011c10f2e6de591f231e6d42fbf6a3bdc7102dde18db8f8626a816602d7045916170808da587a133dcc94898b5a6d1cabb9212260cc0a71fac4fcbbacb6d3d69683cfb037e335f6327ff215639ff033ee569822eb98c4b636dc68dfdb0b31c392d29b97294e865f07a93c5a58fdc22b992647d669bd85947a044c3bf828ed35c7d77d1b00bb965b03c58a2178082f4b65396c4f5aea93875d7f26ffdfe94f4623ffef383f819ca8a6158f81d9fd8f9073f18118a61dd60a0f231778c1c8874f148a61b9840f81b26532421b91116e03e2fd8f2fbd16ba1850140832d325ce8380f715154dc61784bafef0a7439117b9558057473aef1e2b7424b3ad45be88a1fd673874b76cb195783de8563c54b7bd0caf36e962afc742acbe3edb13c680dc31a9aab41ca739b54d8a18f7a990d816d970f6e10f3f18ab1eca1f97d7ebe48530d2ff6e1d43e742d21005f5419612d5c53e9ac8fb8d7aa823a3bb93c0be37a2ff36ac0034d9195c717971e10eeab3fa4e2b85d6c8622efd4349907549f4ffacdb1f299b29336117f9c4ebce8371a61e7997292bad9a06ddd6ecc44fbb3bfba9632f1d1fea0768f6048241616e6c02b276251fce9adce5eae5613eb95efef83cadadcc33c3d89e24769fc78704fd04d22e19f831ce9e56db9d51bac88bc3b37b7571cc73e477f7f5f7286a4003f546a2c48bd40c79e606056803540b6dcd2ac6d6971f6a0a65f49812254d0605064eba255a8fd88060683603bea2f16e8fee29e91226e32b90033cdbf359961cdd6083811eb2b6347bfa738bf970c486e98966193d6ed00407ad584b335cc374586077b045a5db3539001883e2d85a95bb9e9c5f78d84b5ebc3014270cc665ba6a60b08d0d1a826cc5','sync','ak',0,0,X'd0ff386a0d6ffeae54265e05a7f43660d779dae6','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(31,540009247.7490609884,540009247.7490609884,X'3c585604e87f855973731fea83e21fab9392d2fc',X'99fdfe59349928e9738ad0df3273b8af98c84667',NULL,1,1,1,X'869030dcf5b3d97e2032f936ea0827ec50b045a4',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000b2b9b6ab92c3c0e383b37c661830132ffac9b1525d453aa3adc86b822719f08bffffffffffffffff00c5a2a77ee31136d60b6e894656722334d4f56c64fd30bdd8606f29e7ee0eacd6397a69a800a64b35c1d6ec5f95e36c569d3a4cff9a0466a03785ebf0276b81e9c51f1dbececaf208ebe8cea358c0e3d10fb37063e47957b65db94ba40871e7996b63585b1cb6afc93f6dde168302ef36e92476fc2946db6f347600a840c7ce8f2baab0c780b416158320cc4cf946e4a129bee3fde53459c9a4bf492b3375c6e7be31532930ce4bf3bb3cfa2d230f3f1ceabd01cd4d32a97f47873ddd068832b61fc38d39df77e7334013692361a7b85349bdd73c1cef75bce1a4d859e512a1def3af789e0437cf451787ed146d50123e542923289e0df687a6f22ca68733f9ffd13f33c71aa62b39bc69c70de2b81c84cc2c5b20db3f7f9ee7f080a1bfd8bee947072313d91594e9cc56d0ce10d9191199a89e0878c1950c958dd63903d093cbd5821152678891e71ed33adea6906368e1306ce41598d9c53c0bd92e741fdea1be9c6cced2baaaad698a3220ba4265f91e97eff4ca37531c9c8ad925d9beaad62f20f8c810145eb3c2a8cbea790bf8fdc0729fea17ed6b21b6fd04a4140509edb099f8c1a0f5a7af8cc0932ce4e5c8a278fa6482291db646723011830f0f72d629f4e634fd52614dd7295f3fea3e8065cb093d5a7af287bb1e600a18f62294a31ad05a0c057e35e1ae22d8987b4ab197e5976022999f3c9fb12aeaa93fac4e350c4809c6a3e164c46db4cb21a0f29fa3c0bed976faff43d886e7c1a43f8d1da2c1078901763a6c497122e1337d771ea39015669a2db7be45be077b5050e45b78ce37c8a65977868c39388cf97e914ec697a5b6eb9bf1bdbe52719f638faa94063f7a7b21e80086901d75accb43505deec25842f70309c27d33fa74139b6179c0ac321333834a34879cb51ee173bba2ccb97349bc4b89c633b189a77e8a47da70b84554a3b75f9cc65628b5fa4e9ca1516cdc41136e6f5a9c40e8e56e39c7c3f15c781e301297e14182bb142f9d10bc1efe465f19da3951bbc8d116b06ce9f12bf77142d464b35f67b50ba05b909559f84109998a4c64cbd67f70b7a8ac6424265f2e33f6fee7b01f938b8e992e5dfa3df14d3b6408b0a0847977f0c62f5e65b7fb9ce37a7b928972485bb96e2b17dfe47527dbe6076ae78f513045f438733ffdb3b71fc6b6ac3e082094c12d778fbd0f836364f06e3c5e0c8146dec4642fa63f25543dd325d197cdc9cbb00795e45f95835722dd5e3dc63561022f6f8663f8ebfaaad5f28787feeaad959b4a9529099a70bbcd173c734879c248e8dcc33dd11314f359bb2e6f92de3e658ee6241eceb74f15ef6f6bd5bda23dce52999d68d3f8a8c6d46bed1918908e297d56ffd25814a0a618b0a96cbd7d9a012d7f513e2cb39448becf572bdd3c8bd60f5e7bcf9ee6b0c1e1edcceb96dd4eb5899eb8ec9a7e874426f6ea8fe13305c9316a906358a757ab9ec3fed207403c596bfae766318dcf291b679153773c4c5374387a6320d5b4771573fbdf9164fbb6c874eea081dec2adde5d1a9a2f001e56a2f386087eee3a5013d7fd5ed2f53f629a60abfbacc10404fc0f08','sync','ak',0,0,X'baf41f7fcfdd65e78feecffb5dff2f802563b55c','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(32,540009247.81093597414,540009247.81093597414,X'3c585604e87f855973731fea83e21fab9392d2fc',X'f237c1fdab441014ec4c677a3ab26766601329c9',NULL,1,1,1,X'121ee0b74c76e0d9fe804489a301ef889fbb1810',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'0300008006000000280000002c8748227f882683f39dfdc22e357cd392786a8e69cd8df2fe94a01e76303de0ffffffffffffffff2b2802af13fb8f488f5ac063705e387bd545f8a590a19aa460db02b2034ef4ffe244160424db7c64f46a52c79096b2c12e246804c581a5aa88a73c9ce5300f5559f6a4cd40118abbf229cf7abaf62f060cc72fd7ea5602804cb26e96e072d447b44b3f566b30f9b0726c520ff2fb8b1e908e4d816cac4be87bdfb3ee7162b440d5a73876d1e34abcf3bdb2c4c3ccde19784423382c2a55f40fe56a294a91c5489d5549337066af2dc9eae522090da0c63c47c01c4ed813dd364e81c14e771bebfb6687a31e9530f3f7e917f8bfaa033a97ce476619125848bbdbbad5459673fa28b39890da9135da25c78e4f84836cffe6de44b4596bfb5878ee143e3e3b2f8b654a05070e953dc4b56ca6b974a67fbba2956760ddfdd110bea5c5a74ad9c892b2b2b0f1043a4d7fffff8195e79992acb5b559684e07efa9002aaecab405ebee1513cc3debccbaf0a7946006a988b638a68c79cc9fbd17e80dccc9e4e61c4c3c89838c26bfd14abc8d0050432abfda75d13b86182b265ef1d223f6ff15cab5cdbe775760c05a2cdfd162e3a63b42a41bafc2804de2c0cfa723b95bdd1d741c7abd2e6f06c9ed1a57e55bfead3106c1c0634b54ef68003d9a219a0a75abcf9269da1c0e98c7df7b828ff169bc1c242a05af0e1a1a2f33db17917b1ab582d6c6172ecdf72b99a3fe1fb78f9db3ce2b0095e4b0d36ae95da80ef9f077f55e05e70160e4ca48812089389f9562fd3d1abd59c051c3aac00464a9b13bdf1c52b1c906d23db5bd6914ebd0080db4faba33d7121c21ab9db596fafb7675bd4872ac98f1addbe6d868122ae993355544ec8c40a0deb6301181bfbcf17c3d8098ce97c9ad172b85f5b78f7c6c5b040ab22e91b00eb8463107c53974097cd5db90df4feef29e065427cf61e4cd9ca247a9ee8f06ac209cb49759dec8d510b6e2546315c0398ab1a6a5c6870b49db728ad2e50a83687cc43e09c4d47f8925a19aa57de8db81b75bb2d267a3876c91d629fd16f9c0ba0380b66506cd8046b0578ffaefaf4245687d83dbebf61f72d8d6e3233f3460a977f833e88e2848c90f62fdb17d279b2b6b4a464efce4e491f33535783dd4bd26b1d0cde9a68bd8a0e78665099a3ef347ee6eaa67604581953e2ec3a3749a8bc59b70278436ba6808538bc3a8f618a930d689280c484db56fe8ba1c57c921f894b3cb5470c838d0679fbbf429d4de085332cfa4bb9846a1466e33d7997156d34a76e3c774525cf02c7574c34556d6c169b7bb432d28ccb20d4a2528c0b0af897a0576700e355e9f7b883f74fc7c375612c461574da55bf91eba52274bbfdd5150cc5d6bdc1e9da5eaa891f19c19d73af538dc567317e573217e9ebc75f0331632cc06d4fd3825064ea29674aa23b3c3f28ae65f6edfc63cfd9621bd642df503a64c0ccd19bf28ab4d462d5cdb3684764977f94b08611ac13814ef60ebef44550cfa4da8406b90801a82b095c69ad4da0e1c6c2602f8ea694e6e743c72f09c9f13c21cf1a0ba53191297f00658943a381cfb0428b6c0ef23cb945bf94728873d4a524ab795a8f144abf7231f3100da7f59302e91ee1804bf','sync','ak',0,0,X'6a057646fedba9f6c541f1590bbcaf66e1069458','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(33,540009247.88870799542,540009247.88870799542,X'3c585604e87f855973731fea83e21fab9392d2fc',X'f8fdca5808fd57068b26a631f9ba3d2c34536c88',NULL,1,1,1,X'de8c1ba3ea9c4c108db296178124d4750cee0828',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'0300008006000000280000000d4c1ebe16735ae5b2ec21143c7b7c7f9ef5107126cc507b55e40a3bea6bc2d1ffffffffffffffff1b9f5dbac42b7587ad06d1b0748862cafb5e635567c111b10fe9ecc48468f1935b1ae7e784936cd3a3ece172081041d69534318aa161cb0518f8d1b62b9e7a51f1e5d41dd204fa6ef1a825a3819bc2b4fa80a0a578cf41d16a4faf4eea2aacd75baeb3e122cd18d4c2d9eda9e059c411ff1d51b46062593eabd007192018804d09ce1b229d0396b1e60ed720cf69778bd1ab4d43c5f253a598737b84ea4bcf60958ccc3e617ef4acba75ed2e422c6445ad540ac0a92237dad20ed8f43fb7d67f1788bfe321dc5b34667ff6d5925d6e2517d9240410e43341f48a65d706fec31c34fd96ad28d26e99241ede416088ddabf6af32af27ec2c6d51680ea2e3f1417c0e69bbf7c72bcd5ef996cfadad94ab49cfb98adb559dd9b5ab91bf0140eb5ce7a56a23bf232364b9140339d4303ca535bfa5716cf7d0462029184078961d0ebdc6f797c98ef4c178dc4c1061b3c0bf3b34cf3aea712b09f6c93cb1534a67bdd3ba2827b60a4811b04f07c5b9ca377d31b16c7799171aea3ba417084fb26ae027cc829aedd452e2acb87d35d2b3c916b1f4efb2d2d6c5c302fa729bd4180ceaaa8916f56f2f5e1fd4b7802d14461a53ed1cf6d7e4b46ccc87aab2d5976ebe16dd66b1be8d075b4577e29f708ef889a41c4944176a91103eb9238614d53a76e35f05ed0ab5b5a013fd4ac33bbcd40f832596ca8b9d4bce993271303f3c3d8b6dfa719b5dc13f95ceceadcec718b27bcacd404045a9c7a18f81f8bf8d4edccaf432f82f6298d5d7f1da65cd53c4d22646449103bd0fa2d0d0528236fdb765e35f7178bfc86f4a1d78abc03c9363d4c30f43f178a92b16ed6a968610c2d3204db655c7e2a8d90c92c77b589213d822488d7faf828bdffafaca742af10c939714e601db58ce43b8b33348d7155537b3f570b3eedb6cce27dccf3004a6d0a5eee0d03f6c8f2248bad1ca64b5faf1593510c900b95afb463a358917565e9416d2ce9dc1b484f1dd37d5642be17d00c878dada819e5e41857893faa21b8b35efd79e30326365cd161821442be8381698496c5b13c26e2d6c4777f97c1a81b439c3d8473fe0fc381a23426717b95b46e9cd531a0255bf3041532c7a601af01160503a183fa9ccc900ff42588a1809746b2a0c9146d166f49eacecd6fee0facbef5fd88198b2a6554eba422f02bbeee83c4698e41bc65693bfcec67430563fcbdf72dae662e4db23fd1544a331322f5ccd21ad4d73e9ff29c337cceae508f8739b474468f4c1988b4d8cff22a15fefbb067801d5a159929804d2810aca1f2e10a1b3c590bf76fc568c23eced837f4cee3dfe6c2a69bf28bee572862115cd8906276ae059bf500ed01342dacffe0529f94765d644da6a0e6790dea97016e090f92b68df498f063a8ff66b939dae2f8b116ec721999c5487e52f3c578a908d6bfeee5a77db543608f74f38d6b0ea9e4cb86452485f785eb766b9439db3164bd9bc571c165e1acfb53c542dc6106fd3257bf0c162207e8e1d4027c50421a22cdf262b11e33cf93a5d1b45e32c1f6e6558c5abc09fdd997000e2c3c2b1caba572ef70ea42fdbad22b91517eca04198','sync','ak',0,0,X'e32e69d3c70375ce8d7d98861ebf2018f3759786','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(34,540009247.98529994488,540009247.98529994488,X'3c585604e87f855973731fea83e21fab9392d2fc',X'4631b17e5ce00604a8d3b2b9691cc27efb471d7c',NULL,1,1,1,X'0c973b023e62103d7355e7b1c7d2e471f99d0060',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'0300008006000000280000008dafa7a607a34f3242e1f7cc9845857dde8ff54d1b52a8af0adb23ded312818affffffffffffffffa9f17f7aa133bf3720a0f3f7c25160fb603358406770b46bec69ccfd429c3552f788d9f1e12718b6752283d7dd1ee003f25a6fbbd3d7c6e827c080c4945bf18bf11c3001699276c56509b44e3211d3a0c223a24d1df9224964fcaa6b409b5d73f0e08db1291f2ae97f0f9e53ec8de6def45bc8e4d1258ed7d0ffff95b184b4b47d7c5e2f477066898a21c829da5b8530bab6c83254c0fc4ab6104b1146e17740b393fe805cf32fcec79ebb7031dcd07aa5f7e94f296df779bcaf0ee84a0ff47c2da484cc1fb29a2f47733da9ecdc83bbff0f67cc5d7b5fb0c8543d8e9423ca97936e124a3448861f183dc03f725a6941b0f4a9affeaf4f3d446f0f8045b5fb28cdb7e3dd70ac80c931656043aa70fd5096f8a530b0b3f1fef0e8d0167f1d6c85b45bcabfbb9e16334c7d0605b15d83828b77174671a593eb5262c7a7a6034af1e05cb5d5a0876820a7a62ea192c35e96a3bf4d194c4b9e782c7405b8aacf41fe2d65ac4edd536bb2a2eed5ea494b41dc98458e7b7d8d158e55247c6b0017fc0ead0eddbfac25d40a78ec1c1704605253b0a689570b0eb9380772dc635b90f9172fd253e266b2e67f9dba82f5d1544c0746d7722bd15dc912f0eafb384e6b2cef13e37053d346b3a37d35129d8e8c8dc977b9b465c376e83bf5ee04364befdf0c61e72c3262dd04380252de0a205ac1b58bde11c4d01a05e9319862e1a31f66e7e09bd4d435621af7179ddc918542345135276c510d45c2d8405107df0984e2cd52825515ed42579720bffc8f5a6146a04c58dd94b50445c3cf9f985558652d469329381e2bc44466caa9f3ba29cf416f926057c8edd561b86539e583c610af59cfd548ab1fd4fa2ba2beec436dd946b7be16237fed49212ff385d42d3fb457585c33a31f9f31753d46aaa9244a36defd0b1571f281fab1223ff1b2b685331bb635bf5737c9b142836f375f3ce4cf8138cc51abc197fafec4db427a2b9f8c98da4587dc4953edd1628736634128bedf9393668b330548717a0890c08da36382cfec479336b94abe6a6bf114ff7a2a59b683d0724658ac315006e1a6d26be760d524d1b5c7c47737024608ee7566aba270e0ce8d155efad71c618c86047d3ec8c7d897aa51bfa2f74edeeeb9f25ca9274e4861d0e91a075280cebc2a883270ed273328cb93a004b0eb8f90050a8f9a1bc796f85db1703533f96c557ba989321e9c392bc407aca57fc3a11285935ceaeda4cdd3f8546894854374c42fa912327ba4909093220890f2a251b9c6456d2a5de09e6734dc0099dd9ffedb25f862096952a2ea59cc48771f713efc272b1ea02ee9f544cefbe2f9b855e960901a5e0ae717f8bc1f95ee34d5d1f1b5e7c58f8235124f4e17cb2b8d4a6fba1f82383f5770ce0d5c453c794749f1248990d8901d79ea9317ce82e53b34ba975d948386569206a2965b08aa5ce634e2246e673992d28a6d54d54fc9653e4a6728329ea7789809768bf0be2a53bafa3af144cbc49c3fc8939085b02b79b63b4c70d4e3a33403d4442a4a2e0b37f75fa1ca0cdb76a3ddbf6d11ce8aa1d30ced53a9e56373c0069725f81a','sync','ak',0,0,X'5e7d9ecf48f7aad9e82e8e17b1832a5aaec3a4c6','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(35,540009248.03348696232,540009248.03348696232,X'3c585604e87f855973731fea83e21fab9392d2fc',X'2cd4f1af1f630ce1912f0c46a5f745d3f8940129',NULL,1,1,1,X'76d5ab1128ef898bc3aa8e4babc0bc1cf26c479d',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000cb615bfa42ac19c9eadd5ef99020438ef69390016fcdad5519e9ee45d6a71bc0ffffffffffffffffe0119fb8775b7047fb5fc554d0671e8ceef729aaed14b63b3cf6c61fa813d68e7c5c0771dc17ed19d481052528cf27c66c066ae5f9ca1c6599f3673dcb453ea1a1e9f55cef4c4ef4f7de6045e0a7f13393ca08991826958a13047b2b5290b7f42618841b6fab42c008173d831cd2438079f43d21bdf587584e8cf84b6cdae66a4d371f7dfb984d6e6f873acd83d86e2becdf86bdf2df404a2c0dcf16827d52cc57c854c943cc18e0e00042c955ef66837d04477d2b1fe0e69a039be00c608944f2359d0fa785754dd8bb3b060c48b441e5f4b78b2acc04054788f13d4d8c7852125ccc30c69a80440f6c3ce30f389fb3ac9b295f9c190bd2884b4123afe9afebdd7eed7e16abe4dbc82c810cb51789768422d2efd9aed574c4c13e1eab0d7ca18a8b80b4880a9d40ef1eb5e475c65d4047aff89e7c85c688281d124a68b3ed661e38270b0c5b9ed0fcf7b8f3000605c19859e23aeaf3275125204540885b0bd0cc880f1496d5b9bffe9af1f838e8ad2f8fd4f65cbe3699375048bfb9c67b9f3ad9e59834833f4ae5563169de276edecb7852acf8cb744d791e98041fbc32af75be2c8b34877171b92cfc7508f4cd910b43d5bc56a3159ce6aff2f799ea04869a6034f205c1c29777dec615e6cd897350cf023b10860afe7da96f637260a1f1ebc93a3ce152e13977c284a233abeea1fec6728238a934c22936bd83b5d28ac85782e73b1486c640758c87ca94665c131c24b84164ff2b3c7910c86d7d5968d7b07331797ace3eaf179795497bc36163b7c7bfb07faf092c61f1b0090e79d72fda60c3fed29dc7b827012f062d4939c83ca01465fb90b9d41d21ccba2888f8d37fd6625d57a13011c093288c313b99d4f26b87783dab2f60df87f07899603ce4efb0b0a6cb9fef19cc15f10e2ba16f47ff752a3d9fdec02997595e2fd5238e1cd9249844f7c3b478625bdbcfea42dd2491ed8cde0856cbd3533e48423dafaa0da6b68a366e51ebf878a96ecb25fe8d83a8878720c90d9d6c42ef5d51eebaf99bba5e41d35488b5cfdba457386c453ea11be0991def21d867946dedd986071367f7edb7fcb588f83300355beb248ff21498d5188863e499c006980ab76d5b52492a8158d53849db8382594b51aceab2b51f8a2efd396453f66f21817b80128593e35ebfd9453a9f8d9048c1a6da1e9a7cb018156b42198babfc9c7a17be4bc3c51b249eb4f229a019688a6bfc48104091492842efc2700209c9f89203d3dab21e5ad7f4fe163e923b210c2cafe1bc1e3cdb39d4b0ee92be19820c5949f189cc8915fa19df8a039c4276abf5c48cdc03e50cdae7d1428c51231001b3eab94c73b16278026f66756d7b574e0f15821527304f641dfdee55cf657eca1dc13031349fc640663245f3ee1663b9aed40f5cbb5b0d0032d56ce673a7169dd594efbab8f9471f886eb77e763ee3dddc8730bab68132288aa2d7a0344048efb8306283a3379ec63ef53c56d21691f991e67ae09cf0d2765505363a47b5a59284f525cf1b913dfdb1e715e84805360da49497700f0bae979b35913652d7fc138d001140e177853b335a9037fb5b','sync','ak',0,0,X'718bcc07c07b98d3a275f2812f930b1905ae3f6a','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(36,540009248.09169495105,540009248.09169495105,X'3c585604e87f855973731fea83e21fab9392d2fc',X'ba03b2e1909c9ae7375454fbc6a2f4d66df94aee',NULL,1,1,1,X'44eb66520fe8eafaec370f97e1d7c8467392740c',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'03000080060000002800000070d6c7cb465aa50d48662388557728b11a99c5064b3f0e40e9c6d5e4bff85154ffffffffffffffffc5d4aa323d851965846a677bbc0a989190f5d53730894e18dd1fba06f6de5a0c73de9e5186fef65c6b953da4ae3ccf8cb31cd5f2bc553e0c1250ff6ce83a75c707a1170379fae5c12fb38971138a31fcd1bb401978e3e42612fc7ebb5b01c920ac2600881e70c730537855905ea09915ac3a2bcae4880146194fff63656299172746198384c5a9af8e55f74eac0573f75e5554fd3efbae004daf2f6bfc08baa33d893c323f5e015a4d656b1b01b498ad0827ec95025753bf0c37be8e8ef7b8c2deac45b7517f0eff752265ca7d33aed5a9fd7add7dcbeef393b6d6dfc3461342a5c5e9646c110847a65e2e0f46f07585ab82750095918e9ab998c476d14df8fdc73703f5a99af6ceab0c608cba513f0eaf5a2904867eb775889290cca9e30db526f97f9469635f90833ff653c06f76106b6826c7f2bac972ae564f46c040ecc06a563a914822d847ac9651e5f89e139a33fb4c96e22681ffb8e90d1d4984b2d282008991e8ec497a3378413e04d4951ec0aadd25829ff32b01651277d6f150116ffc54be50122a2e9311d0b73f354eac31f0c05bfa488f380e10faaee9a6a9388f08c5cb3d1120740a5d443fad97db970785f6adece9592f83744abaef1216b7a365fe4a3c83d5a3a84e920e81d184560badc95b77dd2e04ebb18c2ed7b0a6d4dd2abdcd8663afee5e69bcedc493e6d4370f9890068a1588368594875c9b51c2d4ba2eed0e86912106889ff42c18a460137f67fe229a7af35c00d0cb3e9ca3e9143b8db6bcfaba35bd71da21d419b5be5e5963aaf1f8a24afb8b0ac115f45d350bb80b2b6a66f822e83c46a82aa0af02c64fa30fa5d9c704444758fc9419d574f0e49075c8bdc6e781359f5bdae5634f75a62e3d7b4117dd13ec6b029a9687067b05be25d185e4be3e8ba61599f01db4695675f232cffd920d4f29d35aeeec995d6346b22af180c783c7f831b3cb0e8ecff06cd64303a81ca6da54709f5669a2100c8ae90c3d40186da47ef9219d103f65edfa054f6ce7e4caee61af3f3c6f58ad6d0bae5ac72c9364c63e45e8e66f52b503b8d2de111260936776aaf9e7628b274caf4141cfe34fecf94c3ce7abdf8edf68cbd2e09e588563256727831b913565608101ee86367d180b927a5b34056f13107d7aff5e8e0c9cecad3487627275daa58e5614200fccc6706088cbd0e56e214d7597af2f9b88c42d483efa06a5f8a181bedc481e233bd9054c590efc7f42765465c2f3d3a69c0e8fcfdc06ad23b47180654e572ae1f8b730c8f2c812832bf1098c1918401fd6169d18d41696bb1e07f50c16cb0fc5a7d29d79cb7f439d0c198156cce1b136d051bd4983c3f84a7721effa255df0e6142b07d320370c01daae3a9cbbc86336ad35d6f3ad55b828550f96c0f52aaaafd1a60c4a1f166dd34b7a70130d5d575f3fa6ba112b4542b98793404dd05cfbeaa1537de2bb05ee84de2831e5b20988da09a9d6e0b0acd3845b2a307bfb9b760f86388bff3e3118c5cf2ab03eead50c93265ee6e7541fb69e3dba4c989438862744638c1b0257f58f21cab9500a0bc3362db3c152c9cfc461d2ce6c72cb5e5f','sync','ak',0,0,X'2459f4c51dfe9cf662d3402c8b83c67a92334b00','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(37,540009248.15771901609,540009248.15771901609,X'3c585604e87f855973731fea83e21fab9392d2fc',X'aafdab94f36402c0dba1213feb30fee7ad111d9e',NULL,1,1,1,X'92b3bf04c33dbfe2f62834d7eec13d41cdec487b',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000c838ef134dc5d63841c3046ea569bedec1a8a21be7c2ffd312e50e447543f7c0ffffffffffffffffd68a1e0398c2b4e3c553cb7f46318f5874c7f99c2402d49f12748057b941ea879ec637cca418fb23de0f448abe5f40e301eb6a577d7b20de8c1df692e246e884ee4add20f1ac8b3db77d83e5287a8249977a4518a595fe3763a02fc9bd8a672575ee12945945dc9b5da42bf0e5cbfdba893aebfcd7575d111c519d7f4b6200ac4e55026c7164dd6e3f862551080b3403eb28d722c38e0fb85a982eb4752821fba9be4cda18e859584045847d680f4a7aa420033bc98f862b12d0ed7fe6ee07bbb485a6d37d2d3a9a69a8692b711f87b5f634f4945f6626a8f6a09cab1bacc1a91627ef51f3a7f29d7af8d1eeeca48a21f5abe8c0e47cdf7663a6084f6bcb5680590c5dbcffdd864f4c4bb041fb0d04a82bb65fad168a794355b27f5f78c2e0277466c8b7dc7404b72a3f79d674fa444ad8f43dcfb5f8a05439a852e289b6228587982e17aeff8b2cfd176bd25e3b92a87eea68d4651e0923c7e07d7d91513b97bbe0759eaa6ff9ae01d80d33f4d0cf6668fce039b4089423324d0915263a279eeef36064e0993da4d0995bfaaa1ea89270999a9ae5d05c2b6b345cfd2ec450132bfdc7115e3e0fb160bdea18e2cb18efe08742197a72bb36a3a9392e000b478153b428e40d936bf64ec4aa9c7ff8bf8399608f82c7188eedcff44fb7210264c07e430cf6b258895aeb38d9780745a810a807841ec846b2e27280ae52a791fa759870c66af989b9ae91c51c66e0a013d190cee476e70c9a8fbb830e5b330590d71c6a9a578a920fd9e1916a1e292c03ad43d2837106aa704d523201222f883b7f37cec66ca273c65ea216a48eed86a9552ddc2026c12edc73aab06b774d64f8b6c9c046814913669d0482e3d5594a76218639e1ae0425969bad413835cbe0da0676e1f6228dfde120c4235f188a0d7787d09c90df73d3c30074cdbf376a76861a8a5967f8caa8de1e83406c964a1b3c051b9777b7bbbb3dc0a1acb95b48a676a7a9f169062d071e5daa2f37777822477545023c61bdd4f3f7b99f738dfa121f59e97aa72bf4134363c110a3588cd41ccbfdb438ce05a4f2831a0538324df7a38be19374851e06cff1794e8ef90763b852ee442a9a4ccc727629f7ce468422a38e6b43f2e09b2d258c9ee2ed90ca08925b295767b127917767c7ff7a721ae60eb6ef9252b8d3bf7d6ebea865588a47865a3aa3c35a9b54d51ea5bcce2bb3d65d77fa9ce73b5c5a3f2c541985faa6391e483583aeaa8ea9d7a8ef4a943715566543e7d82cbcf01491a148431d8fc630e656307d43a0e98927def40eab85cec89ad15f08a541ac3948d66e997368fd5e4f866f16de30cbed52ffc4a81bc4fa547fe946513b751fc3446c4c44c7bdd8f1cf15fbcc27916f0736f5dd16945a07cc75e89178b8048a6f61c6c69b2c13aae6048d4fb57b083915b5c1c588c4001442abaefc7c9c47bfbf89ccb42c7be52dc2a4aa39b28b6fc40f5ab90911f4367dc9cc3a43d95a96a5d586e3d4393b57ecbd4a75f09ec8938d00ccdd3ee98e2699c385b4ecde1eab8f74f0f91cf8402dfc3c1dcc6a8c23a7055f14a00596d17f0a06949113aae9c13694c6','sync','ak',0,0,X'bf5cfafbe2347bfefed68b0b82421d7dac283969','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(38,540009248.20999002457,540009248.20999002457,X'3c585604e87f855973731fea83e21fab9392d2fc',X'7478d998e42061cf5f6a7538d49a442d3dc813e4',NULL,1,1,1,X'13d6f6f137bf024bb8906cfcfd3c893ad303c67b',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'0300008006000000280000003f759a8d8fc3b11160e10f0f547b041f9253fc9dff8cf9ac0d2364a7892d7717ffffffffffffffff386734a8f4d42614a354517c3b5bfbf694d2a315e18585009e04867a7ef752893c84cae14e4f54d173f9cb061a35545bae19cdd7591e9873dda6068dbf7df4487a27c17d3ae69dfe3c6f4795e22c9f33a3e2b609eeac777f6030f1e0df0892abc7136e82140e1a6248574688c09cc46dedaa89b9accad5f0d7b5c057440a95eaa38555e8f4ddfc9be6cebb985c01893182128257a2e39f9663fd6fcc83ca43695c19d912ef7baa8af392b7cf4286a0d85f683db091b616c7f68230a65d0c53e4e95a147004f5f3e8f91456f31b58ca095e8e3bee897297fed0fa3d6133aefc6a2cbbfc7d0ff104e9c56e220a8ded2aea60e47edb309995a188eef31332133cbf844ee9d6b3590731a7c16339a41bf5d1665c88bba3f7f8efc46665892c6ac8dc5338a7de2669d4b87967d14953393552b4a09018ea2eff0027e29b0bbe50d3978a22be64a7c390ca4ba612eaf39dad5f202056647d42f2d7afa8c6fe064e2eab1ffebc98fecdf60522ce8b8d3a39d9bc2cf05df47cbc1cc9b27c5d25294d144de41a028501f0a25f38caf84d0799dba032c7cb1d72a855141e0845dc5ce23b9752afa727ebb18f41e11de7b90d0ca3767b34280c22ed059a2b897592423b9fa4f4519613d3244e7aae1151c3e9382b7ad9a4d188e9943b263d56d669a25c73187c8afaa0f5bc456f55089b2d1d39a7ab997d3e3341a0a69730ce2bac40a1fa48dc33e9a5d84a9f45a666b729683052e7670168ac550365cd33a215f32a20bb64667de8f0013c88e9f9e38f23c49625c9c403db233e6095b11d2d961e50e245e5c67a33cc252506482ed5dc1bd8c324fce5ee27c3d9253dd9c7e57106ccf4e221aa14940f143c748896f1cd3f74e59a39576fdc9347692e51dfe4d4ede3c0660c48d9a6c2cf26cc25f989f5e16fa0d153591a60f85b699f3a44b7451dceb6ac5fbded680cc6495c34672d106355d683deb03541d3f7871f48c325c6444a8836ebd4e0c92caaa5914d11ff6eba33554b7b02502da560775725ca51c43025b48e7d6b5692a6e431acafdfbaffe6f86c6e111f9015e47b8b11543baf1020eb34967aca74a264002cc52bd707fd82fcd971e9319fa294ef736b632483d5dfd42676b66a4ec4df63a8316498e3197657c4d65f2da0ea8821443ea1796468b458f65d00ffe4814978a3eaadd36261e3f00af65f4890af576576c7f242d3fcd0d02ed1d981150a27220fc44f2a47538a26eca5ee564d68f34a333533048c59b1d72187cd94079bfea235b66b464287c3ade48f8c5083568b1be7c3372951d75ddc7cb6de210b7199c6908791464eb4de38b39a24eb999c554752ee5e17f5b5a6d1a2d68b6bb218bae75124293d15fde62945efb51a624eb7c7ee51077985f68fb02197bc87aa07a5f8e7c3dfff2609ae90ac9988ffcf59ad139fa7a1168e3eba3477752bbeaae582b85a6d0ab5e003a95c61b89c8f7ae1db4466b976c5d5985491fa518bca2873ab708eda98f9f0b0331fa98d85691f7aca97c71aa5ff383ff19feda2165d2ba14e6004609b18ee3034b51ffbaef1dd1e57a2958679818ab76e9da243599ccb3a672a','sync','ak',0,0,X'365aec9adbd4ffebc74782a5f1c64baaeed8912d','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(39,540009248.27032601833,540009248.27032601833,X'3c585604e87f855973731fea83e21fab9392d2fc',X'6c498326893a1920377c7a35a5206c03c3b8f130',NULL,1,1,1,X'd7dd2a6f5887a9291d26a99b1076a2986b05b062',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000e33b7388e66bb46179ba96dca8c26259ae0fdb2159966c49e295fe70092fd6e1ffffffffffffffff90455fed1f24b4c8448f624c87ec8101aedaab96985b56a256f3364089a425cb3dccc6346e145db74d7e3d2690d488f6f05dc6fa754f2e860b937cce0ca0c576adbea0c4fb60731292e09478a3bd2e7147e9ac31b9caba970e4e4b430c054a4e044de67edc0cb16e3adfb254799581e299dcb6625b325536fff1072361a1da178562336d438db1fc5fba80cf83a20de8f315af7078ca7e69c0f3d924bcca25dc7d25a90f6cc820e325cf4f186a4ba1d8a2acbabaf841c10fac073b9bb83450fcd88d3ff8fca9051207c91143499ab6eaaa4a675412c3bfb9ce6a96fd5b83bdd7bfa8542e9b6c87d473bcb8f43577d77e372134bd0ceb6228598f37ce2f3e43466544273d027c655ff8392cbdc727a43013cd710af5859294a359332481e30d9707aa1289a83a2f2b9f8ed5626d5f2cdd41436c10c58be3997022094614585a04745df15752dc5bcf8a0fbc3b358d4cf46f5849f17a34ec0ede99caba960efac82440da532958894f5142524b252a561b3bd043cf9e594cf7fe8c9f557a44eaf036e44bbdcccd1068a9ab6926e60c341c587ccf9743bf2d88ab6da50b1ce619cc2cdc19789eb72851d862526d8fffbf31e61ec36eb50352d3f6e7a92abf7ee7df4191da21d089c6554b201079dfcbf5550da7fce86ac59ab090b66bcfd361a0c0b12a5a8b974cabe8bf2a54f5c11bdf655623a6a1298687c83d0a0103c5b2e6e7853cc3b0f7b89bf0774730154835aeddf97b86388190f95be4fef8a5ea1a66d82c7d3dd44f9eb61b9a49a87c6a355adee6d277a4329ab0ae3e208fed5908c9728777e7e4baecf3b1a278b1b91de6287be619a904f6a750408d67d96bd057947b77d4e3939c78496dbacecc5d8b2c03c4a23bd8823d318e83cdb7eb0f9156d5772368d6f26238d7ce399d5d9d7fc6e1d324445c5f5ca2a98e8c6ae2bac66a591751a17b2099d6b8345e95443f60ea52e67222893dd06a92e96eaeb522eea80169591d2c8c4745af5a60707acf22fee3c4d52b1a9c2f6f6670219ede56e4fdc41e50877c05f1bbfed8f6ad2e7214437f02112967440038d213d97a6fc0a8d1cc25a5e7225c472cc026f5897fa24817d0adfd36e3e21ff0027d629eb4174d0b41d51940ba8e68631f54eafbaa733237398dedbb0036c8855454802bd390ae91d792e96b23b40b13143dbef5874b8756a49b2383e6934189e5065170c7435bddc4f2049a0a449dc518609fd57b1488f1efe1579da2329cb5ffde34e0f37e69fca798dfe6a994b34ba6f9f6061cd533df63450cf444683917ba5b57b04b4056ec3a88062fe164eaf8e048c4a66ea400dca106ba19211a86416c973ce696f9f30d2adfdaa5d1f6229c2e8a2c7c6e76becc728e77b9d7a9b9d5011645b9cf453ec81e104677d085cba7010be48078809a033f9b005403496f15d3fe0b723d8162a0f395b6323a375020ec11d4dad9ae3369fb593606cef8ceeb3ededd57f02e7b6272f5abb015a286ea28d71acd2ef27e5a2ab5448d0b45e0f9f99a2ba388abbd88c5a9853054058944b0f04a1a62a7ca93b64132b827a115989a958753156ca6873740859b6721b107b237','sync','ak',0,0,X'a945392868f0e61f716c61bdda7a40d759a34138','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(40,540009248.34564304351,540009248.34564304351,X'3c585604e87f855973731fea83e21fab9392d2fc',X'014de7d3657cabb3fd84c5011d5e4a67c366e8a3',NULL,1,1,1,X'dae6654459a08dfdbabc1c0642ba1846cc3fa42f',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000826ed464ca2728a956a1a00ba15a8bc193fe7d92a52fde2e8854a75c123691e5ffffffffffffffff754addfd88e8a105cccc90f47988567cfcd03b752780ffdfc31c0c244957e36702a7807a5fb4baf3bf7f7f97fa023490f26ac5df7ec36b4b8fae4af96ef66ef33bbbbf7add42c6fb999a531c7e304f0e1d51f13b99ddca3e435240f9eac1f13a3b81985a8ec9faeeb00c776b6b4256d01aef910aef355582b3b8030fbdada24da300e3d3af922134da432216101af38fd6b3e315a1f52a1ab8b495c1382a461c67df78d77d775e994e2c303ef41564cd46368178744a94ecf0f40cf1d60bdea525740c3d3a5c3093088f5b3ad3a76426ce0688dcca467d6517fa4a5682f72468e8ebf81ed26e013048c613d134e507daf8d1369eb420446fe2cd2c6ec300b5a944743a4a89035848dff70544df26c45dddb07a141c0655ea1c4196a72434bd7c93146e4ee573d1018c39e3549e708396b5c1c52af0b32d3530ab06321ab33fbe53c1889fa99fb9ee04cdcd09628cb357537d145167980b2aab1d30ff63df5744cb5bef6410e60e30d7cc4ed29ac119255c9fba07a29e0544210e0fcf7d4192852bc9a53bc2f90ded6fe01f03809e63de14ce882d01e8da80a9927c0d826353dac7dfebf6c5b1e9b042258a2114dfa67e8f87e85f7d12dc27892a11adf20cf12be27736896d8a90885ab2cb595bc9c2e7725807c8c1ba8a5be8572d0f0c0f5c3b0d08b16af255ae438a8d53413a828972694d8346ae4707a5241f3d38d7e2040c98c759cf185f28c30a93b1c773353e7a3ee5d5ae6898510a6491c680068c4cfd853621ab11b47abec629e97a81e0e72858c3e4bb9b2e85589d9f53f67b8cbdf6f06d1f2b6812f2fa0c6833acc036e5dd16949250c9edc899f688da3f2f1805cd1dffa71cbe80cfa187ab284895662b32986de9372c8616c09b5211887f99238b48717748ef00c6ba49d262c4b07ed9f2739effa819b75c0b4e1b07bed2030d066941114728e456e6681ba6e8c1175f2df2a423772f03b369437bb78a8065eb412b4d6ac7cc382d47942fdac3fb362c5920e2f480e376ffc559ca30cfbf387edf5c27e7651253a587925e2305b35f9e138e7c76c89b1bf5e53f12934e13a591e68861a9a038f02303f4d9302781ebc7818293f13d420825c136576becbaf510752992e44f40b9663f97be251c05ad3e54d1b07283149003dbb3006afdc8d25c172df0a01343843152087412f2b4460738c03b4844412f7e7de9fed7e658b7bda2a23b3b0db01abdf23f1d75130356c69f0347e17dcb08fcf91b51b298e89975a13f6db8e755a6b565e75ad69fe34e6123359ff53366111294eaa0eb08dd2626ca6fdd444fcbd3e94150f3ac73169eb484d8589222feff21c8f074568f64d434663c953ea0335d850a6f05b01837ae3ca9d03f06f27aa4900da9cad42195a4dbb7bd81f437e731348ac736b195dc9764e4b411d364b27cc5f16dcb5fee40036bc992a328927d60c68a1696d6f1f4244462eb03efb365a53fa8e712796fecc29915b57227b54dd981dc6f319ee699544961317989b094ed46dbfe8f297e8768d8c08375630bf099d5910f8e7570abfd3e00495e2f67d21c10197a7571f9117463b3dd52debe3ffa0e6f6f','sync','ak',0,0,X'c9f75feade79d28b7a393b23accc1a230c6d0de8','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(41,540009248.39385795591,540009248.39385795591,X'3c585604e87f855973731fea83e21fab9392d2fc',X'1100dfeba7e2286479b530628c4fc8eefe42ffe7',NULL,1,1,1,X'1a8d191b0bf7c44ff48077c9fb60b0b1c1f7d239',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000825472c5a0c7a8e0ab04ec38362c37676fe200bd33f7846722bb3edc3d33af50ffffffffffffffffeec520dc689dc6e0f163017309c82ebb27096e45783b665f9830b06405752369d508c72772fc7e6db5f23adf2b00859b08c5d6c1131fc536cb3fc869c1309a5d403594069f8cd28a202940ba0226c2cb9d7ef88a486796c0601d7b40c290be79f9a9185e1aa1f5c07d9cfe06a6d76e545d0c7cbbec4b0de463b38b7b57f17954f0e812f62222fb80c5b54c72c077a031fb244cad23a2688fafcca8371317b56f04dfce21731c81f5c704a9ff13a4f4cb797f85fda78e989f13de7626c02282a603240fa43cbbe59dba9346a7f247ad4551b2dbcf75a68ade35f2fe92b96d176b13d42a1a8dccb0ca6982c6df408a74dafd2f0ee12a0ae6f6f5d2e251826bac696b434748d539237c66830475ff83fa079181130c555c2a911ef9e0d40702985851727ec8622c047cb07825f30bce5ecc77926de91c39741922cb664089e5968a83cd68eec4a1622639e9cebe9a2f2abd94a68fa3688e52626f0a158063d29d0f1744a648b55e3734057a758aa449e09efd2cb3e12fbe0a65b5e76f546b57fc602e76097a0488acbef698f430518bd6cd264f4ab3e64d47fbdf385bc849ae0b018d1385f7d7741fa533d4fafd7c98025fca1b0f51237a982c65b86de7ad832f18d0704cb30ac759d20af15839c73ec213d37e33b013f9113c9966332df23a38127ecc042748d317926a2ef2bf665122746090d5a6b7e2aaa204331ece082a4af145040dbfae3a743d73e59397507cf6cfd8f9f6600b52fa7aec7c372b6d2b22cd1a5a1aafc9a4cd2ffe03377b744f958c5757939664cb854eab81249372fe1b9d054b2af8a6a48a5ab5db55af2722795c9ee43d27a563a64bd66a8f2689e0b53acd6bf82a5b2be6aaee8d0a1d6c0d2679c0e5fcf29529daa56e32d68f173061dbb62c6f0e59eba801bda1590eb78ed1222096a9691b9ca8763282fc83f6a629a853f8801b9b5622e74dd711d27a92331a9d100c1705089f642eda0ed1d8f41e6e2a0ed238354c5700b29fc02948c133705e61a77bf9d093e79068359015300a40a5a8d89dc6d956f17d1b6912e2879c2b05aeac69561f2342623475fd63dcb8b689cfc3a2598be1ffcbb539ea0793d7acbd58af4892da7a55b45440429b4093b237331b77fdff7a58ae14a43ea0ce7b3ce57f493f2b72a66908fddcb372d8c3962ebd365cc7f62910f98f4bfad13bf198922db67d040a859683bce67f4146b9f61b2440f42f5b8a2155318c5d5a9b1088b7f5c590f50bf0edbb059630abad60535351ecd2d4a29a4238836a55c858ead13a929913ccef78e5c9903434037079ad36d27c5f95b54993328b6a2a06b901428a396d47b65f45b540eab021e23abb7a4056b427244b28f3455a3b831e51f9061af5dbdebfa57b637a45b797fdc3c6080b5eea9eefe10ff0b95357108b69e3487a6df34a3e4db028ec5909b210384eb17e1e9161d67c927792d25ccde26643c1d9f438f33642f99f09579704603d9b131de8bd88759fca60291b81edc5eda00fbcd86fe16fedd54ee5b43f1d81743b0c9c780a12cfabcad27732c91501925da18f288993df692025d86bd0438d5994d492b96183c5f0','sync','ak',0,0,X'49654b3d29faf2d84085c746734d588315a7202f','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(42,540009248.50240600108,540009248.50240600108,X'3c585604e87f855973731fea83e21fab9392d2fc',X'c4a1f453662bbf3ebb18128793afad059c129dd5',NULL,1,1,1,X'e880819d6a52c8d1c80c09603a49d410137f13f1',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000d59ee11b1f5f3fca6e7fe9e135ccf9c88c9971b504d88179f30c51ff4a976097ffffffffffffffff71328dacc539b19e6610228340d74b8f206cf3fba2a125b257ac15ce68e80b5b7633824b5f4a78ab0fd40a0bc458e0d1d0a5ccf355e0f4256785050aa0aea70e9534df0588ea46abbf3cab4ad72cb1965d664c897bb7a8333bd9fb9f8ec1ea3b11f0f56cd95db68a0ba1a6090a8b5519097a92415ca02cb2c8d318a668a317fd4c9708dbdffac3e8862dde63708bee6f441095c8a6d48edcead29e4cc3bcf2d412207ae9afdda79eeb11fc6d37d26836e11b5c3bd9db8cce7b2059b1090bb63d8601a1413f0f03eee5576e95a0ceaa8a83d224f5f22e518b62c8f9a3a15119f3f9ce4adb1b4cadda8975b64640c9199d6809c3ed15d646acf942cea77a5f8d25e61f17208d424153b1d9920f2ce5996245b367688289c919f3b665c8e62100b6932d86e029141f711488db1d0a643d30209968816ffb356e50d33b83746fba53d253cc5ca89d84bea2d24a490c0e71b6b938a8a4c8f143e0ce206a58d886e912e40af3a4ea3961819a7ef2dd64be75a34c1fe5600bf9f00a2bacd7b2c7d70a49d4cf6d1a89d8ef96652f9c408e3c2043113abb28e7125a100c911aeb811cdf8520c7fba3ee5c6cf66253beb2f284cb162c94b67fc14043bea99377c542ea63ffedc06acd4b399a327a5ca9358f3ff768b14cba3127cf2051ba47f17dae1bbf595d930e96a02a44f1c4089ecdc3363c50165a371069936e6e490e30ea1ac08d99e5144978b7e7a0e5b623163887bb2b456c16af4958f13650390571d90429f28f1a405ebc518fe4152e5c7ee4b999fea962879b4dfc2f518d3d278f13363737f33a698893c8801a683a0fb370273928ba1512c9a56d40175b2534c87e6edab6ceb08e14900427a925eb5e1c199757ad7ef00a64b3e239fdd5e352aa8e8be9e8948c6c3c3b52da2633161c1685e27799d660793a0ac8f0abdea7761477c5685655b4a6e5ccf968f663efdfc3b57a0d066239e6d474e11d046d61b8557ab3e0bcc6e8e6b221e0aec713a73ff4f8599fc4c7ad8f7232efd0d37154b0cc4cdd73e73a87835a9647b95fa8688d4d4064095d4a6da57bd94f8de3f748e2aef2de10a308a326def73f30ca23871ea25e54dc243b049c14d12ae995121da2345b9e02234f54c0a798c9554d5ebbcea7a7da4adf0b83f04e8b218786ead26d83eea91700a37940174dc9f0bef8d94e0069b5447134c2231e0fd00dbbdbb0f5a04e1e177abcc50c6d0d712eabaaefabe33b1471940135036aad96e2ad8f43c595df8c6ad4c19e3a8878b1708fa5f16b7d78ba1d557ed1f3d5ca496b81bf740e56d6674ccbc8fa25e2a2e1d5477b5dc9ad376305cb8c248f84eed420bc6ba2d3a53ef050489681c6d3d0fdec37939a57e72374af900381c7ff255a6dba637f53a67d804d5d02b430e24186b860613b2192da5a06f38d9df35675b8d65dfbf3fdda83d69efba854fbc64bad2a350de535e6cc5d1b825e0bcfbfee681314e7759abc3785b0117b9f05d382e78d142c610964365023708eedcd8978a7ca2562dca7fef6ed1de708d25ecf978d0397f3177f8cf06a591e724cffbf0365ba811dc8587989551be54233423cd36118','sync','ak',0,0,X'dd63841f0f9503f06cb72731db948d1ce0d60f92','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(43,540009248.5388059616,540009248.5388059616,X'3c585604e87f855973731fea83e21fab9392d2fc',X'8f2a41b73b30f3b029e935864cdefc8c6fcc1703',NULL,1,1,1,X'43ab1e4d92b3ca044f82071be19a1e6df4b3fc1a',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'0300008006000000280000007cd2daf7eebdd3c5b7471dbdd8bf07b7a78561e6a33032b77e90ecba0eed2d1fffffffffffffffff27ccc3ab6eb9cffa0d9b3c8ec701b21161fffe57936561cb68b3a74bc4a7a01a20ea9cc33465d56d0446fd27ad735343b3b5501337b604cbfe636c6125eefdaf2a27059757ec334b95315d7f56b33db100616ade57534088195859452c07983a068961bf44d9fe875d8b7803e894eef174d5e9ea3bbd92c2870f3e47b24e9d053688dc0e281a42e399b29383737416adc8af8feb5c5f045d9e1fbf17020363184a639b50d8bf3d4ab643fd5a2fcbdbb1ae30b0f98867d072311be6531b6d0d7d6f1adacbe23f978628c6fd9e150f19f18bd5de4a9022b041d5a1d5f4ac857ec6d9052d55c7603f338ecaccd396885ab783ab8218c95712cc84b4b590c3de3f09decaf4416e5c2b7ec2102cd579b36fe7aac7030197bf297eabfb1d1ec66bc6858c2bc92200c696a827ae5e50a8fcf6dd19728a43dc1ad53b1dc3bed561e60a08cbc078552c563b04e9c7dd239b22eb2f8cbd1a7f2fec2aa02548abd8fa3aa576c517c410f6730775faf1aba8cb8b3ce4479b3437d4569f552e236c60505007ee44bf33187049225de953abfbc7806cd5631651edd32f801d92aefcca8f7a6359df2f868af218bc7665e9190d01ea150488343bbb49b44d2f23ae1721cb851981873b5595ae4ff8e54f5334ec19ad68e95c37cf556a376b12df3373400c1d5c34386c3432826bc8c044eb6a3b30b9dc1405a9a2bc17e2e1f6cbc4240ca09b7d5f05d2499cd5953e0dfbd7c00fc9f075e8962697a4170c1412050ff615e89d77896d8dd40b60bf8ace95a5d4116cbee09b8286919f1e3b658f40ea836d2605e1731e3cd61e213dc3c6bdf7f244867522f1f96d8cda8b44e3bca0e0ab09ce884a49e863573bc29d7bc4fe2f9a316ea45b87981a3eafd2db6a8850c72542e6b8fcc0c3113a176457b620695af7ee9c74729f74029b9a0983b75d4d044e880321248ffd87ece2e004b194eae90c7f87ad387a6a8b9458b3204133e953902773b4bf0741803053252a30d3d9c8bdcd4e8c092df777fd549fe95102fbfa92df3eb22642c8a1799b10c62a67e9249e89d93826f9de33e74fc7f97aee3ad9cb6740c226b884753357de72ebbdef9cce69ba11254b4505ffe65c6f6c5cbaef7d1c069f81b3ecc9e5b1a582a73c50a94a19d4739eb3e7e69b240f3a2a7db0d448aa426695dd8912df55586d196a2c24cbd61a0efe33b3502618059ca495701d7b44a5924118f3b618958f825d657f8c30512d0558dca36132d44a57c554443adc30621e1a0b06c9b19f030eab668fc681d593c849c6b3602f35b89dd0153694a4b88cb218d168c8be799ad1e955484de339a9eb3b8d958a930089abedc90f811c3399049752a7b79b7629188be26947ee826c5bdc4e353d31f459470210aa913de4a7ed70f8eed052b389d46c4691b5fa2dc10053e4b96d64765b5b0cc3947bde1a06c7587ec83b750dd8dc7c7a9f2eeea52083b3f57d3a32ac919de4894c03205e5a527498ccb5c9d131bec045c2f67020838eb0f681aff3e65cb3e0e0d26154272f56d9bca00075229d5c0097e3c9efcaa3299e89c5667f07be46f1e4a88f51b4d3d171fb7487120ccd1e62','sync','ak',0,0,X'772f831c8f0d2c5e705fc8310b68b49dd20d743a','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(44,540009248.59195899964,540009248.59195899964,X'3c585604e87f855973731fea83e21fab9392d2fc',X'84ad88d2e855b268a74aadef0df73b058c533650',NULL,1,1,1,X'6c250285bf047a5751399f34470399c03b75061c',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'0300008006000000280000000bf32371f6d6a94b775bd10b2406125c909cba179ba9fa39c8dca7795cde06b9ffffffffffffffffa9d79c7b40ba0db6f8a6534d750888cb0a9554e5a004b31c8f4f57b8f1dd58b5c00e03114e42a789e0b39c550e07cf46b5e36500bf2d2900e1de973364077827a44a1b0e18f8a1c25e3f12641cbb73c775b8333ed4ee3ae597206ba98aae865abcee1cc4c3ee69653710743f79fc8f939e2b39749a9020176397bed784dfbb0457c5c7849c5ce898aeba9edf81b070b1292854c0b53bc343b37a31615b5ef74581c00470818c513d068ad150210a072042a858316b32918e65c5c9b8b308057a994c24ded6a8a7f809d7db771a71dbdecee7ee7c3ce7b9d6391a26040f60719b4e491b742a1e4088be098cd960d4e3bcda19c5c75a67026aa57d7bf0d0ee25b5a6b39875d0dc040164d6d872627a34d56a0b85e3607ffd71ec6bee11a1b61db3ba2e6a3842942ac46ab7df6aa8cb76b4551cedb9839c887a156a93a6cb4fe091bd5c68efc9cbb1c867f73ce9f59d10e77ace546f7348cc28aa28da1069a39eca5cf8f27df041187808b6a3ae966ca3434fb0e7dce74d4059cc28a12d40a4780832fcd35ef47449d45e51b40f9ba4df43dafe465ca424422068d35017cf2c1ee0b319cc1d5cce568daaaae70eac630788dcaf79feec841fa580ae72aca01acdc8f06bba16eaf4dfb93bebd28cc1612b7d7ca0424817212bddf7305106f8a8468a9010bdcb73fdba0344ab0c336291e2ae31381f118845efbc531ede2c4fdb31d2e48de766f51c8aaa6448ccefdec4837173a01fb1ebda0e39c2db92a7694968e1bbe7ea11e3fdd9be65ca25697f8c4376f2c736e43fdbac696ce904a7b6f0b8610882480f26248ecb428e39d14f9d8d9facd83ff4c921ba188b1eddd6b0822fac2d936957f197e206fc8204477cd456b839fff57b522d313c74a34e5f53cca080c600f82a427d5e1e3452b8818fecf451780c824acf120a53575f9062a9db62c74c1e9185758b124f852771fc68d62b8b0e76595eabac0d89c3f49643eb039c29d244f5c9de4a363988ae53c0910a04ae34e02fa899c1971f20c32b361ec70a3bf410fc361dd25c79563e398c02a582e3895fdc0005f40c5faf79202099c11904c1096e5f55bbbfe35a25640c1254f890156218999e48b689fae0699f2ecffb5e24d8c4f4429e038c418ebac402639e76ee6348d31eef5cc3aa0d2d15ab82402a4aaab59e4923acb0c506140cbc9121e2b7fe2c4292d4e7ad57d54049e7042bec591271a150645a493e0284278750ef9e8192d799d7fa1146853387d9690c27958cb52d9fb3290c7a69798ab25c687582d2e0275f6c630c463fd5815a8cac6eb58e103c3cf96178d26f4583d232e8bf9828305be2e77a4544d2fcab4a897d62ec081c6e0527e4a976c88d53880f248ea0ec930460e54f499cf7d637b57418b1ed3ba8e80ea7c82f6218b534b2914ac230b3ff306619745785911689dfb5f962ae6fe54db03f0fcee53523316362c316b0517deab0460e7b9b44d9e4647a86b612599692ab6c4fda34f6cd7d59f754759432428e8bb2878f7f8536ec95a828f33bc2dd0cd1574ef5dd9b0e243db6c0316ff2f262e4b00fde2708e24ecc170e4a2945c24dae969b97','sync','ak',0,0,X'2fc5c1e61e9e01d3090974c701256e78c5717f3c','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(45,540009248.67277097702,540009248.67277097702,X'3c585604e87f855973731fea83e21fab9392d2fc',X'f30eb1e9a890195c52f60709a8edeefe4715c538',NULL,1,1,1,X'38f1fc5e9d8dcafcfcb5283d5ceeaf86527f364e',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'03000080060000002800000008fffa9d415631a70fa3e97bd0cc834861c3b63e0f0989d1bf86c0b367fd47c3ffffffffffffffff4c10e49d13133b4afca137c14965fdde264d5c6c35d9e6e4b2f8c083bb0722c6e0ece1c6afa7bf185198fa46c25dac328b7f713576d6f71a59335dbffd0c9bfc2e2ce0b296633dc5ffef7326045e223f06426d40a47540d8deb30b57e2a9cb99ccc689083a93e77139a7fb66d11712c83ef0f872d2e6b22f22fe6b7e8907322e23e27f1931c367fab27ce4e91f0e36c860c61ec6f8795d36fb0515f82f3dd3257d4dc3fba53e2fa815b4c2ffba5e392cdf0a0c48c103943db0f8ed7e2078b0603d5f82f7966d0a6918c1976a4126c40a74f427f2dce021555c7e555549a6a420676da2cd5798ce79875c8b5ab2f96238062eb60c33be8fe927d7749f4fb4f21a8077f1fd312e14b8ad92c72a10f2aca022881288cc243b2630d78a4bdc581201a2b1ff6123d49280e60c3780efd5bcb3b4295d4ece13de058e5d202bcbf891f337661e36e230f2579ee38659541d70d71a28f1a1d41c49499f3597ce640168c425439d9c70e083001639da033deaac2569d766bd4301ca432dbecd50cdd85f1b44c667f6970d8ed793242f97948b119ac0a71de0e744c5ea011fc9b367e876ac74663f6790d1cc1970b36d041c57e09b087c56ad6c13de211644a5214be3f0c507a5def884d54f6b596e420ba25cbe3b748a82ee7cf7bc0a747ceceba20efa4e9ce0458c1b27a777adadedd8eb6138152e20788c14541194a99d80b8688560e7c14f54e4ed9ff9520839dd72b686b1407ce5c22d535a10e2a9dca9a8a944ab0152e9799b683eafef583dee3a0d9352142b44742000934e6c02136ba6b634284ec6a16480f6fe1cbdc4bc7256960d245da7a09c5ffe6ae9ac2e4596230842277440e41b503dfdb6db1c028defc544e8fce196e51c3993fa78413387841b373bd9d55e9e7358c1732fa9a202a1d17018d7607b080b3bb87d7ef9871812bd36e72433e89ca0e231498af795767053587239c462c6fbd734661ea0bfe834323813b40a956b6b0492c5fd2913137c7071ccf77a8083e4397d3dfd55525f7a19e95e0f5b278a9f23fdd0d7b130681a509d2663db5958051886c93ca4ac5f5dd90127b2f2a497f516c25549922d8c681f30bb730e0839585c6c2ba1d1c0222c7ff7db1c5ca38edb9ad9d4e92a5e1c9085918982b5e94364352a6e9d1ffdba08130cc10c70bb6e32a5c5465afcf3a52a0c30461b80111a1cd6a4e2f28107902059bc9a0be6d9c2e5c868a9f94db93e042913ed4730702220e5cf22b2e61dd8dca6e8b880d8f2c97616d96236d989f4dd283bd493f14d9c1f7236ce23f22a659360315b76b91869b208a8cea2cf080b3920dcf750cf4bfb7b09219a976aee4815a7a20b29700bfe3ec5a10acb6ca7e561fcd64b7b7e53afc68544ed871aa2b1300e95ec2ac39f5291f306ce27cae5d590486d457fdd0aeb5ca3e2c4a5cf0a612aa4a9c69a3aa3274931557589345bf2f03ef40750be0f360aa75e2d4eeca328d0e913c22c2a33dce5ed4b6cd311dc9a3e7b35ca0da31b6f5855911e2409c79d2b581037174a8a1f1e88799a5cfc43570c3ea010a41478b394ef53fbcdc3c5d1336278468c6cc91d74c6e9','sync','ak',0,0,X'679577bdbdda37b15de9cba129e23e549b1a004c','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(46,540009248.73954999445,540009248.73954999445,X'3c585604e87f855973731fea83e21fab9392d2fc',X'83cb86811c2df44980ceed332adee9447b9031e4',NULL,1,1,1,X'832e0d541a80ff89ba43bd71ef289c78d435b8ed',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'0300008006000000280000002c6452bb76182baeaae87e602f1c927538057137b86dd9a3f21524341a75dfe1fffffffffffffffff3dfc120ec4cdcfae5ca3c3111377ed552fbc9ab4361d00da5bb528c60a08f7abf757fc3a6d5c46aa8ef73ea15ff6fe52b1684240a5ec9db7a2481a295f476440fb77d93464dff613e23cba9ef4297272c9a4d313336fec9eb1ad435626360bccc2059fa68668951cf0263f6dd08f9fc5ba0e4ed5b5e717e4668e7dcd5b473fbf23a092a81ca6c7a6a1ad0ebd12461c75357b913ab12a0e37b1ad28c390ca5b6508a5cfa98e5b090a4d8dd3880aad5c50d25e79e6e1b3adc30dc9bddf6148a53207ef8f39a3d53cfc302655b1c9acce9a113e51ead4668d7789ba02e9c05e8ecd65f70db8c5a0fb4653f895218c10f871a3acf2e9956f9ad5bc2cc80ee67c40e606f5f90002e88137095fe069c2035fa55151acfafd8d2cddc111f66bc10900e37f21ac405cd2bff4b7209aa454cb3f78f8f152fb9a331137f9f25c8f260a4a63133ce6e973dca7804fc83d8617bdb564e6c8a8c6c31c6170d7661314841a9b180f79a6296570585fd7e7f1123ef822ec214e5ccb404af4257b4d318e6ff2dab782d590db23f8e422005d77a26c7741fb964c9ec7bf1865bdad7a861496100dc414d82fb74d8b5cdc69a4729e0e959ef800760d87bfc876ed0025edcc78d2744f11d855f2b4760a6c8c674ac7d3422228da1fe0f259032c0d6cbc1894c74369fa6f6bf4bafa890d29782ba78d795c280336186a35aeec3ee8b979702c1e322fec3fa8814fa1f902de6f7166415c8a986a1bac8c07c9e7a3f5885454da8c800eef1ea71f9e74fb3098dfdcf6cc9a98018342b77f17f65d72af9efac3dc79649a04be2c9e6038053e4fd15a0ba8a4f06961c34eb50a4fb7231d9c44dcf9ad428f19e2d9ea36c4e4ad679f279949074e8f359a486df12d6457fc4f73c2438525ee06ca0da504ef4882d0c2eee9443a44c9932d437a0c5ca1caa6af4f80c89f036dfe30ac8cf09d4552729c0849ecd8d0c42a6eb260567f61dff894ee58b2e737b15a0869d025b99877c31ab3ae814ac68e2608417c97507e13ca39f8194f75dd43a2c6c9a132f76bf8c3afd096597177bfd6e7477e9e1f7195c0a1351ccf1221460012e8afcd84087af13448ecd58e9fc69c8d3d0d7ac387f39deace14c181af17d3d121c19d9ed1be882f16de4236b255111a4b01be66aaf0dc44f26b05c6a6f4b631f33f1fd0261a5e6f100197c13df31a69d13ab34d4e7d5b6c7cc1b742be71d66b290002b0dabed9e5311c0906eaa3a514cec627b4773be530b6182ad50065ad9dd251bacee41ef3523500f567cf56a17f5641bcce8a44b54c322ac15f73bc1b6a264716ca1d468d7b8afe2f9e44517c0c80d33afd3c1588f3a7659ab1053be61a43e8ffc57e99ed5d250425790e0bb466f682dbbdf6c7b5ba2a1d8c2db340ac26e76644550d4a317c850dda45c37ef03f71d2a2d5c84ae7168c854e315fc23ead9ba35e578126abe230180c5473ff452928f1809fe9b5f850b0fad0e4762d1cd90977c5b2b5eebf5c99480e4d12bad61b5fca96a01437cfc4d82f78b27c52698f5eb3216f82afaa7bbec8d5ea18b688271b77bca1b45bf7f7390457f350ff895d08383e9','sync','ak',0,0,X'18aa6c2f5a8e9b62507da7704d23e9be20024dc6','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(47,540009248.76412105561,540009248.76412105561,X'3c585604e87f855973731fea83e21fab9392d2fc',X'e6aae5fcf4d720683edab9804f620cbc0844265b',NULL,1,1,1,X'd27cb1777d93737af194a9519993b10547ff9fb7',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000c170a23ce3d3cd4a1222c03f0ea8890166c00c93164e1983fd7909aca50e2ae8ffffffffffffffff7b3317adc49eb302a6a2416ccebc3ed650c60e631280173b752976323a8d490396416881182cfe0387f7959197159b6c7b0df1ace555b516d36b9c5228e0b0025a0c7d201b0748edf9998fb088c25e03066c0cb20792b2b07e79e9c02733f40afa59a7f9105c8ac42f97a9e1f4e80a19acb08eb5ca5d0a30903c6f679e4d9be4d454638383349df0a2e4cead880e0832015fe07cbd06375d871cb032d83275ae059ee97c36e405f682bc011259350c85c752bc61ce592fb61de41e3179226506c3fffd9da27132b2cb71f9d49caaf5a1e99f28c1f3928c89bd0188525506cb163482d7b7cefae89bf34fb3a8f866b8f8bccec971bf712b6f9d4ac9d78f30bb0208530059745daa284947c12a87ced30c553a23fd9eed2fb5d96ffd76b48d383e529afbe2e8ea55b80ee31b9f0d8226e6f35ba9992f76f6ab95489ef9c235c099d6e56e5b6b680fc6c5658e5d897135f7db2205710db05eff5c37522eaa673b02a14efd84d014ca7a64f0c6d71907fd685cf3ff979a97c31310eb92f630fe90c49afc2969698aecdeaa4f915cd2929bfe93162c45ec84b17e8b2f12f6cbfb4543b783c7fccf98c561c16ab194cc2c1d4904ca42c000233bbbdf5ddb02f64a49559f8bc2cef64b546dbff37d2cdb2968c1aeb180b9f763e5e29cc7f707c3366bfe6d504209c779d3327b6feb57eb4f886d99018b9bdee2ad48fb6d30268983c798c548d710ed013ff46ab2b14d8a745933d63db4fd182fac03f59cda95be57bf25545a34b08e3549466bfe6963a64d6b0ce010cd71deb6329166d009a7c5a026bb7f6a83886da9d80f47cb76e19a65944d45167d9f8315336d0f88049cc3b560d6607594b809fd8bfd7e061d8d9f1ca89bea2550c7b2f888b262097c457925f8da3e3e0fe7453f933aef93bf37691fd7d7f7acec3ae246a3d93caad8d72585eaaf4328a6ae042a83789f7c2fbedf8bc3a42ded6ad17326d04cf5595bd24ef6c7cff212f4bbbd069c8f4fad6890018450834c8f0b6119f7ec11b67d1228e3986011c951c170fc374a61af04d4cccdc3fdd72620556211f08dd44d75dcf809001f3a1996c523c07543c8bd7c0290c69d93a6201ce6b23bc0dff840bc4782c4ad4f4d334e8b768749f092f0fb328165632b0e466bfe85e9631c977df38587eefb18c960029fcc6220bddbc071b71533cfd4cb973521ea195c5457b60d6a408dc8f2b8045b41591c6d90da2181f08ec5aed48189414e3f85f24e8035e52ed9d0e774a8222d7090bbd3ced9b447317d5c80a2dc51cbe443d3eb68011ee2e5f5e48750da4734cbb4bd6232738263c08697622c272bef6722455738b8e1785c20201ef6665b63f5cf5a4387f2e7eadaf83640f2f07008e122f68fd57cc8973242f6f1b46fe677b0dc2729afb0cde9f2b1fe493bf732b0d6de893cce154768da1c2bf6e452ad94ee7bd1838beb6965506c11084f5ce5b93f35a78f13f1f943d59d03147105c212d9a91164e532fe5f1f48d60370a8342a6a4a793ee7903bf063de906ce5ed1ee6e1c4665af81e6d64d46a56cdac678194e6712365108261f4124b36b8cf4a2f21e5a9813b0d','sync','ak',0,0,X'd8f8ecd1e06ddd14fae661920e8162abd41b0b2f','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(48,540009248.83140194415,540009248.83140194415,X'3c585604e87f855973731fea83e21fab9392d2fc',X'416a44e9737de60ae5c6a67953c9aa481883d378',NULL,1,1,1,X'2ceb76e29c9442f200885895f43473ccdbb99288',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'0300008006000000280000005c6781d080530e1375e46ab826888d940d01cae875642cdddb7314631a1e51c9ffffffffffffffff9333f1e3f9c38f3cbd865a2ec3078250ec6629b85f5cced15a761c5040cda8d9671c6199c476606521fdd74a75f2576901071e9c9fb683be514e51c128aaa77d9f12f36df8b87aa18f2a39af838296cfdf575e84ae3072f683c5885259beb38371d7c2392d51551fbfc63f274e5064c41b4f70f89aa97dc5f44987e14cab51589bca96bdc120a2637b982f79dbb24b1b717a23cd34d48c1545be0d86c0261bf3326259dac7d68e2a2c1d514433c11b1528ed4854136f9a779bf91eb319312249cdfde3bcd236836d722d357888a668145d68a960bcce4ae6b601a34ba655370570c6897a30294933f6e1c1ce8dfdf20404e73cac04698733be9811a5148403eb692ffd07ec6e2faad3544b742f4f905202a59e78d27339dc800d409c1d30ee55b3dd768ab4ff0d7f646f59af90e58b569f7d12dd52bbe31fc9c0ab7b8e99882c5ef86c426c03d4348aa0c9b458edfb69d0f7514f1827bcdb181c77d3e3417d7db2df1c145f5e45766a2bd4fe1d45bd5c2d191645dd644660087751feeab03d453063342b0ed60f4f47ac811d8e3b03592b10990f634a5f5dc00723f47f784870863064942f707928ee8d046d14a2b7e379d3bb8227e254a9a01d8b2c2836ba10b8303e4eadce068391b258b3f0fc9e9ba607e0fb41d2ef254f2a0edfc71dfb95cf56e16fd45db825bc0334c447a4a630ba3323a4859dee02e0eb4f0a6c4b977e7b26014ba32cf6acf7c4689ba6899624783e0c64dcc875121eeba60255ced4efa20de602952040d9170dfb2728ccb1185d209d326f28c60291610f7821adc79ffc4a978a9e211057cc8a476a6f666401b95da1b744cb0384c918fe29ded64026e6b5fce99cb20ab221d737718717153f3dc557b1c1437cff61b0c9e5a9d92975b090f4a49f8e09a01032d76db33f9d90172600db2ebd777f9c4fb265d1885c0a284b636c6c74c0856ec0c0f3e2660072c68e37c25561cfefcf6a17fb7fe883e7ade402d22f8f8c122298b0c855d4a733341f2e911d0898c479264ebc27e06fc859ebbf050db5f93e45d28168debab0e7b365bc71d7353f4a9ab121c382b8c88e7f815200a7335159ad62c7fbfea8edc7a73ef1a487f278de69067709f5440cfa49e361e2ed0e21c9136ad72312b03dc8e7324d79806d587ef5727dc74c3f6cd310239149b72371ba07a2b6d0b1c5e2d3a0ebef180248228c6135911c5fc9815fe33f12f3eadd46499c184fcf512a8de2ab158a051984aece4c7f06bb0b6ae0ee0e6da8c97f30d9169c20b5346e557b5c3858db359a048616c61d27b50d661f0d95e5befd18a6a7c29fd84280ebb3bfb7a45498866972786e187d6e4c45275e884f4bde2d4af48f655e46cb1c3539f1c2b55229ef5b47f173ef603cb8a10710ff97b49815ceffe96207565c82de39c4f0caf19d514a2d914192d60881aef1a412c553bfe481cf3b94db57b16393a5cb55c723aee7f3361a52feb80f1682b9d126feaef5bbac6bd5c47822a156d892eacc94fe2f0d91cea7738bab503b626af674dcc1177317e9e2b58719c91d77b6dcc7dc5525c4000cc8cc36323f0a3ccf46c199f8ca475d59841a34','sync','ak',0,0,X'e400d1472cde60a637898b247a3cfe6e385b5d19','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(49,540009248.87445402146,540009248.87445402146,X'3c585604e87f855973731fea83e21fab9392d2fc',X'6634f5d1c2b1cb7d347d3e9a38ec7f7c5fccb905',NULL,1,1,1,X'427e71398059645d6e9f92db62204320c200cabd',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'030000800600000028000000ed106bf0ae12db4c11621e6d8690bd578ef6f58158670286fb027e370fca5ea5ffffffffffffffffa2d533c2fafd900a257a464d6b3a700a99133cc8e1cea0018e6a8932cefe8e997217f3c23c6c7675025a50c90e7ce733797103387433f57757bd3ba48cdbe1646cb302dcef1ad7cad96ca080efe4762a93b290f43b4dedfc9b74fe2d089a2411b780e2b253f789d905c76d2a4c5844604fdf687e89e2db428c87267dec1a18fba4e50ab30a3a789e66604ae858f307cb99d488d136f89a8aeaa2641a217769646b47cc7afaf7d994ca1ddd2c76b07af4266c0ecf53db58f1f6800ff6fe426f4767646378e91ba2ae9d7228a6e8ec994d41963d15314970bc791df5558ef6fc6655a0aa2d149eb3789cabdd6de95be2c8693e6dd14cfb130a5f0856a9f6863064a0d38fe1a369919c9b8e898eeec286fa04a0f279fbcf3273adfbf3013a375f70117b526d98326bbb0b06aa88a0ba8fe6c45645da7012f8ab88eb28608eee9fff6106e3d3c200e0660190d30728493f1ec08ca8e7692fb94bd3a580f138aeee2dc71cd7d94631acdb0372bf670575514de4f4575d58c7b54f7709f2d0f8be6d517faac1ea1dda117106bfe8fb8b1c218180b050873b9af4a2464aad0385d5e509d69c647684f2babeb58f4ae01972c1f92e5839f6244a3bb7beaba845bf74e3edd6fdbf2c19b4ff6473686fa7a10e86d2053a4a22f7a2b65ac7a13fc60d5941a1b750aefeb1fa34f57f1d2ed3e0e65b15b5f0eb20784fd81fefdee3f8f94d33d74708ef7514c404ab7cdafabc0b6b46bdcd9cefa8d27f99771d5bfcd71a0476e145be30b134680531a4a7035f4aa297c9c74f112fc9c72f40597ce148678a269d0307dbe1bf36f31241270a2812a3ee6622cf98fc572ef9ab3c314866898549cb08dbff09bc9b8516a7aad4f0ec1db11c299b3b9459daddf13c63b51a4c40f882a4717cae396809893cc9625c38e9da0ea382129797ae9900a00a83f6e6aa5488ba51f1ea69384a090e5399f03b8ac14e8157d527bfdb999b4613ce384555602d0652440160dbb04afa8176c5019617be600bb0d2d05c9f8c54681c49573218c597701d0cedb0fb6f3bdef553237e152e98105169b97f504b0a89ef7b5638b677b97ddf3e94b0bb9cd8e0986a027da596a8dbdde42dfd64acc80acc394da394d83b8fe35a8bbd08e3e5284dc12de7654fdfe68a8dd8bea3dc9b640ab67b74cabceb2d2b7e50269dab0c9d5f661b122e818ba8a449d65b60eb23d515c20043ab9b7bc8a1d08bb7a6810dfca3ae5f22f67ef05db21fcb73d2d3769534f78849d6399dfdf3c8408b92eda7a453cd6a494a683321aefc689db232e403a8a39dc48dd46a46bc39ed3e4572f994ae0a2e79da2f4ff36fc25185872ea90776e6094c4483c4db952a5d3e10418c9d1d7c98cce7a2e4e2b1f04582ccb670c8a85ceea3c8041695f8ae1e070eb909fbf6eee0667f2f67d4e3546d638f6896eb39221d2f91144ef6a738cb0123ff54193ed01ef0a89433dbbecaf749fc555ae6bd6894039e4b2a3254074bb03798420e5d85b960a41b8a3649b50a1ce91b62ee3767c58a4fc9334e2341b24592e4309b6422dd8d642ab55c4b45aa4f6b65ee4b55c47d06bf4453cf7f98db35d6','sync','ak',0,0,X'202d96072affd57cca755b6610b5ac69b33cd5b4','','','',NULL,NULL,NULL,NULL,NULL,'');", +"INSERT INTO keys VALUES(50,540009248.93132698535,540009248.93132698535,X'3c585604e87f855973731fea83e21fab9392d2fc',X'73264e5a2eda14e1e8f06b4f6cf1342cc547d0cb',NULL,1,1,1,X'8e5f6694686a1bd054c113e7538bb416db138b27',X'da39a3ee5e6b4b0d3255bfef95601890afd80709',0,42,1024,1024,0.0,0.0,0,0,1,0,0,1,0,1,0,0,0,0,1,X'03000080060000002800000044928bf95f52dcabe33d7e16a7327095662a93ded1c4bc41faf3f6c728026004ffffffffffffffffe012d14f1ab701f72d25a9e2e74ba3bd31bb1719352485685fadd036695d0ef868f06a0aaba70a802486a4f9e8d1ea2f63ce195864547067baf38d87acf494354ec01d90aa72b03dd039cc2135361cb48985d5b5ee5aad88fe46572a4c8d8412788e99344f53df110ef8d4eed7138f671f6dd311877ec97513817f598c51febe4b5b0b6f6cb354e3adfbcd68bbd17f058e356fd1f9ed7ba2db647f504ce056d4186b08d82e7bc95cb23cb173d3d3121b1c22ae6636b58a887139b4e4406a39f5a5ba719ffd5951cbbe34d529f5b892168a031eacbddaf53b80b0a3592eec556d3acb04dd34509c506c137fe4b03f7584b306691f5ce303db471a2b5a7a54af594a5b7f057717cc927dadd6daed6e037e12f3f3bac38a42198d32930445a608558bea544349a5ab2e20949279e828e9b7e977738beabd3dbd3ab06f8af936d24cba677b204552738444ddbb3b118207041f93598db6a271ba936fe32eceed10d4eaa1496816c5c04d55ad57db909be2fda9bddc4de72078fd6440cffc7221067706cb614a906b0d447adc0679f5861c6965f2e8cf8b5af5b2a4b511b985670df87d4c89849abab347fd60172c376b82140808c2545a7b639533a18e743554a21a96424153fadba500a4eecc6409b0ea3cb877d18f5394a5dbb0e811ba519c39538eee8a87dfcbf0637a5ce6c86d7623065fe604ea7d0134a8a3bcc23f1dec9d033e8dfd9428352a9dcadccc21b37c4819dfa1733e26e3ac289997ea4bf4417963a21236e58a16e21dfad23ca73fad2ecbb6df092c27fcb8e0ff0727cecbcaa0acb33146b289de227d6091c00fb865743a6c5c3c4cc4df20e85a90dcd7041491e806d62550aaf587f842df99a170653ecbe451b3f7ae97bcbe7a2b8c905d745d5416a1c5b1a5388bdc51840a236a8c8a83464e7777443c4439e17ed2e3a4c6d0379fd369d18d99f15dc2dbcd5d17a50ee9b6373d5d3aeb5ac259dd513080766316f3f0805012fbb42fecfd26aa21404c71774aa8c28f9fa152ac9ad5d6fed40108e3a6031e496d943d499e0a8b43c2a05f20626aa5b4a801e2a1599d605aa2ca3a175d00d6c65de47f923528aa27c10d58f393c6666116eb5172a183184b0ed2efe8d79723cfec337ebf5cd45d4bac7100d32b62b9fadc32cc2f3e3ee9d9592de987173d81dc8039b8a8c7c0a81787763d2a0872547c9435bcf5a782de938a6e68a47cc47e68872d9f065116726949b741a0155b9d8020ac80518fc3439ca2a6d3ef4e6e588dc0c1b3cb3827419f8dce75bae26791f33b453dda74a96ed763e2ff711afd39baf27f6adf33fd055204bef80ff117c4170f2e73e7d5f0e6f8b4aa5c76793105f5266e6de64e3debe92fa420086fb9092f116c546b87b991ab73d2e486c605cdcdae9fbaa76772676c1fcda8aa47f220c2c7acc765b85fbdcfe48bfb6659b93fd515053090d6bb5b5f73a986acfd3bbc648434385b86855a8058fdd339de9dfed795435b9b594d19632c1f1f2ed127f3ce1152c1260953aa1a44be439bb24659cd277538f26af49b5b366cc43235022afd7847739102b486fc33353d41c8f768bf08','sync','ak',0,0,X'830dae8c17a3805e28c99f99695c2890274ccca4','','','',NULL,NULL,NULL,NULL,NULL,'');", +"CREATE TABLE tversion(rowid INTEGER PRIMARY KEY AUTOINCREMENT,version INTEGER NOT NULL,minor INTEGER NOT NULL DEFAULT 0,UNIQUE(version));", +"INSERT INTO tversion VALUES(1,10,5);", +"CREATE TABLE outgoingqueue(ckzone TEXT NOT NULL,UUID TEXT,parentKeyUUID TEXT NOT NULL,action TEXT NOT NULL,state TEXT NOT NULL,waituntil TEXT,accessgroup TEXT NOT NULL,gencount INTEGER NOT NULL DEFAULT 0,wrappedkey BLOB NOT NULL,encitem BLOB NOT NULL,encver INTEGER NOT NULL DEFAULT 0,ckrecord TEXT,pcss INTEGER,pcsk BLOB,pcsi BLOB,UNIQUE(ckzone,UUID,state));", +"CREATE TABLE incomingqueue(ckzone TEXT NOT NULL,UUID TEXT,parentKeyUUID TEXT NOT NULL,action TEXT NOT NULL,state TEXT NOT NULL,gencount INTEGER NOT NULL DEFAULT 0,wrappedkey BLOB NOT NULL,encitem BLOB NOT NULL,encver INTEGER NOT NULL DEFAULT 0,ckrecord TEXT,pcss INTEGER,pcsk BLOB,pcsi BLOB,UNIQUE(ckzone,UUID,state));", +"CREATE TABLE synckeys(ckzone TEXT NOT NULL,UUID TEXT,keyclass TEXT NOT NULL,currentkey INTEGER NOT NULL,parentKeyUUID TEXT NOT NULL,state TEXT NOT NULL,wrappedkey BLOB NOT NULL,ckrecord BLOB NOT NULL,UNIQUE(ckzone,UUID,keyclass,state));", +"CREATE TABLE ckmirror(ckzone TEXT NOT NULL,UUID TEXT,parentKeyUUID TEXT NOT NULL,gencount INTEGER NOT NULL DEFAULT 0,wrappedkey BLOB NOT NULL,encitem BLOB NOT NULL,ckrecord BLOB NOT NULL,encver INTEGER NOT NULL DEFAULT 0,wascurrent INTEGER,pcss INTEGER,pcsk BLOB,pcsi BLOB,UNIQUE(ckzone,UUID));", +"CREATE TABLE currentkeys(ckzone TEXT NOT NULL,keyclass TEXT NOT NULL,currentKeyUUID TEXT,ckrecord BLOB NOT NULL,UNIQUE(ckzone,keyclass));", +"CREATE TABLE ckstate(ckzone TEXT NOT NULL,ckzonecreated INTEGER NOT NULL DEFAULT 0,ckzonesubscribed INTEGER NOT NULL DEFAULT 0,lastfetch TEXT,changetoken TEXT,ratelimiter BLOB,lastfixup INTEGER NOT NULL DEFAULT 0,UNIQUE(ckzone));", +"CREATE TABLE item_backup(rowid INTEGER PRIMARY KEY AUTOINCREMENT,primaryKey TEXT NOT NULL,musr BLOB NOT NULL,sha1 BLOB,backupData BLOB NOT NULL,pkhh BLOB,UNIQUE(primaryKey,musr));", +"CREATE TABLE backup_keybag(rowid INTEGER PRIMARY KEY AUTOINCREMENT,publickeyHash BLOB NOT NULL,musr BLOB NOT NULL,publickey BLOB NOT NULL,agrp TEXT NOT NULL,UNIQUE(publickeyHash,musr,agrp));", +"CREATE TABLE ckmanifest(ckzone TEXT NOT NULL,gencount INTEGER NOT NULL DEFAULT 0,digest BLOB NOT NULL,signatures BLOB NOT NULL,signerID TEXT NOT NULL,leafIDs BLOB NOT NULL,peerManifests BLOB NOT NULL,currentItems BLOB NOT NULL,futureData BLOB NOT NULL,schema BLOB NOT NULL,ckrecord BLOB,UNIQUE(ckzone));", +"CREATE TABLE pending_manifest(ckzone TEXT NOT NULL,gencount INTEGER NOT NULL DEFAULT 0,digest BLOB NOT NULL,signatures BLOB NOT NULL,signerID TEXT NOT NULL,leafIDs BLOB NOT NULL,peerManifests BLOB NOT NULL,currentItems BLOB NOT NULL,futureData BLOB NOT NULL,schema BLOB NOT NULL,ckrecord BLOB,UNIQUE(ckzone));", +"CREATE TABLE ckmanifest_leaf(ckzone TEXT NOT NULL,UUID TEXT,digest BLOB NOT NULL,entryDigests BLOB NOT NULL,ckrecord BLOB,UNIQUE(ckzone,UUID));", +"CREATE TABLE backup_keyarchive(key_archive_hash TEXT NOT NULL,musr BLOB NOT NULL,key_archive TEXT NOT NULL,ckzone TEXT NOT NULL,ckrecord TEXT,archive_escrowid TEXT,UNIQUE(key_archive_hash,musr,key_archive,ckzone));", +"CREATE TABLE currentkeyarchives(key_archive_hash TEXT NOT NULL,keyarchive_name TEXT NOT NULL,UNIQUE(key_archive_hash));", +"CREATE TABLE archived_key_backup(pdmn TEXT,UUID TEXT,musr BLOB NOT NULL,agrp TEXT NOT NULL,key_archive_hash TEXT NOT NULL,archived_key TEXT NOT NULL,ckzone TEXT NOT NULL,ckrecord TEXT,archive_escrowid TEXT,UNIQUE(UUID,musr,agrp,key_archive_hash,ckzone));", +"CREATE TABLE pending_manifest_leaf(ckzone TEXT NOT NULL,UUID TEXT,digest BLOB NOT NULL,entryDigests BLOB NOT NULL,ckrecord BLOB,UNIQUE(ckzone,UUID));", +"CREATE TABLE currentitems(ckzone TEXT NOT NULL,identifier TEXT,currentItemUUID TEXT,state TEXT NOT NULL,ckrecord BLOB NOT NULL,UNIQUE(ckzone,identifier,state));", +"CREATE TABLE ckdevicestate(ckzone TEXT NOT NULL,device TEXT,peerid TEXT,circlestatus TEXT,keystate TEXT,currentTLK TEXT,currentClassA TEXT,currentClassC TEXT,ckrecord BLOB,UNIQUE(ckzone,device));", +"CREATE TABLE tlkshare(ckzone TEXT NOT NULL,UUID TEXT,senderpeerid TEXT,recvpeerid TEXT,recvpubenckey BLOB,curve INTEGER,poisoned INTEGER NOT NULL DEFAULT 0,epoch INTEGER NOT NULL DEFAULT 0,wrappedkey BLOB NOT NULL,signature BLOB,ckrecord BLOB,version INTEGER NOT NULL DEFAULT 0,UNIQUE(ckzone,UUID,senderpeerid,recvpeerid));", +"DELETE FROM sqlite_sequence;", +"INSERT INTO sqlite_sequence VALUES('tversion',1);", +"INSERT INTO sqlite_sequence VALUES('genp',50);", +"INSERT INTO sqlite_sequence VALUES('keys',50);", +"CREATE INDEX genpsync ON genp(sync);", +"CREATE INDEX genpsha1 ON genp(sha1);", +"CREATE INDEX genpmusr ON genp(musr);", +"CREATE INDEX genppersistref ON genp(persistref);", +"CREATE INDEX inetsync ON inet(sync);", +"CREATE INDEX inetsha1 ON inet(sha1);", +"CREATE INDEX inetmusr ON inet(musr);", +"CREATE INDEX inetpersistref ON inet(persistref);", +"CREATE INDEX certalis ON cert(alis);", +"CREATE INDEX certsubj ON cert(subj);", +"CREATE INDEX certskid ON cert(skid);", +"CREATE INDEX certpkhh ON cert(pkhh);", +"CREATE INDEX certsync ON cert(sync);", +"CREATE INDEX certsha1 ON cert(sha1);", +"CREATE INDEX certmusr ON cert(musr);", +"CREATE INDEX certpersistref ON cert(persistref);", +"CREATE INDEX keyskcls ON keys(kcls);", +"CREATE INDEX keysklbl ON keys(klbl);", +"CREATE INDEX keysencr ON keys(encr);", +"CREATE INDEX keysdecr ON keys(decr);", +"CREATE INDEX keysdrve ON keys(drve);", +"CREATE INDEX keyssign ON keys(sign);", +"CREATE INDEX keysvrfy ON keys(vrfy);", +"CREATE INDEX keyswrap ON keys(wrap);", +"CREATE INDEX keysunwp ON keys(unwp);", +"CREATE INDEX keyssync ON keys(sync);", +"CREATE INDEX keyssha1 ON keys(sha1);", +"CREATE INDEX keysmusr ON keys(musr);", +"CREATE INDEX keyspersistref ON keys(persistref);", +"CREATE INDEX item_backupmusr ON item_backup(musr);", +"CREATE INDEX item_backupsha1 ON item_backup(sha1);", +"CREATE INDEX item_backuppkhh ON item_backup(pkhh);", +"CREATE INDEX backup_keybagmusr ON backup_keybag(musr);", +"CREATE INDEX backup_keyarchivemusr ON backup_keyarchive(musr);", +"CREATE INDEX archived_key_backupmusr ON archived_key_backup(musr);", +"COMMIT;", +NULL +}; diff --git a/tests/secdmockaks/secdmockaks.m b/tests/secdmockaks/secdmockaks.m new file mode 100644 index 00000000..885b0f1a --- /dev/null +++ b/tests/secdmockaks/secdmockaks.m @@ -0,0 +1,429 @@ +/* + * Copyright (c) 2018 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import "SecDbKeychainItem.h" +#import "SecdTestKeychainUtilities.h" +#import "CKKS.h" +#import "SecItemPriv.h" +#import "SecItemServer.h" +#import "spi.h" +#import +#import +#import +#import +#import +#import +#import +#import "mockaks.h" + +#import "secdmock_db_version_10_5.h" + +@interface secdmockaks : XCTestCase +@property NSString *testHomeDirectory; +@property long lockCounter; +@end + +@implementation secdmockaks + ++ (void)setUp +{ + [super setUp]; + + SecCKKSDisable(); + /* + * Disable all of SOS syncing since that triggers retains of database + * and these tests muck around with the database over and over again, so + * that leads to the vnode delete kevent trap triggering for sqlite + * over and over again. + */ + SecCKKSTestSetDisableSOS(true); + securityd_init(NULL); +} + +- (void)createKeychainDirectory +{ + [[NSFileManager defaultManager] createDirectoryAtPath:[NSString stringWithFormat: @"%@/Library/Keychains", self.testHomeDirectory] withIntermediateDirectories:YES attributes:nil error:NULL]; +} + +- (void)removeHomeDirectory +{ + if (self.testHomeDirectory) { + [[NSFileManager defaultManager] removeItemAtPath:self.testHomeDirectory error:NULL]; + } +} + +- (void)setUp { + [super setUp]; + + NSString* testName = [self.name componentsSeparatedByString:@" "][1]; + testName = [testName stringByReplacingOccurrencesOfString:@"]" withString:@""]; + secnotice("ckkstest", "Beginning test %@", testName); + + // Make a new fake keychain + self.testHomeDirectory = [NSString stringWithFormat: @"/tmp/%@.%X", testName, arc4random()]; + [self createKeychainDirectory]; + + SetCustomHomeURLString((__bridge CFStringRef) self.testHomeDirectory); + SecKeychainDbReset(NULL); + + // Actually load the database. + kc_with_dbt(true, NULL, ^bool (SecDbConnectionRef dbt) { return false; }); +} + +- (void)tearDown +{ + SetCustomHomeURLString(NULL); + SecKeychainDbReset(^{ + [self removeHomeDirectory]; + self.testHomeDirectory = nil; + }); + kc_with_dbt(true, NULL, ^bool (SecDbConnectionRef dbt) { return false; }); +} + +- (void)testAddKeyByReference +{ + NSDictionary* keyParams = @{ (id)kSecAttrKeyType : (id)kSecAttrKeyTypeRSA, (id)kSecAttrKeySizeInBits : @(1024) }; + SecKeyRef key = SecKeyCreateRandomKey((__bridge CFDictionaryRef)keyParams, NULL); + NSDictionary* item = @{ (id)kSecClass : (id)kSecClassKey, + (id)kSecValueRef : (__bridge id)key, + (id)kSecAttrLabel : @"TestLabel", + (id)kSecAttrNoLegacy : @(YES) }; + + OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to add test item to keychain"); + + NSMutableDictionary* refQuery = item.mutableCopy; + [refQuery removeObjectForKey:(id)kSecValueData]; + refQuery[(id)kSecReturnRef] = @(YES); + CFTypeRef foundItem = NULL; + result = SecItemCopyMatching((__bridge CFDictionaryRef)refQuery, &foundItem); + XCTAssertEqual(result, 0, @"failed to find the reference for the item we just added in the keychain"); + + NSData* originalKeyData = (__bridge_transfer NSData*)SecKeyCopyExternalRepresentation(key, NULL); + NSData* foundKeyData = (__bridge_transfer NSData*)SecKeyCopyExternalRepresentation((SecKeyRef)foundItem, NULL); + XCTAssertEqualObjects(originalKeyData, foundKeyData, @"found key does not match the key we put in the keychain"); + + result = SecItemDelete((__bridge CFDictionaryRef)refQuery); + XCTAssertEqual(result, 0, @"failed to delete key"); +} + + +- (void)testAddDeleteItem +{ + NSDictionary* item = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrService : @"TestService", + (id)kSecAttrNoLegacy : @(YES) }; + + OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to add test item to keychain"); + + NSMutableDictionary* dataQuery = item.mutableCopy; + [dataQuery removeObjectForKey:(id)kSecValueData]; + dataQuery[(id)kSecReturnData] = @(YES); + CFTypeRef foundItem = NULL; + result = SecItemCopyMatching((__bridge CFDictionaryRef)dataQuery, &foundItem); + XCTAssertEqual(result, 0, @"failed to find the data for the item we just added in the keychain"); + + result = SecItemDelete((__bridge CFDictionaryRef)dataQuery); + XCTAssertEqual(result, 0, @"failed to delete item"); +} + + +- (void)createManyItems +{ + unsigned n; + for (n = 0; n < 50; n++) { + NSDictionary* item = @{ + (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : [NSString stringWithFormat:@"TestAccount-%u", n], + (id)kSecAttrService : @"TestService", + (id)kSecAttrNoLegacy : @(YES) + }; + OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to add test item to keychain: %u", n); + } +} + +- (void)findManyItems:(unsigned)searchLimit +{ + unsigned n; + for (n = 0; n < searchLimit; n++) { + NSDictionary* item = @{ + (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrAccount : [NSString stringWithFormat:@"TestAccount-%u", n], + (id)kSecAttrService : @"TestService", + (id)kSecAttrNoLegacy : @(YES) + }; + OSStatus result = SecItemCopyMatching((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to find test item to keychain: %u", n); + } +} + +- (void)createManyKeys +{ + unsigned n; + for (n = 0; n < 50; n++) { + NSDictionary* keyParams = @{ + (id)kSecAttrKeyType : (id)kSecAttrKeyTypeRSA, + (id)kSecAttrKeySizeInBits : @(1024) + }; + SecKeyRef key = SecKeyCreateRandomKey((__bridge CFDictionaryRef)keyParams, NULL); + NSDictionary* item = @{ (id)kSecClass : (id)kSecClassKey, + (id)kSecValueRef : (__bridge id)key, + (id)kSecAttrLabel : [NSString stringWithFormat:@"TestLabel-%u", n], + (id)kSecAttrNoLegacy : @(YES) }; + + OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to add test key to keychain: %u", n); + } +} + + +- (void)testBackupRestoreItem +{ + [self createManyItems]; + [self createManyKeys]; + + + NSDictionary* item = @{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrService : @"TestService", + (id)kSecAttrNoLegacy : @(YES) }; + + OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to add test item to keychain"); + + NSMutableDictionary* dataQuery = item.mutableCopy; + [dataQuery removeObjectForKey:(id)kSecValueData]; + dataQuery[(id)kSecReturnData] = @(YES); + CFTypeRef foundItem = NULL; + + /* + * Create backup + */ + + CFDataRef keybag = CFDataCreate(kCFAllocatorDefault, NULL, 0); + CFDataRef password = CFDataCreate(kCFAllocatorDefault, NULL, 0); + + CFDataRef backup = _SecKeychainCopyBackup(keybag, password); + XCTAssert(backup, "expected to have a backup"); + + result = SecItemDelete((__bridge CFDictionaryRef)dataQuery); + XCTAssertEqual(result, 0, @"failed to delete item"); + + result = SecItemCopyMatching((__bridge CFDictionaryRef)dataQuery, &foundItem); + XCTAssertEqual(result, errSecItemNotFound, + @"failed to find the data for the item we just added in the keychain"); + CFReleaseNull(foundItem); + + /* + * Restore backup and see that item is resurected + */ + + XCTAssertEqual(0, _SecKeychainRestoreBackup(backup, keybag, password)); + + CFReleaseNull(backup); + CFReleaseNull(password); + CFReleaseNull(keybag); + + result = SecItemCopyMatching((__bridge CFDictionaryRef)dataQuery, &foundItem); + XCTAssertEqual(result, 0, @"failed to find the data for the item we just added in the keychain"); + CFReleaseNull(foundItem); + + result = SecItemDelete((__bridge CFDictionaryRef)dataQuery); + XCTAssertEqual(result, 0, @"failed to delete item"); +} + +- (void)testCreateSampleDatabase +{ + id mock = OCMClassMock([SecMockAKS class]); + + [self createManyItems]; + [self createManyKeys]; + + /* + sleep(600); + lsof -p $(pgrep xctest) + sqlite3 database + .output mydatabase.h + .dump + + add header and footer + */ + + [self findManyItems:50]; +} + +- (void)testTestAKSGenerationCount +{ + id mock = OCMClassMock([SecMockAKS class]); + OCMStub([mock useGenerationCount]).andReturn(true); + + [self createManyItems]; + [self findManyItems:50]; +} + + +- (void)loadDatabase:(const char **)dumpstring +{ + const char *s; + unsigned n = 0; + + [self removeHomeDirectory]; + [self createKeychainDirectory]; + + NSString *path = CFBridgingRelease(__SecKeychainCopyPath()); + sqlite3 *handle = NULL; + + XCTAssertEqual(SQLITE_OK, sqlite3_open([path UTF8String], &handle), "create keychain"); + + while ((s = dumpstring[n++]) != NULL) { + char * errmsg = NULL; + XCTAssertEqual(SQLITE_OK, sqlite3_exec(handle, s, NULL, NULL, &errmsg), + "exec: %s: %s", s, errmsg); + if (errmsg) { + sqlite3_free(errmsg); + } + } + XCTAssertEqual(SQLITE_OK, sqlite3_close(handle), "close sqlite"); +} + +- (void)testUpgradeFromVersion10_5 +{ + SecKeychainDbReset(^{ + NSLog(@"resetting database"); + [self loadDatabase:secdmock_db_version10_5]; + }); + + NSLog(@"find items from old database"); + [self findManyItems:50]; +} + +- (bool)isLockedSoon:(keyclass_t)key_class +{ + if (key_class == key_class_d || key_class == key_class_dku) + return false; + if (self.lockCounter <= 0) + return true; + self.lockCounter--; + return false; +} + + +/* + * Lock in the middle of migration + */ +- (void)testUpgradeFromVersion10_5WhileLocked +{ + OSStatus result = 0; + id mock = OCMClassMock([SecMockAKS class]); +// OCMStub([mock isLocked:[OCMArg any]]).andCall(self, @selector(isLockedSoon:)); + + [[[[mock stub] andCall:@selector(isLockedSoon:) onObject:self] ignoringNonObjectArgs] isLocked:0]; + + SecKeychainDbReset(^{ + NSLog(@"resetting database"); + [self loadDatabase:secdmock_db_version10_5]; + }); + + self.lockCounter = 0; + + NSDictionary* item = @{ + (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrAccount : @"TestAccount-11", + (id)kSecAttrService : @"TestService", + (id)kSecReturnData : @YES, + (id)kSecAttrNoLegacy : @YES + }; + result = SecItemCopyMatching((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, errSecInteractionNotAllowed, @"SEP not locked?"); + + XCTAssertEqual(self.lockCounter, 0, "Device didn't lock"); + + NSLog(@"user unlock"); + [mock stopMocking]; + + + result = SecItemCopyMatching((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"can't find item"); + + + NSLog(@"find items from old database"); + [self findManyItems:50]; +} + + +- (void)testUpgradeFromVersion10_5HungSEP +{ + id mock = OCMClassMock([SecMockAKS class]); + OSStatus result = 0; + + OCMStub([mock isSEPDown]).andReturn(true); + + SecKeychainDbReset(^{ + NSLog(@"resetting database"); + [self loadDatabase:secdmock_db_version10_5]; + }); + + NSDictionary* item = @{ + (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrAccount : @"TestAccount-0", + (id)kSecAttrService : @"TestService", + (id)kSecAttrNoLegacy : @(YES) + }; + result = SecItemCopyMatching((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, errSecNotAvailable, @"SEP not down?"); + + kc_with_dbt(true, NULL, ^bool (SecDbConnectionRef dbt) { + CFErrorRef error = NULL; + int version = 0; + SecKeychainDbGetVersion(dbt, &version, &error); + XCTAssertEqual(error, NULL, "error getting version"); + XCTAssertEqual(version, 0x50a, "managed to upgrade when we shouldn't have"); + }); + + /* user got the SEP out of DFU */ + NSLog(@"SEP alive"); + [mock stopMocking]; + + result = SecItemCopyMatching((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, 0, @"failed to find test item to keychain"); + + kc_with_dbt(true, NULL, ^bool (SecDbConnectionRef dbt) { + CFErrorRef error = NULL; + int version = 0; + SecKeychainDbGetVersion(dbt, &version, &error); + XCTAssertEqual(error, NULL, "error getting version"); + XCTAssertEqual(version, 0x10b, "didnt managed to upgrade"); + }); + + NSLog(@"find items from old database"); + [self findManyItems:50]; +} + + +@end diff --git a/tests/secdmockaks/testPlistDER.m b/tests/secdmockaks/testPlistDER.m new file mode 100644 index 00000000..e2a779e1 --- /dev/null +++ b/tests/secdmockaks/testPlistDER.m @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2018 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#import +#include "utilities/der_plist.h" +#include "SecCFWrappers.h" + +@interface testPlistDER : XCTestCase +@end + +static CFDataRef CreateDERFromDictionary(CFDictionaryRef di, CFErrorRef *error) +{ + size_t size = der_sizeof_plist(di, error); + if (size == 0) + return NULL; + uint8_t *der = malloc(size); + if (der == NULL) { + return NULL; + } + der_encode_plist(di, error, der, der+size); + return CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, der, size, kCFAllocatorMalloc); +} + +@implementation testPlistDER + + +- (void)testSecPListLargeData { + NSMutableData *data = [NSMutableData dataWithLength:650000]; + memset([data mutableBytes], 'A', [data length]); + + NSDictionary *dictionary = @{ + @"BackupKey" : [NSMutableData dataWithLength:32], + @"DeviceID" : data, + @"EscrowRecord" : @"", + @"PreferIDFragmentation" : @(1), + @"PreferIDS" : @(0), + @"PreferIDSAckModel" : @(1), + @"SecurityProperties" : @{}, + @"SerialNumber" : @"C02TD01QHXCW", + @"TransportType" : @"KVS", + @"Views" : @[ + @"iCloudIdentity", + @"BackupBagV0", + @"PCS-Maildrop", + @"PCS-iMessage", + @"PCS-Notes", + @"PCS-FDE", + @"PCS-MasterKey", + @"NanoRegistry", + @"PCS-Feldspar", + @"PCS-iCloudDrive", + @"AccessoryPairing", + @"ContinuityUnlock", + @"WatchMigration", + @"PCS-Sharing", + @"PCS-Photos", + @"PCS-Escrow", + @"AppleTV", + @"HomeKit", + @"PCS-Backup", + @"PCS-CloudKit" + ], + }; + CFErrorRef error = NULL; + + size_t size = der_sizeof_plist((__bridge CFTypeRef)dictionary, &error); + XCTAssertNotEqual(size, (size_t)0, "no data?: %@", error); + CFReleaseNull(error); + + uint8_t *der = malloc(size); + uint8_t *der_end = der + size; + uint8_t *der_fin = der_encode_plist((__bridge CFTypeRef)dictionary, &error, der, der_end); + + XCTAssert(error == NULL, "error should be NULL: %@", error); + XCTAssertEqual(der, der_fin, "under/over-flow"); + + free(der); + + CFReleaseNull(error); + + NSData *outdata = (__bridge NSData *)CreateDERFromDictionary((__bridge CFTypeRef)dictionary, &error); + XCTAssertEqual(error, NULL, "error should be NULL: %@", error); + XCTAssertNotEqual(outdata, NULL, "should have data"); + +} + +- (void)testSecPListLargeDataOtherThread +{ + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{ + [self testSecPListLargeData]; + dispatch_semaphore_signal(sema); + }); + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); +} + + +@end diff --git a/trust/SecCertificatePriv.h b/trust/SecCertificatePriv.h index 93fa1641..a874f611 100644 --- a/trust/SecCertificatePriv.h +++ b/trust/SecCertificatePriv.h @@ -366,6 +366,7 @@ typedef CF_ENUM(uint32_t, SeciAuthVersion) { kSeciAuthVersion1 = 1, /* unused */ kSeciAuthVersion2 = 2, kSeciAuthVersion3 = 3, + kSeciAuthVersionSW = 4, } __OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0); /* Return the iAuth version indicated by the certificate. This function does @@ -389,6 +390,28 @@ CFArrayRef SecCertificateCopyiPhoneDeviceCAChain(void) __OSX_AVAILABLE_STARTING(__MAC_10_13, __IPHONE_11_0); +/*! + @function SecCertificateCopyExtensionValue + @abstract Return the value in an extension of a certificate. + @param certificate A reference to the certificate containing the desired extension + @param extensionOID A CFData containing the binary value of ObjectIdentifier of the + desired extension or a CFString containing the decimal value of the ObjectIdentifier. + @param isCritical On return, a boolean value representing whether the extension was critical. + @result If an extension exists in the certificate with the extensionOID, the returned CFData + is the (unparsed) Value of the extension. + @discussion If the certificate has multiple extensions with the same extension OID, the first + extension with the input OID is returned. + */ +CF_RETURNS_RETAINED +CFDataRef SecCertificateCopyExtensionValue(SecCertificateRef certificate, + CFTypeRef extensionOID, bool *isCritical) + __OSX_AVAILABLE_STARTING(__MAC_10_13_4, __IPHONE_11_3); + +/* Return a (modern) SecKeyRef for the public key embedded in the cert. */ +#if TARGET_OS_OSX + SecKeyRef SecCertificateCopyPublicKey_ios(SecCertificateRef certificate); +#endif + /* * Legacy functions (OS X only) */ diff --git a/trust/SecCertificateRequest.h b/trust/SecCertificateRequest.h index baac95d9..efb37676 100644 --- a/trust/SecCertificateRequest.h +++ b/trust/SecCertificateRequest.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2004,2008-2009,2011-2014,2016 Apple Inc. All Rights Reserved. + * Copyright (c) 2002-2017 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -33,15 +33,18 @@ #include #include #include +#include __BEGIN_DECLS -extern const void * kSecOidCommonName; -extern const void * kSecOidCountryName; -extern const void * kSecOidStateProvinceName; -extern const void * kSecOidLocalityName; -extern const void * kSecOidOrganization; -extern const void * kSecOidOrganizationalUnit; +CF_ASSUME_NONNULL_BEGIN + +extern const CFStringRef kSecOidCommonName; +extern const CFStringRef kSecOidCountryName; +extern const CFStringRef kSecOidStateProvinceName; +extern const CFStringRef kSecOidLocalityName; +extern const CFStringRef kSecOidOrganization; +extern const CFStringRef kSecOidOrganizationalUnit; extern const unsigned char SecASN1PrintableString; extern const unsigned char SecASN1UTF8String; @@ -52,9 +55,8 @@ extern const unsigned char SecASN1UTF8String; conversion to PrintableString or UTF8String needs to be possible. @param kSecCertificateKeyUsage CFNumberRef with key usage mask using kSecKeyUsage constants. - @param kSecSubjectAltName CFArrayRef of CFStringRef or CFDataRef - either dnsName or emailAddress (if contains @) or - ipAddress, ipv4 (4) or ipv6 (16) bytes + @param kSecSubjectAltName CFDictionaryRef + with keys defined below. @param kSecCSRBasicContraintsPathLen CFNumberRef if set will include basic constraints and mark it as a CA cert. If 0 <= number < 256, specifies path length, otherwise @@ -69,30 +71,56 @@ extern const unsigned char SecASN1UTF8String; as extensions with accompanying value. It is assumed that the value is a CFDataRef and is already properly encoded. This value will be placed straight into the extension value OCTET STRING. + @param kSecCMSSignHashAlgorithm CFStringRef + (Declared in SecCMS.h) + if set, determines the hash algorithm used to create the signing + request or certificate. If this parameter is omitted, the default + hash algorithm will be used (SHA1 for RSA and SHA256 for ECDSA). + Supported digest algorithm strings are defined in + SecCMS.h, e.g. kSecCMSHashingAlgorithmSHA256;. +*/ +extern const CFStringRef kSecCSRChallengePassword; +extern const CFStringRef kSecSubjectAltName; +extern const CFStringRef kSecCertificateKeyUsage; +extern const CFStringRef kSecCSRBasicContraintsPathLen; +extern const CFStringRef kSecCertificateExtensions; +extern const CFStringRef kSecCertificateExtensionsEncoded; + +/* + Keys for kSecSubjectAltName dictionaries: + @param kSecSubjectAltNameDNSName CFArrayRef or CFStringRef + The value for this key is either a CFStringRef containing a single DNS name, + or a CFArrayRef of CFStringRefs, each containing a single DNS Name. + @param kkSecSubjectAltNameEmailAddress CFArrayRef or CFStringRef + The value for this key is either a CFStringRef containing a single email + address (RFC 822 Name), or a CFArrayRef of CFStringRefs, each containing a + single email address. + @param kSecSubjectAltNameURI CFArrayRef or CFStringRef + The value for this key is either a CFStringRef containing a single URI, + or a CFArrayRef of CFStringRefs, each containing a single URI. + @param kSecSubjectAltNameNTPrincipalName CFStringRef + The value for this key is a CFStringRef containing the NTPrincipalName. */ -extern const void * kSecCSRChallengePassword; -extern const void * kSecSubjectAltName; -extern const void * kSecCertificateKeyUsage; -extern const void * kSecCSRBasicContraintsPathLen; -extern const void * kSecCertificateExtensions; -extern const void * kSecCertificateExtensionsEncoded; +extern const CFStringRef kSecSubjectAltNameDNSName; +extern const CFStringRef kSecSubjectAltNameEmailAddress; +extern const CFStringRef kSecSubjectAltNameURI; +extern const CFStringRef kSecSubjectAltNameNTPrincipalName; typedef struct { - const void *oid; /* kSecOid constant or CFDataRef with oid */ - unsigned char type; /* currently only SecASN1PrintableString */ + CFTypeRef oid; /* kSecOid constant or CFDataRef with oid */ + unsigned char type; /* currently only SecASN1PrintableString or SecASN1UTF8String */ CFTypeRef value; /* CFStringRef -> ASCII, UTF8, CFDataRef -> binary */ } SecATV; typedef SecATV *SecRDN; /* - @function SecGenerateCertificateRequest + @function SecGenerateCertificateRequestWithParameters @abstract Return a newly generated CSR for subject and keypair. @param subject RDNs in the subject - @param num Number of RDNs - @param publicKey Public key + @param paramters Parameters for the CSR generation. See above. + @param publicKey Public key (NOTE: This is unused) @param privateKey Private key - @discussion only handles RSA keypairs and uses a SHA-1 PKCS1 signature @result On success, a newly allocated CSR, otherwise NULL Example for subject: @@ -101,11 +129,32 @@ Example for subject: SecATV o[] = { { kSecOidOrganization, SecASN1PrintableString, CFSTR("Apple Inc.") }, {} }; SecRDN atvs[] = { cn, c, o, NULL }; */ -CFDataRef SecGenerateCertificateRequestWithParameters(SecRDN *subject, - CFDictionaryRef parameters, SecKeyRef publicKey, SecKeyRef privateKey) CF_RETURNS_RETAINED; +CF_RETURNS_RETAINED _Nullable +CFDataRef SecGenerateCertificateRequestWithParameters(SecRDN _Nonnull * _Nonnull subject, + CFDictionaryRef _Nullable parameters, SecKeyRef _Nullable publicKey, SecKeyRef privateKey) CF_RETURNS_RETAINED; +/* + @function SecGenerateCertificateRequest + @abstract Return a newly generated CSR for subject and keypair. + @param subject RDNs in the subject in array format + @param paramters Parameters for the CSR generation. See above. + @param publicKey Public key (NOTE: This is unused) + @param privateKey Private key + @result On success, a newly allocated CSR, otherwise NULL + @discussion The subject array contains an array of the RDNS. Each RDN is + itself an array of ATVs. Each ATV is an array of length two containing + first the OID and then the value. + +Example for subject (in Objective-C for ease of reading): + NSArray *subject = @[ + @[@[(__bridge NSString*)kSecOidCommonName, @"test"]] + @[@[(__bridge NSString*)kSecOidCountryName, @"US"]], + @[@[(__bridge NSString*)kSecOidOrganization, @"Apple Inc"]], + ]; + */ +CF_RETURNS_RETAINED _Nullable CFDataRef SecGenerateCertificateRequest(CFArrayRef subject, - CFDictionaryRef parameters, SecKeyRef publicKey, SecKeyRef privateKey) CF_RETURNS_RETAINED; + CFDictionaryRef _Nullable parameters, SecKeyRef _Nullable publicKey, SecKeyRef privateKey) CF_RETURNS_RETAINED; /* @function SecVerifyCertificateRequest @@ -115,22 +164,68 @@ CFDataRef SecGenerateCertificateRequest(CFArrayRef subject, @param subject (optional/out) encoded subject RDNs @param extensions (optional/out) encoded extensions */ -bool SecVerifyCertificateRequest(CFDataRef csr, SecKeyRef *publicKey, - CFStringRef *challenge, CFDataRef *subject, CFDataRef *extensions); +bool SecVerifyCertificateRequest(CFDataRef csr, SecKeyRef CF_RETURNS_RETAINED * _Nullable publicKey, + CFStringRef CF_RETURNS_RETAINED _Nullable * _Nullable challenge, + CFDataRef CF_RETURNS_RETAINED _Nullable * _Nullable subject, + CFDataRef CF_RETURNS_RETAINED _Nullable * _Nullable extensions); -SecCertificateRef -SecGenerateSelfSignedCertificate(CFArrayRef subject, CFDictionaryRef parameters, - SecKeyRef publicKey, SecKeyRef privateKey); -SecCertificateRef -SecIdentitySignCertificate(SecIdentityRef issuer, CFDataRef serialno, - SecKeyRef publicKey, CFTypeRef subject, CFTypeRef extensions); +/* + @function SecGenerateSelfSignedCertificate + @abstract Return a newly generated certificate for subject and keypair. + @param subject RDNs in the subject in array format + @param paramters Parameters for the CSR generation. See above. + @param publicKey Public key (NOTE: This is unused) + @param privateKey Private key + @result On success, a newly allocated certificate, otherwise NULL + @discussion The subject array contains an array of the RDNS. Each RDN is + itself an array of ATVs. Each ATV is an array of length two containing + first the OID and then the value. + + Example for subject (in Objective-C for ease of reading): + NSArray *subject = @[ + @[@[(__bridge NSString*)kSecOidCommonName, @"test"]] + @[@[(__bridge NSString*)kSecOidCountryName, @"US"]], + @[@[(__bridge NSString*)kSecOidOrganization, @"Apple Inc"]], + ]; + */ +CF_RETURNS_RETAINED _Nullable +SecCertificateRef SecGenerateSelfSignedCertificate(CFArrayRef subject, CFDictionaryRef parameters, + SecKeyRef _Nullable publicKey, SecKeyRef privateKey); + +/* + @function SecIdentitySignCertificate + @param issuer issuer's identity (certificate/private key pair) + @param serialno serial number for the issued certificate + @param publicKey public key for the issued certificate + @param subject subject name for the issued certificate + @param extensions extensions for the issued certificate + @param hashingAlgorithm hash algorithm to use for signature + @result On success, a newly allocated certificate, otherwise NULL + @discussion This call can be used in combination with SecVerifyCertificateRequest + to generate a signed certifcate from a CSR after verifying it. The outputs + of SecVerifyCertificateRequest may be passed as inputs to this function. + + The subject may be an array, as specified in SecCertificateGenerateRequest, + or a data containing an encoded subject sequence, as specified by RFC 5280. + + Supported digest algorithm strings are defined in SecCMS.h, e.g. + kSecCMSHashingAlgorithmSHA256. + */ +CF_RETURNS_RETAINED _Nullable +SecCertificateRef SecIdentitySignCertificate(SecIdentityRef issuer, CFDataRef serialno, + SecKeyRef publicKey, CFTypeRef subject, CFTypeRef _Nullable extensions); + +CF_RETURNS_RETAINED _Nullable +SecCertificateRef SecIdentitySignCertificateWithAlgorithm(SecIdentityRef issuer, CFDataRef serialno, + SecKeyRef publicKey, CFTypeRef subject, CFTypeRef _Nullable extensions, CFStringRef _Nullable hashingAlgorithm); /* PRIVATE */ -CF_RETURNS_RETAINED -CFDataRef -SecGenerateCertificateRequestSubject(SecCertificateRef ca_certificate, CFArrayRef subject); +CF_RETURNS_RETAINED _Nullable +CFDataRef SecGenerateCertificateRequestSubject(SecCertificateRef ca_certificate, CFArrayRef subject); + +CF_ASSUME_NONNULL_END __END_DECLS diff --git a/trust/SecPolicy.h b/trust/SecPolicy.h index 26bd586d..04b25e74 100644 --- a/trust/SecPolicy.h +++ b/trust/SecPolicy.h @@ -68,7 +68,7 @@ extern const CFStringRef kSecPolicyAppleEAP __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0); extern const CFStringRef kSecPolicyAppleIPsec __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0); -#if TARGET_OS_MAC && !TARGET_OS_IPHONE +#if TARGET_OS_OSX extern const CFStringRef kSecPolicyAppleiChat __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_9, __IPHONE_NA, __IPHONE_NA); #endif diff --git a/trust/SecPolicyPriv.h b/trust/SecPolicyPriv.h index 2f70ab0b..694a775d 100644 --- a/trust/SecPolicyPriv.h +++ b/trust/SecPolicyPriv.h @@ -36,6 +36,7 @@ #include #include #include +#include __BEGIN_DECLS @@ -45,67 +46,6 @@ CF_IMPLICIT_BRIDGING_ENABLED /*! @enum Policy Constants (Private) @discussion Predefined constants used to specify a policy. - @constant kSecPolicyAppleMobileStore - @constant kSecPolicyAppleTestMobileStore - @constant kSecPolicyAppleEscrowService - @constant kSecPolicyAppleProfileSigner - @constant kSecPolicyAppleQAProfileSigner - @constant kSecPolicyAppleServerAuthentication - @constant kSecPolicyAppleOTAPKISigner - @constant kSecPolicyAppleTestOTAPKISigner - @constant kSecPolicyAppleIDValidationRecordSigning - @constant kSecPolicyAppleSMPEncryption - @constant kSecPolicyAppleTestSMPEncryption - @constant kSecPolicyApplePCSEscrowService - @constant kSecPolicyApplePPQSigning - @constant kSecPolicyAppleTestPPQSigning - @constant kSecPolicyAppleSWUpdateSigning - @constant kSecPolicyApplePackageSigning - @constant kSecPolicyAppleOSXProvisioningProfileSigning - @constant kSecPolicyAppleATVVPNProfileSigning - @constant kSecPolicyAppleAST2DiagnosticsServerAuth - @constant kSecPolicyAppleEscrowProxyServerAuth - @constant kSecPolicyAppleFMiPServerAuth - @constant kSecPolicyAppleMMCService - @constant kSecPolicyAppleGSService - @constant kSecPolicyApplePPQService - @constant kSecPolicyAppleHomeKitServerAuth - @constant kSecPolicyAppleiPhoneActivation - @constant kSecPolicyAppleiPhoneDeviceCertificate - @constant kSecPolicyAppleFactoryDeviceCertificate - @constant kSecPolicyAppleiAP - @constant kSecPolicyAppleiTunesStoreURLBag - @constant kSecPolicyAppleiPhoneApplicationSigning - @constant kSecPolicyAppleiPhoneProfileApplicationSigning - @constant kSecPolicyAppleiPhoneProvisioningProfileSigning - @constant kSecPolicyAppleLockdownPairing - @constant kSecPolicyAppleURLBag - @constant kSecPolicyAppleOTATasking - @constant kSecPolicyAppleMobileAsset - @constant kSecPolicyAppleIDAuthority - @constant kSecPolicyAppleGenericApplePinned - @constant kSecPolicyAppleGenericAppleSSLPinned - @constant kSecPolicyAppleSoftwareSigning - @constant kSecPolicyAppleExternalDeveloper - @constant kSecPolicyAppleOCSPSigner - @constant kSecPolicyAppleIDSService - @constant kSecPolicyAppleIDSServiceContext - @constant kSecPolicyApplePushService - @constant kSecPolicyAppleLegacyPushService - @constant kSecPolicyAppleTVOSApplicationSigning - @constant kSecPolicyAppleUniqueDeviceIdentifierCertificate - @constant kSecPolicyAppleEscrowProxyCompatibilityServerAuth - @constant kSecPolicyAppleMMCSCompatibilityServerAuth - @constant kSecPolicyAppleSecureIOStaticAsset - @constant kSecPolicyAppleWarsaw - @constant kSecPolicyAppleiCloudSetupServerAuth - @constant kSecPolicyAppleiCloudSetupCompatibilityServerAuth - @constant kSecPolicyAppleAppTransportSecurity - @constant kSecPolicyAppleMobileSoftwareUpdate - @constant kSecPolicyAppleMobileAssetDevelopment - @constant kSecPolicyAppleBasicAttestationSystem - @constant kSecPolicyAppleBasicAttestationUser - @constant kSecPolicyAppleiPhoneVPNApplicationSigning */ extern const CFStringRef kSecPolicyAppleMobileStore __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); @@ -120,9 +60,9 @@ extern const CFStringRef kSecPolicyAppleQAProfileSigner extern const CFStringRef kSecPolicyAppleServerAuthentication __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); extern const CFStringRef kSecPolicyAppleOTAPKISigner - __OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_7_0); + __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_12, __MAC_10_13_4, __IPHONE_7_0, __IPHONE_11_3); extern const CFStringRef kSecPolicyAppleTestOTAPKISigner - __OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_7_0); + __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_12, __MAC_10_13_4, __IPHONE_7_0, __IPHONE_11_3); extern const CFStringRef kSecPolicyAppleIDValidationRecordSigningPolicy __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA, __MAC_NA, __IPHONE_7_0, __IPHONE_10_0); extern const CFStringRef kSecPolicyAppleIDValidationRecordSigning @@ -248,7 +188,10 @@ extern const CFStringRef kSecPolicyAppleiPhoneVPNApplicationSigning @constant kSecPolicyNameAppleMMCSService @constant kSecPolicyNameApplePPQService @constant kSecPolicyNameApplePushService - @constant kSecPolicyNameAppleGalaxyProviderService + @constant kSecPolicyNameAppleAIDCService + @constant kSecPolicyNameAppleMapsService + @constant kSecPolicyNameAppleHealthProviderService + @constant kSecPolicyNameAppleParsecService */ extern const CFStringRef kSecPolicyNameAppleAST2Service __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); @@ -270,8 +213,14 @@ extern const CFStringRef kSecPolicyNameApplePPQService __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); extern const CFStringRef kSecPolicyNameApplePushService __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); -extern const CFStringRef kSecPolicyNameAppleGalaxyProviderService - __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); +extern const CFStringRef kSecPolicyNameAppleAIDCService + __OSX_AVAILABLE(10.13.4) __IOS_AVAILABLE(11.3) __TVOS_AVAILABLE(11.3) __WATCHOS_AVAILABLE(4.3); +extern const CFStringRef kSecPolicyNameAppleMapsService + __OSX_AVAILABLE(10.13.4) __IOS_AVAILABLE(11.3) __TVOS_AVAILABLE(11.3) __WATCHOS_AVAILABLE(4.3); +extern const CFStringRef kSecPolicyNameAppleHealthProviderService + __OSX_AVAILABLE(10.13.4) __IOS_AVAILABLE(11.3) __TVOS_AVAILABLE(11.3) __WATCHOS_AVAILABLE(4.3); +extern const CFStringRef kSecPolicyNameAppleParsecService + __OSX_AVAILABLE(10.13.4) __IOS_AVAILABLE(11.3) __TVOS_AVAILABLE(11.3) __WATCHOS_AVAILABLE(4.3); /*! @enum Policy Value Constants @@ -979,7 +928,8 @@ SecPolicyRef SecPolicyCreateQAConfigurationProfileSigner(void); on this when it is no longer needed. */ __nullable CF_RETURNS_RETAINED -SecPolicyRef SecPolicyCreateOTAPKISigner(void); +SecPolicyRef SecPolicyCreateOTAPKISigner(void) + __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_12, __MAC_10_13_4, __IPHONE_7_0, __IPHONE_11_3); /*! @function SecPolicyCreateTestOTAPKISigner @@ -992,7 +942,8 @@ SecPolicyRef SecPolicyCreateOTAPKISigner(void); on this when it is no longer needed. */ __nullable CF_RETURNS_RETAINED -SecPolicyRef SecPolicyCreateTestOTAPKISigner(void); +SecPolicyRef SecPolicyCreateTestOTAPKISigner(void) + __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_12, __MAC_10_13_4, __IPHONE_7_0, __IPHONE_11_3); /*! @function SecPolicyCreateAppleIDValidationRecordSigningPolicy @@ -1688,17 +1639,27 @@ __nullable CF_RETURNS_RETAINED SecPolicyRef SecPolicyCreateAppleBasicAttestationUser(CFDataRef __nullable testRootHash) __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); -CF_IMPLICIT_BRIDGING_DISABLED -CF_ASSUME_NONNULL_END +/*! + @function SecPolicyCreateDemoDigitalCatalog + @abstract Returns a policy object for evaluating certificate chains for signing Digital + Catalog manifests for Demo units. + @discussion This policy uses the Basic X.509 policy with validity check and + pinning options: + * There are exactly 3 certs in the chain. + * The intermediate has common name "DemoUnit CA" + * The leaf has a marker extension with OID 1.2.840.113635.100.6.60 + @result A policy object. The caller is responsible for calling CFRelease + on this when it is no longer needed. + */ +__nullable CF_RETURNS_RETAINED +SecPolicyRef SecPolicyCreateDemoDigitalCatalogSigning(void) + __OSX_AVAILABLE(10.13.4) __IOS_AVAILABLE(11.3) __TVOS_AVAILABLE(11.3) __WATCHOS_AVAILABLE(4.3); /* * Legacy functions (OS X only) */ #if TARGET_OS_MAC && !TARGET_OS_IPHONE -CF_ASSUME_NONNULL_BEGIN -CF_IMPLICIT_BRIDGING_ENABLED - /*! @function SecPolicyCopy @abstract Returns a copy of a policy reference based on certificate type and OID. @@ -1750,12 +1711,133 @@ __nullable CF_RETURNS_RETAINED CFArrayRef SecPolicyCreateAppleTimeStampingAndRevocationPolicies(CFTypeRef policyOrArray) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_10, __MAC_10_13, __IPHONE_NA, __IPHONE_NA); +#endif /* TARGET_OS_MAC && !TARGET_OS_IPHONE */ + +/* MARK: WARNING: The following constants and functions are for project use + * within the Security project and are subject to change without warning */ + +/*! + @enum Policy Check Keys + @discussion Keys that represent various checks that can be done in a trust + policy. Use outside of the Security project at your own peril. + */ +extern const CFStringRef kSecPolicyCheckAnchorApple; +extern const CFStringRef kSecPolicyCheckAnchorSHA1; +extern const CFStringRef kSecPolicyCheckAnchorSHA256; +extern const CFStringRef kSecPolicyCheckAnchorTrusted; +extern const CFStringRef kSecPolicyCheckBasicCertificateProcessing; +extern const CFStringRef kSecPolicyCheckBasicConstraints; +extern const CFStringRef kSecPolicyCheckBasicConstraintsCA; +extern const CFStringRef kSecPolicyCheckBasicConstraintsPathLen; +extern const CFStringRef kSecPolicyCheckBlackListedKey; +extern const CFStringRef kSecPolicyCheckBlackListedLeaf; +extern const CFStringRef kSecPolicyCheckCertificatePolicy; +extern const CFStringRef kSecPolicyCheckChainLength; +extern const CFStringRef kSecPolicyCheckCriticalExtensions; +extern const CFStringRef kSecPolicyCheckEAPTrustedServerNames; +extern const CFStringRef kSecPolicyCheckEmail; +extern const CFStringRef kSecPolicyCheckExtendedKeyUsage; +extern const CFStringRef kSecPolicyCheckExtendedValidation; +extern const CFStringRef kSecPolicyCheckGrayListedKey; +extern const CFStringRef kSecPolicyCheckGrayListedLeaf; +extern const CFStringRef kSecPolicyCheckIdLinkage; +extern const CFStringRef kSecPolicyCheckIntermediateCountry; +extern const CFStringRef kSecPolicyCheckIntermediateEKU; +extern const CFStringRef kSecPolicyCheckIntermediateMarkerOid; +extern const CFStringRef kSecPolicyCheckIntermediateOrganization; +extern const CFStringRef kSecPolicyCheckIntermediateSPKISHA256; +extern const CFStringRef kSecPolicyCheckIssuerCommonName; +extern const CFStringRef kSecPolicyCheckKeySize; +extern const CFStringRef kSecPolicyCheckKeyUsage; +extern const CFStringRef kSecPolicyCheckLeafMarkerOid; +extern const CFStringRef kSecPolicyCheckLeafMarkerOidWithoutValueCheck; +extern const CFStringRef kSecPolicyCheckLeafMarkersProdAndQA; +extern const CFStringRef kSecPolicyCheckMissingIntermediate; +extern const CFStringRef kSecPolicyCheckNameConstraints; +extern const CFStringRef kSecPolicyCheckNoNetworkAccess; +extern const CFStringRef kSecPolicyCheckNonEmptySubject; +extern const CFStringRef kSecPolicyCheckNotValidBefore; +extern const CFStringRef kSecPolicyCheckPinningRequired; +extern const CFStringRef kSecPolicyCheckPolicyConstraints; +extern const CFStringRef kSecPolicyCheckRevocation; +extern const CFStringRef kSecPolicyCheckRevocationOnline; +extern const CFStringRef kSecPolicyCheckRevocationResponseRequired; +extern const CFStringRef kSecPolicyCheckSSLHostname; +extern const CFStringRef kSecPolicyCheckSignatureHashAlgorithms; +extern const CFStringRef kSecPolicyCheckSubjectCommonName; +extern const CFStringRef kSecPolicyCheckSubjectCommonNamePrefix; +extern const CFStringRef kSecPolicyCheckSubjectCommonNameTEST; +extern const CFStringRef kSecPolicyCheckSubjectOrganization; +extern const CFStringRef kSecPolicyCheckSubjectOrganizationalUnit; +extern const CFStringRef kSecPolicyCheckSystemTrustedWeakHash; +extern const CFStringRef kSecPolicyCheckSystemTrustedWeakKey; +extern const CFStringRef kSecPolicyCheckTemporalValidity; +extern const CFStringRef kSecPolicyCheckUsageConstraints; +extern const CFStringRef kSecPolicyCheckValidRoot; +extern const CFStringRef kSecPolicyCheckWeakKeySize; +extern const CFStringRef kSecPolicyCheckWeakSignature; +extern const CFStringRef kSecPolicyCheckCTRequired; + +/* Special option for checking Apple Anchors */ +extern const CFStringRef kSecPolicyAppleAnchorIncludeTestRoots; + +/* Special option for checking Prod and QA Markers */ +extern const CFStringRef kSecPolicyLeafMarkerProd; +extern const CFStringRef kSecPolicyLeafMarkerQA; + +/* Special option for checking Revocation */ +extern const CFStringRef kSecPolicyCheckRevocationOCSP; +extern const CFStringRef kSecPolicyCheckRevocationCRL; +extern const CFStringRef kSecPolicyCheckRevocationAny; + +/* Policy Names */ +extern const CFStringRef kSecPolicyNameX509Basic; +extern const CFStringRef kSecPolicyNameSSLServer; +extern const CFStringRef kSecPolicyNameSSLClient; +extern const CFStringRef kSecPolicyNameEAPServer; +extern const CFStringRef kSecPolicyNameEAPClient; +extern const CFStringRef kSecPolicyNameIPSecServer; +extern const CFStringRef kSecPolicyNameIPSecClient; +extern const CFStringRef kSecPolicyNameSMIME; +extern const CFStringRef kSecPolicyNameCodeSigning; +extern const CFStringRef kSecPolicyNameTimeStamping; +extern const CFStringRef kSecPolicyNameOCSPSigner; + +/* + * MARK: SecPolicyCheckCert functions + */ +bool SecPolicyCheckCertSSLHostname(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertEmail(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertTemporalValidity(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertWeakKeySize(SecCertificateRef cert, CFTypeRef __nullable pvcValue); +bool SecPolicyCheckCertKeyUsage(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertExtendedKeyUsage(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertSubjectCommonName(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertSubjectCommonNamePrefix(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertSubjectCommonNameTEST(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertSubjectOrganization(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertSubjectOrganizationalUnit(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertNotValidBefore(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertEAPTrustedServerNames(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertLeafMarkerOid(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertLeafMarkerOidWithoutValueCheck(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertLeafMarkersProdAndQA(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertNonEmptySubject(SecCertificateRef cert, CFTypeRef __nullable pvcValue); +bool SecPolicyCheckCertKeySize(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertWeakSignature(SecCertificateRef cert, CFTypeRef __nullable pvcValue); +bool SecPolicyCheckCertSignatureHashAlgorithms(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertCertificatePolicy(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertCriticalExtensions(SecCertificateRef cert, CFTypeRef __nullable pvcValue); +bool SecPolicyCheckCertSubjectCountry(SecCertificateRef cert, CFTypeRef pvcValue); + +void SecPolicySetName(SecPolicyRef policy, CFStringRef policyName); +__nullable CFArrayRef SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies, CFErrorRef *error); + +void SecPolicySetOptionsValue(SecPolicyRef policy, CFStringRef key, CFTypeRef value); CF_IMPLICIT_BRIDGING_DISABLED CF_ASSUME_NONNULL_END -#endif /* TARGET_OS_MAC && !TARGET_OS_IPHONE */ - __END_DECLS #endif /* !_SECURITY_SECPOLICYPRIV_H_ */ diff --git a/trust/SecTrustPriv.h b/trust/SecTrustPriv.h index a616b86a..b04be624 100644 --- a/trust/SecTrustPriv.h +++ b/trust/SecTrustPriv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2003-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -34,6 +34,7 @@ #include #include #include +#include __BEGIN_DECLS @@ -245,9 +246,35 @@ Boolean SecTrustIsExpiredOnly(SecTrustRef trust) __nullable CF_RETURNS_RETAINED CFStringRef SecTrustCopyFailureDescription(SecTrustRef trust); -OSStatus SecTrustGetOTAPKIAssetVersionNumber(int* versionNumber); +/* + @function SecTrustGetTrustStoreVersionNumber + @abstract Ask trustd what trust store version it is using. + @param error A returned error if trustd failed to answer. + @result The current version of the trust store. 0 upon failure. + */ +uint64_t SecTrustGetTrustStoreVersionNumber(CFErrorRef _Nullable * _Nullable CF_RETURNS_RETAINED error); -OSStatus SecTrustOTAPKIGetUpdatedAsset(int* didUpdateAsset); +/* + @function SecTrustOTAPKIGetUpdatedAsset + @abstract Trigger trustd to fetch a new trust supplementals asset right now. + @param error A returned error if trustd failed to update the asset. + @result The current version of the update, regardless of the success of the update. + @discussion This function blocks up to 1 minute until trustd has finished with the + asset download and update. You should use the error parameter to determine whether + the update was was successful. The current asset version is always returned. + */ +uint64_t SecTrustOTAPKIGetUpdatedAsset(CFErrorRef _Nullable * _Nullable CF_RETURNS_RETAINED error); + +/*! + @function SecTrustFlushResponseCache + @abstract Removes all OCSP responses from the per-user response cache. + @param error An optional pointer to an error object + @result A boolean value indicating whether the operation was successful. + @discussion If the error parameter is supplied, and the function returns false, + the caller is subsequently responsible for releasing the returned CFErrorRef. + */ +Boolean SecTrustFlushResponseCache(CFErrorRef _Nullable * _Nullable CF_RETURNS_RETAINED error) + __OSX_AVAILABLE(10.13.4) __IOS_AVAILABLE(11.3) __TVOS_AVAILABLE(11.3) __WATCHOS_AVAILABLE(4.3); /*! @function SecTrustSignedCertificateTimestampList @@ -387,6 +414,38 @@ OSStatus SecTrustSetPinningPolicyName(SecTrustRef trust, CFStringRef policyName) OSStatus SecTrustSetPinningException(SecTrustRef trust) __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); +/*! + @function SecTrustEvaluateWithError + @abstract Evaluates a trust reference synchronously. + @param trust A reference to the trust object to evaluate. + @param error A pointer to an error object + @result A boolean value indicating whether the certificate is trusted + @discussion This function will completely evaluate trust before returning, + possibly including network access to fetch intermediate certificates or to + perform revocation checking. Since this function can block during those + operations, you should call it from within a function that is placed on a + dispatch queue, or in a separate thread from your application's main + run loop. + If the certificate is trusted and the result is true, the error will be set to NULL. + If the certificate is not trusted or the evaluation was unable to complete, the result + will be false and the error will be set with a description of the failure. + The error contains a code for the most serious error encountered (if multiple trust + failures occurred). The localized description indicates the certificate with the most + serious problem and the type of error. The underlying error contains a localized + description of each certificate in the chain that had an error and all errors found + with that certificate. + */ +__attribute__((warn_unused_result)) bool +SecTrustEvaluateWithError(SecTrustRef trust, CFErrorRef _Nullable * _Nullable CF_RETURNS_RETAINED error) + __OSX_AVAILABLE(10.13.4) __IOS_AVAILABLE(11.3) __TVOS_AVAILABLE(11.3) __WATCHOS_AVAILABLE(4.3); + +/*! + @function SecTrustReportTLSAnalytics + @discussion This function MUST NOT be called outside of the TLS stack. +*/ +bool SecTrustReportTLSAnalytics(CFStringRef eventName, xpc_object_t eventAttributes, CFErrorRef _Nullable * _Nullable CF_RETURNS_RETAINED error) + __API_AVAILABLE(macos(10.13.4), ios(11.3), tvos(11.3), watchos(4.3)); + CF_IMPLICIT_BRIDGING_DISABLED CF_ASSUME_NONNULL_END diff --git a/trust/oids.h b/trust/oids.h new file mode 100644 index 00000000..4a1d490d --- /dev/null +++ b/trust/oids.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2005-2009,2011-2016 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + +/* + * oids.h - declaration of OID consts + * + */ + +#ifndef _SECURITY_OIDS_H_ +#define _SECURITY_OIDS_H_ + +#include +#include + +__BEGIN_DECLS + +/* This is a subset of libDER's oids.h. If the types header has + * already been included, we should skip these typedef declarations. */ +#ifndef _LIB_DER_H_ +/* + * Basic data types + */ +typedef uint8_t DERByte; +typedef size_t DERSize; + +/* + * Primary representation of a block of memory. + */ +typedef struct { + DERByte *data; + DERSize length; +} DERItem; +#endif /* _LIB_DER_H_ */ + +/* Algorithm oids. */ +extern const DERItem + oidRsa, /* PKCS1 RSA encryption, used to identify RSA keys */ + oidMd2Rsa, /* PKCS1 md2withRSAEncryption signature alg */ + oidMd4Rsa, /* PKCS1 md4withRSAEncryption signature alg */ + oidMd5Rsa, /* PKCS1 md5withRSAEncryption signature alg */ + oidSha1Rsa, /* PKCS1 sha1withRSAEncryption signature alg */ + oidSha256Rsa, /* PKCS1 sha256WithRSAEncryption signature alg */ + oidSha384Rsa, /* PKCS1 sha384WithRSAEncryption signature alg */ + oidSha512Rsa, /* PKCS1 sha512WithRSAEncryption signature alg */ + oidSha224Rsa, /* PKCS1 sha224WithRSAEncryption signature alg */ + oidEcPubKey, /* ECDH or ECDSA public key in a certificate */ + oidSha1Ecdsa, /* ECDSA with SHA1 signature alg */ + oidSha224Ecdsa, /* ECDSA with SHA224 signature alg */ + oidSha256Ecdsa, /* ECDSA with SHA256 signature alg */ + oidSha384Ecdsa, /* ECDSA with SHA384 signature alg */ + oidSha512Ecdsa, /* ECDSA with SHA512 signature alg */ + oidSha1Dsa, /* ANSI X9.57 DSA with SHA1 signature alg */ + oidMd2, /* OID_RSA_HASH 2 */ + oidMd4, /* OID_RSA_HASH 4 */ + oidMd5, /* OID_RSA_HASH 5 */ + oidSha1, /* OID_OIW_ALGORITHM 26 */ + oidSha1DsaOIW, /* OID_OIW_ALGORITHM 27 */ + oidSha1DsaCommonOIW,/* OID_OIW_ALGORITHM 28 */ + oidSha1RsaOIW, /* OID_OIW_ALGORITHM 29 */ + oidSha256, /* OID_NIST_HASHALG 1 */ + oidSha384, /* OID_NIST_HASHALG 2 */ + oidSha512, /* OID_NIST_HASHALG 3 */ + oidSha224, /* OID_NIST_HASHALG 4 */ + oidFee, /* APPLE_ALG_OID 1 */ + oidMd5Fee, /* APPLE_ALG_OID 3 */ + oidSha1Fee, /* APPLE_ALG_OID 4 */ + oidEcPrime192v1, /* OID_EC_CURVE 1 prime192v1/secp192r1/ansiX9p192r1*/ + oidEcPrime256v1, /* OID_EC_CURVE 7 prime256v1/secp256r1*/ + oidAnsip384r1, /* OID_CERTICOM_EC_CURVE 34 ansip384r1/secp384r1*/ + oidAnsip521r1; /* OID_CERTICOM_EC_CURVE 35 ansip521r1/secp521r1*/ + +/* Standard X.509 Cert and CRL extensions. */ +extern const DERItem + oidSubjectKeyIdentifier, + oidKeyUsage, + oidPrivateKeyUsagePeriod, + oidSubjectAltName, + oidIssuerAltName, + oidBasicConstraints, + oidNameConstraints, + oidCrlDistributionPoints, + oidCertificatePolicies, + oidAnyPolicy, + oidPolicyMappings, + oidAuthorityKeyIdentifier, + oidPolicyConstraints, + oidExtendedKeyUsage, + oidAnyExtendedKeyUsage, + oidInhibitAnyPolicy, + oidAuthorityInfoAccess, + oidSubjectInfoAccess, + oidAdOCSP, + oidAdCAIssuer, + oidNetscapeCertType, + oidEntrustVersInfo, + oidMSNTPrincipalName; + +/* Policy Qualifier IDs for Internet policy qualifiers. */ +extern const DERItem + oidQtCps, + oidQtUNotice; + +/* X.501 Name IDs. */ +extern const DERItem + oidCommonName, + oidCountryName, + oidLocalityName, + oidStateOrProvinceName, + oidOrganizationName, + oidOrganizationalUnitName, + oidDescription, + oidEmailAddress, + oidFriendlyName, + oidLocalKeyId; + +/* X.509 Extended Key Usages */ +extern const DERItem + oidExtendedKeyUsageServerAuth, + oidExtendedKeyUsageClientAuth, + oidExtendedKeyUsageCodeSigning, + oidExtendedKeyUsageEmailProtection, + oidExtendedKeyUsageTimeStamping, + oidExtendedKeyUsageOCSPSigning, + oidExtendedKeyUsageIPSec, + oidExtendedKeyUsageMicrosoftSGC, + oidExtendedKeyUsageNetscapeSGC; + +/* Google Certificate Transparency OIDs */ +extern const DERItem + oidGoogleEmbeddedSignedCertificateTimestamp, + oidGoogleOCSPSignedCertificateTimestamp; + +__END_DECLS + +#endif /* _SECURITY_OIDS_H_ */ diff --git a/xcconfig/PlatformFeatures.xcconfig b/xcconfig/PlatformFeatures.xcconfig index 3c5e655d..872aec9f 100644 --- a/xcconfig/PlatformFeatures.xcconfig +++ b/xcconfig/PlatformFeatures.xcconfig @@ -2,7 +2,7 @@ #include "xcconfig/PlatformLibraries.xcconfig" PLATFORM_STR = "unknown" -PLATFORM_STR[sdk=macosx*] = "macos" +PLATFORM_STR[sdk=macosx*] = "macOS" PLATFORM_STR[sdk=iphoneos*] = "iphone" PLATFORM_STR[sdk=watchos*] = "watch" PLATFORM_STR[sdk=appletvos*] = "tv" diff --git a/xcconfig/PlatformLibraries.xcconfig b/xcconfig/PlatformLibraries.xcconfig index 3d2828a7..3a36cf4c 100644 --- a/xcconfig/PlatformLibraries.xcconfig +++ b/xcconfig/PlatformLibraries.xcconfig @@ -1,5 +1,5 @@ -AOSKIT_FRAMEWORK[sdk=macosx*] = -framework AOSAccounts +AOSKIT_FRAMEWORK[sdk=macosx*] = -weak_framework AOSAccounts -weak_framework AOSAccountsLite APPLE_AKS_LIBRARY[sdk=macosx*] = -L$(SDKROOT)/usr/local/lib -laks -framework MobileKeyBag APPLE_AKS_LIBRARY[sdk=iphoneos*] = -L$(SDKROOT)/usr/local/lib -laks -framework MobileKeyBag APPLE_AKS_LIBRARY[sdk=watchos*] = -L$(SDKROOT)/usr/local/lib -laks -framework MobileKeyBag @@ -11,6 +11,12 @@ OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT[sdk=macosx*] = -lDiagnosticMessagesClien OTHER_LDFLAGS_LIBCMS[sdk=embedded*] = -lCMS OTHER_LDFLAGS_MOBILEGESTALT[sdk=embedded*] = -lMobileGestalt +OTHER_LDFLAGS_CRASHREPORTER[sdk=embedded] = -framework CrashReporterSupport +OTHER_LDFLAGS_CRASHREPORTER[sdk=macos*] = -framework CrashReporterSupport + +OTHER_CODE_SIGN_FLAGS_LIBRARY_VALIDATION = -o library +OTHER_CODE_SIGN_FLAGS_LIBRARY_VALIDATION[sdk=*simulator*] = + // // Play games to avoid issues with bridge trains // @@ -27,6 +33,26 @@ OTHER_LDFLAGS_CLOUDKIT_BRIDGE_NO = -framework CloudKit OTHER_LDFLAGS_CLOUDKIT_BRIDGE_YES = OTHER_LDFLAGS_CLOUDKIT = $(OTHER_LDFLAGS_CLOUDKIT_BRIDGE_$(BRIDGE)) +OTHER_LDFLAGS_PREQUELITE_BRIDGE_NO = -l prequelite +OTHER_LDFLAGS_PREQUELITE_BRIDGE_YES = +OTHER_LDFLAGS_PREQUELITE = $(OTHER_LDFLAGS_PREQUELITE_BRIDGE_$(BRIDGE)) + +OTHER_LDFLAGS_ACCOUNTS_BRIDGE_NO = -framework Accounts +OTHER_LDFLAGS_ACCOUNTS_BRIDGE_YES = +OTHER_LDFLAGS_ACCOUNTS = $(OTHER_LDFLAGS_ACCOUNTS_BRIDGE_$(BRIDGE)) + +OTHER_LDFLAGS_APPLEACCOUNT_IOS_NO = -framework AppleAccount +OTHER_LDFLAGS_APPLEACCOUNT_IOS_YES = + +OTHER_LDFLAGS_APPLEACCOUNT[sdk=iphoneos*] = $(OTHER_LDFLAGS_APPLEACCOUNT_IOS_$(BRIDGE)) +OTHER_LDFLAGS_APPLEACCOUNT[sdk=iphonesimulator*] = $(OTHER_LDFLAGS_APPLEACCOUNT_IOS_$(BRIDGE)) +OTHER_LDFLAGS_APPLEACCOUNT[sdk=appletv*] = $(OTHER_LDFLAGS_APPLEACCOUNT_IOS_$(BRIDGE)) +OTHER_LDFLAGS_APPLEACCOUNT[sdk=watchos*] = $(OTHER_LDFLAGS_APPLEACCOUNT_IOS_$(BRIDGE)) + +OTHER_LDFLAGS_CORECDP_BRIDGE_NO = -framework CoreCDP +OTHER_LDFLAGS_CORECDP_BRIDGE_YES = +OTHER_LDFLAGS_CORECDP = $(OTHER_LDFLAGS_CORECDP_BRIDGE_$(BRIDGE)) + // The bridge appears to support protocol buffers. OTHER_LDFLAGS_PROTOBUF = -framework ProtocolBuffer @@ -52,3 +78,9 @@ OTHER_LDFLAGS_MOBILEASSET = $(OTHER_LDFLAGS_MOBILEASSET_BRIDGE_$(BRIDGE)) OTHER_LDFLAGS_SECURITYFOUNDATION_BRIDGE_NO = -framework SecurityFoundation OTHER_LDFLAGS_SECURITYFOUNDATION_BRIDGE_YES = OTHER_LDFLAGS_SECURITYFOUNDATION = $(OTHER_LDFLAGS_SECURITYFOUNDATION_BRIDGE_$(BRIDGE)) + +// Breaks the BaseSystem: fixing in Re-enable IMCore autosysdiagnose capture to securityd +//OTHER_LDFLAGS_IMCORE_BRIDGE_NO = -framework IMCore +//OTHER_LDFLAGS_IMCORE_BRIDGE_YES = +OTHER_LDFLAGS_IMCORE = $(OTHER_LDFLAGS_IMCORE_BRIDGE_$(BRIDGE)) +OTHER_LDFLAGS_IMCORE[sdk=appletv*] = diff --git a/xcconfig/Security.xcconfig b/xcconfig/Security.xcconfig index 6a48d3cb..a9a2b0a0 100644 --- a/xcconfig/Security.xcconfig +++ b/xcconfig/Security.xcconfig @@ -1,23 +1,38 @@ SYSTEM_FRAMEWORK_SEARCH_PATHS = $(inherited) $(SDKROOT)/$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks +MACOSX_DEPLOYMENT_TARGET = 10.13.4 + OTHER_CFLAGS = -isystem $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders -fconstant-cfstrings -HEADER_SEARCH_PATHS = $(PROJECT_DIR) $(PROJECT_DIR)/OSX/libsecurity_keychain/libDER $(PROJECT_DIR)/OSX/libsecurity_asn1 $(PROJECT_DIR)/OSX/sec/ProjectHeaders $(PROJECT_DIR)/OSX/sec $(PROJECT_DIR)/OSX/utilities $(PROJECT_DIR)/OSX $(inherited) +HEADER_SYMLINKS = $(PROJECT_DIR)/header_symlinks +HEADER_SYMLINKS[sdk=macosx*] = $(PROJECT_DIR)/header_symlinks $(PROJECT_DIR)/header_symlinks/macOS +HEADER_SYMLINKS[sdk=embedded*] = $(PROJECT_DIR)/header_symlinks $(PROJECT_DIR)/header_symlinks/iOS + +HEADER_SEARCH_PATHS = $(PROJECT_DIR) $(HEADER_SYMLINKS) $(SDKROOT)/usr/local/include/security_libDER $(PROJECT_DIR)/OSX/libsecurity_asn1 $(PROJECT_DIR)/OSX/sec/ProjectHeaders $(PROJECT_DIR)/OSX/sec $(PROJECT_DIR)/OSX/utilities $(PROJECT_DIR)/OSX $(inherited) ARCHS[sdk=macosx*] = $(ARCHS_STANDARD) +LIBRARY_SEARCH_PATHS = $(inherited) $(SDKROOT)/usr/local/lib/security_libDER + #include "xcconfig/PlatformFeatures.xcconfig" #include "xcconfig/Version.xcconfig" // Note that the 'Settings' view in Xcode will display the wrong values for platform-dependent settings // Refer to the actual build command for final computed value -GCC_PREPROCESSOR_DEFINITIONS = __KEYCHAINCORE__=1 CORECRYPTO_DONOT_USE_TRANSPARENT_UNION=1 OCTAGON=$(OCTAGON_ON) PLATFORM=$(PLATFORM_STR) SECURITY_BUILD_VERSION=\"$(SECURITY_BUILD_VERSION)\" $(GCC_PREPROCESSOR_DEFINITIONS) +GCC_PREPROCESSOR_DEFINITIONS = __KEYCHAINCORE__=1 CORECRYPTO_DONOT_USE_TRANSPARENT_UNION=1 OCTAGON=$(OCTAGON_ON) PLATFORM=$(PLATFORM_STR) SECURITY_BUILD_VERSION="\"$(SECURITY_BUILD_VERSION)\"" $(GCC_PREPROCESSOR_DEFINITIONS) SECURITY_FUZZER_BASE_DIR = /AppleInternal/CoreOS/Fuzzers/Security WARNING_CFLAGS = -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wno-error=deprecated-declarations -Wno-error=implicit-retain-self -Wno-error=#warnings -Wno-error=unused-function -Wno-error=unused-variable -WARNING_CFLAGS[sdk=iphone*] = $(WARNING_CFLAGS) -Wformat=2 -WARNING_CFLAGS[sdk=tvos*] = $(WARNING_CFLAGS) -Wformat=2 -WARNING_CFLAGS[sdk=watchos*] = $(WARNING_CFLAGS) -Wformat=2 +WARNING_CFLAGS[sdk=embedded*] = $(WARNING_CFLAGS) -Wformat=2 + +// The SOS headers get copied into a specific directory in the framework during their own copy files phase. +// This breaks TAPI during the build, which does INSTALLHDR -> INSTALLAPI without running any copy files phases. +// So, we must include each file as a 'public' header in the TAPI command. +OTHER_TAPI_FLAGS_SOS = -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoCollections.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSCircleDer.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSGenCount.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSPiggyback.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircleInternal.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSTypes.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSViews.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.h -extra-public-header $(PROJECT_DIR)/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupSliceKeyBag.h + +// This isn't OTHER_TAPI_FLAGS because we'll mess up other, non-Security.framework frameworks in the project +// Please don't add any more headers here. +OTHER_TAPI_FLAGS_SECURITY_FRAMEWORK = -D SECURITY_PROJECT_TAPI_HACKS=1 -extra-private-header $(PROJECT_DIR)/OSX/sec/Security/SecTrustInternal.h $(OTHER_TAPI_FLAGS_SOS) diff --git a/xcconfig/lib_ios.xcconfig b/xcconfig/lib_ios.xcconfig index f848c535..3c1e5eb9 100644 --- a/xcconfig/lib_ios.xcconfig +++ b/xcconfig/lib_ios.xcconfig @@ -5,7 +5,7 @@ EXECUTABLE_EXTENSION = a CODE_SIGN_IDENTITY = -HEADER_SEARCH_PATHS = $(inherited) $(PROJECT_DIR) $(PROJECT_DIR)/header_symlinks $(PROJECT_DIR)/OSX/sec/ProjectHeaders $(PROJECT_DIR)/OSX/utilities $(PROJECT_DIR)/OSX/sec/ipc $(PROJECT_DIR)/OSX/sectask $(PROJECT_DIR)/OSX/libsecurity_asn1 $(PROJECT_DIR)/OSX/libsecurity_ssl $(PROJECT_DIR)/OSX/regressions $(PROJECT_DIR)/OSX/ibsecurity_keychain/libDER $(BUILT_PRODUCTS_DIR)/usr/local/include +HEADER_SEARCH_PATHS = $(inherited) $(PROJECT_DIR) $(PROJECT_DIR)/header_symlinks $(PROJECT_DIR)/OSX/sec/ProjectHeaders $(PROJECT_DIR)/OSX/utilities $(PROJECT_DIR)/OSX/sec/ipc $(PROJECT_DIR)/OSX/sectask $(PROJECT_DIR)/OSX/libsecurity_asn1 $(PROJECT_DIR)/OSX/libsecurity_ssl $(PROJECT_DIR)/OSX/regressions $(SDKROOT)/usr/local/include/security_libDER $(BUILT_PRODUCTS_DIR)/usr/local/include HEADER_SEARCH_PATHS[sdk=macosx*] = $(inherited) $(PROJECT_DIR)/OSX/libsecurity_smime $(PROJECT_DIR)/header_symlinks/macOS $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers HEADER_SEARCH_PATHS[sdk=embedded*] = $(inherited) $(PROJECT_DIR)/libsecurity_smime $(PROJECT_DIR)/OSX/sec/sectask $(PROJECT_DIR)/header_symlinks/iOS diff --git a/xcconfig/macos_legacy_lib.xcconfig b/xcconfig/macos_legacy_lib.xcconfig index 34d7d2c9..c2b91129 100644 --- a/xcconfig/macos_legacy_lib.xcconfig +++ b/xcconfig/macos_legacy_lib.xcconfig @@ -5,7 +5,7 @@ EXECUTABLE_PREFIX = lib SUPPORTED_PLATFORMS = macosx ARCHS = $(ARCHS_STANDARD_32_64_BIT) -HEADER_SEARCH_PATHS = $(PROJECT_DIR)/OSX/libsecurity_cssm/lib/ $(PROJECT_DIR)/header_symlinks/macOS/ $(PROJECT_DIR)/OSX/include/ $(inherited) $(PROJECT_DIR) $(PROJECT_DIR)/OSX/libsecurity_apple_csp/open_ssl $(PROJECT_DIR)/OSX/lib$(PRODUCT_NAME)/lib/ +HEADER_SEARCH_PATHS = $(PROJECT_DIR)/OSX/libsecurity_cssm/lib/ $(PROJECT_DIR)/header_symlinks/ $(PROJECT_DIR)/header_symlinks/macOS/ $(PROJECT_DIR)/OSX/include/ $(inherited) $(PROJECT_DIR) $(PROJECT_DIR)/OSX/libsecurity_apple_csp/open_ssl $(PROJECT_DIR)/OSX/lib$(PRODUCT_NAME)/lib/ STRIP_INSTALLED_PRODUCT = NO COPY_PHASE_STRIP = NO